Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
T
Taiko Web
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Taiko Web
Commits
8e99da6a
Commit
8e99da6a
authored
Sep 12, 2018
by
LoveEevee
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add 2-player mode
parent
7744fdac
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
815 additions
and
372 deletions
+815
-372
public/index.html
public/index.html
+1
-0
public/src/css/songselect.css
public/src/css/songselect.css
+10
-0
public/src/js/controller.js
public/src/js/controller.js
+219
-225
public/src/js/game.js
public/src/js/game.js
+116
-104
public/src/js/keyboard.js
public/src/js/keyboard.js
+16
-9
public/src/js/loader.js
public/src/js/loader.js
+3
-0
public/src/js/loadsong.js
public/src/js/loadsong.js
+42
-5
public/src/js/mekadon.js
public/src/js/mekadon.js
+48
-19
public/src/js/p2.js
public/src/js/p2.js
+132
-0
public/src/js/songselect.js
public/src/js/songselect.js
+37
-1
public/src/js/view.js
public/src/js/view.js
+23
-9
server.py
server.py
+168
-0
No files found.
public/index.html
View file @
8e99da6a
...
@@ -45,6 +45,7 @@
...
@@ -45,6 +45,7 @@
<script
src=
"/src/js/scalablecanvas.js"
></script>
<script
src=
"/src/js/scalablecanvas.js"
></script>
<script
src=
"/src/js/element.js"
></script>
<script
src=
"/src/js/element.js"
></script>
<script
src=
"/src/js/soundbuffer.js"
></script>
<script
src=
"/src/js/soundbuffer.js"
></script>
<script
src=
"/src/js/p2.js"
></script>
</head>
</head>
<body>
<body>
...
...
public/src/css/songselect.css
View file @
8e99da6a
...
@@ -75,6 +75,7 @@ ul li{
...
@@ -75,6 +75,7 @@ ul li{
box-shadow
:
2px
2px
10px
black
;
box-shadow
:
2px
2px
10px
black
;
overflow
:
hidden
;
overflow
:
hidden
;
cursor
:
pointer
;
cursor
:
pointer
;
position
:
relative
;
}
}
.opened
{
.opened
{
...
@@ -127,3 +128,12 @@ ul li{
...
@@ -127,3 +128,12 @@ ul li{
.difficulty
:hover
.stars
{
.difficulty
:hover
.stars
{
color
:
white
;
color
:
white
;
}
}
.song.p2
:not
(
.opened
)
::after
,
.difficulty.p2
::after
{
content
:
"P2"
;
display
:
block
;
position
:
absolute
;
bottom
:
0
;
width
:
100%
;
}
public/src/js/controller.js
View file @
8e99da6a
This diff is collapsed.
Click to expand it.
public/src/js/game.js
View file @
8e99da6a
This diff is collapsed.
Click to expand it.
public/src/js/keyboard.js
View file @
8e99da6a
...
@@ -65,14 +65,21 @@ function Keyboard(controller){
...
@@ -65,14 +65,21 @@ function Keyboard(controller){
}
}
this
.
checkMenuKeys
=
function
(){
this
.
checkMenuKeys
=
function
(){
_gamepad
.
play
(
1
)
if
(
!
controller
.
multiplayer
){
_this
.
checkKey
(
_kbd
[
"
back
"
],
"
menu
"
,
function
(){
_gamepad
.
play
(
1
)
controller
.
togglePause
();
_this
.
checkKey
(
_kbd
[
"
pause
"
],
"
menu
"
,
function
(){
controller
.
songSelection
();
controller
.
togglePauseMenu
();
})
})
_this
.
checkKey
(
_kbd
[
"
pause
"
],
"
menu
"
,
function
(){
}
controller
.
togglePauseMenu
();
if
(
controller
.
multiplayer
!=
2
){
})
_this
.
checkKey
(
_kbd
[
"
back
"
],
"
menu
"
,
function
(){
if
(
controller
.
multiplayer
==
1
){
p2
.
send
(
"
gameend
"
)
}
controller
.
togglePause
();
controller
.
songSelection
();
})
}
}
}
this
.
checkKey
=
function
(
keyCode
,
keyup
,
callback
){
this
.
checkKey
=
function
(
keyCode
,
keyup
,
callback
){
...
@@ -85,7 +92,7 @@ function Keyboard(controller){
...
@@ -85,7 +92,7 @@ function Keyboard(controller){
this
.
checkKeySound
=
function
(
keyCode
,
sound
){
this
.
checkKeySound
=
function
(
keyCode
,
sound
){
_this
.
checkKey
(
keyCode
,
"
sound
"
,
function
(){
_this
.
checkKey
(
keyCode
,
"
sound
"
,
function
(){
assets
.
sounds
[
"
note_
"
+
sound
].
play
()
assets
.
sounds
[
"
note_
"
+
sound
].
play
()
_keyTime
[
sound
]
=
controller
.
getEl
l
apsedTime
().
ms
_keyTime
[
sound
]
=
controller
.
getElapsedTime
().
ms
})
})
}
}
...
...
public/src/js/loader.js
View file @
8e99da6a
...
@@ -51,6 +51,8 @@ class Loader{
...
@@ -51,6 +51,8 @@ class Loader{
}))
}))
})
})
p2
=
new
P2Connection
()
this
.
promises
.
push
(
ajax
(
"
/api/songs
"
).
then
(
songs
=>
{
this
.
promises
.
push
(
ajax
(
"
/api/songs
"
).
then
(
songs
=>
{
assets
.
songs
=
JSON
.
parse
(
songs
)
assets
.
songs
=
JSON
.
parse
(
songs
)
}))
}))
...
@@ -100,4 +102,5 @@ function promiseLoad(asset){
...
@@ -100,4 +102,5 @@ function promiseLoad(asset){
}
}
var
snd
=
{}
var
snd
=
{}
var
p2
new
Loader
()
new
Loader
()
public/src/js/loadsong.js
View file @
8e99da6a
class
loadSong
{
class
loadSong
{
constructor
(
selectedSong
,
autoPlayEnabled
){
constructor
(
selectedSong
,
autoPlayEnabled
,
multiplayer
){
this
.
selectedSong
=
selectedSong
this
.
selectedSong
=
selectedSong
this
.
multiplayer
=
multiplayer
this
.
autoPlayEnabled
=
autoPlayEnabled
this
.
autoPlayEnabled
=
autoPlayEnabled
this
.
diff
=
this
.
selectedSong
.
difficulty
.
slice
(
0
,
-
4
)
this
.
songFilePath
=
"
/songs/
"
+
this
.
selectedSong
.
folder
+
"
/
"
+
this
.
selectedSong
.
difficulty
this
.
songFilePath
=
"
/songs/
"
+
this
.
selectedSong
.
folder
+
"
/
"
+
this
.
selectedSong
.
difficulty
$
(
"
#screen
"
).
load
(
"
/src/views/loadsong.html
"
,
()
=>
{
$
(
"
#screen
"
).
load
(
"
/src/views/loadsong.html
"
,
()
=>
{
this
.
run
()
this
.
run
()
...
@@ -42,11 +44,46 @@ class loadSong{
...
@@ -42,11 +44,46 @@ class loadSong{
Promise
.
all
(
promises
).
then
(()
=>
{
Promise
.
all
(
promises
).
then
(()
=>
{
$
(
"
#screen
"
).
load
(
"
/src/views/game.html
"
,
()
=>
{
$
(
"
#screen
"
).
load
(
"
/src/views/game.html
"
,
()
=>
{
var
taikoGame
=
new
Controller
(
this
.
selectedSong
,
this
.
songData
,
this
.
autoPlayEnabled
)
this
.
setupMultiplayer
()
taikoGame
.
run
()
})
})
},
()
=>
{
},
error
=>
{
console
.
error
(
error
)
alert
(
"
An error occurred, please refresh
"
)
alert
(
"
An error occurred, please refresh
"
)
})
})
}
}
}
setupMultiplayer
(){
\ No newline at end of file
if
(
this
.
multiplayer
){
this
.
song2Data
=
this
.
songData
this
.
selectedSong2
=
this
.
selectedSong
p2
.
onmessage
(
"
gamestart
"
,
()
=>
{
var
taikoGame1
=
new
Controller
(
this
.
selectedSong
,
this
.
songData
,
false
,
1
)
var
taikoGame2
=
new
Controller
(
this
.
selectedSong2
,
this
.
song2Data
,
true
,
2
)
taikoGame1
.
run
(
taikoGame2
)
},
true
)
p2
.
onmessage
(
"
gameload
"
,
response
=>
{
if
(
response
==
this
.
diff
){
p2
.
send
(
"
gamestart
"
)
}
else
{
this
.
selectedSong2
=
{
title
:
this
.
selectedSong
.
title
,
folder
:
this
.
selectedSong
.
folder
,
difficulty
:
response
+
"
.osu
"
}
ajax
(
"
/songs/
"
+
this
.
selectedSong2
.
folder
+
"
/
"
+
this
.
selectedSong2
.
difficulty
).
then
(
data
=>
{
this
.
song2Data
=
data
.
replace
(
/
\0
/g
,
""
).
split
(
"
\n
"
)
p2
.
send
(
"
gamestart
"
)
},
()
=>
{
p2
.
send
(
"
gamestart
"
)
})
}
},
true
)
p2
.
send
(
"
join
"
,
{
id
:
this
.
selectedSong
.
folder
,
diff
:
this
.
diff
})
}
else
{
var
taikoGame
=
new
Controller
(
this
.
selectedSong
,
this
.
songData
,
this
.
autoPlayEnabled
)
taikoGame
.
run
()
}
}
}
public/src/js/mekadon.js
View file @
8e99da6a
...
@@ -7,27 +7,56 @@ class Mekadon{
...
@@ -7,27 +7,56 @@ class Mekadon{
}
}
play
(
circle
){
play
(
circle
){
if
(
circle
.
getStatus
()
==
450
){
if
(
circle
.
getStatus
()
==
450
){
var
kbd
=
this
.
controller
.
getBindings
()
return
this
.
playNow
(
circle
)
if
(
circle
.
getType
()
==
"
don
"
){
this
.
setKey
(
this
.
lr
?
kbd
[
"
don_l
"
]
:
kbd
[
"
don_r
"
])
this
.
lr
=
!
this
.
lr
}
else
if
(
circle
.
getType
()
==
"
daiDon
"
){
this
.
setKey
(
kbd
[
"
don_l
"
])
this
.
setKey
(
kbd
[
"
don_r
"
])
this
.
lr
=
false
}
else
if
(
circle
.
getType
()
==
"
ka
"
){
this
.
setKey
(
this
.
lr
?
kbd
[
"
ka_l
"
]
:
kbd
[
"
ka_r
"
])
this
.
lr
=
!
this
.
lr
}
else
if
(
circle
.
getType
()
==
"
daiKa
"
){
this
.
setKey
(
kbd
[
"
ka_l
"
])
this
.
setKey
(
kbd
[
"
ka_r
"
])
this
.
lr
=
false
}
var
score
=
this
.
game
.
checkScore
(
circle
);
circle
.
played
(
score
);
this
.
game
.
updateCurrentCircle
();
}
}
}
}
playAt
(
circle
,
ms
,
score
){
var
currentMs
=
circle
.
getMS
()
-
this
.
controller
.
getElapsedTime
().
ms
if
(
ms
>
currentMs
-
10
){
return
this
.
playNow
(
circle
,
score
)
}
}
miss
(
circle
){
var
currentMs
=
circle
.
getMS
()
-
this
.
controller
.
getElapsedTime
().
ms
if
(
0
>
currentMs
-
10
){
circle
.
updateStatus
(
-
1
)
circle
.
played
(
0
)
this
.
controller
.
displayScore
(
0
,
true
)
this
.
game
.
updateCurrentCircle
()
this
.
game
.
updateCombo
(
0
)
this
.
game
.
updateGlobalScore
(
0
)
return
true
}
}
playNow
(
circle
,
score
){
var
kbd
=
this
.
controller
.
getBindings
()
if
(
circle
.
getType
()
==
"
don
"
){
this
.
setKey
(
this
.
lr
?
kbd
[
"
don_l
"
]
:
kbd
[
"
don_r
"
])
this
.
lr
=
!
this
.
lr
}
else
if
(
circle
.
getType
()
==
"
daiDon
"
){
this
.
setKey
(
kbd
[
"
don_l
"
])
this
.
setKey
(
kbd
[
"
don_r
"
])
this
.
lr
=
false
}
else
if
(
circle
.
getType
()
==
"
ka
"
){
this
.
setKey
(
this
.
lr
?
kbd
[
"
ka_l
"
]
:
kbd
[
"
ka_r
"
])
this
.
lr
=
!
this
.
lr
}
else
if
(
circle
.
getType
()
==
"
daiKa
"
){
this
.
setKey
(
kbd
[
"
ka_l
"
])
this
.
setKey
(
kbd
[
"
ka_r
"
])
this
.
lr
=
false
}
if
(
typeof
score
==
"
undefined
"
){
score
=
this
.
game
.
checkScore
(
circle
)
}
else
{
this
.
controller
.
displayScore
(
score
)
this
.
game
.
updateCombo
(
score
)
this
.
game
.
updateGlobalScore
(
score
)
}
circle
.
updateStatus
(
score
)
circle
.
played
(
score
)
this
.
game
.
updateCurrentCircle
()
return
true
}
setKey
(
keyCode
){
setKey
(
keyCode
){
var
self
=
this
var
self
=
this
if
(
this
.
keys
[
keyCode
]){
if
(
this
.
keys
[
keyCode
]){
...
...
public/src/js/p2.js
0 → 100644
View file @
8e99da6a
class
P2Connection
{
constructor
(){
this
.
closed
=
true
this
.
lastMessages
=
{}
this
.
msgCallbacks
=
{}
this
.
closeCallbacks
=
new
Set
()
this
.
openCallbacks
=
new
Set
()
this
.
notes
=
[]
this
.
otherConnected
=
false
this
.
onmessage
(
"
gamestart
"
,
()
=>
{
this
.
otherConnected
=
true
this
.
notes
=
[]
})
this
.
onmessage
(
"
gameend
"
,
()
=>
{
this
.
otherConnected
=
false
})
this
.
onmessage
(
"
note
"
,
response
=>
{
this
.
notes
.
push
(
response
)
})
}
open
(){
this
.
closed
=
false
var
wsProtocol
=
location
.
protocol
==
"
https:
"
?
"
wss:
"
:
"
ws:
"
this
.
socket
=
new
WebSocket
(
wsProtocol
+
"
//
"
+
window
.
location
.
hostname
+
"
/p2
"
)
var
events
=
[
"
open
"
,
"
close
"
,
"
message
"
]
events
.
forEach
(
eventName
=>
{
this
.
socket
.
addEventListener
(
eventName
,
event
=>
{
this
[
eventName
+
"
Event
"
](
event
)
})
})
}
openEvent
(
event
){
this
.
openCallbacks
.
forEach
(
obj
=>
{
obj
.
callback
()
if
(
obj
.
once
){
this
.
openCallbacks
.
delete
(
obj
)
}
})
}
onopen
(
callback
,
once
){
this
.
openCallbacks
.
add
({
callback
:
callback
,
once
:
once
})
}
close
(){
this
.
closed
=
true
this
.
socket
.
close
()
}
closeEvent
(
event
){
if
(
!
this
.
closed
){
setTimeout
(()
=>
{
if
(
this
.
socket
.
readyState
!=
this
.
socket
.
OPEN
){
this
.
open
()
}
},
500
)
}
this
.
closeCallbacks
.
forEach
(
obj
=>
{
obj
.
callback
()
if
(
obj
.
once
){
this
.
closeCallbacks
.
delete
(
obj
)
}
})
}
onclose
(
callback
,
once
){
this
.
closeCallbacks
.
add
({
callback
:
callback
,
once
:
once
})
}
send
(
type
,
value
){
if
(
this
.
socket
.
readyState
==
this
.
socket
.
OPEN
){
if
(
typeof
value
==
"
undefined
"
){
this
.
socket
.
send
(
JSON
.
stringify
({
type
:
type
}))
}
else
{
this
.
socket
.
send
(
JSON
.
stringify
({
type
:
type
,
value
:
value
}))
}
}
else
{
this
.
onopen
(()
=>
{
this
.
send
(
type
,
value
)
},
true
)
}
}
messageEvent
(
event
){
try
{
var
data
=
JSON
.
parse
(
event
.
data
)
}
catch
(
e
){
var
data
=
{}
}
this
.
lastMessages
[
data
.
type
]
=
data
.
value
if
(
this
.
msgCallbacks
[
data
.
type
]){
this
.
msgCallbacks
[
data
.
type
].
forEach
(
obj
=>
{
obj
.
callback
(
data
.
value
)
if
(
obj
.
once
){
delete
this
.
msgCallbacks
[
obj
]
}
})
}
}
onmessage
(
type
,
callback
,
once
){
if
(
!
(
type
in
this
.
msgCallbacks
)){
this
.
msgCallbacks
[
type
]
=
new
Set
()
}
this
.
msgCallbacks
[
type
].
add
({
callback
:
callback
,
once
:
once
})
}
getMessage
(
type
,
callback
){
if
(
type
in
this
.
lastMessages
){
callback
(
this
.
lastMessages
[
type
])
}
}
play
(
circle
,
mekadon
){
if
(
this
.
otherConnected
){
if
(
this
.
notes
.
length
==
0
){
mekadon
.
play
(
circle
)
}
else
{
var
note
=
this
.
notes
[
0
]
if
(
note
.
score
>=
0
){
if
(
mekadon
.
playAt
(
circle
,
note
.
ms
,
note
.
score
)){
this
.
notes
.
shift
()
}
}
else
{
if
(
mekadon
.
miss
(
circle
)){
this
.
notes
.
shift
()
}
}
}
}
}
}
public/src/js/songselect.js
View file @
8e99da6a
...
@@ -56,6 +56,7 @@ function SongSelect(){
...
@@ -56,6 +56,7 @@ function SongSelect(){
this
.
run
=
function
(){
this
.
run
=
function
(){
_this
.
createCode
();
_this
.
createCode
();
_this
.
startP2
();
$
(
"
#song-container
"
).
show
();
$
(
"
#song-container
"
).
show
();
...
@@ -84,7 +85,7 @@ function SongSelect(){
...
@@ -84,7 +85,7 @@ function SongSelect(){
_selectedSong
.
folder
=
songID
;
_selectedSong
.
folder
=
songID
;
snd
.
musicGain
.
fadeIn
()
snd
.
musicGain
.
fadeIn
()
new
loadSong
(
_selectedSong
,
e
.
shiftKey
);
new
loadSong
(
_selectedSong
,
e
.
shiftKey
,
e
.
ctrlKey
);
});
});
$
(
"
.song
"
).
hover
(
function
(){
$
(
"
.song
"
).
hover
(
function
(){
...
@@ -236,6 +237,41 @@ function SongSelect(){
...
@@ -236,6 +237,41 @@ function SongSelect(){
$
(
'
.difficulty
'
).
hide
();
$
(
'
.difficulty
'
).
hide
();
}
}
this
.
onusers
=
function
(
response
){
var
oldP2Elements
=
document
.
getElementsByClassName
(
"
p2
"
)
for
(
var
i
=
oldP2Elements
.
length
;
i
--
;){
oldP2Elements
[
i
].
classList
.
remove
(
"
p2
"
)
}
if
(
response
){
response
.
forEach
(
idDiff
=>
{
id
=
idDiff
.
id
|
0
diff
=
idDiff
.
diff
if
(
diff
in
_diffNames
){
var
idElement
=
document
.
getElementById
(
"
song-
"
+
id
)
if
(
idElement
){
idElement
.
classList
.
add
(
"
p2
"
)
var
diffElement
=
idElement
.
getElementsByClassName
(
"
difficulty
"
+
diff
)[
0
]
if
(
diffElement
){
diffElement
.
classList
.
add
(
"
p2
"
)
}
}
}
})
}
}
this
.
startP2
=
function
(){
p2
.
getMessage
(
"
users
"
,
response
=>
{
this
.
onusers
(
response
)
})
p2
.
onmessage
(
"
users
"
,
response
=>
{
this
.
onusers
(
response
)
})
if
(
p2
.
closed
){
p2
.
open
()
}
}
$
(
"
#screen
"
).
load
(
"
/src/views/songselect.html
"
,
_this
.
run
);
$
(
"
#screen
"
).
load
(
"
/src/views/songselect.html
"
,
_this
.
run
);
}
}
\ No newline at end of file
public/src/js/view.js
View file @
8e99da6a
...
@@ -4,7 +4,14 @@ class View{
...
@@ -4,7 +4,14 @@ class View{
this
.
bg
=
bg
this
.
bg
=
bg
this
.
diff
=
diff
this
.
diff
=
diff
this
.
canvas
=
new
ScalableCanvas
(
"
canvas
"
,
$
(
window
).
width
(),
$
(
window
).
height
())
if
(
this
.
controller
.
multiplayer
==
2
){
this
.
canvas
=
new
ScalableCanvas
(
"
canvas-p2
"
,
$
(
window
).
width
(),
$
(
window
).
height
()
/
3
*
2
)
this
.
canvas
.
canvas
.
style
.
position
=
"
absolute
"
this
.
canvas
.
canvas
.
style
.
top
=
"
33%
"
document
.
getElementById
(
"
game
"
).
appendChild
(
this
.
canvas
.
canvas
)
}
else
{
this
.
canvas
=
new
ScalableCanvas
(
"
canvas
"
,
$
(
window
).
width
(),
$
(
window
).
height
())
}
this
.
winW
=
this
.
canvas
.
scaledWidth
this
.
winW
=
this
.
canvas
.
scaledWidth
this
.
winH
=
this
.
canvas
.
scaledHeight
this
.
winH
=
this
.
canvas
.
scaledHeight
this
.
ctx
=
this
.
canvas
.
ctx
this
.
ctx
=
this
.
canvas
.
ctx
...
@@ -50,9 +57,16 @@ class View{
...
@@ -50,9 +57,16 @@ class View{
positionning
(){
positionning
(){
this
.
canvas
.
rescale
()
this
.
canvas
.
rescale
()
this
.
canvas
.
resize
(
$
(
window
).
width
(),
$
(
window
).
height
())
var
height
=
$
(
window
).
height
()
if
(
this
.
controller
.
multiplayer
==
2
){
height
=
height
/
3
*
2
}
this
.
canvas
.
resize
(
$
(
window
).
width
(),
height
)
this
.
winW
=
this
.
canvas
.
scaledWidth
this
.
winW
=
this
.
canvas
.
scaledWidth
this
.
winH
=
this
.
canvas
.
scaledHeight
this
.
winH
=
this
.
canvas
.
scaledHeight
if
(
this
.
controller
.
multiplayer
==
2
){
this
.
winH
=
this
.
winH
/
2
*
3
}
this
.
barY
=
0.25
*
this
.
winH
this
.
barY
=
0.25
*
this
.
winH
this
.
barH
=
0.23
*
this
.
winH
this
.
barH
=
0.23
*
this
.
winH
...
@@ -113,7 +127,7 @@ class View{
...
@@ -113,7 +127,7 @@ class View{
}
}
updateDonFaces
(){
updateDonFaces
(){
if
(
this
.
controller
.
getEl
l
apsedTime
().
ms
>=
this
.
nextBeat
){
if
(
this
.
controller
.
getElapsedTime
().
ms
>=
this
.
nextBeat
){
this
.
nextBeat
+=
this
.
controller
.
getSongData
().
beatInfo
.
beatInterval
this
.
nextBeat
+=
this
.
controller
.
getSongData
().
beatInfo
.
beatInterval
if
(
this
.
controller
.
getCombo
()
>=
50
){
if
(
this
.
controller
.
getCombo
()
>=
50
){
this
.
currentBigDonFace
=
(
this
.
currentBigDonFace
+
1
)
%
2
this
.
currentBigDonFace
=
(
this
.
currentBigDonFace
+
1
)
%
2
...
@@ -190,7 +204,7 @@ class View{
...
@@ -190,7 +204,7 @@ class View{
drawMeasures
(){
drawMeasures
(){
var
measures
=
this
.
controller
.
getSongData
().
measures
var
measures
=
this
.
controller
.
getSongData
().
measures
var
currentTime
=
this
.
controller
.
getEl
l
apsedTime
().
ms
var
currentTime
=
this
.
controller
.
getElapsedTime
().
ms
measures
.
forEach
((
measure
,
index
)
=>
{
measures
.
forEach
((
measure
,
index
)
=>
{
var
timeForDistance
=
70
/
this
.
circleSize
*
this
.
distanceForCircle
/
measure
.
speed
var
timeForDistance
=
70
/
this
.
circleSize
*
this
.
distanceForCircle
/
measure
.
speed
...
@@ -206,7 +220,7 @@ class View{
...
@@ -206,7 +220,7 @@ class View{
drawMeasure
(
measure
){
drawMeasure
(
measure
){
var
z
=
this
.
canvas
.
scale
var
z
=
this
.
canvas
.
scale
var
currentTime
=
this
.
controller
.
getEl
l
apsedTime
().
ms
var
currentTime
=
this
.
controller
.
getElapsedTime
().
ms
var
measureX
=
this
.
slotX
+
measure
.
speed
/
(
70
/
this
.
circleSize
)
*
(
measure
.
ms
-
currentTime
)
var
measureX
=
this
.
slotX
+
measure
.
speed
/
(
70
/
this
.
circleSize
)
*
(
measure
.
ms
-
currentTime
)
this
.
ctx
.
strokeStyle
=
"
#bab8b8
"
this
.
ctx
.
strokeStyle
=
"
#bab8b8
"
this
.
ctx
.
lineWidth
=
2
this
.
ctx
.
lineWidth
=
2
...
@@ -388,7 +402,7 @@ class View{
...
@@ -388,7 +402,7 @@ class View{
for
(
var
i
=
circles
.
length
;
i
--
;){
for
(
var
i
=
circles
.
length
;
i
--
;){
var
circle
=
circles
[
i
]
var
circle
=
circles
[
i
]
var
currentTime
=
this
.
controller
.
getEl
l
apsedTime
().
ms
var
currentTime
=
this
.
controller
.
getElapsedTime
().
ms
var
timeForDistance
=
70
/
this
.
circleSize
*
this
.
distanceForCircle
/
circle
.
getSpeed
()
+
this
.
bigCircleSize
/
2
var
timeForDistance
=
70
/
this
.
circleSize
*
this
.
distanceForCircle
/
circle
.
getSpeed
()
+
this
.
bigCircleSize
/
2
var
startingTime
=
circle
.
getMS
()
-
timeForDistance
var
startingTime
=
circle
.
getMS
()
-
timeForDistance
// At circle.getMS(), the cirlce fits the slot
// At circle.getMS(), the cirlce fits the slot
...
@@ -459,7 +473,7 @@ class View{
...
@@ -459,7 +473,7 @@ class View{
var
fill
,
size
,
faceID
var
fill
,
size
,
faceID
if
(
!
circlePos
){
if
(
!
circlePos
){
var
currentTime
=
this
.
controller
.
getEl
l
apsedTime
().
ms
var
currentTime
=
this
.
controller
.
getElapsedTime
().
ms
circlePos
=
{
circlePos
=
{
x
:
this
.
slotX
+
circle
.
getSpeed
()
/
(
70
/
this
.
circleSize
)
*
(
circle
.
getMS
()
-
currentTime
),
x
:
this
.
slotX
+
circle
.
getSpeed
()
/
(
70
/
this
.
circleSize
)
*
(
circle
.
getMS
()
-
currentTime
),
y
:
this
.
circleY
y
:
this
.
circleY
...
@@ -549,7 +563,7 @@ class View{
...
@@ -549,7 +563,7 @@ class View{
drawTime
(){
drawTime
(){
var
z
=
this
.
canvas
.
scale
var
z
=
this
.
canvas
.
scale
var
time
=
this
.
controller
.
getEl
l
apsedTime
()
var
time
=
this
.
controller
.
getElapsedTime
()
this
.
ctx
.
globalAlpha
=
0.7
this
.
ctx
.
globalAlpha
=
0.7
this
.
ctx
.
fillStyle
=
"
#000
"
this
.
ctx
.
fillStyle
=
"
#000
"
...
@@ -579,7 +593,7 @@ class View{
...
@@ -579,7 +593,7 @@ class View{
this
.
ctx
.
closePath
()
this
.
ctx
.
closePath
()
this
.
ctx
.
fill
()
this
.
ctx
.
fill
()
var
currentTime
=
this
.
controller
.
getEl
l
apsedTime
().
ms
var
currentTime
=
this
.
controller
.
getElapsedTime
().
ms
var
keyTime
=
this
.
controller
.
getKeyTime
()
var
keyTime
=
this
.
controller
.
getKeyTime
()
var
sound
=
keyTime
[
"
don
"
]
>
keyTime
[
"
ka
"
]
?
"
don
"
:
"
ka
"
var
sound
=
keyTime
[
"
don
"
]
>
keyTime
[
"
ka
"
]
?
"
don
"
:
"
ka
"
if
(
keyTime
[
sound
]
>
currentTime
-
200
){
if
(
keyTime
[
sound
]
>
currentTime
-
200
){
...
...
server.py
0 → 100644
View file @
8e99da6a
#!/usr/bin/env python
import
asyncio
import
websockets
import
json
users
=
[]
server_status
=
{
"waiting"
:
{}
}
def
msgobj
(
type
,
value
=
None
):
if
value
==
None
:
return
json
.
dumps
({
"type"
:
type
})
else
:
return
json
.
dumps
({
"type"
:
type
,
"value"
:
value
})
def
status_event
():
value
=
[]
for
id
,
userDiff
in
server_status
[
"waiting"
]
.
items
():
value
.
append
({
"id"
:
id
,
"diff"
:
userDiff
[
"diff"
]
})
return
msgobj
(
"users"
,
value
)
async
def
notify_status
():
ready_users
=
[
user
for
user
in
users
if
"ws"
in
user
and
user
[
"action"
]
==
"ready"
]
if
ready_users
:
sent_msg
=
status_event
()
await
asyncio
.
wait
([
user
[
"ws"
]
.
send
(
sent_msg
)
for
user
in
ready_users
])
async
def
connection
(
ws
,
path
):
# User connected
user
=
{
"ws"
:
ws
,
"action"
:
"ready"
}
users
.
append
(
user
)
try
:
# Notify user about other users
await
ws
.
send
(
status_event
())
while
True
:
try
:
message
=
await
asyncio
.
wait_for
(
ws
.
recv
(),
timeout
=
5
)
except
asyncio
.
TimeoutError
:
# Keep user connected
pong_waiter
=
await
ws
.
ping
()
try
:
await
asyncio
.
wait_for
(
pong_waiter
,
timeout
=
5
)
except
asyncio
.
TimeoutError
:
# Disconnect
break
else
:
# Message received
try
:
data
=
json
.
loads
(
message
)
except
json
.
decoder
.
JSONDecodeError
:
data
=
{}
action
=
user
[
"action"
]
type
=
data
[
"type"
]
if
"type"
in
data
else
None
value
=
data
[
"value"
]
if
"value"
in
data
else
None
if
action
==
"ready"
:
# Not playing or waiting
if
type
==
"join"
:
waiting
=
server_status
[
"waiting"
]
id
=
value
[
"id"
]
if
"id"
in
value
else
None
diff
=
value
[
"diff"
]
if
"diff"
in
value
else
None
if
not
id
or
not
diff
:
continue
if
id
not
in
waiting
:
# Wait for another user
user
[
"action"
]
=
"waiting"
user
[
"gameid"
]
=
id
waiting
[
id
]
=
{
"user"
:
user
,
"diff"
:
diff
}
await
ws
.
send
(
msgobj
(
"waiting"
))
else
:
# Join the other user and start game
user
[
"other_user"
]
=
waiting
[
id
][
"user"
]
waiting_diff
=
waiting
[
id
][
"diff"
]
del
waiting
[
id
]
if
"ws"
in
user
[
"other_user"
]:
user
[
"action"
]
=
"loading"
user
[
"other_user"
][
"action"
]
=
"loading"
user
[
"other_user"
][
"other_user"
]
=
user
await
asyncio
.
wait
([
ws
.
send
(
msgobj
(
"gameload"
,
waiting_diff
)),
user
[
"other_user"
][
"ws"
]
.
send
(
msgobj
(
"gameload"
,
diff
))
])
else
:
# Wait for another user
user
[
"action"
]
=
"waiting"
user
[
"gameid"
]
=
id
waiting
[
id
]
=
{
"user"
:
user
,
"diff"
:
diff
}
await
ws
.
send
(
msgobj
(
"waiting"
))
# Update others on waiting players
await
notify_status
()
elif
action
==
"waiting"
or
action
==
"loading"
or
action
==
"loaded"
:
# Waiting for another user
if
type
==
"leave"
:
# Stop waiting
del
server_status
[
"waiting"
][
user
[
"gameid"
]]
del
user
[
"gameid"
]
user
[
"action"
]
=
"ready"
await
asyncio
.
wait
([
ws
.
send
(
msgobj
(
"left"
)),
notify_status
()
])
if
action
==
"loading"
:
if
type
==
"gamestart"
:
user
[
"action"
]
=
"loaded"
if
user
[
"other_user"
][
"action"
]
==
"loaded"
:
user
[
"action"
]
=
"playing"
user
[
"other_user"
][
"action"
]
=
"playing"
sent_msg
=
msgobj
(
"gamestart"
)
await
asyncio
.
wait
([
ws
.
send
(
sent_msg
),
user
[
"other_user"
][
"ws"
]
.
send
(
sent_msg
)
])
elif
action
==
"playing"
:
# Playing with another user
if
"other_user"
in
user
and
"ws"
in
user
[
"other_user"
]:
if
type
==
"note"
:
await
user
[
"other_user"
][
"ws"
]
.
send
(
msgobj
(
"note"
,
value
))
if
type
==
"gameend"
:
# User wants to disconnect
user
[
"action"
]
=
"ready"
user
[
"other_user"
][
"action"
]
=
"ready"
sent_msg1
=
msgobj
(
"gameend"
)
sent_msg2
=
status_event
()
await
asyncio
.
wait
([
ws
.
send
(
sent_msg1
),
ws
.
send
(
sent_msg2
),
user
[
"other_user"
][
"ws"
]
.
send
(
sent_msg1
),
user
[
"other_user"
][
"ws"
]
.
send
(
sent_msg2
)
])
del
user
[
"other_user"
]
else
:
# Other user disconnected
user
[
"action"
]
=
"ready"
await
asyncio
.
wait
([
ws
.
send
(
msgobj
(
"gameend"
)),
ws
.
send
(
status_event
())
])
finally
:
# User disconnected
del
user
[
"ws"
]
del
users
[
users
.
index
(
user
)]
if
"other_user"
in
user
and
"ws"
in
user
[
"other_user"
]:
user
[
"other_user"
][
"action"
]
=
"ready"
await
asyncio
.
wait
([
user
[
"other_user"
][
"ws"
]
.
send
(
msgobj
(
"gameend"
)),
user
[
"other_user"
][
"ws"
]
.
send
(
status_event
())
])
if
user
[
"action"
]
==
"waiting"
:
del
server_status
[
"waiting"
][
user
[
"gameid"
]]
await
notify_status
()
asyncio
.
get_event_loop
()
.
run_until_complete
(
websockets
.
serve
(
connection
,
"localhost"
,
34802
)
)
asyncio
.
get_event_loop
()
.
run_forever
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment