WIP
0
games/zelda.rom → games/Zelda II.rom
vendored
455
static/css/main.css
vendored
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
#gamebody {
|
||||
display: block;
|
||||
width: 556px;
|
||||
height: 278px;
|
||||
background-color: #edf1f0;
|
||||
-moz-border-radius: 30px;
|
||||
-webkit-border-radius: 30px;
|
||||
border-radius: 30px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position: fixed;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
-webkit-box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
|
||||
#circle-pad-holder {
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position: absolute;
|
||||
top: 155px;
|
||||
left: 30px;
|
||||
background-color: #eaebeb;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-webkit-box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
|
||||
#circle-pad {
|
||||
display: block;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
position: absolute;
|
||||
/* transform: translate(-50%, -50%);
|
||||
-moz-transform: translate(-50%, -50%);
|
||||
-webkit-transform: translate(-50%, -50%); */
|
||||
top: 15px;
|
||||
left: 15px;
|
||||
background-color: #00f;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-webkit-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
|
||||
.dpad {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
background-color: #e4e5e5;
|
||||
border: 2px solid rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
|
||||
#btn-up {
|
||||
top: 18px;
|
||||
left: 50%;
|
||||
border-bottom: 0px;
|
||||
transform: translateX(-50%);
|
||||
-webkit-transform: translateX(-50%);
|
||||
-moz-transform: translateX(-50%);
|
||||
}
|
||||
|
||||
#btn-down {
|
||||
bottom: 18px;
|
||||
left: 50%;
|
||||
border-top: 0px;
|
||||
transform: translateX(-50%);
|
||||
-webkit-transform: translateX(-50%);
|
||||
-moz-transform: translateX(-50%);
|
||||
}
|
||||
|
||||
|
||||
#btn-left {
|
||||
left: 18px;
|
||||
top: 50%;
|
||||
border-right: 0px;
|
||||
transform: translateY(-50%);
|
||||
-webkit-transform: translateY(-50%);
|
||||
-moz-transform: translateY(-50%);
|
||||
}
|
||||
|
||||
#btn-right {
|
||||
right: 18px;
|
||||
top: 50%;
|
||||
border-left: 0px;
|
||||
transform: translateY(-50%);
|
||||
-webkit-transform: translateY(-50%);
|
||||
-moz-transform: translateY(-50%);
|
||||
}
|
||||
|
||||
|
||||
#bottom-screen {
|
||||
display: block;
|
||||
width: 256px;
|
||||
height: 240px;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 150px;
|
||||
overflow: hidden;
|
||||
background-color: #333;
|
||||
|
||||
-moz-border-radius: 5px 5px 5px 5px;
|
||||
-webkit-border-radius: 5px 5px 5px 5px;
|
||||
border-radius: 5px 5px 5px 5px;
|
||||
|
||||
-webkit-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
#color-button-holder {
|
||||
display: block;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
position: absolute;
|
||||
top: 135px;
|
||||
left: 425px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
width: 40px;
|
||||
height: 30px;
|
||||
position: absolute;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-webkit-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
|
||||
.btn-big {
|
||||
display: block;
|
||||
padding-top: 5px;
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
height: 25px;
|
||||
position: absolute;
|
||||
-moz-border-radius: 25px;
|
||||
-webkit-border-radius: 25px;
|
||||
border-radius: 25px;
|
||||
-webkit-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
#btn-load {
|
||||
top: 30px;
|
||||
left: 435px;
|
||||
background-color: #f5a54b;
|
||||
}
|
||||
|
||||
#btn-save {
|
||||
top: 70px;
|
||||
left: 435px;
|
||||
background-color: #b844ee;
|
||||
}
|
||||
|
||||
#btn-join {
|
||||
background-color: #52f367;
|
||||
top: 70px;
|
||||
left: 20px;
|
||||
border-radius: 25px 0 0 25px;
|
||||
width: 55px;
|
||||
}
|
||||
|
||||
#btn-quit {
|
||||
background-color: #5947f5;
|
||||
top: 70px;
|
||||
left: 75px;
|
||||
border-radius: 0px 25px 25px 0px;
|
||||
width: 55px;
|
||||
}
|
||||
|
||||
|
||||
#btn-select {
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
-webkit-transform: translateX(-50%);
|
||||
-moz-transform: translateX(-50%);
|
||||
background-color: #6fa8eb;
|
||||
}
|
||||
|
||||
#btn-start {
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
-webkit-transform: translateY(-50%);
|
||||
-moz-transform: translateY(-50%);
|
||||
background-color: #43be85;
|
||||
}
|
||||
|
||||
#btn-a {
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
-webkit-transform: translateX(-50%);
|
||||
-moz-transform: translateX(-50%);
|
||||
background-color: #ea6e4a;
|
||||
}
|
||||
|
||||
|
||||
#btn-b {
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
-webkit-transform: translateY(-50%);
|
||||
-moz-transform: translateY(-50%);
|
||||
background-color: #d4b95e;
|
||||
}
|
||||
|
||||
|
||||
#lights-holder {
|
||||
display: block;
|
||||
width: 45px;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 460px;
|
||||
}
|
||||
|
||||
#light-1 {
|
||||
display: block;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
background-color: #009BEB;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#light-2 {
|
||||
display: block;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
background-color: #7a7e7d;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
#light-3 {
|
||||
display: block;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
background-color: #7a7e7d;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 40px;
|
||||
animation: blink 1.5s cubic-bezier(1.0, 0, 0, 1.0) infinite;
|
||||
-webkit-animation: blink 1.5s cubic-bezier(1.0, 0, 0, 1.0) infinite;
|
||||
-moz-animation: blink 1.5s cubic-bezier(1.0, 0, 0, 1.0) infinite;
|
||||
}
|
||||
|
||||
|
||||
@-webkit-keyframes blink {
|
||||
0% {
|
||||
background: #7a7e7d;
|
||||
}
|
||||
|
||||
100% {
|
||||
background: yellow;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes blink {
|
||||
0% {
|
||||
background: #7a7e7d;
|
||||
}
|
||||
|
||||
100% {
|
||||
background: yellow;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0% {
|
||||
background: #7a7e7d;
|
||||
}
|
||||
|
||||
100% {
|
||||
background: yellow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*.unselectable {
|
||||
-moz-user-select: -moz-none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#room-txt {
|
||||
position: absolute;
|
||||
width: 110px;
|
||||
top: 40px;
|
||||
left: 25px;
|
||||
padding-left: 2px;
|
||||
-moz-border-radius: 8px;
|
||||
-webkit-border-radius: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
||||
.pressed {
|
||||
background-color: #333 !important;
|
||||
}
|
||||
|
||||
|
||||
#game-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: none;
|
||||
background-color: #222222;
|
||||
}
|
||||
|
||||
#menu-screen {
|
||||
display:none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('https://data.whicdn.com/images/275493408/original.gif');
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
#menu-screen #box-art {
|
||||
position: absolute;
|
||||
width:55%;
|
||||
height: 85%;
|
||||
top: 5px;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, -0%);
|
||||
transform: translate(-50%, -0%);
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'YourFontName'; /*a name to be used later*/
|
||||
src: url('/static/fonts/8-Bit-Madness.ttf'); /*URL to font*/
|
||||
}
|
||||
|
||||
#menu-screen #title {
|
||||
position: absolute;
|
||||
width:100%;
|
||||
height: 10%;
|
||||
bottom: 0px;
|
||||
font-family: 'YourFontName';
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#menu-screen #title p {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
|
||||
/* Starting position */
|
||||
-moz-transform:translateX(50%);
|
||||
-webkit-transform:translateX(50%);
|
||||
transform:translateX(50%);
|
||||
|
||||
/* Apply animation to this element */
|
||||
-moz-animation: horizontally 5s linear infinite alternate;
|
||||
-webkit-animation: horizontally 5s linear infinite alternate;
|
||||
animation: horizontally 5s linear infinite alternate;
|
||||
}
|
||||
|
||||
/* Move it (define the animation) */
|
||||
@-moz-keyframes horizontally {
|
||||
0% { -moz-transform: translateX(50%); }
|
||||
100% { -moz-transform: translateX(-50%); }
|
||||
}
|
||||
@-webkit-keyframes horizontally {
|
||||
0% { -webkit-transform: translateX(50%); }
|
||||
100% { -webkit-transform: translateX(-50%); }
|
||||
}
|
||||
@keyframes horizontally {
|
||||
0% { transform: translateX(50%); }
|
||||
100% { transform: translateX(-50%); }
|
||||
}
|
||||
|
||||
|
||||
#menu-screen .arrow {
|
||||
position: absolute;
|
||||
width:20px;
|
||||
height: 20px;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
-moz-transform: translate(0%, -50%);
|
||||
-webkit-transform: translate(0%, -50%);
|
||||
transform: translate(0%, -50%);
|
||||
|
||||
-moz-animation: breathing 1s infinite normal;
|
||||
-webkit-animation: breathing 1s infinite normal;
|
||||
animation: breathing 1s infinite normal;
|
||||
}
|
||||
|
||||
#menu-screen .left {
|
||||
left: 10px;
|
||||
-webkit-transform: scaleX(-1) translate(0%, -50%);
|
||||
-moz-transform: scaleX(-1) translate(0%, -50%);
|
||||
transform: scaleX(-1) translate(0%, -50%);
|
||||
|
||||
-webkit-animation: breathing 1s infinite normal;
|
||||
-moz-animation: breathing 1s infinite normal;
|
||||
animation: breathing 1s infinite normal;
|
||||
}
|
||||
|
||||
|
||||
@-webkit-keyframes breathing {
|
||||
0% { opacity: 1; }
|
||||
25% { opacity: 0.5; }
|
||||
50% { opacity: 0; }
|
||||
75% { opacity: 0.5; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@-moz-keyframes breathing {
|
||||
0% { opacity: 1; }
|
||||
25% { opacity: 0.5; }
|
||||
50% { opacity: 0; }
|
||||
75% { opacity: 0.5; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes breathing {
|
||||
0% { opacity: 1; }
|
||||
25% { opacity: 0.5; }
|
||||
50% { opacity: 0; }
|
||||
75% { opacity: 0.5; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
450
static/gameboy2.html
vendored
|
|
@ -5,359 +5,47 @@
|
|||
<meta name="viewport" content="user-scalable=0">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
|
||||
<link href="//netdna.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.css" rel="stylesheet">
|
||||
|
||||
|
||||
<style>
|
||||
#gamebody {
|
||||
display: block;
|
||||
width: 556px;
|
||||
height: 278px;
|
||||
background-color: #edf1f0;
|
||||
-moz-border-radius: 30px;
|
||||
-webkit-border-radius: 30px;
|
||||
border-radius: 30px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position: fixed;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
-webkit-box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
|
||||
#circle-pad-holder {
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position: absolute;
|
||||
top: 155px;
|
||||
left: 30px;
|
||||
background-color: #eaebeb;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-webkit-box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: inset 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
|
||||
#circle-pad {
|
||||
display: block;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
position: absolute;
|
||||
/* transform: translate(-50%, -50%);
|
||||
-moz-transform: translate(-50%, -50%);
|
||||
-webkit-transform: translate(-50%, -50%); */
|
||||
top: 15px;
|
||||
left: 15px;
|
||||
background-color: #00f;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-webkit-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
|
||||
.dpad {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
background-color: #e4e5e5;
|
||||
border: 2px solid rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
|
||||
#dpad-up {
|
||||
top: 18px;
|
||||
left: 50%;
|
||||
border-bottom: 0px;
|
||||
transform: translateX(-50%);
|
||||
-webkit-transform: translateX(-50%);
|
||||
-moz-transform: translateX(-50%);
|
||||
}
|
||||
|
||||
#dpad-down {
|
||||
bottom: 18px;
|
||||
left: 50%;
|
||||
border-top: 0px;
|
||||
transform: translateX(-50%);
|
||||
-webkit-transform: translateX(-50%);
|
||||
-moz-transform: translateX(-50%);
|
||||
}
|
||||
|
||||
|
||||
#dpad-left {
|
||||
left: 18px;
|
||||
top: 50%;
|
||||
border-right: 0px;
|
||||
transform: translateY(-50%);
|
||||
-webkit-transform: translateY(-50%);
|
||||
-moz-transform: translateY(-50%);
|
||||
}
|
||||
|
||||
#dpad-right {
|
||||
right: 18px;
|
||||
top: 50%;
|
||||
border-left: 0px;
|
||||
transform: translateY(-50%);
|
||||
-webkit-transform: translateY(-50%);
|
||||
-moz-transform: translateY(-50%);
|
||||
}
|
||||
|
||||
|
||||
#bottom-screen {
|
||||
display: block;
|
||||
width: 256px;
|
||||
height: 240px;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 150px;
|
||||
/* background-color: #EAEBEB; */
|
||||
background-color: #333;
|
||||
-moz-border-radius: 5px 5px 5px 5px;
|
||||
-webkit-border-radius: 15px 15px 25px 25px;
|
||||
border-radius: 5px 5px 5px 5px;
|
||||
-webkit-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
#color-button-holder {
|
||||
display: block;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
position: absolute;
|
||||
top: 135px;
|
||||
left: 425px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
width: 40px;
|
||||
height: 30px;
|
||||
position: absolute;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-webkit-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
|
||||
.btn-big {
|
||||
display: block;
|
||||
padding-top: 5px;
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
height: 25px;
|
||||
position: absolute;
|
||||
-moz-border-radius: 50px;
|
||||
-webkit-border-radius: 50px;
|
||||
border-radius: 50px;
|
||||
-webkit-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
-moz-box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
box-shadow: 0px 0px 2px 2px rgba(219, 222, 222, 1);
|
||||
}
|
||||
|
||||
#load-btn {
|
||||
top: 30px;
|
||||
left: 435px;
|
||||
background-color: #f5a54b;
|
||||
}
|
||||
|
||||
#save-btn {
|
||||
top: 70px;
|
||||
left: 435px;
|
||||
background-color: #b844ee;
|
||||
}
|
||||
|
||||
#start-btn {
|
||||
background-color: #52f367;
|
||||
top: 70px;
|
||||
left: 30px;
|
||||
}
|
||||
|
||||
|
||||
#blue-btn {
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
-webkit-transform: translateX(-50%);
|
||||
-moz-transform: translateX(-50%);
|
||||
background-color: #6fa8eb;
|
||||
}
|
||||
|
||||
#green-btn {
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
-webkit-transform: translateY(-50%);
|
||||
-moz-transform: translateY(-50%);
|
||||
background-color: #43be85;
|
||||
}
|
||||
|
||||
#red-btn {
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
-webkit-transform: translateX(-50%);
|
||||
-moz-transform: translateX(-50%);
|
||||
background-color: #ea6e4a;
|
||||
}
|
||||
|
||||
|
||||
#yellow-btn {
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
-webkit-transform: translateY(-50%);
|
||||
-moz-transform: translateY(-50%);
|
||||
background-color: #d4b95e;
|
||||
}
|
||||
|
||||
|
||||
#lights-holder {
|
||||
display: block;
|
||||
width: 45px;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 460px;
|
||||
}
|
||||
|
||||
#light-1 {
|
||||
display: block;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
background-color: #009BEB;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#light-2 {
|
||||
display: block;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
background-color: #7a7e7d;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
#light-3 {
|
||||
display: block;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
background-color: #7a7e7d;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 40px;
|
||||
animation: blink 1.5s cubic-bezier(1.0, 0, 0, 1.0) infinite;
|
||||
-webkit-animation: blink 1.5s cubic-bezier(1.0, 0, 0, 1.0) infinite;
|
||||
-moz-animation: blink 1.5s cubic-bezier(1.0, 0, 0, 1.0) infinite;
|
||||
}
|
||||
|
||||
|
||||
@-webkit-keyframes blink {
|
||||
0% {
|
||||
background: #7a7e7d;
|
||||
}
|
||||
|
||||
100% {
|
||||
background: yellow;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes blink {
|
||||
0% {
|
||||
background: #7a7e7d;
|
||||
}
|
||||
|
||||
100% {
|
||||
background: yellow;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0% {
|
||||
background: #7a7e7d;
|
||||
}
|
||||
|
||||
100% {
|
||||
background: yellow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*.unselectable {
|
||||
-moz-user-select: -moz-none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#room-txt {
|
||||
position: absolute;
|
||||
width: 110px;
|
||||
top: 40px;
|
||||
left: 25px;
|
||||
padding-left: 2px;
|
||||
-moz-border-radius: 8px;
|
||||
-webkit-border-radius: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
||||
.pressed {
|
||||
background-color: #333 !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<link href="/static/css/main.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="gamebody">
|
||||
|
||||
<div id="circle-pad-holder">
|
||||
<div id="dpad-up" class="dpad"></div>
|
||||
<div id="dpad-down" class="dpad"></div>
|
||||
<div id="dpad-left" class="dpad"></div>
|
||||
<div id="dpad-right" class="dpad"></div>
|
||||
<div id="btn-up" class="dpad"></div>
|
||||
<div id="btn-down" class="dpad"></div>
|
||||
<div id="btn-left" class="dpad"></div>
|
||||
<div id="btn-right" class="dpad"></div>
|
||||
<div id="circle-pad"></div>
|
||||
</div>
|
||||
|
||||
<div id="bottom-screen">
|
||||
<video id="game-screen" autoplay=true width=256 height=240
|
||||
poster="https://orig00.deviantart.net/cdcd/f/2017/276/a/a/october_2nd___gameboy_poltergeist_by_wanyo-dbpdmnd.gif">
|
||||
<video id="game-screen" autoplay=true poster="https://orig00.deviantart.net/cdcd/f/2017/276/a/a/october_2nd___gameboy_poltergeist_by_wanyo-dbpdmnd.gif"></video>
|
||||
|
||||
<div id="menu-screen">
|
||||
<img id="box-art" src="/static/img/404.jpg" onerror="this.src='/static/img/404.jpg'">
|
||||
<div id="title">
|
||||
<p>What the game ?!?</p>
|
||||
</div>
|
||||
|
||||
<img class="arrow left" src="/static/img/arrow2_e.gif">
|
||||
<img class="arrow right" src="/static/img/arrow2_e.gif">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="load-btn" unselectable="on" class="btn-big unselectable">load</div>
|
||||
<div id="save-btn" unselectable="on" class="btn-big unselectable">save</div>
|
||||
|
||||
<div id="start-btn" unselectable="on" class="btn-big unselectable">start</div>
|
||||
<div id="btn-load" unselectable="on" class="btn-big unselectable">load</div>
|
||||
<div id="btn-save" unselectable="on" class="btn-big unselectable">save</div>
|
||||
<div id="btn-join" unselectable="on" class="btn-big unselectable">join</div>
|
||||
<div id="btn-quit" unselectable="on" class="btn-big unselectable">quit</div>
|
||||
|
||||
|
||||
<div id="color-button-holder">
|
||||
<div id="blue-btn" unselectable="on" class="btn unselectable">Y</div>
|
||||
<div id="green-btn" unselectable="on" class="btn unselectable">X</div>
|
||||
<div id="red-btn" unselectable="on" class="btn unselectable">A</div>
|
||||
<div id="yellow-btn" unselectable="on" class="btn unselectable">B</div>
|
||||
<div id="btn-select" unselectable="on" class="btn unselectable">Y</div>
|
||||
<div id="btn-start" unselectable="on" class="btn unselectable">X</div>
|
||||
<div id="btn-a" unselectable="on" class="btn unselectable">A</div>
|
||||
<div id="btn-b" unselectable="on" class="btn unselectable">B</div>
|
||||
</div>
|
||||
|
||||
<div id="lights-holder">
|
||||
|
|
@ -372,60 +60,25 @@
|
|||
|
||||
|
||||
<script>
|
||||
DEBUG = true;
|
||||
</script>
|
||||
|
||||
<!-- https://rawgit.com/Rillke/opus.js-sample/master/index.xhtml -->
|
||||
<script src="/static/js/libopus.js"></script>
|
||||
<script src="/static/js/opus.js"></script>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||
<script src="/static/js/const.js"></script>
|
||||
<script src="/static/js/global.js"></script>
|
||||
<script src="/static/js/gameboy_controller.js"></script>
|
||||
<script src="/static/js/ws.js"></script>
|
||||
|
||||
<script>
|
||||
$("#gameOp").on("change", function () {
|
||||
gameIdx = gameOp.selectedIndex;
|
||||
});
|
||||
|
||||
gameIdx = 1;
|
||||
|
||||
</script>
|
||||
|
||||
DEBUG = true;
|
||||
</script>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||
<script src="/static/js/utils.js"></script>
|
||||
|
||||
<!-- https://rawgit.com/Rillke/opus.js-sample/master/index.xhtml -->
|
||||
<script src="/static/js/libopus.js"></script>
|
||||
<script src="/static/js/opus.js"></script>
|
||||
|
||||
<script src="/static/js/global.js"></script>
|
||||
<script src="/static/js/controller.js"></script>
|
||||
<script src="/static/js/gesture_keyboard.js"></script>
|
||||
<script src="/static/js/gesture_touch.js"></script>
|
||||
<script src="/static/js/gesture_joystick.js"></script>
|
||||
<script src="/static/js/ws.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
//disable gesture
|
||||
xxx = (e) => {
|
||||
e.preventDefault();
|
||||
}
|
||||
window.addEventListener("touchmove", xxx, { passive: false });
|
||||
// window.addEventListener("mousedown", xxx, { passive: false });
|
||||
// window.addEventListener("touchstart", xxx, { passive: false });
|
||||
|
||||
|
||||
function isPortrait() {
|
||||
// ios / mobile app
|
||||
switch (window.orientation) {
|
||||
case 0:
|
||||
case 180:
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
// desktop
|
||||
orient = screen.msOrientation || screen.mozOrientation || (screen.orientation || {}).type;
|
||||
if (orient == "portrait-primary") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function fix() {
|
||||
function fixScreen() {
|
||||
target = $(window);
|
||||
child = $("#gamebody");
|
||||
|
||||
|
|
@ -433,8 +86,15 @@
|
|||
height = child.height();
|
||||
|
||||
// should have maximum for desktop
|
||||
targetWidth = target.width();
|
||||
targetHeight = target.height();
|
||||
if (["win", "mac", "linux"].indexOf(getOS()) != -1) {
|
||||
targetWidth = Math.min(800, target.width());
|
||||
targetHeight = Math.min(600, target.height());
|
||||
} else {
|
||||
targetWidth = target.width();
|
||||
targetHeight = target.height();
|
||||
}
|
||||
console.log(targetHeight);
|
||||
console.log(targetWidth);
|
||||
|
||||
screenWidth = targetWidth;
|
||||
screenHeight = targetHeight;
|
||||
|
|
@ -455,10 +115,10 @@
|
|||
child.css("-moz-transform", st);
|
||||
child.css("-ms-transform", st);
|
||||
}
|
||||
fix();
|
||||
fixScreen();
|
||||
|
||||
$(window).on("resize", fix);
|
||||
$(window).on("orientationchange", fix);
|
||||
$(window).on("resize", fixScreen);
|
||||
$(window).on("orientationchange", fixScreen);
|
||||
|
||||
</script>
|
||||
|
||||
|
|
|
|||
BIN
static/img/404.jpg
vendored
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
static/img/boxarts/1943.png
vendored
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
static/img/boxarts/Battle City.png
vendored
Normal file
|
After Width: | Height: | Size: 354 KiB |
BIN
static/img/boxarts/Bubble Bobble.png
vendored
Normal file
|
After Width: | Height: | Size: 441 KiB |
BIN
static/img/boxarts/Captain America and the Avengers.png
vendored
Normal file
|
After Width: | Height: | Size: 168 KiB |
BIN
static/img/boxarts/Chip 'n Dale Rescue Rangers 2.png
vendored
Normal file
|
After Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 146 KiB |
BIN
static/img/boxarts/Gradius.png
vendored
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
static/img/boxarts/Ice Climber.png
vendored
Normal file
|
After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 156 KiB |
BIN
static/img/boxarts/Mega Man 6.png
vendored
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
static/img/boxarts/Mega Man.png
vendored
Normal file
|
After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 188 KiB |
BIN
static/img/boxarts/Mike Tyson's Punch-Out!!.png
vendored
Normal file
|
After Width: | Height: | Size: 173 KiB |
|
Before Width: | Height: | Size: 338 KiB After Width: | Height: | Size: 338 KiB |
BIN
static/img/boxarts/Ninja Gaiden.png
vendored
Normal file
|
After Width: | Height: | Size: 185 KiB |
BIN
static/img/boxarts/Nintendo World Cup.png
vendored
Normal file
|
After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 207 KiB After Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
84
static/js/const.js
vendored
|
|
@ -1,84 +0,0 @@
|
|||
// list game
|
||||
GAME_LIST = [
|
||||
{
|
||||
name: "Contra",
|
||||
nes: "Contra.nes",
|
||||
art: "Contra (USA).png"
|
||||
},
|
||||
|
||||
{
|
||||
name: "Kirby's Adventure",
|
||||
nes: "Kirby's Adventure.nes",
|
||||
art: "Kirby's Adventure (Canada).png"
|
||||
},
|
||||
|
||||
{
|
||||
name: "Mega Man 2",
|
||||
nes: "Mega Man 2.nes",
|
||||
art: "Mega Man 2 (USA).png"
|
||||
},
|
||||
|
||||
{
|
||||
name: "Metal Gear",
|
||||
nes: "Metal Gear.nes",
|
||||
art: "Metal Gear (USA).png"
|
||||
},
|
||||
|
||||
{
|
||||
name: "Mortal Kombat 4",
|
||||
nes: "Mortal Kombat 4.nes",
|
||||
art: "mortal-kombat-x-box-art-revealed-as-pre-orders-ope_5pxd.jpg"
|
||||
},
|
||||
|
||||
{
|
||||
name: "Super Mario Bros 2",
|
||||
nes: "Super Mario Bros 2.nes",
|
||||
art: "Super Mario Bros. 2 (USA).png"
|
||||
},
|
||||
|
||||
{
|
||||
name: "Super Mario Bros 3",
|
||||
nes: "Super Mario Bros 3.nes",
|
||||
art: "Super Mario Bros. 3 (USA).png"
|
||||
},
|
||||
|
||||
{
|
||||
name: "Super Mario Bros",
|
||||
nes: "Super Mario Bros.nes",
|
||||
art: "Super Mario Bros. (World).png"
|
||||
},
|
||||
|
||||
{
|
||||
name: "TMNT 3",
|
||||
nes: "Teenage Mutant Ninja Turtles 3.nes",
|
||||
art: "Teenage Mutant Ninja Turtles III - The Manhattan Project (USA).png"
|
||||
},
|
||||
|
||||
{
|
||||
name: "Zelda",
|
||||
nes: "zelda.rom",
|
||||
art: "Zelda II - The Adventure of Link (Europe) (Rev A).png"
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
|
||||
/*
|
||||
const (
|
||||
ButtonA = iota
|
||||
ButtonB
|
||||
ButtonSelect
|
||||
ButtonStart
|
||||
ButtonUp
|
||||
ButtonDown
|
||||
ButtonLeft
|
||||
ButtonRight
|
||||
)
|
||||
*/
|
||||
// KEY_BIT = ["a", "b", "select", "start", "up", "down", "left", "right", "save", "load"];
|
||||
KEY_BIT = ["a", "b", "select", "start", "up", "down", "left", "right"];
|
||||
|
||||
|
||||
INPUT_FPS = 100;
|
||||
PINGPONGPS = 5;
|
||||
INPUT_STATE_PACKET = 5;
|
||||
153
static/js/controller.js
vendored
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
// menu screen
|
||||
function showMenuScreen() {
|
||||
log("Clean up connection / frame");
|
||||
|
||||
$("#game-screen").hide();
|
||||
$("#menu-screen").hide();
|
||||
// show
|
||||
$("#game-screen").show().delay(DEBUG?0:1000).fadeOut(400, () => {
|
||||
log("Loading menu screen");
|
||||
$("#menu-screen").fadeIn(400, () => {
|
||||
chooseGame(gameIdx, true);
|
||||
screenState = "menu";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// game menu
|
||||
function chooseGame(idx, force = false) {
|
||||
if (idx < 0 || (idx == gameIdx && !force) || idx >= gameList.length) return false;
|
||||
|
||||
$("#menu-screen #box-art").fadeOut(DEBUG?0:400, function () {
|
||||
$(this).attr("src", `/static/img/boxarts/${gameList[idx].name}.png`);
|
||||
$(this).fadeIn(400, function () {
|
||||
$("#menu-screen #title p").html(gameList[idx].name);
|
||||
});
|
||||
});
|
||||
|
||||
if (idx == 0) {
|
||||
$("#menu-screen .left").hide();
|
||||
} else {
|
||||
$("#menu-screen .left").show();
|
||||
}
|
||||
|
||||
if (idx == gameList.length - 1) {
|
||||
$("#menu-screen .right").hide();
|
||||
} else {
|
||||
$("#menu-screen .right").show();
|
||||
}
|
||||
|
||||
gameIdx = idx;
|
||||
log(`> [Pick] game ${gameIdx + 1}/${gameList.length} - ${gameList[gameIdx].name}`);
|
||||
}
|
||||
|
||||
|
||||
// global func
|
||||
|
||||
|
||||
function sendInputData() {
|
||||
// prepare key
|
||||
if (unchangePacket > 0) {
|
||||
bits = "";
|
||||
KEY_BIT.slice().reverse().forEach(elem => {
|
||||
bits += keyState[elem] ? 1 : 0;
|
||||
});
|
||||
data = parseInt(bits, 2);
|
||||
console.log(`Key state string: ${bits} ==> ${data}`);
|
||||
|
||||
// send
|
||||
arrBuf = new Uint8Array(1);
|
||||
arrBuf[0] = data;
|
||||
inputChannel.send(arrBuf);
|
||||
|
||||
unchangePacket--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function startInputTimer() {
|
||||
if (inputTimer == null) {
|
||||
inputTimer = setInterval(sendInputData, 1000 / INPUT_FPS)
|
||||
}
|
||||
}
|
||||
|
||||
function stopInputTimer() {
|
||||
clearInterval(inputTimer);
|
||||
inputTimer = null;
|
||||
}
|
||||
|
||||
|
||||
function setState(name, bo) {
|
||||
if (name in keyState) {
|
||||
keyState[name] = bo;
|
||||
unchangePacket = INPUT_STATE_PACKET;
|
||||
}
|
||||
}
|
||||
|
||||
function doButton(bo, name) {
|
||||
if (bo == true) {
|
||||
doButtonDown(name);
|
||||
} else if (bo == false) {
|
||||
doButtonUp(name);
|
||||
}
|
||||
}
|
||||
|
||||
function doButtonDown(name) {
|
||||
$(`#btn-${name}`).addClass("pressed");
|
||||
|
||||
if (screenState === "game") {
|
||||
// game keys
|
||||
setState(name, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function doButtonUp(name) {
|
||||
$(`#btn-${name}`).removeClass("pressed");
|
||||
|
||||
if (screenState === "menu") {
|
||||
switch (name) {
|
||||
case "left":
|
||||
chooseGame(gameIdx - 1);
|
||||
break;
|
||||
|
||||
case "right":
|
||||
chooseGame(gameIdx + 1);
|
||||
break;
|
||||
|
||||
case "join":
|
||||
startGame();
|
||||
// log("select game");
|
||||
}
|
||||
} else if (screenState === "game") {
|
||||
setState(name, false);
|
||||
|
||||
switch (name) {
|
||||
case "save":
|
||||
conn.send(JSON.stringify({ "id": "save", "data": "" }));
|
||||
break;
|
||||
case "load":
|
||||
conn.send(JSON.stringify({ "id": "load", "data": "" }));
|
||||
break;
|
||||
case "full":
|
||||
// Fullscreen
|
||||
screen = document.getElementById("game-screen");
|
||||
|
||||
console.log(screen.height, window.innerHeight);
|
||||
if (screen.height === window.innerHeight) {
|
||||
closeFullscreen();
|
||||
} else {
|
||||
openFullscreen(screen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// global reset
|
||||
if (name === "quit") {
|
||||
stopInputTimer();
|
||||
showMenuScreen();
|
||||
}
|
||||
}
|
||||
|
||||
478
static/js/gameboy_controller.js
vendored
|
|
@ -1,478 +0,0 @@
|
|||
// menu screen
|
||||
function showMenuScreen() {
|
||||
log("Clean up connection / frame");
|
||||
|
||||
$("#game-screen").hide();
|
||||
if (!DEBUG) {
|
||||
$("#menu-screen").hide();
|
||||
// show
|
||||
$("#game-screen").show().delay(1000).fadeOut(400, () => {
|
||||
log("Loading menu screen");
|
||||
$("#menu-screen").fadeIn(400, () => {
|
||||
chooseGame(gameIdx, true);
|
||||
screenState = "menu";
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
screenState = "debug";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// game menu
|
||||
function chooseGame(idx, force = false) {
|
||||
if (idx < 0 || (idx == gameIdx && !force) || idx >= GAME_LIST.length) return false;
|
||||
|
||||
$("#menu-screen #box-art").fadeOut(400, function () {
|
||||
$(this).attr("src", `/static/img/boxarts/${GAME_LIST[idx].art}`);
|
||||
$(this).fadeIn(400, function () {
|
||||
$("#menu-screen #title p").html(GAME_LIST[idx].name);
|
||||
});
|
||||
});
|
||||
|
||||
if (idx == 0) {
|
||||
$("#menu-screen .left").hide();
|
||||
} else {
|
||||
$("#menu-screen .left").show();
|
||||
}
|
||||
|
||||
if (idx == GAME_LIST.length - 1) {
|
||||
$("#menu-screen .right").hide();
|
||||
} else {
|
||||
$("#menu-screen .right").show();
|
||||
}
|
||||
|
||||
gameIdx = idx;
|
||||
log(`> [Pick] game ${gameIdx + 1}/${GAME_LIST.length} - ${GAME_LIST[gameIdx].name}`);
|
||||
}
|
||||
|
||||
|
||||
// global func
|
||||
|
||||
function openFullscreen(elem) {
|
||||
if (elem.requestFullscreen) {
|
||||
elem.requestFullscreen();
|
||||
} else if (elem.mozRequestFullScreen) { /* Firefox */
|
||||
elem.mozRequestFullScreen();
|
||||
} else if (elem.webkitRequestFullscreen) { /* Chrome, Safari and Opera */
|
||||
elem.webkitRequestFullscreen();
|
||||
} else if (elem.msRequestFullscreen) { /* IE/Edge */
|
||||
elem.msRequestFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
function closeFullscreen() {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
} else if (document.mozCancelFullScreen) { /* Firefox */
|
||||
document.mozCancelFullScreen();
|
||||
} else if (document.webkitExitFullscreen) { /* Chrome, Safari and Opera */
|
||||
document.webkitExitFullscreen();
|
||||
} else if (document.msExitFullscreen) { /* IE/Edge */
|
||||
document.msExitFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function sendInputData() {
|
||||
// prepare key
|
||||
if (unchangePacket > 0) {
|
||||
bits = "";
|
||||
KEY_BIT.slice().reverse().forEach(elem => {
|
||||
bits += keyState[elem] ? 1 : 0;
|
||||
});
|
||||
data = parseInt(bits, 2);
|
||||
console.log(`Key state string: ${bits} ==> ${data}`);
|
||||
|
||||
// send
|
||||
arrBuf = new Uint8Array(1);
|
||||
arrBuf[0] = data;
|
||||
inputChannel.send(arrBuf);
|
||||
|
||||
unchangePacket--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function startInputTimer() {
|
||||
if (inputTimer == null) {
|
||||
inputTimer = setInterval(sendInputData, 1000 / INPUT_FPS)
|
||||
}
|
||||
}
|
||||
|
||||
function stopInputTimer() {
|
||||
clearInterval(inputTimer);
|
||||
inputTimer = null;
|
||||
}
|
||||
|
||||
|
||||
function setState(name, bo) {
|
||||
if (name in keyState) {
|
||||
keyState[name] = bo;
|
||||
unchangePacket = INPUT_STATE_PACKET;
|
||||
}
|
||||
}
|
||||
|
||||
function doButton(bo, name) {
|
||||
if (bo == true) {
|
||||
doButtonDown(name);
|
||||
} else if (bo == false) {
|
||||
doButtonUp(name);
|
||||
}
|
||||
}
|
||||
|
||||
function doButtonDown(name) {
|
||||
if (screenState === "game") {
|
||||
// game keys
|
||||
setState(name, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function doButtonUp(name) {
|
||||
if (screenState === "menu") {
|
||||
switch (name) {
|
||||
case "left":
|
||||
chooseGame(gameIdx - 1);
|
||||
break;
|
||||
|
||||
case "right":
|
||||
chooseGame(gameIdx + 1);
|
||||
break;
|
||||
|
||||
case "select":
|
||||
startGame();
|
||||
}
|
||||
} else if (screenState === "game") {
|
||||
setState(name, false);
|
||||
|
||||
switch (name) {
|
||||
case "save":
|
||||
conn.send(JSON.stringify({ "id": "save", "data": "" }));
|
||||
break;
|
||||
case "load":
|
||||
conn.send(JSON.stringify({ "id": "load", "data": "" }));
|
||||
break;
|
||||
case "full":
|
||||
// Fullscreen
|
||||
screen = document.getElementById("game-screen");
|
||||
|
||||
console.log(screen.height, window.innerHeight);
|
||||
if (screen.height === window.innerHeight) {
|
||||
closeFullscreen();
|
||||
} else {
|
||||
openFullscreen(screen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// global reset
|
||||
if (name === "quit") {
|
||||
stopInputTimer();
|
||||
showMenuScreen();
|
||||
}
|
||||
}
|
||||
|
||||
// KEYBOARD
|
||||
|
||||
KEYBOARD_MAP = {
|
||||
37: "left",
|
||||
38: "up",
|
||||
39: "right",
|
||||
40: "down",
|
||||
|
||||
90: "a", // z
|
||||
88: "b", // x
|
||||
67: "start", // c
|
||||
86: "select", // v
|
||||
|
||||
// non-game
|
||||
81: "quit", // q
|
||||
83: "save", // s
|
||||
76: "load", // l
|
||||
70: "full", // f
|
||||
}
|
||||
|
||||
document.body.onkeyup = function (e) {
|
||||
if (e.keyCode in KEYBOARD_MAP) {
|
||||
doButtonUp(KEYBOARD_MAP[e.keyCode]);
|
||||
}
|
||||
}
|
||||
|
||||
document.body.onkeydown = function (e) {
|
||||
if (e.keyCode in KEYBOARD_MAP) {
|
||||
doButtonDown(KEYBOARD_MAP[e.keyCode]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// JOYSTICK
|
||||
|
||||
/*
|
||||
cross == a <--> a
|
||||
circle == b <--> b
|
||||
square == x <--> start
|
||||
triangle == y <--> select
|
||||
share <--> load
|
||||
option <--> save
|
||||
L2 == LT <--> full
|
||||
R2 == RT <--> quit
|
||||
dpad <--> up down left right
|
||||
axis 0, 1 <--> second dpad
|
||||
*/
|
||||
var padState, gamepadTimer;
|
||||
|
||||
function getOS() {
|
||||
// linux? ios?
|
||||
var OSName = "unknown";
|
||||
if (navigator.appVersion.indexOf("Win") != -1) OSName = "win";
|
||||
else if (navigator.appVersion.indexOf("Mac") != -1) OSName = "mac";
|
||||
else if (navigator.userAgent.indexOf("Android") != -1) OSName = "android";
|
||||
return OSName;
|
||||
}
|
||||
|
||||
function getBrowser() {
|
||||
var browserName = "unknown";
|
||||
if (navigator.userAgent.indexOf("Firefox") != -1) browserName = "firefox";
|
||||
if (navigator.userAgent.indexOf("Chrome") != -1) browserName = "chrome";
|
||||
if (navigator.userAgent.indexOf("Edge") != -1) browserName = "edge";
|
||||
if (navigator.userAgent.indexOf("Version/") != -1) browserName = "safari";
|
||||
if (navigator.userAgent.indexOf("UCBrowser") != -1) browserName = "uc";
|
||||
return browserName;
|
||||
}
|
||||
|
||||
|
||||
// only capture the last plugged joystick
|
||||
window.addEventListener("gamepadconnected", (e) => {
|
||||
gamepad = e.gamepad;
|
||||
log(`Gamepad connected at index ${gamepad.index}: ${gamepad.id}. ${gamepad.buttons.length} buttons, ${gamepad.axes.length} axes.`);
|
||||
|
||||
padIdx = gamepad.index;
|
||||
|
||||
// Ref: https://github.com/giongto35/cloud-game/issues/14
|
||||
// get mapping first (default KeyMap2)
|
||||
os = getOS();
|
||||
browser = getBrowser();
|
||||
|
||||
console.log(os);
|
||||
console.log(browser);
|
||||
|
||||
if (os == "android") {
|
||||
// default of android is KeyMap1
|
||||
padMap = { 2: "a", 0: "b", 3: "start", 4: "select", 10: "load", 11: "save", 8: "full", 9: "quit", 12: "up", 13: "down", 14: "left", 15: "right" };
|
||||
} else {
|
||||
// default of other OS is KeyMap2
|
||||
padMap = { 0: "a", 1: "b", 2: "start", 3: "select", 8: "load", 9: "save", 6: "full", 7: "quit", 12: "up", 13: "down", 14: "left", 15: "right" };
|
||||
}
|
||||
|
||||
if (os == "android" && (browser == "firefox" || browser == "uc")) { //KeyMap2
|
||||
padMap = { 0: "a", 1: "b", 2: "start", 3: "select", 8: "load", 9: "save", 6: "full", 7: "quit", 12: "up", 13: "down", 14: "left", 15: "right" };
|
||||
}
|
||||
|
||||
if (os == "win" && browser == "firefox") { //KeyMap3
|
||||
padMap = { 1: "a", 2: "b", 0: "start", 3: "select", 8: "load", 9: "save", 6: "full", 7: "quit" };
|
||||
}
|
||||
|
||||
if (os == "mac" && browser == "safari") { //KeyMap4
|
||||
padMap = { 1: "a", 2: "b", 0: "start", 3: "select", 8: "load", 9: "save", 6: "full", 7: "quit", 14: "up", 15: "down", 16: "left", 17: "right" };
|
||||
}
|
||||
|
||||
if (os == "mac" && browser == "firefox") { //KeyMap5
|
||||
padMap = { 1: "a", 2: "b", 0: "start", 3: "select", 8: "load", 9: "save", 6: "full", 7: "quit", 14: "up", 15: "down", 16: "left", 17: "right" };
|
||||
}
|
||||
|
||||
// reset state
|
||||
padState = {
|
||||
left: false,
|
||||
right: false,
|
||||
up: false,
|
||||
down: false,
|
||||
};
|
||||
Object.keys(padMap).forEach(k => {
|
||||
padState[k] = false;
|
||||
});
|
||||
|
||||
|
||||
// looper, too intense?
|
||||
if (gamepadTimer) {
|
||||
clearInterval(gamepadTimer);
|
||||
}
|
||||
|
||||
function checkAxis(bo, axis) {
|
||||
if (bo != padState[axis]) {
|
||||
padState[axis] = bo;
|
||||
doButton(bo, axis);
|
||||
}
|
||||
}
|
||||
|
||||
gamepadTimer = setInterval(function () {
|
||||
gamepad = navigator.getGamepads()[padIdx];
|
||||
if (gamepad) {
|
||||
// axis pad
|
||||
corX = gamepad.axes[0]; // -1 -> 1, left -> right
|
||||
corY = gamepad.axes[1]; // -1 -> 1, up -> down
|
||||
checkAxis(corX <= -0.5, "left");
|
||||
checkAxis(corX >= 0.5, "right");
|
||||
checkAxis(corY <= -0.5, "up");
|
||||
checkAxis(corY >= 0.5, "down");
|
||||
|
||||
// normal button
|
||||
Object.keys(padMap).forEach(k => {
|
||||
if (navigator.webkitGetGamepads) {
|
||||
curPressed = (gamepad.buttons[k] == 1);
|
||||
} else {
|
||||
curPressed = (gamepad.buttons[k].value > 0 || gamepad.buttons[k].pressed == true);
|
||||
}
|
||||
|
||||
if (padState[k] != curPressed) {
|
||||
padState[k] = curPressed;
|
||||
doButton(curPressed, padMap[k]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}, 10); // miliseconds per hit
|
||||
|
||||
});
|
||||
|
||||
window.addEventListener("gamepaddisconnected", (event) => {
|
||||
clearInterval(gamepadTimer);
|
||||
log(`Gamepad disconnected at index ${e.gamepad.index}`);
|
||||
});
|
||||
|
||||
|
||||
|
||||
// VIRTUAL JOYSTICK
|
||||
// Ref: https://jsfiddle.net/aa0et7tr/5/
|
||||
|
||||
var dpadState = {};
|
||||
var touchIdx = null;
|
||||
const maxDiff = 20;
|
||||
|
||||
|
||||
function resetDPad() {
|
||||
dpadState = {
|
||||
up: false,
|
||||
down: false,
|
||||
left: false,
|
||||
right: false,
|
||||
};
|
||||
$(".dpad").removeClass("pressed");
|
||||
}
|
||||
|
||||
function checkDPadAxis(bo, axis) {
|
||||
if (bo != dpadState[axis]) {
|
||||
dpadState[axis] = bo;
|
||||
|
||||
if (dpadState[axis]) {
|
||||
$(`#dpad-${axis}`).addClass("pressed");
|
||||
} else {
|
||||
$(`#dpad-${axis}`).removeClass("pressed");
|
||||
}
|
||||
|
||||
// doButton(bo, axis);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
parent = $("#circle-pad-holder");
|
||||
stick = document.getElementById("circle-pad");
|
||||
|
||||
// TODO: REMOVE MOUSE
|
||||
parent.on('mousedown', handleMouseDown);
|
||||
$(document).on('mousemove', handleMouseMove);
|
||||
$(document).on('mouseup', handleMouseUp);
|
||||
|
||||
parent.on('touchstart', handleMouseDown);
|
||||
parent.on('touchmove', handleMouseMove);
|
||||
parent.on('touchend', handleMouseUp);
|
||||
|
||||
let dragStart = null;
|
||||
let currentPos = { x: 0, y: 0 };
|
||||
|
||||
function handleMouseDown(event) {
|
||||
// event.preventDefault();
|
||||
stick.style.transition = '0s';
|
||||
if (event.changedTouches) {
|
||||
touchIdx = event.changedTouches[0].identifier;
|
||||
dragStart = {
|
||||
x: event.changedTouches[0].clientX,
|
||||
y: event.changedTouches[0].clientY,
|
||||
};
|
||||
resetDPad();
|
||||
return;
|
||||
}
|
||||
dragStart = {
|
||||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function handleMouseMove(event) {
|
||||
// event.preventDefault();
|
||||
if (dragStart === null) return;
|
||||
if (event.changedTouches) {
|
||||
event.clientX = event.changedTouches[touchIdx].clientX;
|
||||
event.clientY = event.changedTouches[touchIdx].clientY;
|
||||
}
|
||||
const xDiff = event.clientX - dragStart.x;
|
||||
const yDiff = event.clientY - dragStart.y;
|
||||
const angle = Math.atan2(yDiff, xDiff);
|
||||
const distance = Math.min(maxDiff, Math.hypot(xDiff, yDiff));
|
||||
const xNew = distance * Math.cos(angle);
|
||||
const yNew = distance * Math.sin(angle);
|
||||
stick.style.transform = `translate(${xNew}px, ${yNew}px)`;
|
||||
currentPos = { x: xNew, y: yNew };
|
||||
|
||||
const xRatio = xNew / maxDiff;
|
||||
const yRatio = yNew / maxDiff;
|
||||
checkDPadAxis(xRatio <= -0.5, "left");
|
||||
checkDPadAxis(xRatio >= 0.5, "right");
|
||||
checkDPadAxis(yRatio <= -0.5, "up");
|
||||
checkDPadAxis(yRatio >= 0.5, "down");
|
||||
}
|
||||
|
||||
function handleMouseUp(event) {
|
||||
event.preventDefault();
|
||||
if (dragStart === null) return;
|
||||
stick.style.transition = '.2s';
|
||||
stick.style.transform = `translate3d(0px, 0px, 0px)`;
|
||||
dragStart = null;
|
||||
currentPos = { x: 0, y: 0 };
|
||||
resetDPad();
|
||||
|
||||
// $(".abxy .button").removeClass("pressed");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function handleButtonDown(event) {
|
||||
$(this).addClass("pressed");
|
||||
// doButtonDown($(this).attr("value"));
|
||||
}
|
||||
|
||||
function handleButtonUp(event) {
|
||||
$(this).removeClass("pressed");
|
||||
// doButtonUp($(this).attr("value"));
|
||||
}
|
||||
|
||||
|
||||
// TODO: REMOVE MOUSE
|
||||
// $(".abxy .button").on("mousedown", handleButtonDown);
|
||||
// $(".abxy .button").on("mouseup", handleButtonUp);
|
||||
$(".btn").on("mousedown", handleButtonDown);
|
||||
$(".btn").on("mouseup", handleButtonUp);
|
||||
$(".btn").on("touchstart", handleButtonDown);
|
||||
$(".btn").on("touchend", handleButtonUp);
|
||||
|
||||
$(".btn-big").on("mousedown", handleButtonDown);
|
||||
$(".btn-big").on("mouseup", handleButtonUp);
|
||||
$(".btn-big").on("touchstart", handleButtonDown);
|
||||
$(".btn-big").on("touchend", handleButtonUp);
|
||||
35
static/js/gameboy_loader.js
vendored
|
|
@ -1,35 +0,0 @@
|
|||
// A tiny bit of javascript code for color selection
|
||||
window.onload = function() {
|
||||
var colors = ['red', 'purple', 'green', 'yellow', 'teal', 'transparent'];
|
||||
var last = null;
|
||||
Array.prototype.slice.call(document.querySelectorAll('.color')).forEach(function(el) {
|
||||
el.addEventListener('click', function() {
|
||||
log("Starting gameboy");
|
||||
screenState = "loader";
|
||||
|
||||
if (last) {
|
||||
last.classList.remove('active');
|
||||
}
|
||||
var color = el.getAttribute('data-color');
|
||||
var gameboy = document.querySelector('#gameboy');
|
||||
gameboy.style.opacity = 0;
|
||||
gameboy.classList.remove(gameboy.classList[0]);
|
||||
var clone = gameboy.cloneNode(true);
|
||||
gameboy.remove();
|
||||
clone.classList.add(color);
|
||||
clone.style.opacity = 1;
|
||||
var colors = document.querySelector('#colors');
|
||||
colors.parentNode.insertBefore(clone, colors);
|
||||
el.classList.add('active');
|
||||
last = el;
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelector('.color[data-color="green"]').dispatchEvent(new MouseEvent('click', {
|
||||
'view': window,
|
||||
'bubbles': true
|
||||
}));
|
||||
|
||||
$("#screen-gameboy-text").on("webkitAnimationEnd", showMenuScreen);
|
||||
$("#screen-gameboy-text").on("animationend", showMenuScreen);
|
||||
}
|
||||
117
static/js/gesture_joystick.js
vendored
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
|
||||
// JOYSTICK
|
||||
|
||||
/*
|
||||
cross == a <--> a
|
||||
circle == b <--> b
|
||||
square == x <--> start
|
||||
triangle == y <--> select
|
||||
share <--> load
|
||||
option <--> save
|
||||
L2 == LT <--> full
|
||||
R2 == RT <--> quit
|
||||
dpad <--> up down left right
|
||||
axis 0, 1 <--> second dpad
|
||||
*/
|
||||
var padState, gamepadTimer;
|
||||
|
||||
|
||||
// only capture the last plugged joystick
|
||||
window.addEventListener("gamepadconnected", (e) => {
|
||||
gamepad = e.gamepad;
|
||||
log(`Gamepad connected at index ${gamepad.index}: ${gamepad.id}. ${gamepad.buttons.length} buttons, ${gamepad.axes.length} axes.`);
|
||||
|
||||
padIdx = gamepad.index;
|
||||
|
||||
// Ref: https://github.com/giongto35/cloud-game/issues/14
|
||||
// get mapping first (default KeyMap2)
|
||||
os = getOS();
|
||||
browser = getBrowser();
|
||||
|
||||
console.log(os);
|
||||
console.log(browser);
|
||||
|
||||
if (os == "android") {
|
||||
// default of android is KeyMap1
|
||||
padMap = { 2: "a", 0: "b", 3: "start", 4: "select", 10: "load", 11: "save", 8: "full", 9: "quit", 12: "up", 13: "down", 14: "left", 15: "right" };
|
||||
} else {
|
||||
// default of other OS is KeyMap2
|
||||
padMap = { 0: "a", 1: "b", 2: "start", 3: "select", 8: "load", 9: "save", 6: "full", 7: "quit", 12: "up", 13: "down", 14: "left", 15: "right" };
|
||||
}
|
||||
|
||||
if (os == "android" && (browser == "firefox" || browser == "uc")) { //KeyMap2
|
||||
padMap = { 0: "a", 1: "b", 2: "start", 3: "select", 8: "load", 9: "save", 6: "full", 7: "quit", 12: "up", 13: "down", 14: "left", 15: "right" };
|
||||
}
|
||||
|
||||
if (os == "win" && browser == "firefox") { //KeyMap3
|
||||
padMap = { 1: "a", 2: "b", 0: "start", 3: "select", 8: "load", 9: "save", 6: "full", 7: "quit" };
|
||||
}
|
||||
|
||||
if (os == "mac" && browser == "safari") { //KeyMap4
|
||||
padMap = { 1: "a", 2: "b", 0: "start", 3: "select", 8: "load", 9: "save", 6: "full", 7: "quit", 14: "up", 15: "down", 16: "left", 17: "right" };
|
||||
}
|
||||
|
||||
if (os == "mac" && browser == "firefox") { //KeyMap5
|
||||
padMap = { 1: "a", 2: "b", 0: "start", 3: "select", 8: "load", 9: "save", 6: "full", 7: "quit", 14: "up", 15: "down", 16: "left", 17: "right" };
|
||||
}
|
||||
|
||||
// reset state
|
||||
padState = {
|
||||
left: false,
|
||||
right: false,
|
||||
up: false,
|
||||
down: false,
|
||||
};
|
||||
Object.keys(padMap).forEach(k => {
|
||||
padState[k] = false;
|
||||
});
|
||||
|
||||
|
||||
// looper, too intense?
|
||||
if (gamepadTimer) {
|
||||
clearInterval(gamepadTimer);
|
||||
}
|
||||
|
||||
function checkAxis(bo, axis) {
|
||||
if (bo != padState[axis]) {
|
||||
padState[axis] = bo;
|
||||
doButton(bo, axis);
|
||||
}
|
||||
}
|
||||
|
||||
gamepadTimer = setInterval(function () {
|
||||
gamepad = navigator.getGamepads()[padIdx];
|
||||
if (gamepad) {
|
||||
// axis pad
|
||||
corX = gamepad.axes[0]; // -1 -> 1, left -> right
|
||||
corY = gamepad.axes[1]; // -1 -> 1, up -> down
|
||||
checkAxis(corX <= -0.5, "left");
|
||||
checkAxis(corX >= 0.5, "right");
|
||||
checkAxis(corY <= -0.5, "up");
|
||||
checkAxis(corY >= 0.5, "down");
|
||||
|
||||
// normal button
|
||||
Object.keys(padMap).forEach(k => {
|
||||
if (navigator.webkitGetGamepads) {
|
||||
curPressed = (gamepad.buttons[k] == 1);
|
||||
} else {
|
||||
curPressed = (gamepad.buttons[k].value > 0 || gamepad.buttons[k].pressed == true);
|
||||
}
|
||||
|
||||
if (padState[k] != curPressed) {
|
||||
padState[k] = curPressed;
|
||||
doButton(curPressed, padMap[k]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}, 10); // miliseconds per hit
|
||||
|
||||
});
|
||||
|
||||
window.addEventListener("gamepaddisconnected", (event) => {
|
||||
clearInterval(gamepadTimer);
|
||||
log(`Gamepad disconnected at index ${e.gamepad.index}`);
|
||||
});
|
||||
|
||||
|
||||
33
static/js/gesture_keyboard.js
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// KEYBOARD
|
||||
|
||||
KEYBOARD_MAP = {
|
||||
37: "left",
|
||||
38: "up",
|
||||
39: "right",
|
||||
40: "down",
|
||||
|
||||
90: "a", // z
|
||||
88: "b", // x
|
||||
67: "start", // c
|
||||
86: "select", // v
|
||||
|
||||
// non-game
|
||||
81: "quit", // q
|
||||
83: "save", // s
|
||||
87: "join", // w
|
||||
65: "load", // a
|
||||
70: "full", // f
|
||||
}
|
||||
|
||||
document.body.onkeyup = function (e) {
|
||||
if (e.keyCode in KEYBOARD_MAP) {
|
||||
doButtonUp(KEYBOARD_MAP[e.keyCode]);
|
||||
}
|
||||
}
|
||||
|
||||
document.body.onkeydown = function (e) {
|
||||
if (e.keyCode in KEYBOARD_MAP) {
|
||||
doButtonDown(KEYBOARD_MAP[e.keyCode]);
|
||||
}
|
||||
};
|
||||
|
||||
133
static/js/gesture_touch.js
vendored
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
|
||||
// VIRTUAL JOYSTICK
|
||||
// Ref: https://jsfiddle.net/aa0et7tr/5/
|
||||
|
||||
var dpadState = {};
|
||||
var touchIdx = null;
|
||||
const maxDiff = 20;
|
||||
|
||||
|
||||
function resetDPad() {
|
||||
dpadState = {
|
||||
up: false,
|
||||
down: false,
|
||||
left: false,
|
||||
right: false,
|
||||
};
|
||||
$(".dpad").removeClass("pressed");
|
||||
}
|
||||
|
||||
function checkDPadAxis(bo, axis) {
|
||||
if (bo != dpadState[axis]) {
|
||||
dpadState[axis] = bo;
|
||||
|
||||
if (dpadState[axis]) {
|
||||
$(`#dpad-${axis}`).addClass("pressed");
|
||||
} else {
|
||||
$(`#dpad-${axis}`).removeClass("pressed");
|
||||
}
|
||||
|
||||
// doButton(bo, axis);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
parent = $("#circle-pad-holder");
|
||||
stick = document.getElementById("circle-pad");
|
||||
|
||||
// TODO: REMOVE MOUSE
|
||||
parent.on('mousedown', handleMouseDown);
|
||||
$(document).on('mousemove', handleMouseMove);
|
||||
$(document).on('mouseup', handleMouseUp);
|
||||
|
||||
parent.on('touchstart', handleMouseDown);
|
||||
parent.on('touchmove', handleMouseMove);
|
||||
parent.on('touchend', handleMouseUp);
|
||||
|
||||
let dragStart = null;
|
||||
let currentPos = { x: 0, y: 0 };
|
||||
|
||||
function handleMouseDown(event) {
|
||||
// event.preventDefault();
|
||||
stick.style.transition = '0s';
|
||||
if (event.changedTouches) {
|
||||
touchIdx = event.changedTouches[0].identifier;
|
||||
dragStart = {
|
||||
x: event.changedTouches[0].clientX,
|
||||
y: event.changedTouches[0].clientY,
|
||||
};
|
||||
resetDPad();
|
||||
return;
|
||||
}
|
||||
dragStart = {
|
||||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function handleMouseMove(event) {
|
||||
// event.preventDefault();
|
||||
if (dragStart === null) return;
|
||||
if (event.changedTouches) {
|
||||
event.clientX = event.changedTouches[touchIdx].clientX;
|
||||
event.clientY = event.changedTouches[touchIdx].clientY;
|
||||
}
|
||||
const xDiff = event.clientX - dragStart.x;
|
||||
const yDiff = event.clientY - dragStart.y;
|
||||
const angle = Math.atan2(yDiff, xDiff);
|
||||
const distance = Math.min(maxDiff, Math.hypot(xDiff, yDiff));
|
||||
const xNew = distance * Math.cos(angle);
|
||||
const yNew = distance * Math.sin(angle);
|
||||
stick.style.transform = `translate(${xNew}px, ${yNew}px)`;
|
||||
currentPos = { x: xNew, y: yNew };
|
||||
|
||||
const xRatio = xNew / maxDiff;
|
||||
const yRatio = yNew / maxDiff;
|
||||
checkDPadAxis(xRatio <= -0.5, "left");
|
||||
checkDPadAxis(xRatio >= 0.5, "right");
|
||||
checkDPadAxis(yRatio <= -0.5, "up");
|
||||
checkDPadAxis(yRatio >= 0.5, "down");
|
||||
}
|
||||
|
||||
function handleMouseUp(event) {
|
||||
event.preventDefault();
|
||||
if (dragStart === null) return;
|
||||
stick.style.transition = '.2s';
|
||||
stick.style.transform = `translate3d(0px, 0px, 0px)`;
|
||||
dragStart = null;
|
||||
currentPos = { x: 0, y: 0 };
|
||||
resetDPad();
|
||||
|
||||
// $(".abxy .button").removeClass("pressed");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function handleButtonDown(event) {
|
||||
$(this).addClass("pressed");
|
||||
// doButtonDown($(this).attr("value"));
|
||||
}
|
||||
|
||||
function handleButtonUp(event) {
|
||||
$(this).removeClass("pressed");
|
||||
// doButtonUp($(this).attr("value"));
|
||||
}
|
||||
|
||||
|
||||
// TODO: REMOVE MOUSE
|
||||
// $(".abxy .button").on("mousedown", handleButtonDown);
|
||||
// $(".abxy .button").on("mouseup", handleButtonUp);
|
||||
$(".btn").on("mousedown", handleButtonDown);
|
||||
$(".btn").on("mouseup", handleButtonUp);
|
||||
$(".btn").on("touchstart", handleButtonDown);
|
||||
$(".btn").on("touchend", handleButtonUp);
|
||||
|
||||
$(".btn-big").on("mousedown", handleButtonDown);
|
||||
$(".btn-big").on("mouseup", handleButtonUp);
|
||||
$(".btn-big").on("touchstart", handleButtonDown);
|
||||
$(".btn-big").on("touchend", handleButtonUp);
|
||||
52
static/js/global.js
vendored
|
|
@ -1,17 +1,27 @@
|
|||
/*
|
||||
GLOBAL CONSTS
|
||||
*/
|
||||
DEBUG = true;
|
||||
|
||||
KEY_BIT = ["a", "b", "select", "start", "up", "down", "left", "right"];
|
||||
|
||||
INPUT_FPS = 100;
|
||||
PINGPONGPS = 5;
|
||||
INPUT_STATE_PACKET = 5;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*
|
||||
GLOBAL VARS
|
||||
*/
|
||||
LOG = true;
|
||||
if (!("DEBUG" in window)) {
|
||||
window.DEBUG = false;
|
||||
}
|
||||
|
||||
// Game state
|
||||
screenState = "loader";
|
||||
gameIdx = 0;
|
||||
var screenState = "loader";
|
||||
var gameList = [];
|
||||
var gameIdx = 5;
|
||||
|
||||
// Input vars
|
||||
keyState = {
|
||||
var keyState = {
|
||||
// controllers
|
||||
a: false,
|
||||
b: false,
|
||||
|
|
@ -22,34 +32,14 @@ keyState = {
|
|||
up: false,
|
||||
down: false,
|
||||
left: false,
|
||||
right: false,
|
||||
|
||||
// game meta keys
|
||||
// save: false,
|
||||
// load: false,
|
||||
|
||||
// unofficial
|
||||
// quit: false
|
||||
right: false
|
||||
}
|
||||
|
||||
unchangePacket = INPUT_STATE_PACKET;
|
||||
inputTimer = null;
|
||||
var unchangePacket = INPUT_STATE_PACKET;
|
||||
var inputTimer = null;
|
||||
|
||||
// Connection vars
|
||||
var pc, inputChannel;
|
||||
var localSessionDescription = "";
|
||||
var remoteSessionDescription = "";
|
||||
var conn;
|
||||
|
||||
|
||||
/*
|
||||
FUNCTIONS
|
||||
*/
|
||||
|
||||
// miscs
|
||||
function log(msg) {
|
||||
if (LOG) {
|
||||
document.getElementById('div').innerHTML += msg + '<br>'
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
var conn;
|
||||
69
static/js/utils.js
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
function log(msg) {
|
||||
// if (LOG) {
|
||||
// document.getElementById('div').innerHTML += msg + '<br>'
|
||||
// }
|
||||
console.log(msg);
|
||||
}
|
||||
|
||||
|
||||
function openFullscreen(elem) {
|
||||
if (elem.requestFullscreen) {
|
||||
elem.requestFullscreen();
|
||||
} else if (elem.mozRequestFullScreen) { /* Firefox */
|
||||
elem.mozRequestFullScreen();
|
||||
} else if (elem.webkitRequestFullscreen) { /* Chrome, Safari and Opera */
|
||||
elem.webkitRequestFullscreen();
|
||||
} else if (elem.msRequestFullscreen) { /* IE/Edge */
|
||||
elem.msRequestFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
function closeFullscreen() {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
} else if (document.mozCancelFullScreen) { /* Firefox */
|
||||
document.mozCancelFullScreen();
|
||||
} else if (document.webkitExitFullscreen) { /* Chrome, Safari and Opera */
|
||||
document.webkitExitFullscreen();
|
||||
} else if (document.msExitFullscreen) { /* IE/Edge */
|
||||
document.msExitFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getOS() {
|
||||
// linux? ios?
|
||||
var OSName = "unknown";
|
||||
if (navigator.appVersion.indexOf("Win") != -1) OSName = "win";
|
||||
else if (navigator.appVersion.indexOf("Mac") != -1) OSName = "mac";
|
||||
else if (navigator.userAgent.indexOf("Android") != -1) OSName = "android";
|
||||
return OSName;
|
||||
}
|
||||
|
||||
function getBrowser() {
|
||||
var browserName = "unknown";
|
||||
if (navigator.userAgent.indexOf("Firefox") != -1) browserName = "firefox";
|
||||
if (navigator.userAgent.indexOf("Chrome") != -1) browserName = "chrome";
|
||||
if (navigator.userAgent.indexOf("Edge") != -1) browserName = "edge";
|
||||
if (navigator.userAgent.indexOf("Version/") != -1) browserName = "safari";
|
||||
if (navigator.userAgent.indexOf("UCBrowser") != -1) browserName = "uc";
|
||||
return browserName;
|
||||
}
|
||||
|
||||
function isPortrait() {
|
||||
// ios / mobile app
|
||||
switch (window.orientation) {
|
||||
case 0:
|
||||
case 180:
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
// desktop
|
||||
orient = screen.msOrientation || screen.mozOrientation || (screen.orientation || {}).type;
|
||||
if (orient == "portrait-primary") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
41
static/js/ws.js
vendored
|
|
@ -1,7 +1,5 @@
|
|||
var pc;
|
||||
var curPacketID = "";
|
||||
var curSessionID = "";
|
||||
var gamelist = [];
|
||||
// web socket
|
||||
|
||||
conn = new WebSocket(`ws://${location.host}/ws`);
|
||||
|
|
@ -28,30 +26,28 @@ conn.onmessage = e => {
|
|||
switch (d["id"]) {
|
||||
|
||||
case "gamelist":
|
||||
files = JSON.parse(d["data"])
|
||||
files = JSON.parse(d["data"]);
|
||||
// parse files list to gamelist
|
||||
gamelist = []
|
||||
|
||||
gameList = [];
|
||||
files.forEach(file => {
|
||||
var file = file
|
||||
var name = file.substr(0, file.indexOf('.'));
|
||||
// var image = name + '.png'
|
||||
gamelist.push({file: file, name: name})
|
||||
})
|
||||
|
||||
// Update Game Options
|
||||
gamelist.forEach(game => {
|
||||
ee = document.createElement("option");
|
||||
ee.value = game.file;
|
||||
ee.innerHTML = game.name;
|
||||
gameOp.append(ee);
|
||||
gameList.push({file: file, name: name});
|
||||
});
|
||||
log("Received game list", gamelist)
|
||||
log("Received game list");
|
||||
|
||||
// change screen to menu
|
||||
showMenuScreen();
|
||||
|
||||
break;
|
||||
|
||||
case "sdp":
|
||||
log("Got remote sdp");
|
||||
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(d["data"]))));
|
||||
//conn.send(JSON.stringify({"id": "sdpdon", "packet_id": d["packet_id"]}));
|
||||
break;
|
||||
|
||||
case "requestOffer":
|
||||
curPacketID = d["packet_id"];
|
||||
log("Received request offer ", curPacketID)
|
||||
|
|
@ -71,8 +67,7 @@ conn.onmessage = e => {
|
|||
break;
|
||||
case "start":
|
||||
log("Got start");
|
||||
roomID.value = ""
|
||||
currentRoomID.innerText = d["room_id"]
|
||||
$("#room-txt").val(d["room_id"]);
|
||||
break;
|
||||
case "save":
|
||||
log(`Got save response: ${d["data"]}`);
|
||||
|
|
@ -211,16 +206,14 @@ function startGame() {
|
|||
log("Starting game screen");
|
||||
screenState = "game";
|
||||
|
||||
conn.send(JSON.stringify({"id": "start", "data": gamelist[gameIdx].file, "room_id": roomID.value, "player_index": parseInt(playerIndex.value, 10)}));
|
||||
// conn.send(JSON.stringify({"id": "start", "data": gameList[gameIdx].file, "room_id": $("#room-txt").val(), "player_index": parseInt(playerIndex.value, 10)}));
|
||||
conn.send(JSON.stringify({"id": "start", "data": gameList[gameIdx].file, "room_id": $("#room-txt").val(), "player_index": 0}));
|
||||
|
||||
// clear menu screen
|
||||
stopInputTimer();
|
||||
document.getElementById('div').innerHTML = "";
|
||||
if (!DEBUG) {
|
||||
$("#menu-screen").fadeOut(400, function() {
|
||||
$("#game-screen").show();
|
||||
});
|
||||
}
|
||||
$("#menu-screen").fadeOut(DEBUG?0:400, function() {
|
||||
$("#game-screen").show();
|
||||
});
|
||||
// end clear
|
||||
startInputTimer();
|
||||
}
|
||||
|
|
|
|||