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
e8809285
Commit
e8809285
authored
Sep 18, 2018
by
LoveEevee
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Clean up classes before exiting them
parent
f19fbf53
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
1202 additions
and
1191 deletions
+1202
-1191
public/index.html
public/index.html
+1
-1
public/src/css/animations.css
public/src/css/animations.css
+0
-58
public/src/css/loadsong.css
public/src/css/loadsong.css
+20
-20
public/src/css/main.css
public/src/css/main.css
+180
-219
public/src/css/songselect.css
public/src/css/songselect.css
+143
-108
public/src/css/titlescreen.css
public/src/css/titlescreen.css
+33
-45
public/src/js/assets.js
public/src/js/assets.js
+98
-95
public/src/js/controller.js
public/src/js/controller.js
+42
-29
public/src/js/game.js
public/src/js/game.js
+17
-12
public/src/js/keyboard.js
public/src/js/keyboard.js
+134
-145
public/src/js/loader.js
public/src/js/loader.js
+65
-49
public/src/js/loadsong.js
public/src/js/loadsong.js
+38
-30
public/src/js/p2.js
public/src/js/p2.js
+69
-78
public/src/js/pageevents.js
public/src/js/pageevents.js
+115
-0
public/src/js/scoresheet.js
public/src/js/scoresheet.js
+11
-9
public/src/js/songselect.js
public/src/js/songselect.js
+143
-182
public/src/js/soundbuffer.js
public/src/js/soundbuffer.js
+7
-15
public/src/js/titlescreen.js
public/src/js/titlescreen.js
+23
-52
public/src/js/tutorial.js
public/src/js/tutorial.js
+19
-17
public/src/js/view.js
public/src/js/view.js
+25
-12
public/src/views/loader.html
public/src/views/loader.html
+3
-3
public/src/views/loadsong.html
public/src/views/loadsong.html
+5
-5
public/src/views/songselect.html
public/src/views/songselect.html
+4
-3
public/src/views/titlescreen.html
public/src/views/titlescreen.html
+4
-4
server.py
server.py
+3
-0
No files found.
public/index.html
View file @
e8809285
...
...
@@ -22,7 +22,6 @@
<link
rel=
"stylesheet"
href=
"/src/css/scoresheet.css"
>
<link
rel=
"stylesheet"
href=
"/src/css/loadsong.css"
>
<link
rel=
"stylesheet"
href=
"/src/css/game.css"
>
<link
rel=
"stylesheet"
href=
"/src/css/animations.css"
>
<script
src=
"/src/js/lib/jquery.js"
></script>
<script
src=
"/src/js/lib/jquery-ui.js"
></script>
...
...
@@ -47,6 +46,7 @@
<script
src=
"/src/js/soundbuffer.js"
></script>
<script
src=
"/src/js/p2.js"
></script>
<script
src=
"/src/js/canvasasset.js"
></script>
<script
src=
"/src/js/pageevents.js"
></script>
</head>
<body>
...
...
public/src/css/animations.css
deleted
100644 → 0
View file @
f19fbf53
@keyframes
don-normal
{
0
%
{
background-position-y
:
0px
}
6
.35
%
{
background-position-y
:
-184px
}
7
.94
%
{
background-position-y
:
-368px
}
9
.52
%
{
background-position-y
:
-552px
}
11
.11
%
{
background-position-y
:
-736px
}
12
.7
%
{
background-position-y
:
-920px
}
14
.29
%
{
background-position-y
:
-1104px
}
15
.87
%
{
background-position-y
:
-1104px
}
17
.46
%
{
background-position-y
:
-920px
}
19
.05
%
{
background-position-y
:
-736px
}
20
.63
%
{
background-position-y
:
-552px
}
22
.22
%
{
background-position-y
:
-368px
}
23
.81
%
{
background-position-y
:
-184px
}
25
.4
%
{
background-position-y
:
0px
}
31
.75
%
{
background-position-y
:
-184px
}
33
.33
%
{
background-position-y
:
-368px
}
34
.92
%
{
background-position-y
:
-552px
}
36
.51
%
{
background-position-y
:
-736px
}
38
.1
%
{
background-position-y
:
-920px
}
39
.68
%
{
background-position-y
:
-1104px
}
41
.27
%
{
background-position-y
:
-1104px
}
42
.86
%
{
background-position-y
:
-920px
}
44
.44
%
{
background-position-y
:
-736px
}
46
.03
%
{
background-position-y
:
-552px
}
47
.62
%
{
background-position-y
:
-368px
}
49
.21
%
{
background-position-y
:
-184px
}
50
.79
%
{
background-position-y
:
0px
}
57
.14
%
{
background-position-y
:
-184px
}
58
.73
%
{
background-position-y
:
-368px
}
60
.32
%
{
background-position-y
:
-552px
}
61
.9
%
{
background-position-y
:
-736px
}
63
.49
%
{
background-position-y
:
-920px
}
65
.08
%
{
background-position-y
:
-1104px
}
66
.67
%
{
background-position-y
:
-1104px
}
68
.25
%
{
background-position-y
:
-920px
}
69
.84
%
{
background-position-y
:
-1288px
}
71
.43
%
{
background-position-y
:
-1472px
}
73
.02
%
{
background-position-y
:
-1656px
}
74
.6
%
{
background-position-y
:
-1840px
}
76
.19
%
{
background-position-y
:
-2024px
}
77
.78
%
{
background-position-y
:
-2024px
}
79
.37
%
{
background-position-y
:
-2024px
}
80
.95
%
{
background-position-y
:
-2024px
}
82
.54
%
{
background-position-y
:
-1840px
}
84
.13
%
{
background-position-y
:
-1656px
}
85
.71
%
{
background-position-y
:
-1472px
}
87
.3
%
{
background-position-y
:
-1288px
}
88
.89
%
{
background-position-y
:
-2392px
}
90
.48
%
{
background-position-y
:
-2208px
}
92
.06
%
{
background-position-y
:
-2208px
}
93
.65
%
{
background-position-y
:
-2392px
}
95
.24
%
{
background-position-y
:
-2576px
}
96
.83
%
{
background-position-y
:
-2760px
}
98
.41
%
{
background-position-y
:
-2944px
}
100
%
{
background-position-y
:
-3128px
}
}
public/src/css/loadsong.css
View file @
e8809285
#load-song
{
width
:
100%
;
height
:
100%
;
margin
:
0
;
padding
:
0%
;
}
#loading-song
{
width
:
20%
;
height
:
30%
;
position
:
absolute
;
top
:
35%
;
left
:
40%
;
background
:
rgba
(
0
,
0
,
0
,
0.75
);
top
:
0
;
right
:
0
;
bottom
:
0
;
left
:
0
;
margin
:
auto
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
width
:
20vw
;
height
:
15vw
;
background
:
rgba
(
0
,
0
,
0
,
0.75
);
border-radius
:
5px
;
border
:
3px
solid
white
;
border
:
3px
solid
white
;
color
:
#fff
;
}
#loading-don
{
width
:
50%
;
}
.loading-text
{
position
:
relative
;
width
:
50%
;
height
:
65%
;
top
:
12%
;
left
:
30%
;
font-size
:
1.5vw
;
text-align
:
center
;
z-index
:
1
;
}
#loading-song
p
{
position
:
absolute
;
left
:
28%
;
font-size
:
3vmin
;
}
\ No newline at end of file
public/src/css/main.css
View file @
e8809285
@font-face
{
font-family
:
'TnT'
;
src
:
url('../../assets/fonts/TnT.ttf')
format
(
'truetype'
);
@font-face
{
font-family
:
TnT
;
src
:
url("/assets/fonts/TnT.ttf")
format
(
"truetype"
);
}
@font-face
{
font-family
:
'Kozuka'
;
src
:
url('../../assets/fonts/KozGoPro-Bold.otf')
format
(
'truetype'
);
@font-face
{
font-family
:
Kozuka
;
src
:
url("/assets/fonts/KozGoPro-Bold.otf")
format
(
"truetype"
);
}
html
,
body
{
padding
:
0
;
html
,
body
{
margin
:
0
;
width
:
100%
;
width
:
100%
;
height
:
100%
;
background
:
black
;
color
:
white
;
user-select
:
none
;
background
:
#fe7839
;
user-select
:
none
;
}
#screen
{
width
:
100%
;
height
:
100%
;
margin
:
0
;
padding
:
0
;
background
:
url('/assets/img/bg-pattern-1.png')
top
center
;
width
:
100%
;
height
:
100%
;
margin
:
0
;
padding
:
0
;
background
:
#fe7839
url("/assets/img/bg-pattern-1.png")
top
center
;
font-family
:
TnT
;
}
#assets
{
display
:
none
;
display
:
none
;
}
.window
{
width
:
60vmin
;
height
:
23vmin
;
padding
:
3vmin
;
color
:
black
;
background
:
rgba
(
255
,
220
,
47
,
0.95
);
border
:
.5vmin
outset
#f4ae00
;
box-shadow
:
2px
2px
10px
black
;
margin
:
auto
;
position
:
fixed
;
top
:
0
;
right
:
0
;
bottom
:
0
;
left
:
0
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
}
.stroke-main
{
font-weight
:
300
;
}
.result-title
{
margin-top
:
9px
!important
;
margin-left
:
5px
!important
;
z-index
:
1
;
}
.result-song
,
.game-song
{
position
:
absolute
;
right
:
0
;
font-size
:
5vmin
;
margin
:
3vmin
3vmin
0px
0px
;
color
:
white
;
float
:
right
;
z-index
:
1
;
font-weight
:
300
;
}
.stroke-main
:before
{
content
:
attr
(
alt
);
left
:
0
;
z-index
:
-1
;
position
:
absolute
;
-webkit-text-stroke
:
0.3em
#fb3c0c
;
}
.stroke-main
:after
{
content
:
attr
(
alt
);
left
:
0
;
z-index
:
-2
;
position
:
absolute
;
-webkit-text-stroke
:
0.5em
#000
;
}
.stroke-sub
:before
{
content
:
attr
(
alt
);
position
:
absolute
;
-webkit-text-stroke
:
0.25em
#000
;
left
:
0
;
z-index
:
-1
;
}
.songsel-title
{
position
:
absolute
;
z-index
:
1
;
font-size
:
7vmin
;
margin
:
20px
;
}
.click-to-continue
:before
{
width
:
100%
;
}
.don
{
background-position-y
:
0
;
position
:
absolute
;
top
:
0px
;
}
.alpha-title
.song-title-char
{
transform
:
scale
(
1.3
,
1
);
font-size
:
80%
;
line-height
:
22px
;
}
.song-title-apos
{
padding-left
:
4px
;
}
.song-title-char
[
alt
=
"ぁ"
],
.song-title-char
[
alt
=
"ぃ"
],
.song-title-char
[
alt
=
"ぅ"
],
.song-title-char
[
alt
=
"ぇ"
],
.song-title-char
[
alt
=
"ぉ"
],
.song-title-char
[
alt
=
"ゃ"
],
.song-title-char
[
alt
=
"ゅ"
],
.song-title-char
[
alt
=
"ょ"
],
.song-title-char
[
alt
=
"っ"
],
.song-title-char
[
alt
=
"ァ"
],
.song-title-char
[
alt
=
"ィ"
],
.song-title-char
[
alt
=
"ゥ"
],
.song-title-char
[
alt
=
"ェ"
],
.song-title-char
[
alt
=
"ォ"
],
.song-title-char
[
alt
=
"ャ"
],
.song-title-char
[
alt
=
"ュ"
],
.song-title-char
[
alt
=
"ョ"
],
.song-title-char
[
alt
=
"ッ"
]
{
margin-top
:
-6px
;
}
.song-title-char
[
alt
=
"ー"
],
.song-title-char
[
alt
=
"-"
]
{
transform
:
rotate
(
95deg
);
font-size
:
90%
;
}
#tutorial-outer
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
overflow
:
hidden
;
position
:
absolute
;
width
:
100%
;
height
:
100%
;
}
#tutorial
{
background
:
rgb
(
246
,
234
,
212
);
color
:
black
;
border
:
5px
black
solid
;
border-radius
:
10px
;
height
:
65%
;
width
:
50%
;
padding
:
20px
;
font-size
:
16pt
;
position
:
relative
;
}
#tutorial-title
{
z-index
:
1
;
position
:
absolute
;
color
:
white
;
top
:
-25px
;
font-size
:
26pt
;
}
#tutorial-content
{
padding
:
15px
30px
;
}
kbd
{
font-family
:
inherit
;
padding
:
0.1em
0.6em
;
border
:
1px
solid
#ccc
;
font-size
:
13px
;
background-color
:
#f7f7f7
;
color
:
#333
;
-moz-box-shadow
:
0
1px
0px
rgba
(
0
,
0
,
0
,
0.2
),
0
0
0
2px
#ffffff
inset
;
-webkit-box-shadow
:
0
1px
0px
rgba
(
0
,
0
,
0
,
0.2
),
0
0
0
2px
#ffffff
inset
;
box-shadow
:
0
1px
0px
rgba
(
0
,
0
,
0
,
0.2
),
0
0
0
2px
#ffffff
inset
;
-moz-border-radius
:
3px
;
-webkit-border-radius
:
3px
;
border-radius
:
3px
;
display
:
inline-block
;
text-shadow
:
0
1px
0
#fff
;
line-height
:
1.4
;
white-space
:
nowrap
;
}
.taibtn
{
bottom
:
15px
;
margin
:
0
auto
;
position
:
absolute
;
right
:
15px
;
padding
:
10px
40px
;
border-radius
:
15px
;
border
:
3px
rgba
(
218
,
205
,
178
,
1
)
solid
;
cursor
:
pointer
;
}
.taibtn
:hover
{
z-index
:
1
;
color
:
white
;
background
:
rgb
(
255
,
181
,
71
);
border-color
:
white
;
}
.taibtn
:before
{
padding
:
0
40px
;
}
#tutorial-end-button
{
font-size
:
22pt
;
}
#songsel-help
{
float
:
right
;
background
:
rgba
(
255
,
255
,
255
,
0.5
);
color
:
black
;
padding
:
15px
;
margin
:
10px
;
font-size
:
18px
;
border
:
3px
black
solid
;
border-radius
:
50px
;
cursor
:
pointer
;
}
\ No newline at end of file
width
:
60vmin
;
height
:
23vmin
;
padding
:
3vmin
;
color
:
black
;
background
:
rgba
(
255
,
220
,
47
,
0.95
);
border
:
.5vmin
outset
#f4ae00
;
box-shadow
:
2px
2px
10px
black
;
margin
:
auto
;
position
:
fixed
;
top
:
0
;
right
:
0
;
bottom
:
0
;
left
:
0
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
}
.stroke-main
{
font-weight
:
300
;
}
.result-title
{
margin-top
:
9px
!important
;
margin-left
:
5px
!important
;
z-index
:
1
;
}
.result-song
,
.game-song
{
position
:
absolute
;
right
:
0
;
font-size
:
5vmin
;
margin
:
3vmin
3vmin
0px
0px
;
color
:
white
;
float
:
right
;
z-index
:
1
;
font-weight
:
300
;
}
.stroke-main
::before
{
content
:
attr
(
alt
);
left
:
0
;
z-index
:
-1
;
position
:
absolute
;
-webkit-text-stroke
:
0.3em
#fb3c0c
;
}
.stroke-main
::after
{
content
:
attr
(
alt
);
left
:
0
;
z-index
:
-2
;
position
:
absolute
;
-webkit-text-stroke
:
0.5em
#000
;
}
.stroke-sub
::before
{
content
:
attr
(
alt
);
position
:
absolute
;
-webkit-text-stroke
:
0.25em
#000
;
left
:
0
;
z-index
:
-1
;
}
.don
{
background-position-y
:
0
;
position
:
absolute
;
top
:
0px
;
}
.alpha-title
.song-title-char
{
transform
:
scale
(
1.3
,
1
);
font-size
:
80%
;
line-height
:
22px
;
}
.song-title-apos
{
padding-left
:
4px
;
}
.song-title-char
[
alt
=
"ぁ"
],
.song-title-char
[
alt
=
"ぃ"
],
.song-title-char
[
alt
=
"ぅ"
],
.song-title-char
[
alt
=
"ぇ"
],
.song-title-char
[
alt
=
"ぉ"
],
.song-title-char
[
alt
=
"ゃ"
],
.song-title-char
[
alt
=
"ゅ"
],
.song-title-char
[
alt
=
"ょ"
],
.song-title-char
[
alt
=
"っ"
],
.song-title-char
[
alt
=
"ァ"
],
.song-title-char
[
alt
=
"ィ"
],
.song-title-char
[
alt
=
"ゥ"
],
.song-title-char
[
alt
=
"ェ"
],
.song-title-char
[
alt
=
"ォ"
],
.song-title-char
[
alt
=
"ャ"
],
.song-title-char
[
alt
=
"ュ"
],
.song-title-char
[
alt
=
"ョ"
],
.song-title-char
[
alt
=
"ッ"
]
{
margin-top
:
-6px
;
}
.song-title-char
[
alt
=
"ー"
],
.song-title-char
[
alt
=
"-"
]
{
transform
:
rotate
(
95deg
);
font-size
:
90%
;
}
#tutorial-outer
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
overflow
:
hidden
;
position
:
absolute
;
width
:
100%
;
height
:
100%
;
}
#tutorial
{
background
:
rgb
(
246
,
234
,
212
);
color
:
black
;
border
:
5px
black
solid
;
border-radius
:
10px
;
height
:
65%
;
width
:
50%
;
padding
:
20px
;
font-size
:
16pt
;
position
:
relative
;
}
#tutorial-title
{
z-index
:
1
;
position
:
absolute
;
color
:
white
;
top
:
-25px
;
font-size
:
26pt
;
}
#tutorial-content
{
padding
:
15px
30px
;
}
kbd
{
font-family
:
inherit
;
padding
:
0.1em
0.6em
;
border
:
1px
solid
#ccc
;
font-size
:
13px
;
background-color
:
#f7f7f7
;
color
:
#333
;
box-shadow
:
0
1px
0px
rgba
(
0
,
0
,
0
,
0.2
),
0
0
0
2px
#ffffff
inset
;
border-radius
:
3px
;
display
:
inline-block
;
text-shadow
:
0
1px
0
#fff
;
line-height
:
1.4
;
white-space
:
nowrap
;
}
.taibtn
{
bottom
:
15px
;
margin
:
0
auto
;
position
:
absolute
;
right
:
15px
;
padding
:
10px
40px
;
border-radius
:
15px
;
border
:
3px
rgba
(
218
,
205
,
178
,
1
)
solid
;
cursor
:
pointer
;
}
.taibtn
:hover
{
z-index
:
1
;
color
:
white
;
background
:
rgb
(
255
,
181
,
71
);
border-color
:
white
;
}
.taibtn
::before
{
padding
:
0
40px
;
}
#tutorial-end-button
{
font-size
:
22pt
;
}
public/src/css/songselect.css
View file @
e8809285
@-webkit-keyframes
bgscroll
{
from
{
background-position
:
0
0
;}
to
{
background-position
:
-200px
0
;}
@-webkit-keyframes
bgscroll
{
from
{
background-position
:
0
0
;
}
to
{
background-position
:
-200px
0
;
}
}
@keyframes
bgscroll
{
from
{
background-position
:
0
0
;
}
to
{
background-position
:
-200px
0
;
}
}
@keyframes
bgscroll
{
from
{
background-position
:
0
0
;}
to
{
background-position
:
-200px
0
;}
}
#song-select
{
width
:
100%
;
height
:
100%
;
background
:
url(
'/assets/img/bg-pattern-1.png'
)
;
height
:
100%
;
background
:
url(
"/assets/img/bg-pattern-1.png"
)
;
animation
:
bgscroll
3s
infinite
linear
;
-webkit-animation
:
bgscroll
3s
infinite
linear
;
white-space
:
nowrap
;
}
#song-container
{
width
:
98%
;
height
:
80%
;
width
:
98%
;
height
:
80%
;
padding
:
5%
1%
1%
1%
;
text-align
:
center
;
text-align
:
center
;
}
ul
li
{
list-style
:
none
;
list-style
:
none
;
}
.difficulties
{
float
:
left
;
display
:
inline-block
;
width
:
70%
;
height
:
100%
;
}
.song-title-char
{
text-align
:
center
;
width
:
45px
;
display
:
block
;
}
.song-title-char
:before
{
content
:
attr
(
alt
);
position
:
absolute
;
-webkit-text-stroke
:
0.25em
#000
;
z-index
:
-1
;
}
position
:
absolute
;
left
:
0
;
display
:
block
;
width
:
303px
;
height
:
100%
;
opacity
:
0
;
transition
:
opacity
0.1s
;
}
.song.opened
.difficulties
{
opacity
:
1
;
transition
:
opacity
0.1s
0.2s
;
}
.song-title-char
{
text-align
:
center
;
width
:
45px
;
display
:
block
;
}
.song-title-char
::before
{
content
:
attr
(
alt
);
position
:
absolute
;
-webkit-text-stroke
:
0.25em
#000
;
z-index
:
-1
;
}
.song-title
{
float
:
right
;
width
:
45px
;
padding
:
10px
2px
;
word-wrap
:
break-word
;
font-size
:
22pt
;
color
:
white
;
position
:
relative
;
z-index
:
1
;
line-height
:
28px
;
}
.song-title-space
{
line-height
:
25px
;
}
float
:
right
;
width
:
45px
;
height
:
100%
;
padding
:
10px
2px
;
word-wrap
:
break-word
;
font-size
:
22pt
;
color
:
white
;
position
:
relative
;
z-index
:
1
;
line-height
:
28px
;
}
.song-title-space
{
line-height
:
25px
;
}
.song
{
font-size
:
14pt
;
width
:
50px
;
margin-right
:
15px
;
height
:
100%
;
color
:
black
;
display
:
inline-block
;
background
:
rgba
(
255
,
220
,
47
,
0.90
);
border
:
7px
outset
#f4ae00
;
box-shadow
:
2px
2px
10px
black
;
overflow
:
hidden
;
font-size
:
14pt
;
width
:
50px
;
margin-right
:
15px
;
height
:
100%
;
color
:
black
;
display
:
inline-block
;
background
:
rgba
(
255
,
220
,
47
,
0.90
);
border
:
7px
outset
#f4ae00
;
box-shadow
:
2px
2px
10px
black
;
overflow
:
hidden
;
cursor
:
pointer
;
position
:
relative
;
transition
:
width
0.3s
;
}
.song
:not
(
.opened
)
:hover
{
background
:
rgba
(
255
,
233
,
125
,
0.90
);
}
.opened
{
width
:
375px
;
width
:
375px
;
}
.difficulty
{
display
:
none
;
cursor
:
pointer
;
width
:
35px
;
height
:
70%
;
border-radius
:
5px
;
display
:
inline-block
;
margin
:
5px
;
float
:
left
;
background
:
white
;
border
:
10px
solid
#ae7a26
;
position
:
relative
;
}
display
:
none
;
cursor
:
pointer
;
width
:
35px
;
height
:
70%
;
border-radius
:
5px
;
display
:
inline-block
;
margin
:
5px
;
float
:
left
;
background
:
white
;
border
:
10px
solid
#ae7a26
;
position
:
relative
;
}
.difficulty
.diffname
{
word-wrap
:
break-word
;
width
:
20px
;
display
:
block
;
margin
:
auto
;
margin-top
:
10px
;
font-size
:
20pt
;
margin-left
:
6px
;
}
word-wrap
:
break-word
;
width
:
20px
;
display
:
block
;
margin
:
auto
;
margin-top
:
10px
;
font-size
:
20pt
;
margin-left
:
6px
;
white-space
:
normal
;
}
.difficulty
.stars
{
position
:
absolute
;
color
:
#f12b69
;
margin-left
:
-17px
;
width
:
100%
;
bottom
:
10px
;
position
:
absolute
;
color
:
#f12b69
;
margin-left
:
-17px
;
width
:
100%
;
bottom
:
10px
;
}
.difficulty
:hover
{
border-color
:
#fa5d3a
;
color
:
white
;
background
:
#0c6577
;
border-color
:
#fa5d3a
;
color
:
white
;
background
:
#0c6577
;
}
.difficulty
:hover
.diffname
{
-webkit-text-stroke-width
:
1px
;
-webkit-text-stroke-color
:
black
;
-webkit-text-stroke-width
:
1px
;
-webkit-text-stroke-color
:
black
;
}
.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%
;
content
:
"P2"
;
display
:
block
;
position
:
absolute
;
bottom
:
0
;
width
:
100%
;
}
#songsel-help
{
float
:
right
;
background
:
rgba
(
255
,
255
,
255
,
0.5
);
color
:
black
;
padding
:
15px
;
margin
:
10px
;
font-size
:
18px
;
border
:
3px
black
solid
;
border-radius
:
50px
;
cursor
:
pointer
;
}
.songsel-title-song
,
.songsel-title-difficulty
{
position
:
absolute
;
left
:
-300px
;
opacity
:
0
;
margin
:
20px
;
color
:
#fff
;
font-size
:
7vmin
;
z-index
:
1
;
transition
:
left
0s
0.2s
,
opacity
0.2s
;
}
#song-select
.difficulty-select
.songsel-title-difficulty
{
left
:
0
;
opacity
:
1
;
transition
:
left
0.4s
0.2s
,
opacity
0.4s
0.2s
;
}
#song-select
:not
(
.difficulty-select
)
.songsel-title-song
{
left
:
0
;
opacity
:
1
;
transition
:
left
0.4s
0.2s
,
opacity
0.4s
0.2s
;
}
public/src/css/titlescreen.css
View file @
e8809285
@keyframes
toggleFade
{
0
%
{
opacity
:
1
;
}
50
%
{
opacity
:
0
;
}
@keyframes
toggleFade
{
40
%
{
opacity
:
1
;
}
70
%
{
opacity
:
0.2
;
}
}
#title-screen
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
display
:
none
;
margin
:
0px
;
cursor
:
pointer
;
background
:
url('/assets/img/title-screen.png')
;
-webkit-background-size
:
cover
;
/* pour Chrome et Safari */
-moz-background-size
:
cover
;
/* pour Firefox */
-o-background-size
:
cover
;
/* pour Opera */
background-size
:
cover
;
/* version standardis�e */
position
:
absolute
;
top
:
0
;
right
:
0
;
bottom
:
0
;
left
:
0
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
background
:
#1389f0
url("/assets/img/title-screen.png")
no-repeat
center
;
background-size
:
cover
;
cursor
:
pointer
;
}
.logo-big
{
width
:
90vmin
;
height
:
auto
;
}
#logo-big-cont
{
.click-to-continue
{
position
:
absolute
;
max-width
:
654px
;
max-height
:
300px
;
bottom
:
10%
;
color
:
#fff
;
font-size
:
8vmin
;
text-align
:
center
;
z-index
:
1
;
animation
:
toggleFade
2s
infinite
ease-in-out
;
}
#logo-big-cont
img
{
width
:
100%
;
height
:
100%
;
.click-to-continue
::before
{
-webkit-text-stroke
:
0.25em
#f00
;
filter
:
blur
(
0.3vmin
)
;
left
:
auto
;
}
.click-to-continue
{
display
:
block
;
font-size
:
8vmin
;
color
:
white
;
text-align
:
center
;
position
:
absolute
;
bottom
:
2%
;
width
:
100%
;
animation
:
toggleFade
1s
infinite
ease-out
;
z-index
:
1
;
}
\ No newline at end of file
public/src/js/assets.js
View file @
e8809285
var
assets
=
{
img
:
[
'
background.png
'
,
'
title-screen.png
'
,
'
logo-big.png
'
,
'
don-0.png
'
,
'
don-1.png
'
,
'
big-don-0.png
'
,
'
big-don-1.png
'
,
'
taiko.png
'
,
'
taiko-key-blue.png
'
,
'
taiko-key-red.png
'
,
'
hp-bar-bg.png
'
,
'
hp-bar-colour.png
'
,
'
score-0.png
'
,
'
score-0-b.png
'
,
'
score-230.png
'
,
'
score-450.png
'
,
'
dancing-don.gif
'
,
'
scoresheet.jpg
'
,
'
bg-pattern-1.png
'
,
'
bg-pattern-2.png
'
,
'
ranking-S.png
'
,
'
ranking-X.png
'
,
'
muzu_easy.png
'
,
'
muzu_normal.png
'
,
'
muzu_hard.png
'
,
'
muzu_oni.png
'
,
'
don_anim_normal.png
'
,
'
don_anim_10combo.png
'
,
'
balloon.png
'
"
img
"
:
[
"
background.png
"
,
"
title-screen.png
"
,
"
logo-big.png
"
,
"
don-0.png
"
,
"
don-1.png
"
,
"
big-don-0.png
"
,
"
big-don-1.png
"
,
"
taiko.png
"
,
"
taiko-key-blue.png
"
,
"
taiko-key-red.png
"
,
"
hp-bar-bg.png
"
,
"
hp-bar-colour.png
"
,
"
score-0.png
"
,
"
score-0-b.png
"
,
"
score-230.png
"
,
"
score-450.png
"
,
"
dancing-don.gif
"
,
"
scoresheet.jpg
"
,
"
bg-pattern-1.png
"
,
"
bg-pattern-2.png
"
,
"
ranking-S.png
"
,
"
ranking-X.png
"
,
"
muzu_easy.png
"
,
"
muzu_normal.png
"
,
"
muzu_hard.png
"
,
"
muzu_oni.png
"
,
"
don_anim_normal.png
"
,
"
don_anim_10combo.png
"
,
"
balloon.png
"
],
audioSfx
:
[
'
start.wav
'
,
'
don.wav
'
,
'
ka.wav
'
,
"
audioSfx
"
:
[
"
start.wav
"
,
"
don.wav
"
,
"
ka.wav
"
,
'
combo-50.wav
'
,
'
combo-100.wav
'
,
'
combo-200.wav
'
,
'
combo-300.wav
'
,
'
combo-400.wav
'
,
'
combo-500.wav
'
,
'
combo-600.wav
'
,
'
combo-700.wav
'
,
'
combo-800.wav
'
,
'
combo-900.wav
'
,
'
combo-1000.wav
'
,
'
combo-1100.wav
'
,
'
combo-1200.wav
'
,
'
combo-1300.wav
'
,
'
combo-1400.wav
'
,
'
fullcombo.wav
'
,
"
combo-50.wav
"
,
"
combo-100.wav
"
,
"
combo-200.wav
"
,
"
combo-300.wav
"
,
"
combo-400.wav
"
,
"
combo-500.wav
"
,
"
combo-600.wav
"
,
"
combo-700.wav
"
,
"
combo-800.wav
"
,
"
combo-900.wav
"
,
"
combo-1000.wav
"
,
"
combo-1100.wav
"
,
"
combo-1200.wav
"
,
"
combo-1300.wav
"
,
"
combo-1400.wav
"
,
"
fullcombo.wav
"
,
'
combo-50-meka.wav
'
,
'
combo-100-meka.wav
'
,
'
combo-200-meka.wav
'
,
'
combo-300-meka.wav
'
,
'
combo-400-meka.wav
'
,
'
combo-500-meka.wav
'
,
'
combo-600-meka.wav
'
,
'
combo-700-meka.wav
'
,
'
combo-800-meka.wav
'
,
'
combo-900-meka.wav
'
,
'
combo-1000-meka.wav
'
,
'
combo-1100-meka.wav
'
,
'
combo-1200-meka.wav
'
,
'
combo-1300-meka.wav
'
,
'
combo-1400-meka.wav
'
,
'
fullcombo-meka.wav
'
,
"
combo-50-meka.wav
"
,
"
combo-100-meka.wav
"
,
"
combo-200-meka.wav
"
,
"
combo-300-meka.wav
"
,
"
combo-400-meka.wav
"
,
"
combo-500-meka.wav
"
,
"
combo-600-meka.wav
"
,
"
combo-700-meka.wav
"
,
"
combo-800-meka.wav
"
,
"
combo-900-meka.wav
"
,
"
combo-1000-meka.wav
"
,
"
combo-1100-meka.wav
"
,
"
combo-1200-meka.wav
"
,
"
combo-1300-meka.wav
"
,
"
combo-1400-meka.wav
"
,
"
fullcombo-meka.wav
"
,
'
song-select.wav
'
,
'
title.ogg
'
,
'
pause.wav
'
,
'
cancel.wav
'
,
'
results.wav
'
,
'
diffsel.wav
'
,
"
song-select.wav
"
,
"
title.ogg
"
,
"
pause.wav
"
,
"
cancel.wav
"
,
"
results.wav
"
,
"
diffsel.wav
"
,
'
gamefullcombo.wav
'
,
'
gameclear.wav
'
,
'
gamefail.wav
'
,
"
gamefullcombo.wav
"
,
"
gameclear.wav
"
,
"
gamefail.wav
"
,
'
note_don.ogg
'
,
'
note_ka.ogg
'
,
'
balloon.ogg
'
"
note_don.ogg
"
,
"
note_ka.ogg
"
,
"
balloon.ogg
"
],
audioMusic
:[
'
bgm_songsel.ogg
'
,
'
bgm_result.ogg
'
,
'
bgm_setsume.ogg
'
"
audioMusic
"
:
[
"
bgm_songsel.ogg
"
,
"
bgm_result.ogg
"
,
"
bgm_setsume.ogg
"
],
songs
:
[],
fonts
:
[
'
Kozuka
'
,
'
TnT
'
"
fonts
"
:
[
"
Kozuka
"
,
"
TnT
"
],
"
views
"
:
[
"
game.html
"
,
"
loadsong.html
"
,
"
scoresheet.html
"
,
"
songselect.html
"
,
"
titlescreen.html
"
,
"
tutorial.html
"
],
sounds
:
{},
image
:
{}
};
\ No newline at end of file
"
songs
"
:
[],
"
sounds
"
:
{},
"
image
"
:
{},
"
pages
"
:
{}
}
public/src/js/controller.js
View file @
e8809285
...
...
@@ -4,7 +4,6 @@ class Controller{
this
.
songData
=
songData
this
.
autoPlayEnabled
=
autoPlayEnabled
this
.
multiplayer
=
multiplayer
this
.
pauseMenu
=
false
var
backgroundURL
=
"
/songs/
"
+
this
.
selectedSong
.
folder
+
"
/bg.png
"
var
songParser
=
new
ParseSong
(
songData
)
...
...
@@ -40,16 +39,19 @@ class Controller{
}
}
loadUIEvents
(){
$
(
"
#song-selection-butt
"
).
click
(()
=>
{
assets
.
sounds
[
"
don
"
].
play
()
this
.
songSelection
()
this
.
continueBtn
=
document
.
getElementById
(
"
song-selection-butt
"
)
this
.
restartBtn
=
document
.
getElementById
(
"
song-selection-butt
"
)
this
.
songSelBtn
=
document
.
getElementById
(
"
song-selection-butt
"
)
pageEvents
.
add
(
this
.
continueBtn
,
"
click
"
,
()
=>
{
this
.
togglePauseMenu
()
})
$
(
"
#restart-butt
"
).
click
(
()
=>
{
pageEvents
.
add
(
this
.
restartBtn
,
"
click
"
,
()
=>
{
assets
.
sounds
[
"
don
"
].
play
()
this
.
restartSong
()
})
$
(
"
#continue-butt
"
).
click
(()
=>
{
this
.
togglePauseMenu
()
pageEvents
.
add
(
this
.
songSelBtn
,
"
click
"
,
()
=>
{
assets
.
sounds
[
"
don
"
].
play
()
this
.
songSelection
()
})
}
startMainLoop
(){
...
...
@@ -66,7 +68,7 @@ class Controller{
}
mainLoop
(){
if
(
this
.
mainLoopRunning
){
if
(
this
.
multiplayer
!=
2
){
if
(
this
.
multiplayer
!=
=
2
){
requestAnimationFrame
(()
=>
{
if
(
this
.
syncWith
){
this
.
syncWith
.
game
.
elapsedTime
.
ms
=
this
.
game
.
elapsedTime
.
ms
...
...
@@ -87,6 +89,9 @@ class Controller{
}
if
(
this
.
mainLoopStarted
){
this
.
game
.
update
()
if
(
!
this
.
mainLoopRunning
){
return
}
this
.
game
.
playMainMusic
()
}
this
.
view
.
refresh
()
...
...
@@ -99,10 +104,10 @@ class Controller{
this
.
togglePause
()
this
.
view
.
togglePauseMenu
()
}
displayResults
(){
gameEnded
(){
var
score
=
this
.
getGlobalScore
()
var
vp
if
(
score
.
fail
==
0
){
if
(
score
.
fail
==
=
0
){
vp
=
"
fullcombo
"
this
.
playSoundMeka
(
"
fullcombo
"
,
1.350
)
}
else
if
(
score
.
hp
>=
50
){
...
...
@@ -111,33 +116,29 @@ class Controller{
vp
=
"
fail
"
}
assets
.
sounds
[
"
game
"
+
vp
].
play
()
setTimeout
(()
=>
{
if
(
this
.
mainLoopRunning
){
this
.
stopMainLoop
()
if
(
this
.
multiplayer
!=
2
){
new
Scoresheet
(
this
,
this
.
getGlobalScore
(),
this
.
multiplayer
)
}
}
},
7000
)
}
displayResults
(){
this
.
clean
()
if
(
this
.
multiplayer
!==
2
){
new
Scoresheet
(
this
,
this
.
getGlobalScore
(),
this
.
multiplayer
)
}
}
displayScore
(
score
,
notPlayed
){
this
.
view
.
displayScore
(
score
,
notPlayed
)
}
songSelection
(){
$
(
"
#music-bg
"
).
remove
()
this
.
stopMainLoop
()
this
.
clean
()
new
SongSelect
()
}
restartSong
(){
this
.
stopMainLoop
()
$
(
"
#screen
"
).
load
(
"
/src/views/game.html
"
,
()
=>
{
if
(
this
.
multiplayer
){
new
loadSong
(
this
.
selectedSong
,
false
,
true
)
}
else
{
var
taikoGame
=
new
Controller
(
this
.
selectedSong
,
this
.
songData
,
this
.
autoPlayEnabled
)
taikoGame
.
run
()
}
})
this
.
clean
()
if
(
this
.
multiplayer
){
new
loadSong
(
this
.
selectedSong
,
false
,
true
)
}
else
{
loader
.
changePage
(
"
game
"
)
var
taikoGame
=
new
Controller
(
this
.
selectedSong
,
this
.
songData
,
this
.
autoPlayEnabled
)
taikoGame
.
run
()
}
}
playSoundMeka
(
soundID
,
time
){
var
meka
=
""
...
...
@@ -195,4 +196,16 @@ class Controller{
this
.
mekadon
.
play
(
circle
)
}
}
clean
(){
this
.
stopMainLoop
()
this
.
keyboard
.
clean
()
this
.
view
.
clean
()
pageEvents
.
remove
(
this
.
continueBtn
,
"
click
"
)
delete
this
.
continueBtn
pageEvents
.
remove
(
this
.
restartBtn
,
"
click
"
)
delete
this
.
restartBtn
pageEvents
.
remove
(
this
.
songSelBtn
,
"
click
"
)
delete
this
.
songSelBtn
}
}
public/src/js/game.js
View file @
e8809285
...
...
@@ -219,27 +219,32 @@ class Game{
whenLastCirclePlayed
(){
var
circles
=
this
.
songData
.
circles
var
lastCircle
=
circles
[
this
.
songData
.
circles
.
length
-
1
]
if
(
!
this
.
fadeOutStarted
&&
this
.
getElapsedTime
().
ms
>=
lastCircle
.
getEndTime
()
+
1900
){
this
.
fadeOutStarted
=
this
.
getElapsedTime
().
ms
var
ms
=
this
.
getElapsedTime
().
ms
if
(
!
this
.
fadeOutStarted
&&
ms
>=
lastCircle
.
getEndTime
()
+
1900
){
this
.
fadeOutStarted
=
ms
}
}
whenFadeoutMusic
(){
if
(
this
.
fadeOutStarted
){
if
(
this
.
musicFadeOut
==
0
){
var
started
=
this
.
fadeOutStarted
if
(
started
){
var
ms
=
this
.
getElapsedTime
().
ms
if
(
this
.
musicFadeOut
===
0
){
snd
.
musicGain
.
fadeOut
(
1.6
)
if
(
this
.
controller
.
multiplayer
==
1
){
if
(
this
.
controller
.
multiplayer
==
=
1
){
p2
.
send
(
"
gameresults
"
,
this
.
controller
.
getGlobalScore
())
}
this
.
musicFadeOut
++
}
if
(
this
.
musicFadeOut
==
1
&&
this
.
getElapsedTime
().
ms
>=
this
.
fadeOutStarted
+
1600
){
this
.
controller
.
displayResults
()
}
else
if
(
this
.
musicFadeOut
===
1
&&
ms
>=
started
+
1600
){
this
.
controller
.
gameEnded
()
this
.
mainAsset
.
stop
()
p2
.
send
(
"
gameend
"
)
setTimeout
(()
=>
{
snd
.
musicGain
.
fadeIn
()
snd
.
musicGain
.
unmute
()
},
1000
)
this
.
musicFadeOut
++
}
else
if
(
this
.
musicFadeOut
===
2
&&
ms
>=
started
+
2600
){
snd
.
musicGain
.
fadeIn
()
snd
.
musicGain
.
unmute
()
this
.
musicFadeOut
++
}
else
if
(
this
.
musicFadeOut
===
3
&&
ms
>=
started
+
8600
){
this
.
controller
.
displayResults
()
this
.
musicFadeOut
++
}
}
...
...
public/src/js/keyboard.js
View file @
e8809285
function
Keyboard
(
controller
){
var
_kbd
=
{
"
don_l
"
:
86
,
// V
"
don_r
"
:
66
,
// B
"
ka_l
"
:
67
,
// C
"
ka_r
"
:
78
,
// N
"
pause
"
:
81
,
// Q
"
back
"
:
8
// Backspace
}
var
_this
=
this
;
var
_keys
=
{};
var
_waitKeyupScore
=
{};
var
_waitKeyupSound
=
{};
var
_waitKeyupMenu
=
{};
var
_keyTime
=
{
"
don
"
:
-
Infinity
,
"
ka
"
:
-
Infinity
}
this
.
getBindings
=
function
(){
return
_kbd
}
var
_gamepad
=
new
Gamepad
(
this
)
$
(
document
).
keydown
(
function
(
e
){
if
(
e
.
which
===
8
&&
!
$
(
e
.
target
).
is
(
"
input, textarea
"
))
// Disable back navigation when pressing backspace
e
.
preventDefault
();
if
(
_this
.
buttonEnabled
(
e
.
which
)){
_this
.
setKey
(
e
.
which
,
true
);
}
});
$
(
document
).
keyup
(
function
(
e
){
if
(
_this
.
buttonEnabled
(
e
.
which
)){
_this
.
setKey
(
e
.
which
,
false
);
}
});
this
.
buttonEnabled
=
function
(
keyCode
){
if
(
controller
.
autoPlayEnabled
){
switch
(
keyCode
){
case
_kbd
[
"
don_l
"
]:
case
_kbd
[
"
don_r
"
]:
case
_kbd
[
"
ka_l
"
]:
case
_kbd
[
"
ka_r
"
]:
return
false
}
}
return
true
}
this
.
checkGameKeys
=
function
(){
if
(
!
controller
.
autoPlayEnabled
){
_gamepad
.
play
()
}
_this
.
checkKeySound
(
_kbd
[
"
don_l
"
],
"
don
"
)
_this
.
checkKeySound
(
_kbd
[
"
don_r
"
],
"
don
"
)
_this
.
checkKeySound
(
_kbd
[
"
ka_l
"
],
"
ka
"
)
_this
.
checkKeySound
(
_kbd
[
"
ka_r
"
],
"
ka
"
)
}
this
.
checkMenuKeys
=
function
(){
if
(
!
controller
.
multiplayer
){
_gamepad
.
play
(
1
)
_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
){
if
(
_keys
[
keyCode
]
&&
!
_this
.
isWaitingForKeyup
(
keyCode
,
keyup
)){
_this
.
waitForKeyup
(
keyCode
,
keyup
);
callback
()
}
}
this
.
checkKeySound
=
function
(
keyCode
,
sound
){
_this
.
checkKey
(
keyCode
,
"
sound
"
,
function
(){
var
circles
=
controller
.
parsedSongData
.
circles
var
circle
=
circles
[
controller
.
game
.
getCurrentCircle
()]
if
(
(
keyCode
==
_kbd
[
"
don_l
"
]
||
keyCode
==
_kbd
[
"
don_r
"
])
&&
circle
&&
!
circle
.
getPlayed
()
&&
circle
.
getStatus
()
!=
-
1
&&
circle
.
getType
()
==
"
balloon
"
&&
circle
.
requiredHits
-
circle
.
timesHit
<=
1
){
assets
.
sounds
[
"
balloon
"
].
play
()
}
else
{
assets
.
sounds
[
"
note_
"
+
sound
].
play
()
}
_keyTime
[
sound
]
=
controller
.
getElapsedTime
().
ms
})
}
this
.
getKeys
=
function
(){
return
_keys
;
}
this
.
setKey
=
function
(
keyCode
,
down
){
if
(
down
){
_keys
[
keyCode
]
=
true
;
}
else
{
delete
_keys
[
keyCode
];
delete
_waitKeyupScore
[
keyCode
];
delete
_waitKeyupSound
[
keyCode
];
delete
_waitKeyupMenu
[
keyCode
];
}
}
this
.
isWaitingForKeyup
=
function
(
key
,
type
){
var
isWaiting
;
if
(
type
==
"
score
"
)
isWaiting
=
_waitKeyupScore
[
key
];
else
if
(
type
==
"
sound
"
)
isWaiting
=
_waitKeyupSound
[
key
];
else
if
(
type
==
"
menu
"
)
isWaiting
=
_waitKeyupMenu
[
key
];
return
isWaiting
;
}
this
.
waitForKeyup
=
function
(
key
,
type
){
if
(
type
==
"
score
"
)
_waitKeyupScore
[
key
]
=
true
;
else
if
(
type
==
"
sound
"
)
_waitKeyupSound
[
key
]
=
true
;
else
if
(
type
==
"
menu
"
)
_waitKeyupMenu
[
key
]
=
true
;
}
this
.
getKeyTime
=
function
(){
return
_keyTime
;
}
}
\ No newline at end of file
class
Keyboard
{
constructor
(
controller
){
this
.
controller
=
controller
this
.
kbd
=
{
"
don_l
"
:
86
,
// V
"
don_r
"
:
66
,
// B
"
ka_l
"
:
67
,
// C
"
ka_r
"
:
78
,
// N
"
pause
"
:
81
,
// Q
"
back
"
:
8
// Backspace
}
this
.
keys
=
{}
this
.
waitKeyupScore
=
{}
this
.
waitKeyupSound
=
{}
this
.
waitKeyupMenu
=
{}
this
.
keyTime
=
{
"
don
"
:
-
Infinity
,
"
ka
"
:
-
Infinity
}
this
.
gamepad
=
new
Gamepad
(
this
)
pageEvents
.
keyAdd
(
this
,
"
all
"
,
"
both
"
,
event
=>
{
if
(
event
.
keyCode
===
8
){
// Disable back navigation when pressing backspace
event
.
preventDefault
()
}
if
(
this
.
buttonEnabled
(
event
.
keyCode
)){
this
.
setKey
(
event
.
keyCode
,
event
.
type
===
"
keydown
"
)
}
})
}
getBindings
(){
return
this
.
kbd
}
buttonEnabled
(
keyCode
){
if
(
this
.
controller
.
autoPlayEnabled
){
switch
(
keyCode
){
case
this
.
kbd
[
"
don_l
"
]:
case
this
.
kbd
[
"
don_r
"
]:
case
this
.
kbd
[
"
ka_l
"
]:
case
this
.
kbd
[
"
ka_r
"
]:
return
false
}
}
return
true
}
checkGameKeys
(){
if
(
!
this
.
controller
.
autoPlayEnabled
){
this
.
gamepad
.
play
()
}
this
.
checkKeySound
(
this
.
kbd
[
"
don_l
"
],
"
don
"
)
this
.
checkKeySound
(
this
.
kbd
[
"
don_r
"
],
"
don
"
)
this
.
checkKeySound
(
this
.
kbd
[
"
ka_l
"
],
"
ka
"
)
this
.
checkKeySound
(
this
.
kbd
[
"
ka_r
"
],
"
ka
"
)
}
checkMenuKeys
(){
if
(
!
this
.
controller
.
multiplayer
){
this
.
gamepad
.
play
(
true
)
this
.
checkKey
(
this
.
kbd
[
"
pause
"
],
"
menu
"
,
()
=>
{
this
.
controller
.
togglePauseMenu
()
})
}
if
(
this
.
controller
.
multiplayer
!==
2
){
this
.
checkKey
(
this
.
kbd
[
"
back
"
],
"
menu
"
,
()
=>
{
if
(
this
.
controller
.
multiplayer
===
1
){
p2
.
send
(
"
gameend
"
)
}
this
.
controller
.
togglePause
()
this
.
controller
.
songSelection
()
})
}
}
checkKey
(
keyCode
,
keyup
,
callback
){
if
(
this
.
keys
[
keyCode
]
&&
!
this
.
isWaitingForKeyup
(
keyCode
,
keyup
)){
this
.
waitForKeyup
(
keyCode
,
keyup
)
callback
()
}
}
checkKeySound
(
keyCode
,
sound
){
this
.
checkKey
(
keyCode
,
"
sound
"
,
()
=>
{
var
circles
=
this
.
controller
.
parsedSongData
.
circles
var
circle
=
circles
[
this
.
controller
.
game
.
getCurrentCircle
()]
if
(
(
keyCode
===
this
.
kbd
[
"
don_l
"
]
||
keyCode
===
this
.
kbd
[
"
don_r
"
])
&&
circle
&&
!
circle
.
getPlayed
()
&&
circle
.
getStatus
()
!==
-
1
&&
circle
.
getType
()
===
"
balloon
"
&&
circle
.
requiredHits
-
circle
.
timesHit
<=
1
){
assets
.
sounds
[
"
balloon
"
].
play
()
}
else
{
assets
.
sounds
[
"
note_
"
+
sound
].
play
()
}
this
.
keyTime
[
sound
]
=
this
.
controller
.
getElapsedTime
().
ms
})
}
getKeys
(){
return
this
.
keys
}
setKey
(
keyCode
,
down
){
if
(
down
){
this
.
keys
[
keyCode
]
=
true
}
else
{
delete
this
.
keys
[
keyCode
]
delete
this
.
waitKeyupScore
[
keyCode
]
delete
this
.
waitKeyupSound
[
keyCode
]
delete
this
.
waitKeyupMenu
[
keyCode
]
}
}
isWaitingForKeyup
(
key
,
type
){
if
(
type
===
"
score
"
){
return
this
.
waitKeyupScore
[
key
]
}
else
if
(
type
===
"
sound
"
){
return
this
.
waitKeyupSound
[
key
]
}
else
if
(
type
===
"
menu
"
){
return
this
.
waitKeyupMenu
[
key
]
}
}
waitForKeyup
(
key
,
type
){
if
(
type
===
"
score
"
){
this
.
waitKeyupScore
[
key
]
=
true
}
else
if
(
type
===
"
sound
"
){
this
.
waitKeyupSound
[
key
]
=
true
}
else
if
(
type
===
"
menu
"
){
this
.
waitKeyupMenu
[
key
]
=
true
}
}
getKeyTime
(){
return
this
.
keyTime
}
clean
(){
pageEvents
.
keyRemove
(
this
,
"
all
"
)
}
}
public/src/js/loader.js
View file @
e8809285
class
Loader
{
constructor
(){
this
.
loadedAssets
=
0
this
.
errorCount
=
0
this
.
assetsDiv
=
document
.
getElementById
(
"
assets
"
)
this
.
promises
=
[]
$
(
"
#screen
"
).
load
(
"
/src/views/loader.html
"
,
()
=>
{
this
.
run
()
})
this
.
ajax
(
"
src/views/loader.html
"
).
then
(
this
.
run
.
bind
(
this
))
}
run
(){
run
(
page
){
this
.
promises
=
[]
this
.
screen
=
document
.
getElementById
(
"
screen
"
)
this
.
screen
.
innerHTML
=
page
this
.
loaderPercentage
=
document
.
querySelector
(
"
#loader .percentage
"
)
this
.
loaderProgress
=
document
.
querySelector
(
"
#loader .progress
"
)
assets
.
fonts
.
forEach
(
name
=>
{
var
font
=
document
.
createElement
(
"
h1
"
)
...
...
@@ -20,11 +20,13 @@ class Loader{
FontDetect
.
onFontLoaded
(
name
,
resolve
,
reject
,
{
msTimeout
:
90000
})
}))
})
var
fontDetectDiv
=
document
.
getElementById
(
"
fontdetectHelper
"
)
fontDetectDiv
.
parentNode
.
removeChild
(
fontDetectDiv
)
assets
.
img
.
forEach
(
name
=>
{
var
id
=
name
.
substr
(
0
,
name
.
length
-
4
)
var
id
=
this
.
getFilename
(
name
)
var
image
=
document
.
createElement
(
"
img
"
)
this
.
promises
.
push
(
p
romiseL
oad
(
image
))
this
.
promises
.
push
(
p
ageEvents
.
l
oad
(
image
))
image
.
id
=
name
image
.
src
=
"
/assets/img/
"
+
name
this
.
assetsDiv
.
appendChild
(
image
)
...
...
@@ -39,68 +41,82 @@ class Loader{
snd
.
previewGain
.
setVolume
(
0.5
)
assets
.
audioSfx
.
forEach
(
name
=>
{
var
id
=
name
.
substr
(
0
,
name
.
length
-
4
)
this
.
promises
.
push
(
snd
.
sfxGain
.
load
(
"
/assets/audio/
"
+
name
).
then
(
sound
=>
{
assets
.
sounds
[
id
]
=
sound
}))
this
.
promises
.
push
(
this
.
loadSound
(
name
,
snd
.
sfxGain
))
})
assets
.
audioMusic
.
forEach
(
name
=>
{
var
id
=
name
.
substr
(
0
,
name
.
length
-
4
)
this
.
promises
.
push
(
snd
.
musicGain
.
load
(
"
/assets/audio/
"
+
name
).
then
(
sound
=>
{
assets
.
sounds
[
id
]
=
sound
}))
this
.
promises
.
push
(
this
.
loadSound
(
name
,
snd
.
musicGain
))
})
p2
=
new
P2Connection
()
this
.
promises
.
push
(
ajax
(
"
/api/songs
"
).
then
(
songs
=>
{
this
.
promises
.
push
(
this
.
ajax
(
"
/api/songs
"
).
then
(
songs
=>
{
assets
.
songs
=
JSON
.
parse
(
songs
)
}))
assets
.
views
.
forEach
(
name
=>
{
var
id
=
this
.
getFilename
(
name
)
this
.
promises
.
push
(
this
.
ajax
(
"
src/views/
"
+
name
).
then
(
page
=>
{
assets
.
pages
[
id
]
=
page
}))
})
this
.
promises
.
forEach
(
promise
=>
{
promise
.
then
(()
=>
{
this
.
assetLoaded
()
},
()
=>
{
this
.
errorMsg
()
})
promise
.
then
(
this
.
assetLoaded
.
bind
(
this
))
})
Promise
.
all
(
this
.
promises
).
then
(()
=>
{
this
.
clean
()
new
Titlescreen
()
},
this
.
errorMsg
.
bind
(
this
))
}
loadSound
(
name
,
gain
){
var
id
=
this
.
getFilename
(
name
)
return
gain
.
load
(
"
/assets/audio/
"
+
name
).
then
(
sound
=>
{
assets
.
sounds
[
id
]
=
sound
})
}
getFilename
(
name
){
return
name
.
slice
(
0
,
name
.
lastIndexOf
(
"
.
"
))
}
errorMsg
(){
if
(
this
.
errorCount
==
0
){
this
.
loaderPercentage
.
appendChild
(
document
.
createElement
(
"
br
"
))
this
.
loaderPercentage
.
appendChild
(
document
.
createTextNode
(
"
An error occurred, please refresh
"
))
}
this
.
errorCount
++
this
.
error
=
true
this
.
loaderPercentage
.
appendChild
(
document
.
createElement
(
"
br
"
))
this
.
loaderPercentage
.
appendChild
(
document
.
createTextNode
(
"
An error occurred, please refresh
"
))
this
.
clean
()
}
assetLoaded
(){
this
.
loadedAssets
++
var
percentage
=
parseInt
(
this
.
loadedAssets
*
100
/
this
.
promises
.
length
)
document
.
querySelector
(
"
#loader .progress
"
).
style
.
width
=
percentage
+
"
%
"
this
.
loaderPercentage
.
firstChild
.
data
=
percentage
+
"
%
"
if
(
!
this
.
error
){
this
.
loadedAssets
++
var
percentage
=
Math
.
floor
(
this
.
loadedAssets
*
100
/
this
.
promises
.
length
)
this
.
loaderProgress
.
style
.
width
=
percentage
+
"
%
"
this
.
loaderPercentage
.
firstChild
.
data
=
percentage
+
"
%
"
}
}
changePage
(
name
){
document
.
getElementById
(
"
screen
"
).
innerHTML
=
assets
.
pages
[
name
]
}
ajax
(
url
,
customRequest
){
return
new
Promise
((
resolve
,
reject
)
=>
{
var
request
=
new
XMLHttpRequest
()
request
.
open
(
"
GET
"
,
url
)
pageEvents
.
load
(
request
).
then
(()
=>
{
resolve
(
request
.
response
)
},
reject
)
if
(
customRequest
){
customRequest
(
request
)
}
request
.
send
()
})
}
clean
(){
delete
this
.
assetsDiv
delete
this
.
loaderPercentage
delete
this
.
loaderProgress
delete
this
.
promises
}
}
function
ajax
(
url
){
return
new
Promise
((
resolve
,
reject
)
=>
{
var
request
=
new
XMLHttpRequest
()
request
.
open
(
"
GET
"
,
url
)
promiseLoad
(
request
).
then
(()
=>
{
resolve
(
request
.
response
)
},
reject
)
request
.
send
()
})
}
function
promiseLoad
(
asset
){
return
new
Promise
((
resolve
,
reject
)
=>
{
asset
.
addEventListener
(
"
load
"
,
resolve
)
asset
.
addEventListener
(
"
error
"
,
reject
)
asset
.
addEventListener
(
"
abort
"
,
reject
)
})
}
var
pageEvents
=
new
PageEvents
()
var
loader
=
new
Loader
()
var
snd
=
{}
var
p2
new
Loader
()
public/src/js/loadsong.js
View file @
e8809285
...
...
@@ -5,9 +5,8 @@ class loadSong{
this
.
autoPlayEnabled
=
autoPlayEnabled
this
.
diff
=
this
.
selectedSong
.
difficulty
.
slice
(
0
,
-
4
)
this
.
songFilePath
=
"
/songs/
"
+
this
.
selectedSong
.
folder
+
"
/
"
+
this
.
selectedSong
.
difficulty
$
(
"
#screen
"
).
load
(
"
/src/views/loadsong.html
"
,
()
=>
{
this
.
run
()
})
loader
.
changePage
(
"
loadsong
"
)
this
.
run
()
}
run
(){
var
id
=
this
.
selectedSong
.
folder
...
...
@@ -15,7 +14,7 @@ class loadSong{
assets
.
sounds
[
"
start
"
].
play
()
var
img
=
document
.
createElement
(
"
img
"
)
promises
.
push
(
p
romiseL
oad
(
img
))
promises
.
push
(
p
ageEvents
.
l
oad
(
img
))
img
.
id
=
"
music-bg
"
img
.
src
=
"
/songs/
"
+
id
+
"
/bg.png
"
document
.
getElementById
(
"
assets
"
).
appendChild
(
img
)
...
...
@@ -37,15 +36,11 @@ class loadSong{
},
reject
)
}
}))
promises
.
push
(
ajax
(
this
.
songFilePath
).
then
(
data
=>
{
promises
.
push
(
loader
.
ajax
(
this
.
songFilePath
).
then
(
data
=>
{
this
.
songData
=
data
.
replace
(
/
\0
/g
,
""
).
split
(
"
\n
"
)
}))
Promise
.
all
(
promises
).
then
(()
=>
{
$
(
"
#screen
"
).
load
(
"
/src/views/game.html
"
,
()
=>
{
this
.
setupMultiplayer
()
})
this
.
setupMultiplayer
()
},
error
=>
{
console
.
error
(
error
)
alert
(
"
An error occurred, please refresh
"
)
...
...
@@ -53,37 +48,50 @@ class loadSong{
}
setupMultiplayer
(){
if
(
this
.
multiplayer
){
var
loadingText
=
document
.
getElementsByClassName
(
"
loading-text
"
)[
0
]
var
waitingText
=
"
Waiting for Another Player...
"
loadingText
.
firstChild
.
data
=
waitingText
loadingText
.
setAttribute
(
"
alt
"
,
waitingText
)
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
"
)
pageEvents
.
add
(
p2
,
"
message
"
,
event
=>
{
if
(
event
.
type
===
"
gameload
"
){
if
(
event
.
value
===
this
.
diff
){
p2
.
send
(
"
gamestart
"
)
},
()
=>
{
p2
.
send
(
"
gamestart
"
)
})
}
else
{
this
.
selectedSong2
=
{
title
:
this
.
selectedSong
.
title
,
folder
:
this
.
selectedSong
.
folder
,
difficulty
:
event
.
value
+
"
.osu
"
}
loader
.
ajax
(
"
/songs/
"
+
this
.
selectedSong2
.
folder
+
"
/
"
+
this
.
selectedSong2
.
difficulty
).
then
(
data
=>
{
this
.
song2Data
=
data
.
replace
(
/
\0
/g
,
""
).
split
(
"
\n
"
)
p2
.
send
(
"
gamestart
"
)
},
()
=>
{
p2
.
send
(
"
gamestart
"
)
})
}
}
else
if
(
event
.
type
===
"
gamestart
"
){
this
.
clean
()
loader
.
changePage
(
"
game
"
)
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
.
send
(
"
join
"
,
{
id
:
this
.
selectedSong
.
folder
,
diff
:
this
.
diff
})
}
else
{
this
.
clean
()
loader
.
changePage
(
"
game
"
)
var
taikoGame
=
new
Controller
(
this
.
selectedSong
,
this
.
songData
,
this
.
autoPlayEnabled
)
taikoGame
.
run
()
}
}
clean
(){
pageEvents
.
remove
(
p2
,
"
message
"
)
}
}
public/src/js/p2.js
View file @
e8809285
...
...
@@ -2,128 +2,119 @@ class P2Connection{
constructor
(){
this
.
closed
=
true
this
.
lastMessages
=
{}
this
.
msgCallbacks
=
{}
this
.
closeCallbacks
=
new
Set
()
this
.
openCallbacks
=
new
Set
()
this
.
otherConnected
=
false
this
.
onmessage
(
"
gamestart
"
,
()
=>
{
this
.
otherConnected
=
true
this
.
notes
=
[]
this
.
drumrollPace
=
45
this
.
results
=
false
})
this
.
onmessage
(
"
gameend
"
,
()
=>
{
this
.
otherConnected
=
false
})
this
.
onmessage
(
"
gameresults
"
,
response
=>
{
this
.
results
=
response
})
this
.
onmessage
(
"
note
"
,
response
=>
{
this
.
notes
.
push
(
response
)
})
this
.
onmessage
(
"
drumroll
"
,
response
=>
{
this
.
drumrollPace
=
response
.
pace
})
this
.
allEvents
=
new
Map
()
this
.
addEventListener
(
"
message
"
,
this
.
message
.
bind
(
this
))
}
addEventListener
(
type
,
callback
){
var
addedType
=
this
.
allEvents
.
get
(
type
)
if
(
!
addedType
){
addedType
=
new
Set
()
this
.
allEvents
.
set
(
type
,
addedType
)
}
return
addedType
.
add
(
callback
)
}
removeEventListener
(
type
,
callback
){
var
addedType
=
this
.
allEvents
.
get
(
type
)
if
(
addedType
){
return
addedType
.
delete
(
callback
)
}
}
open
(){
this
.
closed
=
false
var
wsProtocol
=
location
.
protocol
==
"
https:
"
?
"
wss:
"
:
"
ws:
"
this
.
socket
=
new
WebSocket
(
wsProtocol
+
"
//
"
+
location
.
host
+
"
/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
)
pageEvents
.
race
(
this
.
socket
,
"
open
"
,
"
close
"
,
listener
=>
{
if
(
listener
===
"
open
"
){
return
this
.
openEvent
()
}
return
this
.
closeEvent
()
})
pageEvents
.
add
(
this
.
socket
,
"
message
"
,
this
.
messageEvent
.
bind
(
this
))
}
o
nopen
(
callback
,
once
){
this
.
openCallbacks
.
add
({
callback
:
callback
,
once
:
once
}
)
o
penEvent
(
){
var
addedType
=
this
.
allEvents
.
get
(
"
open
"
)
if
(
addedType
){
addedType
.
forEach
(
callback
=>
callback
())
}
}
close
(){
this
.
closed
=
true
this
.
socket
.
close
()
}
closeEvent
(
event
){
closeEvent
(){
this
.
removeEventListener
(
onmessage
)
this
.
otherConnected
=
false
if
(
!
this
.
closed
){
setTimeout
(()
=>
{
if
(
this
.
socket
.
readyState
!=
this
.
socket
.
OPEN
){
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
})
var
addedType
=
this
.
allEvents
.
get
(
"
close
"
)
if
(
addedType
){
addedType
.
forEach
(
callback
=>
callback
())
}
}
send
(
type
,
value
){
if
(
this
.
socket
.
readyState
==
this
.
socket
.
OPEN
){
if
(
typeof
value
==
"
undefined
"
){
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
.
onop
en
(()
=>
{
pageEvents
.
once
(
this
,
"
open
"
).
th
en
(()
=>
{
this
.
send
(
type
,
value
)
}
,
true
)
})
}
}
messageEvent
(
event
){
try
{
var
data
=
JSON
.
parse
(
event
.
data
)
var
response
=
JSON
.
parse
(
event
.
data
)
}
catch
(
e
){
var
data
=
{}
var
response
=
{}
}
this
.
lastMessages
[
data
.
type
]
=
data
.
value
if
(
this
.
msgCallbacks
[
data
.
type
]){
this
.
msgCallbacks
[
data
.
type
].
forEach
(
obj
=>
{
obj
.
callback
(
data
.
value
)
if
(
obj
.
once
){
this
.
msgCallbacks
[
data
.
type
].
delete
(
obj
)
}
})
this
.
lastMessages
[
response
.
type
]
=
response
.
value
var
addedType
=
this
.
allEvents
.
get
(
"
message
"
)
if
(
addedType
){
addedType
.
forEach
(
callback
=>
callback
(
response
))
}
}
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
])
return
this
.
lastMessages
[
type
]
}
}
message
(
response
){
switch
(
response
.
type
){
case
"
gamestart
"
:
this
.
otherConnected
=
true
this
.
notes
=
[]
this
.
drumrollPace
=
45
this
.
results
=
false
break
case
"
gameend
"
:
this
.
otherConnected
=
false
break
case
"
gameresults
"
:
this
.
results
=
response
.
value
break
case
"
note
"
:
this
.
notes
.
push
(
response
.
value
)
break
case
"
drumroll
"
:
this
.
drumrollPace
=
response
.
value
.
pace
break
}
}
play
(
circle
,
mekadon
){
if
(
this
.
otherConnected
||
this
.
notes
.
length
>
0
){
var
type
=
circle
.
getType
()
if
(
type
==
"
balloon
"
||
type
==
"
drumroll
"
||
type
==
"
daiDrumroll
"
){
if
(
type
==
=
"
balloon
"
||
type
===
"
drumroll
"
||
type
=
==
"
daiDrumroll
"
){
mekadon
.
playDrumrollAt
(
circle
,
0
,
this
.
drumrollPace
)
}
else
if
(
this
.
notes
.
length
==
0
){
}
else
if
(
this
.
notes
.
length
==
=
0
){
mekadon
.
play
(
circle
)
}
else
{
var
note
=
this
.
notes
[
0
]
...
...
public/src/js/pageevents.js
0 → 100644
View file @
e8809285
class
PageEvents
{
constructor
(){
this
.
allEvents
=
new
Map
()
this
.
keyListeners
=
new
Map
()
this
.
add
(
window
,
"
keydown
"
,
this
.
keyEvent
.
bind
(
this
))
this
.
add
(
window
,
"
keyup
"
,
this
.
keyEvent
.
bind
(
this
))
}
add
(
target
,
type
,
callback
){
this
.
remove
(
target
,
type
)
var
addedEvent
=
this
.
allEvents
.
get
(
target
)
if
(
!
addedEvent
){
addedEvent
=
new
Map
()
this
.
allEvents
.
set
(
target
,
addedEvent
)
}
addedEvent
.
set
(
type
,
callback
)
return
target
.
addEventListener
(
type
,
callback
)
}
remove
(
target
,
type
){
var
addedEvent
=
this
.
allEvents
.
get
(
target
)
if
(
addedEvent
){
var
callback
=
addedEvent
.
get
(
type
)
if
(
callback
){
target
.
removeEventListener
(
type
,
callback
)
addedEvent
.
delete
(
type
)
if
(
addedEvent
.
size
==
0
){
return
this
.
allEvents
.
delete
(
target
)
}
}
}
}
once
(
target
,
type
){
return
new
Promise
(
resolve
=>
{
this
.
add
(
target
,
type
,
event
=>
{
this
.
remove
(
target
,
type
)
return
resolve
(
event
)
})
})
}
race
(){
var
target
=
arguments
[
0
]
return
new
Promise
(
resolve
=>
{
for
(
var
i
=
1
;
i
<
arguments
.
length
;
i
++
){
let
type
=
arguments
[
i
]
this
.
add
(
target
,
type
,
event
=>
{
resolve
({
type
:
type
,
event
:
event
})
})
}
}).
then
(
response
=>
{
for
(
var
i
=
1
;
i
<
arguments
.
length
;
i
++
){
this
.
remove
(
target
,
arguments
[
i
])
}
return
response
})
}
load
(
target
){
return
new
Promise
((
resolve
,
reject
)
=>
{
this
.
race
(
target
,
"
load
"
,
"
error
"
,
"
abort
"
).
then
(
response
=>
{
if
(
response
.
type
===
"
load
"
){
return
resolve
(
response
.
event
)
}
return
reject
()
})
})
}
keyEvent
(
event
){
this
.
keyListeners
.
forEach
(
addedKeyCode
=>
{
this
.
checkListener
(
addedKeyCode
.
get
(
"
all
"
),
event
)
this
.
checkListener
(
addedKeyCode
.
get
(
event
.
keyCode
),
event
)
})
}
checkListener
(
keyObj
,
event
){
if
(
keyObj
&&
(
keyObj
.
type
===
"
both
"
||
keyObj
.
type
===
"
down
"
&&
event
.
type
===
"
keydown
"
||
keyObj
.
type
===
"
up
"
&&
event
.
type
===
"
up
"
)){
keyObj
.
callback
(
event
)
}
}
keyAdd
(
target
,
keyCode
,
type
,
callback
){
// keyCode="all", type="both"
var
addedKeyCode
=
this
.
keyListeners
.
get
(
target
)
if
(
!
addedKeyCode
){
addedKeyCode
=
new
Map
()
this
.
keyListeners
.
set
(
target
,
addedKeyCode
)
}
addedKeyCode
.
set
(
keyCode
,
{
type
:
type
,
callback
:
callback
})
}
keyRemove
(
target
,
keyCode
){
var
addedKeyCode
=
this
.
keyListeners
.
get
(
target
)
if
(
addedKeyCode
){
var
keyObj
=
addedKeyCode
.
get
(
keyCode
)
if
(
keyObj
){
addedKeyCode
.
delete
(
keyCode
)
if
(
addedKeyCode
.
size
==
0
){
return
this
.
keyListeners
.
delete
(
target
)
}
}
}
}
keyOnce
(
target
,
keyCode
,
type
){
return
new
Promise
(
resolve
=>
{
this
.
keyAdd
(
target
,
keyCode
,
type
,
event
=>
{
this
.
keyRemove
(
target
,
keyCode
)
return
resolve
(
event
)
})
})
}
}
public/src/js/scoresheet.js
View file @
e8809285
...
...
@@ -3,9 +3,8 @@ class Scoresheet{
this
.
controller
=
controller
this
.
score
=
score
this
.
multiplayer
=
multiplayer
$
(
"
#screen
"
).
load
(
"
/src/views/scoresheet.html
"
,
()
=>
{
this
.
run
()
})
loader
.
changePage
(
"
scoresheet
"
)
this
.
run
()
}
setResults
(
score
,
scoreCont
){
this
.
positionning
(
scoreCont
)
...
...
@@ -36,7 +35,7 @@ class Scoresheet{
this
.
altText
(
this
.
elem
(
"
max-combo
"
,
scoreCont
),
score
.
maxCombo
)
this
.
altText
(
this
.
elem
(
"
nb-drumroll
"
,
scoreCont
),
score
.
drumroll
)
addEventListener
(
"
resize
"
,
()
=>
{
pageEvents
.
add
(
window
,
"
resize
"
,
()
=>
{
this
.
positionning
(
scoreCont
)
})
}
...
...
@@ -82,17 +81,16 @@ class Scoresheet{
this
.
setResults
(
this
.
score
,
scoreCont
)
this
.
altText
(
this
.
elem
(
"
result-song
"
,
this
.
scoresheet
),
this
.
score
.
song
)
this
.
elem
(
"
song-select
"
,
this
.
scoresheet
).
addEventListener
(
"
click
"
,
()
=>
{
pageEvents
.
once
(
this
.
elem
(
"
song-select
"
,
this
.
scoresheet
),
"
click
"
).
then
(()
=>
{
this
.
clean
()
assets
.
sounds
[
"
don
"
].
play
()
assets
.
sounds
[
"
bgm_result
"
].
stop
()
this
.
controller
.
songSelection
()
})
this
.
elem
(
"
replay
"
,
this
.
scoresheet
).
addEventListener
(
"
click
"
,
()
=>
{
pageEvents
.
once
(
this
.
elem
(
"
replay
"
,
this
.
scoresheet
),
"
click
"
).
then
(()
=>
{
this
.
clean
()
assets
.
sounds
[
"
don
"
].
play
()
assets
.
sounds
[
"
bgm_result
"
].
stop
()
this
.
controller
.
restartSong
()
})
if
(
this
.
multiplayer
&&
p2
.
results
){
var
scoreCont2
=
document
.
createElement
(
"
div
"
)
scoreCont2
.
classList
.
add
(
"
score-cont
"
)
...
...
@@ -101,4 +99,8 @@ class Scoresheet{
this
.
setResults
(
p2
.
results
,
scoreCont2
)
}
}
clean
(){
assets
.
sounds
[
"
bgm_result
"
].
stop
()
pageEvents
.
remove
(
window
,
"
resize
"
)
}
}
public/src/js/songselect.js
View file @
e8809285
function
SongSelect
(){
var
_this
=
this
;
var
_songs
;
var
_selectedSong
=
{
title
:
''
,
folder
:
''
,
difficulty
:
''
};
var
_preview
;
var
_preview_id
=
0
var
_diffNames
=
{
easy
:
"
かんたん
"
,
normal
:
"
ふつう
"
,
hard
:
"
むずかしい
"
,
oni
:
"
おに
"
class
SongSelect
{
constructor
(){
this
.
songs
this
.
selectedSong
=
{
"
title
"
:
""
,
"
folder
"
:
""
,
"
difficulty
"
:
""
}
this
.
previewId
=
0
this
.
diffNames
=
{
"
easy
"
:
"
かんたん
"
,
"
normal
"
:
"
ふつう
"
,
"
hard
"
:
"
むずかしい
"
,
"
oni
"
:
"
おに
"
}
loader
.
changePage
(
"
songselect
"
)
this
.
run
()
}
this
.
startPreview
=
function
(
id
,
prvtime
,
first_open
=
true
)
{
_this
.
endPreview
();
startPreview
(
id
,
prvtime
,
switchedTo
){
this
.
endPreview
()
var
startLoad
=
+
new
Date
var
current
_id
=
_preview_i
d
if
(
first_open
){
var
current
Id
=
this
.
previewI
d
if
(
!
switchedTo
){
snd
.
musicGain
.
fadeOut
(
0.4
)
}
var
songObj
assets
.
songs
.
forEach
(
song
=>
{
if
(
song
.
id
==
id
){
songObj
=
song
}
})
var
songObj
=
assets
.
songs
.
find
(
song
=>
song
.
id
==
id
)
if
(
songObj
.
sound
){
_
preview
=
songObj
.
sound
_
preview
.
gain
=
snd
.
previewGain
this
.
previewLoaded
(
startLoad
,
prvtime
,
first_open
)
this
.
preview
=
songObj
.
sound
this
.
preview
.
gain
=
snd
.
previewGain
this
.
previewLoaded
(
startLoad
,
prvtime
,
switchedTo
)
}
else
{
snd
.
previewGain
.
load
(
"
/songs/
"
+
id
+
"
/main.mp3
"
).
then
(
sound
=>
{
if
(
current
_id
==
_preview_i
d
){
if
(
current
Id
==
this
.
previewI
d
){
songObj
.
sound
=
sound
_
preview
=
sound
this
.
previewLoaded
(
startLoad
,
prvtime
,
first_open
)
this
.
preview
=
sound
this
.
previewLoaded
(
startLoad
,
prvtime
,
switchedTo
)
}
})
}
};
this
.
previewLoaded
=
function
(
startLoad
,
prvtime
,
first_open
){
}
previewLoaded
(
startLoad
,
prvtime
,
switchedTo
){
var
endLoad
=
+
new
Date
var
difference
=
endLoad
-
startLoad
var
minDelay
=
first_open
?
1000
:
3
00
var
minDelay
=
switchedTo
?
300
:
10
00
var
delay
=
minDelay
-
Math
.
min
(
minDelay
,
difference
)
_
preview
.
playLoop
(
delay
/
1000
,
false
,
prvtime
/
1000
)
this
.
preview
.
playLoop
(
delay
/
1000
,
false
,
prvtime
/
1000
)
}
this
.
endPreview
=
function
()
{
_preview_id
++
if
(
_preview
)
{
_preview
.
stop
();
};
};
this
.
run
=
function
(){
_this
.
createCode
();
_this
.
startP2
();
$
(
"
#song-container
"
).
show
();
$
(
'
#songsel-help
'
).
click
(
function
(){
assets
.
sounds
[
"
bgm_songsel
"
].
stop
()
assets
.
sounds
[
"
song-select
"
].
stop
()
assets
.
sounds
[
"
diffsel
"
].
stop
()
assets
.
sounds
[
"
don
"
].
play
()
snd
.
musicGain
.
fadeIn
()
_this
.
endPreview
();
new
Tutorial
();
});
endPreview
()
{
this
.
previewId
++
if
(
this
.
preview
){
this
.
preview
.
stop
()
}
}
run
(){
this
.
createCode
()
this
.
startP2
()
$
(
"
.difficulty
"
).
click
(
function
(
e
){
_this
.
endPreview
();
assets
.
sounds
[
"
bgm_songsel
"
].
stop
()
assets
.
sounds
[
"
diffsel
"
].
stop
()
this
.
songselHelp
=
document
.
getElementById
(
"
songsel-help
"
)
pageEvents
.
once
(
this
.
songselHelp
,
"
click
"
).
then
(()
=>
{
this
.
clean
()
assets
.
sounds
[
"
don
"
].
play
()
var
difficultyElement
=
(
e
.
target
.
className
==
"
stars
"
||
e
.
target
.
className
==
"
diffname
"
)
?
e
.
target
.
parentElement
:
e
.
target
;
_selectedSong
.
difficulty
=
difficultyElement
.
classList
[
1
]
+
'
.osu
'
;
var
parentID
=
$
(
this
).
parent
().
closest
(
"
.song
"
).
attr
(
"
id
"
);
var
songID
=
parseInt
(
parentID
.
substr
(
5
,
parentID
.
length
-
1
));
_selectedSong
.
title
=
$
(
this
).
parent
().
closest
(
'
.song
'
).
data
(
'
title
'
);
_selectedSong
.
folder
=
songID
;
snd
.
musicGain
.
fadeIn
()
new
loadSong
(
_selectedSong
,
e
.
shiftKey
,
e
.
ctrlKey
);
});
new
Tutorial
()
})
this
.
diffElements
=
document
.
getElementsByClassName
(
"
difficulty
"
)
for
(
let
difficulty
of
this
.
diffElements
){
pageEvents
.
once
(
difficulty
,
"
click
"
).
then
(
this
.
onDifficulty
.
bind
(
this
))
}
this
.
songElements
=
document
.
getElementsByClassName
(
"
song
"
)
for
(
let
song
of
this
.
songElements
){
pageEvents
.
add
(
song
,
"
click
"
,
this
.
onSong
.
bind
(
this
))
}
this
.
songSelect
=
document
.
getElementById
(
"
song-select
"
)
}
onDifficulty
(
event
){
this
.
clean
()
var
target
=
event
.
currentTarget
var
song
=
target
.
parentNode
.
parentNode
assets
.
sounds
[
"
don
"
].
play
()
$
(
"
.song
"
).
hover
(
function
(){
if
(
!
$
(
this
).
hasClass
(
"
opened
"
))
$
(
this
).
css
(
"
background
"
,
"
rgba(255, 233, 125, 0.90)
"
);
},
function
(){
if
(
!
$
(
this
).
hasClass
(
"
opened
"
))
$
(
this
).
css
(
"
background
"
,
"
rgba(255, 220, 47, 0.90)
"
);
});
this
.
selectedSong
.
difficulty
=
target
.
classList
[
1
]
+
"
.osu
"
this
.
selectedSong
.
title
=
song
.
dataset
.
title
this
.
selectedSong
.
folder
=
song
.
dataset
.
songId
$
(
"
.song
"
).
click
(
function
(
e
){
if
(
!
$
(
e
.
target
).
parents
(
'
.difficulties
'
).
length
)
{
if
(
$
(
"
.opened
"
).
length
&&
$
(
"
.opened
"
).
attr
(
'
id
'
)
==
$
(
this
).
attr
(
'
id
'
))
{
_this
.
endPreview
();
snd
.
musicGain
.
fadeIn
(
0.4
)
assets
.
sounds
[
"
diffsel
"
].
stop
()
assets
.
sounds
[
"
cancel
"
].
play
()
assets
.
sounds
[
"
song-select
"
].
play
(
0.3
)
$
(
"
.difficulty
"
).
hide
();
$
(
"
.opened
"
).
removeClass
(
"
opened
"
,
300
);
$
(
'
.songsel-title
'
).
fadeOut
(
200
,
function
(){
$
(
'
.songsel-title
'
).
attr
(
'
alt
'
,
'
曲をえらぶ
'
).
html
(
'
曲をえらぶ
'
).
css
(
'
left
'
,
-
300
);
$
(
'
.songsel-title
'
).
animate
({
left
:
0
,
opacity
:
"
show
"
},
400
);
});
return
;
}
if
(
!
$
(
'
.opened
'
).
length
)
{
_this
.
startPreview
(
$
(
this
).
data
(
'
song-id
'
),
$
(
this
).
data
(
'
preview
'
));
assets
.
sounds
[
"
don
"
].
play
()
assets
.
sounds
[
"
song-select
"
].
stop
()
assets
.
sounds
[
"
diffsel
"
].
play
(
0.3
)
$
(
'
.songsel-title
'
).
fadeOut
(
200
,
function
(){
$
(
'
.songsel-title
'
).
attr
(
'
alt
'
,
'
むずかしさをえらぶ
'
).
html
(
'
むずかしさをえらぶ
'
).
css
(
'
left
'
,
-
300
);
$
(
'
.songsel-title
'
).
animate
({
left
:
0
,
opacity
:
"
show
"
},
400
);
});
}
else
{
_this
.
startPreview
(
$
(
this
).
data
(
'
song-id
'
),
$
(
this
).
data
(
'
preview
'
),
false
);
assets
.
sounds
[
"
ka
"
].
play
();
}
};
$
(
"
.difficulty
"
).
hide
();
$
(
"
.opened
"
).
removeClass
(
"
opened
"
,
300
);
$
(
this
).
addClass
(
"
opened
"
,
300
,
"
linear
"
,
function
(){
$
(
this
).
find
(
"
.difficulty
"
).
show
();
$
(
this
).
css
(
"
background
"
,
"
rgba(255, 220, 47, 0.90)
"
);
});
});
new
loadSong
(
this
.
selectedSong
,
event
.
shiftKey
,
event
.
ctrlKey
)
}
onSong
(
event
){
var
target
=
event
.
currentTarget
var
opened
=
document
.
getElementsByClassName
(
"
opened
"
)[
0
]
if
(
!
opened
){
this
.
startPreview
(
target
.
dataset
.
songId
,
target
.
dataset
.
preview
)
assets
.
sounds
[
"
don
"
].
play
()
assets
.
sounds
[
"
song-select
"
].
stop
()
assets
.
sounds
[
"
diffsel
"
].
play
(
0.3
)
target
.
classList
.
add
(
"
opened
"
)
this
.
songSelect
.
classList
.
add
(
"
difficulty-select
"
)
}
else
if
(
opened
==
target
){
this
.
endPreview
()
snd
.
musicGain
.
fadeIn
(
0.4
)
assets
.
sounds
[
"
diffsel
"
].
stop
()
assets
.
sounds
[
"
cancel
"
].
play
()
assets
.
sounds
[
"
song-select
"
].
play
(
0.3
)
opened
.
classList
.
remove
(
"
opened
"
)
this
.
songSelect
.
classList
.
remove
(
"
difficulty-select
"
)
}
else
{
this
.
startPreview
(
target
.
dataset
.
songId
,
target
.
dataset
.
preview
,
true
)
assets
.
sounds
[
"
ka
"
].
play
()
opened
.
classList
.
remove
(
"
opened
"
)
target
.
classList
.
add
(
"
opened
"
)
}
}
this
.
createCode
=
function
(){
createCode
(){
assets
.
sounds
[
"
bgm_songsel
"
].
playLoop
(
0.1
,
false
,
0
,
1.442
,
3.506
)
assets
.
sounds
[
"
song-select
"
].
play
(
0.2
);
assets
.
sounds
[
"
song-select
"
].
play
(
0.2
)
var
songElements
=
[
0
]
for
(
var
i
=
0
;
i
<
assets
.
songs
.
length
;
i
++
){
var
song
=
assets
.
songs
[
i
];
var
songTitle
=
song
.
title
;
var
skipChars
=
[];
assets
.
songs
.
forEach
(
song
=>
{
var
songTitle
=
song
.
title
var
charElements
=
[
0
]
var
diffElements
=
[
0
]
for
(
var
c
=
0
;
c
<
songTitle
.
length
;
c
++
)
{
if
(
skipChars
.
indexOf
(
c
)
>
-
1
)
{
continue
;
};
var
ch
=
songTitle
.
charAt
(
c
)
==
"
"
?
"
\
xa0
"
:
songTitle
.
charAt
(
c
);
var
isApos
=
false
;
if
(
songTitle
.
charAt
(
c
+
1
)
==
"
'
"
)
{
ch
=
ch
+
"
'
"
;
skipChars
.
push
(
c
+
1
);
isApos
=
true
;
};
var
cl
=
ch
==
"
\
xa0
"
?
"
song-title-char song-title-space
"
:
"
song-title-char
"
;
cl
=
isApos
?
cl
+
"
song-title-apos
"
:
cl
;
for
(
var
charIndex
=
0
;
charIndex
<
songTitle
.
length
;
charIndex
++
){
var
ch
=
songTitle
.
charAt
(
charIndex
)
var
cl
=
"
song-title-char
"
if
(
ch
==
"
"
){
ch
=
"
\
xa0
"
cl
+=
"
song-title-space
"
}
else
if
(
songTitle
.
charAt
(
charIndex
+
1
)
==
"
'
"
){
ch
=
ch
+
"
'
"
cl
+=
"
song-title-apos
"
charIndex
++
}
charElements
.
push
(
[
"
span
"
,
{
class
:
cl
,
alt
:
ch
},
ch
]
)
};
for
(
var
diff
in
_diffNames
){
var
diffName
=
diff
;
var
diffLevel
=
song
.
stars
[
diff
];
}
for
(
var
diff
in
this
.
diffNames
){
var
diffName
=
diff
var
diffLevel
=
song
.
stars
[
diff
]
if
(
!
diffLevel
)
{
continue
;
continue
}
var
starsDisplay
=
[
0
]
for
(
var
x
=
1
;
x
<=
diffLevel
;
x
++
){
for
(
var
star
=
1
;
star
<=
diffLevel
;
star
++
){
starsDisplay
.
push
(
"
\
u2605
"
)
starsDisplay
.
push
([
"
br
"
])
}
var
diffTxt
=
_diffNames
[
diffName
]
var
diffTxt
=
this
.
diffNames
[
diffName
]
diffElements
.
push
(
[
"
li
"
,
{
class
:
"
difficulty
"
+
diffName
...
...
@@ -209,9 +160,7 @@ function SongSelect(){
},
starsDisplay
]
]
)
}
songElements
.
push
(
[
"
div
"
,
{
id
:
"
song-
"
+
song
.
id
,
...
...
@@ -228,25 +177,22 @@ function SongSelect(){
},
diffElements
]
]
)
}
})
element
(
document
.
getElementById
(
"
song-container
"
),
songElements
)
$
(
'
.difficulty
'
).
hide
();
}
this
.
onusers
=
function
(
response
){
onusers
(
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
id
=
idDiff
.
id
|
0
var
diff
=
idDiff
.
diff
if
(
diff
in
this
.
diffNames
){
var
idElement
=
document
.
getElementById
(
"
song-
"
+
id
)
if
(
idElement
){
idElement
.
classList
.
add
(
"
p2
"
)
...
...
@@ -259,19 +205,34 @@ function SongSelect(){
})
}
}
this
.
startP2
=
function
(){
p2
.
getMessage
(
"
users
"
,
response
=>
{
this
.
onusers
(
response
)
})
p2
.
onmessage
(
"
users
"
,
response
=>
{
this
.
onusers
(
response
)
startP2
(){
this
.
onusers
(
p2
.
getMessage
(
"
users
"
))
pageEvents
.
add
(
p2
,
"
message
"
,
response
=>
{
if
(
response
.
type
==
"
users
"
){
this
.
onusers
(
response
.
value
)
}
})
if
(
p2
.
closed
){
p2
.
open
()
}
}
$
(
"
#screen
"
).
load
(
"
/src/views/songselect.html
"
,
_this
.
run
);
}
\ No newline at end of file
clean
(){
assets
.
sounds
[
"
bgm_songsel
"
].
stop
()
assets
.
sounds
[
"
song-select
"
].
stop
()
assets
.
sounds
[
"
diffsel
"
].
stop
()
this
.
endPreview
()
snd
.
musicGain
.
fadeIn
()
pageEvents
.
remove
(
p2
,
"
message
"
)
for
(
let
difficulty
of
this
.
diffElements
){
pageEvents
.
remove
(
difficulty
,
"
click
"
)
}
delete
this
.
diffElements
for
(
let
song
of
this
.
songElements
){
pageEvents
.
remove
(
song
,
"
click
"
)
}
delete
this
.
songElements
pageEvents
.
remove
(
this
.
songselHelp
,
"
click
"
)
delete
this
.
songselHelp
delete
this
.
songSelect
}
}
public/src/js/soundbuffer.js
View file @
e8809285
class
SoundBuffer
{
constructor
(){
this
.
context
=
new
AudioContext
()
var
resume
=
()
=>
{
pageEvents
.
once
(
window
,
"
click
"
).
then
(
()
=>
{
if
(
this
.
context
.
state
==
"
suspended
"
){
this
.
context
.
resume
()
}
removeEventListener
(
"
click
"
,
resume
)
}
addEventListener
(
"
click
"
,
resume
)
})
}
load
(
url
,
gain
){
return
new
Promise
((
resolve
,
reject
)
=>
{
var
request
=
new
XMLHttpRequest
()
request
.
open
(
"
GET
"
,
url
)
return
loader
.
ajax
(
url
,
request
=>
{
request
.
responseType
=
"
arraybuffer
"
request
.
addEventListener
(
"
load
"
,
()
=>
{
this
.
context
.
decodeAudioData
(
request
.
response
,
buffer
=>
{
resolve
(
new
Sound
(
gain
||
{
soundBuffer
:
this
},
buffer
))
},
reject
)
})
request
.
addEventListener
(
"
error
"
,
reject
)
request
.
addEventListener
(
"
abort
"
,
reject
)
request
.
send
()
}).
then
(
response
=>
{
return
this
.
context
.
decodeAudioData
(
response
)
}).
then
(
buffer
=>
{
return
new
Sound
(
gain
||
{
soundBuffer
:
this
},
buffer
)
})
}
createGain
(){
...
...
public/src/js/titlescreen.js
View file @
e8809285
function
Titlescreen
(){
var
_this
=
this
;
$
(
"
body
"
).
css
(
"
font-family
"
,
"
TnT
"
);
this
.
positionning
=
function
(){
var
width
=
0.70
*
$
(
window
).
width
();
var
logoW
=
(
width
>=
654
)
?
654
:
width
;
var
logoH
=
logoW
/
2.18
;
$
(
"
#logo-big-cont
"
).
width
(
logoW
);
$
(
"
#logo-big-cont
"
).
height
(
logoH
);
$
(
"
#logo-big-cont
"
).
css
(
"
left
"
,
$
(
window
).
width
()
/
2
-
(
$
(
"
#logo-big-cont
"
).
width
()
/
2
));
$
(
"
#logo-big-cont
"
).
css
(
"
top
"
,
$
(
window
).
height
()
/
2
-
(
$
(
"
#logo-big-cont
"
).
height
()
/
2
));
class
Titlescreen
{
constructor
(){
loader
.
changePage
(
"
titlescreen
"
)
this
.
titleScreen
=
document
.
getElementById
(
"
title-screen
"
)
pageEvents
.
keyOnce
(
this
,
13
,
"
down
"
).
then
(
this
.
goNext
.
bind
(
this
))
pageEvents
.
once
(
this
.
titleScreen
,
"
click
"
).
then
(
this
.
goNext
.
bind
(
this
))
assets
.
sounds
[
"
title
"
].
play
()
}
this
.
run
=
function
(){
$
(
document
).
keypress
(
function
(
e
){
if
(
e
.
keyCode
==
13
&&
$
(
"
#screen
"
).
find
(
"
#title-screen
"
).
html
())
_this
.
goNext
();
});
$
(
"
#screen
"
).
find
(
"
#title-screen
"
).
click
(
function
(){
_this
.
goNext
();
});
_this
.
positionning
();
$
(
"
#screen
"
).
find
(
"
#title-screen
"
).
show
();
$
(
window
).
resize
(
_this
.
positionning
);
assets
.
sounds
[
"
title
"
].
play
();
}
this
.
goNext
=
function
(){
assets
.
sounds
[
"
title
"
].
pause
();
assets
.
sounds
[
"
title
"
].
currentTime
=
0
;
assets
.
sounds
[
"
don
"
].
play
();
if
(
localStorage
.
getItem
(
'
tutorial
'
)
!==
'
true
'
)
{
new
Tutorial
();
}
else
{
new
SongSelect
();
};
}
$
(
"
#screen
"
).
load
(
"
/src/views/titlescreen.html
"
,
_this
.
run
);
}
\ No newline at end of file
goNext
(){
this
.
clean
()
assets
.
sounds
[
"
don
"
].
play
()
if
(
localStorage
.
getItem
(
"
tutorial
"
)
!==
"
true
"
){
new
Tutorial
()
}
else
{
new
SongSelect
()
}
}
clean
(){
assets
.
sounds
[
"
title
"
].
stop
()
pageEvents
.
keyRemove
(
this
,
13
)
pageEvents
.
remove
(
this
.
titleScreen
,
"
click
"
)
delete
this
.
titleScreen
}
}
public/src/js/tutorial.js
View file @
e8809285
function
Tutorial
()
{
var
_this
=
this
;
this
.
run
=
function
()
{
assets
.
sounds
[
"
bgm_setsume
"
].
playLoop
(
0.1
,
false
,
0
,
1.054
,
16.054
)
$
(
'
#tutorial-end-button
'
).
click
(
function
(){
assets
.
sounds
[
"
bgm_setsume
"
].
stop
();
assets
.
sounds
[
"
don
"
].
play
();
localStorage
.
setItem
(
'
tutorial
'
,
'
true
'
);
new
SongSelect
();
});
};
$
(
'
#screen
'
).
load
(
'
/src/views/tutorial.html
'
,
_this
.
run
);
};
class
Tutorial
{
constructor
(){
loader
.
changePage
(
"
tutorial
"
)
assets
.
sounds
[
"
bgm_setsume
"
].
playLoop
(
0.1
,
false
,
0
,
1.054
,
16.054
)
this
.
endButton
=
document
.
getElementById
(
"
tutorial-end-button
"
)
pageEvents
.
once
(
this
.
endButton
,
"
click
"
).
then
(
this
.
onEnd
.
bind
(
this
))
}
onEnd
(){
this
.
clean
()
assets
.
sounds
[
"
don
"
].
play
()
localStorage
.
setItem
(
"
tutorial
"
,
"
true
"
)
new
SongSelect
()
}
clean
(){
assets
.
sounds
[
"
bgm_setsume
"
].
stop
()
pageEvents
.
remove
(
this
.
endButton
,
"
click
"
)
delete
this
.
endButton
}
}
public/src/js/view.js
View file @
e8809285
...
...
@@ -4,17 +4,21 @@ class View{
this
.
bg
=
bg
this
.
diff
=
diff
if
(
this
.
controller
.
multiplayer
==
2
){
this
.
canvas
=
new
ScalableCanvas
(
"
canvas-p2
"
,
$
(
window
).
width
(),
$
(
window
).
height
()
/
3
*
2
)
this
.
pauseMenu
=
document
.
getElementById
(
"
pause-menu
"
)
var
docW
=
document
.
body
.
offsetWidth
var
docH
=
document
.
body
.
offsetHeight
if
(
this
.
controller
.
multiplayer
===
2
){
this
.
canvas
=
new
ScalableCanvas
(
"
canvas-p2
"
,
docW
,
docH
/
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
.
canvas
=
new
ScalableCanvas
(
"
canvas
"
,
docW
,
docH
)
}
this
.
winW
=
this
.
canvas
.
scaledWidth
this
.
winH
=
this
.
canvas
.
scaledHeight
if
(
this
.
controller
.
multiplayer
==
2
){
if
(
this
.
controller
.
multiplayer
==
=
2
){
this
.
winH
=
this
.
winH
/
2
*
3
}
this
.
ctx
=
this
.
canvas
.
ctx
...
...
@@ -74,19 +78,22 @@ class View{
run
(){
this
.
ctx
.
font
=
"
normal 14pt TnT
"
this
.
setBackground
()
$
(
"
.game-song
"
).
attr
(
"
alt
"
,
this
.
songTitle
).
html
(
this
.
songTitle
)
var
gameSong
=
document
.
getElementsByClassName
(
"
game-song
"
)[
0
]
gameSong
.
appendChild
(
document
.
createTextNode
(
this
.
songTitle
))
gameSong
.
setAttribute
(
"
alt
"
,
this
.
songTitle
)
this
.
refresh
()
}
setBackground
(){
$
(
"
#game
"
).
css
(
"
background-image
"
,
"
url('
"
+
this
.
bg
+
"
')
"
)
document
.
getElementById
(
"
game
"
).
style
.
backgroundImage
=
"
url('
"
+
this
.
bg
+
"
')
"
}
positionning
(){
var
docW
=
document
.
body
.
offsetWidth
var
docH
=
document
.
body
.
offsetHeight
this
.
canvas
.
rescale
()
var
height
=
$
(
window
).
height
()
if
(
this
.
controller
.
multiplayer
==
2
){
height
=
height
/
3
*
2
docH
=
docH
/
3
*
2
}
this
.
canvas
.
resize
(
$
(
window
).
width
(),
height
)
this
.
canvas
.
resize
(
docW
,
docH
)
this
.
winW
=
this
.
canvas
.
scaledWidth
this
.
winH
=
this
.
canvas
.
scaledHeight
if
(
this
.
controller
.
multiplayer
==
2
){
...
...
@@ -597,10 +604,10 @@ class View{
}
}
togglePauseMenu
(){
if
(
$
(
"
#pause-menu
"
).
is
(
"
:visible
"
)){
$
(
"
#pause-menu
"
).
hide
()
if
(
this
.
controller
.
game
.
isPaused
(
)){
this
.
pauseMenu
.
style
.
display
=
"
block
"
}
else
{
$
(
"
#pause-menu
"
).
show
()
this
.
pauseMenu
.
style
.
display
=
""
}
}
drawDifficulty
(){
...
...
@@ -728,4 +735,10 @@ class View{
})
}
}
clean
(){
delete
this
.
pauseMenu
delete
this
.
canvas
delete
this
.
ctx
}
}
public/src/views/loader.html
View file @
e8809285
<div
id=
"loader"
>
<div
class=
'progress'
></div>
<span
class=
'percentage'
>
0%
</span>
</div>
\ No newline at end of file
<div
class=
"progress"
></div>
<span
class=
"percentage"
>
0%
</span>
</div>
public/src/views/loadsong.html
View file @
e8809285
<div
id=
'load-song'
>
<div
id=
'loading-song'
>
<img
id=
'loading-don'
src=
"/assets/img/dancing-don.gif"
/
>
<
p>
Loading...
</p
>
<div
id=
"load-song"
>
<div
id=
"loading-song"
>
<img
id=
"loading-don"
src=
"/assets/img/dancing-don.gif"
>
<
div
class=
"loading-text stroke-sub"
alt=
"Loading..."
>
Loading...
</div
>
</div>
</div>
\ No newline at end of file
</div>
public/src/views/songselect.html
View file @
e8809285
<div
id=
"song-select"
>
<h2
alt=
"曲をえらぶ"
class=
"stroke-main songsel-title"
>
曲をえらぶ
</h2>
<h2
alt=
"曲をえらぶ"
class=
"stroke-main songsel-title-song"
>
曲をえらぶ
</h2>
<h2
alt=
"むずかしさをえらぶ"
class=
"stroke-main songsel-title-difficulty"
>
むずかしさをえらぶ
</h2>
<div
id=
"songsel-help"
>
?
</div>
<div
id=
'song-container'
></div>
</div>
\ No newline at end of file
<div
id=
"song-container"
></div>
</div>
public/src/views/titlescreen.html
View file @
e8809285
<div
id=
'title-screen'
>
<div
id=
'logo-big-cont'
><img
src=
"/assets/img/logo-big.png"
alt=
"太鼓の達人ウェブ"
/></div>
<h2
class=
'click-to-continue stroke-sub'
alt=
"Click or press enter"
>
Click or press enter
</h2>
</div>
\ No newline at end of file
<div
id=
"title-screen"
>
<img
class=
"logo-big"
src=
"/assets/img/logo-big.png"
alt=
"太鼓の達人ウェブ"
>
<div
class=
"click-to-continue stroke-sub"
alt=
"Click or Press Enter!"
>
Click or Press Enter!
</h2>
</div>
server.py
View file @
e8809285
...
...
@@ -51,6 +51,9 @@ async def connection(ws, path):
except
asyncio
.
TimeoutError
:
# Disconnect
break
except
websockets
.
exceptions
.
ConnectionClosed
:
# Connection closed
break
else
:
# Message received
try
:
...
...
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