Changed song selection screen

This commit is contained in:
LoveEevee 2018-09-26 21:30:57 +03:00
parent 74a9813c14
commit 71e180c7d7
16 changed files with 1663 additions and 428 deletions

23
app.py
View File

@ -69,6 +69,11 @@ def close_connection(exception):
@app.route('/api/songs') @app.route('/api/songs')
def route_api_songs(): def route_api_songs():
songs = query_db('select * from songs where enabled = 1') songs = query_db('select * from songs where enabled = 1')
raw_categories = query_db('select * from categories')
categories = {}
def_category = {'title': None, 'title_en': None}
for cat in raw_categories:
categories[cat[0]] = {'title': cat[1], 'title_en': cat[2]}
songs_out = [] songs_out = []
for song in songs: for song in songs:
osus = [osu for osu in os.listdir('public/songs/%s' % song[0]) if osu in ['easy.osu', 'normal.osu', 'hard.osu', 'oni.osu']] osus = [osu for osu in os.listdir('public/songs/%s' % song[0]) if osu in ['easy.osu', 'normal.osu', 'hard.osu', 'oni.osu']]
@ -77,13 +82,19 @@ def route_api_songs():
preview = int(get_osu_key(osud, 'General', 'PreviewTime', 0)) preview = int(get_osu_key(osud, 'General', 'PreviewTime', 0))
else: else:
preview = 0 preview = 0
category_out = categories[song[8]] if song[8] in categories else def_category
songs_out.append( songs_out.append({
{'id': song[0], 'title': song[1], 'title_en': song[2], 'stars': { 'id': song[0],
'easy': song[3], 'normal': song[4], 'title': song[1],
'hard': song[5], 'oni': song[6] 'title_en': song[2],
}, 'preview': preview} 'stars': [
) song[3], song[4], song[5], song[6]
],
'preview': preview,
'category': category_out['title'],
'category_en': category_out['title_en']
})
return jsonify(songs_out) return jsonify(songs_out)

View File

@ -19,7 +19,6 @@
<link rel="stylesheet" href="/src/css/main.css"/> <link rel="stylesheet" href="/src/css/main.css"/>
<link rel="stylesheet" href="/src/css/loader.css"> <link rel="stylesheet" href="/src/css/loader.css">
<link rel="stylesheet" href="/src/css/titlescreen.css"> <link rel="stylesheet" href="/src/css/titlescreen.css">
<link rel="stylesheet" href="/src/css/songselect.css">
<link rel="stylesheet" href="/src/css/scoresheet.css"> <link rel="stylesheet" href="/src/css/scoresheet.css">
<link rel="stylesheet" href="/src/css/loadsong.css"> <link rel="stylesheet" href="/src/css/loadsong.css">
<link rel="stylesheet" href="/src/css/game.css"> <link rel="stylesheet" href="/src/css/game.css">

View File

@ -33,11 +33,14 @@
font-size: 3.5vmin; font-size: 3.5vmin;
border-radius: 1.5vmin; border-radius: 1.5vmin;
} }
#pause-menu button:hover{ #pause-menu button:hover,
border-color:#fa5d3a; #pause-menu button.selected{
color:white; color:white;
background:#0c6577; background:#0c6577;
} }
#pause-menu button:hover{
border-color:#fa5d3a;
}
#cursor{ #cursor{
position: fixed; position: fixed;
width: 1px; width: 1px;

View File

@ -188,3 +188,11 @@ kbd{
#tutorial-end-button{ #tutorial-end-button{
font-size: 22pt; font-size: 22pt;
} }
#song-sel-canvas{
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}

View File

@ -1,167 +0,0 @@
@keyframes bgscroll{
from{
background-position: 0 0;
}
to{
background-position: -30vmin 0;
}
}
#song-select{
width: 100%;
height: 100%;
background: url("/assets/img/bg-pattern-1.png");
background-size: 30vmin;
animation: bgscroll 8s infinite linear;
white-space: nowrap;
}
#song-container{
width: 98%;
height: 80%;
padding: 5% 1% 1% 1%;
text-align: center;
}
ul li{
list-style: none;
}
.difficulties{
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;
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;
cursor: pointer;
position: relative;
transition: width 0.3s;
}
.song:not(.opened):hover{
background: rgba(255, 233, 125, 0.90);
}
.opened{
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;
}
.difficulty .diffname{
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;
}
.difficulty:hover{
border-color: #fa5d3a;
color: white;
background: #0c6577;
}
.difficulty:hover .diffname{
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: black;
}
.difficulty:hover .stars{
color: white;
}
.song.p2:not(.opened)::after,
.difficulty.p2::after{
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;
}

View File

@ -32,7 +32,6 @@ var assets = {
"don_anim_gogo.png", "don_anim_gogo.png",
"don_anim_gogostart.png", "don_anim_gogostart.png",
"don_anim_clear.png", "don_anim_clear.png",
"don_anim_endclear.png",
"fire_anim.png", "fire_anim.png",
"fireworks_anim.png" "fireworks_anim.png"
], ],
@ -92,7 +91,6 @@ var assets = {
"renda.ogg" "renda.ogg"
], ],
"audioMusic": [ "audioMusic": [
"bgm_songsel.ogg",
"bgm_result.ogg", "bgm_result.ogg",
"bgm_setsume.ogg" "bgm_setsume.ogg"
], ],

View File

@ -107,7 +107,6 @@ class Controller{
this.view.togglePauseMenu() this.view.togglePauseMenu()
} }
gameEnded(){ gameEnded(){
this.view.gameEnded()
var score = this.getGlobalScore() var score = this.getGlobalScore()
var vp var vp
if(score.fail === 0){ if(score.fail === 0){

View File

@ -1,16 +1,6 @@
class Gamepad{ class Gamepad{
constructor(keyboard){ constructor(bindings, callback){
this.keyboard = keyboard this.bindings = bindings
this.game = this.keyboard.controller.game
var kbd = keyboard.getBindings()
this.gameBtn = {}
this.gameBtn[kbd["don_l"]] = ["u", "d", "l", "r"]
this.gameBtn[kbd["don_r"]] = ["a", "b", "x", "y"]
this.gameBtn[kbd["ka_l"]] = ["lb", "lt"]
this.gameBtn[kbd["ka_r"]] = ["rb", "rt"]
this.menuBtn = {}
this.menuBtn[kbd["pause"]] = ["start"]
this.b = { this.b = {
"a": 0, "a": 0,
"b": 1, "b": 1,
@ -31,15 +21,19 @@ class Gamepad{
"guide": 16 "guide": 16
} }
this.btn = {} this.btn = {}
if(callback){
this.interval = setInterval(() => {
this.play(callback)
}, 100)
} }
play(menuPlay){ }
var ms = this.game.getAccurateTime() play(callback){
if("getGamepads" in navigator){ if("getGamepads" in navigator){
var gamepads = navigator.getGamepads() var gamepads = navigator.getGamepads()
}else{ }else{
return return
} }
var bindings = menuPlay ? this.menuBtn : this.gameBtn var bindings = this.bindings
for(var i = 0; i < gamepads.length; i++){ for(var i = 0; i < gamepads.length; i++){
if(gamepads[i]){ if(gamepads[i]){
this.toRelease = {} this.toRelease = {}
@ -51,7 +45,7 @@ class Gamepad{
for(var bind in bindings){ for(var bind in bindings){
for(var name in bindings[bind]){ for(var name in bindings[bind]){
if(btnName === this.b[bindings[bind][name]]){ if(btnName === this.b[bindings[bind][name]]){
this.checkButton(gamepads, btnName, bind, ms) this.checkButton(gamepads, btnName, bind, callback)
break buttonSearch break buttonSearch
} }
} }
@ -62,7 +56,7 @@ class Gamepad{
} }
} }
} }
checkButton(gamepads, btnName, keyCode, ms){ checkButton(gamepads, btnName, keyCode, callback){
var button = false var button = false
for(var i = 0; i < gamepads.length; i++){ for(var i = 0; i < gamepads.length; i++){
@ -77,7 +71,6 @@ class Gamepad{
} }
} }
var keys = this.keyboard.getKeys()
var pressed = !this.btn[btnName] && button var pressed = !this.btn[btnName] && button
var released = this.btn[btnName] && !button var released = this.btn[btnName] && !button
@ -88,19 +81,18 @@ class Gamepad{
} }
if(pressed){ if(pressed){
if(keys[keyCode]){ callback(true, keyCode)
this.keyboard.setKey(keyCode, false) }else if(!button){
}
this.keyboard.setKey(keyCode, true, ms)
}else if(!button && keys[keyCode]){
if(released){ if(released){
this.toRelease[keyCode + "released"] = true this.toRelease[keyCode + "released"] = true
} }
this.toRelease[keyCode]-- this.toRelease[keyCode]--
if(this.toRelease[keyCode] === 0 && this.toRelease[keyCode + "released"]){ if(this.toRelease[keyCode] === 0 && this.toRelease[keyCode + "released"]){
this.keyboard.setKey(keyCode, false) callback(false, keyCode)
} }
} }
} }
clean(){
clearInterval(this.interval)
}
} }

View File

@ -9,7 +9,10 @@ class Keyboard{
"ka_l": 67, // C "ka_l": 67, // C
"ka_r": 78, // N "ka_r": 78, // N
"pause": 81, // Q "pause": 81, // Q
"back": 8 // Backspace "back": 8, // Backspace
"previous": 38, // Up
"next": 40, // Down
"confirm": 13 // Enter
} }
this.keys = {} this.keys = {}
this.waitKeyupScore = {} this.waitKeyupScore = {}
@ -19,7 +22,24 @@ class Keyboard{
"don": -Infinity, "don": -Infinity,
"ka": -Infinity "ka": -Infinity
} }
this.gamepad = new Gamepad(this)
var gameBtn = {}
gameBtn[this.kbd["don_l"]] = ["u", "d", "l", "r"]
gameBtn[this.kbd["don_r"]] = ["a", "b", "x", "y"]
gameBtn[this.kbd["ka_l"]] = ["lb", "lt"]
gameBtn[this.kbd["ka_r"]] = ["rb", "rt"]
this.gamepad = new Gamepad(gameBtn)
var menuBtn = {
"cancel": ["a"],
}
menuBtn[this.kbd["confirm"]] = ["b"]
menuBtn[this.kbd["previous"]] = ["u", "l", "lb", "lt"],
menuBtn[this.kbd["next"]] = ["d", "r", "rb", "rt"]
menuBtn[this.kbd["pause"]] = ["start"]
this.gamepadMenu = new Gamepad(menuBtn)
pageEvents.keyAdd(this, "all", "both", event => { pageEvents.keyAdd(this, "all", "both", event => {
if(event.keyCode === 8){ if(event.keyCode === 8){
// Disable back navigation when pressing backspace // Disable back navigation when pressing backspace
@ -48,7 +68,17 @@ class Keyboard{
} }
checkGameKeys(){ checkGameKeys(){
if(!this.controller.autoPlayEnabled){ if(!this.controller.autoPlayEnabled){
this.gamepad.play() var ms = this.game.getAccurateTime()
this.gamepad.play((pressed, keyCode) => {
if(pressed){
if(this.keys[keyCode]){
this.setKey(keyCode, false)
}
this.setKey(keyCode, true, ms)
}else{
this.setKey(keyCode, false)
}
})
} }
this.checkKeySound(this.kbd["don_l"], "don") this.checkKeySound(this.kbd["don_l"], "don")
this.checkKeySound(this.kbd["don_r"], "don") this.checkKeySound(this.kbd["don_r"], "don")
@ -57,10 +87,51 @@ class Keyboard{
} }
checkMenuKeys(){ checkMenuKeys(){
if(!this.controller.multiplayer){ if(!this.controller.multiplayer){
this.gamepad.play(true) var moveMenu = 0
var ms = this.game.getAccurateTime()
this.gamepadMenu.play((pressed, keyCode) => {
if(pressed){
if(this.game.isPaused()){
if(keyCode === "cancel"){
return setTimeout(() => {
this.controller.togglePauseMenu()
}, 200)
}
}
if(this.keys[keyCode]){
this.setKey(keyCode, false)
}
this.setKey(keyCode, true, ms)
}else{
this.setKey(keyCode, false)
}
})
this.checkKey(this.kbd["pause"], "menu", () => { this.checkKey(this.kbd["pause"], "menu", () => {
this.controller.togglePauseMenu() this.controller.togglePauseMenu()
}) })
if(this.game.isPaused()){
this.checkKey(this.kbd["previous"], "menu", () => {
moveMenu = -1
})
this.checkKey(this.kbd["next"], "menu", () => {
moveMenu = 1
})
this.checkKey(this.kbd["confirm"], "menu", () => {
setTimeout(() => {
document.getElementsByClassName("selected")[0].click()
}, 200)
})
}
if(moveMenu){
assets.sounds["ka"].play()
var selected = document.getElementsByClassName("selected")[0]
selected.classList.remove("selected")
var next = selected[(moveMenu === 1 ? "next" : "previous") + "ElementSibling"]
if(!next){
next = selected.parentNode[(moveMenu === 1 ? "first" : "last") + "ElementChild"]
}
next.classList.add("selected")
}
} }
if(this.controller.multiplayer !== 2){ if(this.controller.multiplayer !== 2){
this.checkKey(this.kbd["back"], "menu", () => { this.checkKey(this.kbd["back"], "menu", () => {

File diff suppressed because it is too large Load Diff

View File

@ -2,13 +2,24 @@ class Titlescreen{
constructor(){ constructor(){
loader.changePage("titlescreen") loader.changePage("titlescreen")
this.titleScreen = document.getElementById("title-screen") this.titleScreen = document.getElementById("title-screen")
pageEvents.keyOnce(this, 13, "down").then(this.goNext.bind(this)) pageEvents.keyOnce(this, 13, "down").then(this.onPressed.bind(this))
pageEvents.once(this.titleScreen, "click").then(this.goNext.bind(this)) pageEvents.once(this.titleScreen, "click").then(this.onPressed.bind(this))
assets.sounds["title"].play() assets.sounds["title"].play()
this.gamepad = new Gamepad({
"start": ["b", "x", "y", "start"],
"a": ["a"]
}, (pressed, key) => {
if(pressed){
this.onPressed()
} }
goNext(){ })
}
onPressed(){
this.clean() this.clean()
assets.sounds["don"].play() assets.sounds["don"].play()
setTimeout(this.goNext.bind(this), 500)
}
goNext(){
if(localStorage.getItem("tutorial") !== "true"){ if(localStorage.getItem("tutorial") !== "true"){
new Tutorial() new Tutorial()
} else { } else {
@ -16,6 +27,7 @@ class Titlescreen{
} }
} }
clean(){ clean(){
this.gamepad.clean()
assets.sounds["title"].stop() assets.sounds["title"].stop()
pageEvents.keyRemove(this, 13) pageEvents.keyRemove(this, 13)
pageEvents.remove(this.titleScreen, "click") pageEvents.remove(this.titleScreen, "click")

View File

@ -1,19 +1,28 @@
class Tutorial{ class Tutorial{
constructor(){ constructor(fromSongSel){
this.fromSongSel = fromSongSel
loader.changePage("tutorial") loader.changePage("tutorial")
assets.sounds["bgm_setsume"].playLoop(0.1, false, 0, 1.054, 16.054) assets.sounds["bgm_setsume"].playLoop(0.1, false, 0, 1.054, 16.054)
this.endButton = document.getElementById("tutorial-end-button") this.endButton = document.getElementById("tutorial-end-button")
pageEvents.once(this.endButton, "click").then(this.onEnd.bind(this)) pageEvents.once(this.endButton, "click").then(this.onEnd.bind(this))
pageEvents.keyOnce(this, 13, "down").then(this.onEnd.bind(this))
this.gamepad = new Gamepad({
"confirm": ["start", "b"]
}, this.onEnd.bind(this))
} }
onEnd(){ onEnd(){
this.clean() this.clean()
assets.sounds["don"].play() assets.sounds["don"].play()
localStorage.setItem("tutorial", "true") localStorage.setItem("tutorial", "true")
new SongSelect() setTimeout(() => {
new SongSelect(this.fromSongSel)
}, 500)
} }
clean(){ clean(){
this.gamepad.clean()
assets.sounds["bgm_setsume"].stop() assets.sounds["bgm_setsume"].stop()
pageEvents.remove(this.endButton, "click") pageEvents.remove(this.endButton, "click")
pageEvents.keyRemove(this, 13)
delete this.endButton delete this.endButton
} }
} }

View File

@ -777,18 +777,6 @@ class View{
don.setAnimationEnd(ms + length * don.speed, don.normalAnimation) don.setAnimationEnd(ms + length * don.speed, don.normalAnimation)
} }
} }
gameEnded(){
if(this.controller.getGlobalScore().hp >= 50){
var don = this.assets.don
don.setAnimation("endclear")
var ms = this.controller.getElapsedTime().ms
don.setAnimationStart(ms)
var length = don.getAnimationLength("normal")
don.setUpdateSpeed(this.beatInterval / (length / 4))
var length = don.getAnimationLength("endclear")
don.setAnimationEnd(ms + length * don.speed, don.normalAnimation)
}
}
onmousemove(event){ onmousemove(event){
this.lastMousemove = this.controller.getElapsedTime().ms this.lastMousemove = this.controller.getElapsedTime().ms
this.cursorHidden = false this.cursorHidden = false

View File

@ -55,7 +55,6 @@ class ViewAssets{
} }
} }
this.don.addFrames("clear", 30, "don_anim_clear") this.don.addFrames("clear", 30, "don_anim_clear")
this.don.addFrames("endclear", 22, "don_anim_endclear")
this.don.normalAnimation() this.don.normalAnimation()
this.fire = this.createAsset("bar", frame => { this.fire = this.createAsset("bar", frame => {
var imgw = 360 var imgw = 360

View File

@ -3,7 +3,7 @@
<canvas id="canvas"></canvas> <canvas id="canvas"></canvas>
<div id="pause-menu"> <div id="pause-menu">
<div class="window"> <div class="window">
<button type="button" id="continue-butt">Continue</button> <button type="button" id="continue-butt" class="selected">Continue</button>
<button type="button" id="restart-butt">Restart</button> <button type="button" id="restart-butt">Restart</button>
<button type="button" id="song-selection-butt">Song selection</button> <button type="button" id="song-selection-butt">Song selection</button>
</div> </div>

View File

@ -1,6 +1,3 @@
<div id="song-select"> <div id="song-select">
<h2 alt="曲をえらぶ" class="stroke-main songsel-title-song">曲をえらぶ</h2> <canvas id="song-sel-canvas"></canvas>
<h2 alt="むずかしさをえらぶ" class="stroke-main songsel-title-difficulty">むずかしさをえらぶ</h2>
<div id="songsel-help">?</div>
<div id="song-container"></div>
</div> </div>