Split language and tutorial, add gamepad settings

This commit is contained in:
LoveEevee 2019-04-16 21:06:41 +03:00
parent a4d938e888
commit f05b2518f3
26 changed files with 1036 additions and 835 deletions

View File

@ -19,3 +19,7 @@
.settings-outer{ .settings-outer{
background-image: url("bg_settings.png"); background-image: url("bg_settings.png");
} }
#gamepad-bg,
#gamepad-buttons{
background-image: url("settings_gamepad.png");
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

View File

@ -23,117 +23,6 @@
left: 0; left: 0;
z-index: -1; z-index: -1;
} }
#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: 0.25em black solid;
border-radius: 0.5em;
width: 800px;
padding: 1em;
margin: 1em;
font-size: 21px;
position: relative;
}
.touch-enabled #tutorial{
font-size: 3vmin;
}
#tutorial-title{
z-index: 1;
position: absolute;
color: white;
top: -0.7em;
font-size: 1.65em;
}
#tutorial-content{
margin: 0.7em 0;
overflow-y: auto;
max-height: calc(100vh - 14em);
}
kbd{
font-family: inherit;
padding: 0.1em 0.6em;
border: 1px solid #ccc;
font-size: 0.6em;
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{
display: inline-block;
background: #f6ead4;
padding: 0.4em 0.4em;
border-radius: 0.5em;
border: 0.1em rgba(218, 205, 178, 1) solid;
cursor: pointer;
font-size: 1.4em;
box-sizing: border-box;
color: #555;
text-align: center;
}
#tutorial-end-button{
float: right;
padding: 0.4em 1.5em;
font-weight: bold;
border-color: #000;
color: #000;
}
.taibtn:hover,
.taibtn.selected,
#tutorial-end-button:hover,
#tutorial-end-button.selected{
position: relative;
z-index: 1;
color: #fff;
background: #ffb547;
border-color: #fff;
}
.taibtn::before{
padding-left: inherit;
}
#about-link-btns{
float: left;
display: flex;
}
#about-link-btns .taibtn{
margin-right: 0.4em;
}
#diag-txt textarea,
#diag-txt iframe{
width: 100%;
height: 5em;
font-size: inherit;
resize: none;
word-break: break-all;
margin-bottom: 1em;
background: #fff;
border: 1px solid #a9a9a9;
user-select: all;
}
.text-warn{
color: #d00;
}
.link-btn a{
color: inherit;
text-decoration: none;
pointer-events: none;
}
.nowrap{
white-space: nowrap;
}
#session-invite{ #session-invite{
width: 100%; width: 100%;
height: 1.9em; height: 1.9em;
@ -149,78 +38,6 @@ kbd{
cursor: text; cursor: text;
overflow: hidden; overflow: hidden;
} }
@keyframes border-pulse{
0%{border-color: #ff0}
50%{border-color: rgba(255, 255, 0, 0)}
100%{border-color: #ff0}
}
@keyframes border-pulse2{
0%{border-color: #e29e06}
50%{border-color: rgba(226, 158, 6, 0)}
100%{border-color: #e29e06}
}
.settings-outer{
background-size: 50vh;
}
.setting-box{
display: flex;
height: 2em;
margin-top: 1.2em;
border: 0.25em solid #000;
border-radius: 0.5em;
padding: 0.3em;
outline: none;
color: #000;
cursor: pointer;
}
.setting-box:first-child{
margin-top: 0;
}
.settings-outer #tutorial-content:not(:hover) .setting-box.selected,
#tutorial-outer:not(.settings-outer) .setting-box.selected,
.setting-box:hover{
background: #ffb547;
animation: 2s linear border-pulse infinite;
}
.bold-fonts .setting-box{
line-height: 1em;
}
.setting-name{
position: relative;
width: 50%;
padding: 0.3em;
font-size: 1.3em;
box-sizing: border-box;
}
#tutorial-content:not(:hover) .setting-box.selected .setting-name,
#tutorial-outer:not(.settings-outer) .setting-box.selected .setting-name,
.setting-box:hover .setting-name{
color: #fff;
z-index: 0;
}
.setting-name::before{
padding-left: 0.3em;
}
.setting-value{
display: flex;
background: #fff;
width: 50%;
border-radius: 0.2em;
padding: 0.5em;
box-sizing: border-box;
}
.setting-value.selected{
width: calc(50% + 0.2em);
margin: -0.1em;
border: 0.2em solid #e29e06;
padding: 0.4em;
animation: 2s linear border-pulse2 infinite;
}
.setting-value>div{
padding: 0 0.4em;
overflow: hidden;
text-overflow: ellipsis;
}
@keyframes bgscroll{ @keyframes bgscroll{
from{ from{
background-position: 0 top; background-position: 0 top;

235
public/src/css/view.css Normal file
View File

@ -0,0 +1,235 @@
.view-outer{
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
position: absolute;
width: 100%;
height: 100%;
}
.view{
background: rgb(246, 234, 212);
color: black;
border: 0.25em black solid;
border-radius: 0.5em;
width: 800px;
padding: 1em;
margin: 1em;
font-size: 21px;
position: relative;
}
.touch-enabled .view{
font-size: 3vmin;
}
.view-title{
z-index: 1;
position: absolute;
color: white;
top: -0.7em;
font-size: 1.65em;
}
.view-content{
margin: 0.7em 0;
overflow-y: auto;
max-height: calc(100vh - 14em);
}
kbd{
font-family: inherit;
padding: 0.1em 0.6em;
border: 1px solid #ccc;
font-size: 0.6em;
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{
display: inline-block;
background: #f6ead4;
padding: 0.4em 0.4em;
border-radius: 0.5em;
border: 0.1em rgba(218, 205, 178, 1) solid;
cursor: pointer;
font-size: 1.4em;
box-sizing: border-box;
color: #555;
text-align: center;
}
.view-end-button{
float: right;
padding: 0.4em 1.5em;
font-weight: bold;
border-color: #000;
color: #000;
z-index: 1;
}
.taibtn:hover,
.taibtn.selected,
.view-end-button:hover,
.view-end-button.selected{
position: relative;
color: #fff;
background: #ffb547;
border-color: #fff;
}
.taibtn::before,
.view-end-button::before{
display: none;
}
.taibtn:hover::before,
.taibtn.selected::before,
.view-end-button:hover::before,
.view-end-button.selected::before{
display: block
}
.taibtn::before{
padding-left: inherit;
}
.left-buttons{
float: left;
display: flex;
}
.left-buttons .taibtn{
margin-right: 0.4em;
}
#diag-txt textarea,
#diag-txt iframe{
width: 100%;
height: 5em;
font-size: inherit;
resize: none;
word-break: break-all;
margin-bottom: 1em;
background: #fff;
border: 1px solid #a9a9a9;
user-select: all;
}
.text-warn{
color: #d00;
}
.link-btn a{
color: inherit;
text-decoration: none;
pointer-events: none;
}
.nowrap{
white-space: nowrap;
}
@keyframes border-pulse{
0%{border-color: #ff0}
50%{border-color: rgba(255, 255, 0, 0)}
100%{border-color: #ff0}
}
@keyframes border-pulse2{
0%{border-color: #e29e06}
50%{border-color: rgba(226, 158, 6, 0)}
100%{border-color: #e29e06}
}
.settings-outer{
background-size: 50vh;
}
.setting-box{
display: flex;
height: 2em;
margin-top: 1.2em;
border: 0.25em solid #000;
border-radius: 0.5em;
padding: 0.3em;
outline: none;
color: #000;
cursor: pointer;
}
.setting-box:first-child{
margin-top: 0;
}
.settings-outer .view-content:not(:hover) .setting-box.selected,
.view-outer:not(.settings-outer) .setting-box.selected,
.setting-box:hover{
background: #ffb547;
animation: 2s linear border-pulse infinite;
}
.bold-fonts .setting-box{
line-height: 1em;
}
.setting-name{
position: relative;
width: 50%;
padding: 0.3em;
font-size: 1.3em;
box-sizing: border-box;
}
.view-content:not(:hover) .setting-box.selected .setting-name,
.view-outer:not(.settings-outer) .setting-box.selected .setting-name,
.setting-box:hover .setting-name{
color: #fff;
z-index: 0;
}
.setting-name::before{
padding-left: 0.3em;
}
.setting-value{
display: flex;
background: #fff;
width: 50%;
border-radius: 0.2em;
padding: 0.5em;
box-sizing: border-box;
}
.setting-value.selected{
width: calc(50% + 0.2em);
margin: -0.1em;
border: 0.2em solid #e29e06;
padding: 0.4em;
animation: 2s linear border-pulse2 infinite;
}
.setting-value>div{
padding: 0 0.4em;
overflow: hidden;
text-overflow: ellipsis;
}
.shadow-outer{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1;
}
#settings-gamepad{
display: none;
}
#settings-gamepad .view{
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 550px;
height: 417px;
}
#gamepad-bg{
position: relative;
width: 550px;
height: 317px;
max-height: none;
background-repeat: none;
text-align: center;
font-size: 1.4em;
cursor: pointer;
}
#gamepad-buttons{
position: absolute;
left: 141px;
top: 120px;
width: 282px;
height: 131px;
background-position: 0 -318px;
background-repeat: none;
pointer-events: none;
}

View File

@ -4,20 +4,20 @@
loader.changePage("about", true) loader.changePage("about", true)
cancelTouch = false cancelTouch = false
this.endButton = document.getElementById("tutorial-end-button") this.endButton = this.getElement("view-end-button")
this.diagTxt = document.getElementById("diag-txt") this.diagTxt = document.getElementById("diag-txt")
this.version = document.getElementById("version-link").href this.version = document.getElementById("version-link").href
this.tutorialOuter = document.getElementById("tutorial-outer") this.tutorialOuter = this.getElement("view-outer")
if(touchEnabled){ if(touchEnabled){
this.tutorialOuter.classList.add("touch-enabled") this.tutorialOuter.classList.add("touch-enabled")
} }
this.linkIssues = document.getElementById("link-issues") this.linkIssues = document.getElementById("link-issues")
this.linkEmail = document.getElementById("link-email") this.linkEmail = document.getElementById("link-email")
var tutorialTitle = document.getElementById("tutorial-title") var tutorialTitle = this.getElement("view-title")
tutorialTitle.innerText = strings.aboutSimulator tutorialTitle.innerText = strings.aboutSimulator
tutorialTitle.setAttribute("alt", strings.aboutSimulator) tutorialTitle.setAttribute("alt", strings.aboutSimulator)
var tutorialContent = document.getElementById("tutorial-content") var tutorialContent = this.getElement("view-content")
strings.about.bugReporting.forEach(string => { strings.about.bugReporting.forEach(string => {
tutorialContent.appendChild(document.createTextNode(string)) tutorialContent.appendChild(document.createTextNode(string))
tutorialContent.appendChild(document.createElement("br")) tutorialContent.appendChild(document.createElement("br"))
@ -32,20 +32,18 @@
var versionUrl = gameConfig._version.url var versionUrl = gameConfig._version.url
this.getLink(this.linkIssues).href = versionUrl + "issues" this.getLink(this.linkIssues).href = versionUrl + "issues"
var kbdSettings = settings.getItem("keyboardSettings")
this.kbd = {
confirm: ["enter", " ", kbdSettings.don_l[0], kbdSettings.don_r[0]],
previous: ["arrowleft", "arrowup", kbdSettings.ka_l[0]],
next: ["arrowright", "arrowdown", kbdSettings.ka_r[0]],
back: ["backspace", "escape"]
}
pageEvents.add(this.linkIssues, ["click", "touchend"], this.linkButton.bind(this)) pageEvents.add(this.linkIssues, ["click", "touchend"], this.linkButton.bind(this))
pageEvents.add(this.linkEmail, ["click", "touchend"], this.linkButton.bind(this)) pageEvents.add(this.linkEmail, ["click", "touchend"], this.linkButton.bind(this))
pageEvents.add(this.endButton, ["mousedown", "touchstart"], this.onEnd.bind(this)) pageEvents.add(this.endButton, ["mousedown", "touchstart"], this.onEnd.bind(this))
pageEvents.keyAdd(this, "all", "down", this.keyEvent.bind(this))
this.items = [this.linkIssues, this.linkEmail, this.endButton] this.items = [this.linkIssues, this.linkEmail, this.endButton]
this.selected = 2 this.selected = 2
this.keyboard = new Keyboard({
confirm: ["enter", "space", "don_l", "don_r"],
previous: ["left", "up", "ka_l"],
next: ["right", "down", "ka_r"],
back: ["escape"]
}, this.keyPressed.bind(this))
this.gamepad = new Gamepad({ this.gamepad = new Gamepad({
"confirm": ["b", "ls", "rs"], "confirm": ["b", "ls", "rs"],
"previous": ["u", "l", "lb", "lt", "lsu", "lsl"], "previous": ["u", "l", "lb", "lt", "lsu", "lsl"],
@ -55,19 +53,8 @@
pageEvents.send("about", this.addDiag()) pageEvents.send("about", this.addDiag())
} }
keyEvent(event){ getElement(name){
if(event.keyCode === 27 || event.keyCode === 8 || event.keyCode === 9){ return loader.screen.getElementsByClassName(name)[0]
// Escape, Backspace, Tab
event.preventDefault()
}
if(!event.repeat){
for(var i in this.kbd){
if(this.kbd[i].indexOf(event.key.toLowerCase()) !== -1){
this.keyPressed(true, i)
break
}
}
}
} }
keyPressed(pressed, name){ keyPressed(pressed, name){
if(!pressed){ if(!pressed){
@ -215,6 +202,7 @@
} }
clean(){ clean(){
cancelTouch = true cancelTouch = true
this.keyboard.clean()
this.gamepad.clean() this.gamepad.clean()
pageEvents.remove(this.linkIssues, ["click", "touchend"]) pageEvents.remove(this.linkIssues, ["click", "touchend"])
pageEvents.remove(this.linkEmail, ["click", "touchend"]) pageEvents.remove(this.linkEmail, ["click", "touchend"])

View File

@ -7,6 +7,7 @@ var assets = {
"scoresheet.js", "scoresheet.js",
"songselect.js", "songselect.js",
"keyboard.js", "keyboard.js",
"gameinput.js",
"game.js", "game.js",
"controller.js", "controller.js",
"circle.js", "circle.js",
@ -36,7 +37,8 @@ var assets = {
"loadsong.css", "loadsong.css",
"game.css", "game.css",
"debug.css", "debug.css",
"songbg.css" "songbg.css",
"view.css"
], ],
"assetsCss": [ "assetsCss": [
"fonts/fonts.css", "fonts/fonts.css",
@ -79,7 +81,8 @@ var assets = {
"results_flowers.png", "results_flowers.png",
"results_mikoshi.png", "results_mikoshi.png",
"results_tetsuohana.png", "results_tetsuohana.png",
"results_tetsuohana2.png" "results_tetsuohana2.png",
"settings_gamepad.png"
], ],
"audioSfx": [ "audioSfx": [
"se_cancel.wav", "se_cancel.wav",

View File

@ -28,7 +28,7 @@ class Controller{
this.game = new Game(this, this.selectedSong, this.parsedSongData) this.game = new Game(this, this.selectedSong, this.parsedSongData)
this.view = new View(this) this.view = new View(this)
this.mekadon = new Mekadon(this, this.game) this.mekadon = new Mekadon(this, this.game)
this.keyboard = new Keyboard(this) this.keyboard = new GameInput(this)
this.playedSounds = {} this.playedSounds = {}
} }
@ -210,11 +210,8 @@ class Controller{
getKeys(){ getKeys(){
return this.keyboard.getKeys() return this.keyboard.getKeys()
} }
setKey(keyCode, down, ms){ setKey(pressed, name, ms){
return this.keyboard.setKey(keyCode, down, ms) return this.keyboard.setKey(pressed, name, ms)
}
getBindings(){
return this.keyboard.getBindings()
} }
getElapsedTime(){ getElapsedTime(){
return this.game.elapsedTime return this.game.elapsedTime

View File

@ -202,11 +202,10 @@ class Debug{
this.controller.autoPlayEnabled = this.autoplayCheckbox.checked this.controller.autoPlayEnabled = this.autoplayCheckbox.checked
if(!this.controller.autoPlayEnabled){ if(!this.controller.autoPlayEnabled){
var keyboard = debugObj.controller.keyboard var keyboard = debugObj.controller.keyboard
var kbd = keyboard.getBindings() keyboard.setKey(false, "don_l")
keyboard.setKey(kbd.don_l, false) keyboard.setKey(false, "don_r")
keyboard.setKey(kbd.don_r, false) keyboard.setKey(false, "ka_l")
keyboard.setKey(kbd.ka_l, false) keyboard.setKey(false, "ka_r")
keyboard.setKey(kbd.ka_r, false)
} }
} }
} }

View File

@ -254,29 +254,28 @@ class Game{
return return
} }
var keys = this.controller.getKeys() var keys = this.controller.getKeys()
var kbd = this.controller.getBindings()
var don_l = keys[kbd["don_l"]] && !this.controller.isWaiting(kbd["don_l"], "score") var don_l = keys["don_l"] && !this.controller.isWaiting("don_l", "score")
var don_r = keys[kbd["don_r"]] && !this.controller.isWaiting(kbd["don_r"], "score") var don_r = keys["don_r"] && !this.controller.isWaiting("don_r", "score")
var ka_l = keys[kbd["ka_l"]] && !this.controller.isWaiting(kbd["ka_l"], "score") var ka_l = keys["ka_l"] && !this.controller.isWaiting("ka_l", "score")
var ka_r = keys[kbd["ka_r"]] && !this.controller.isWaiting(kbd["ka_r"], "score") var ka_r = keys["ka_r"] && !this.controller.isWaiting("ka_r", "score")
var checkDon = () => { var checkDon = () => {
if(don_l && don_r){ if(don_l && don_r){
this.checkKey([kbd["don_l"], kbd["don_r"]], circle, "daiDon") this.checkKey(["don_l", "don_r"], circle, "daiDon")
}else if(don_l){ }else if(don_l){
this.checkKey([kbd["don_l"]], circle, "don") this.checkKey(["don_l"], circle, "don")
}else if(don_r){ }else if(don_r){
this.checkKey([kbd["don_r"]], circle, "don") this.checkKey(["don_r"], circle, "don")
} }
} }
var checkKa = () => { var checkKa = () => {
if(ka_l && ka_r){ if(ka_l && ka_r){
this.checkKey([kbd["ka_l"], kbd["ka_r"]], circle, "daiKa") this.checkKey(["ka_l", "ka_r"], circle, "daiKa")
}else if(ka_l){ }else if(ka_l){
this.checkKey([kbd["ka_l"]], circle, "ka") this.checkKey(["ka_l"], circle, "ka")
}else if(ka_r){ }else if(ka_r){
this.checkKey([kbd["ka_r"]], circle, "ka") this.checkKey(["ka_r"], circle, "ka")
} }
} }
var keyTime = this.controller.getKeyTime() var keyTime = this.controller.getKeyTime()

247
public/src/js/gameinput.js Normal file
View File

@ -0,0 +1,247 @@
class GameInput{
constructor(controller){
this.controller = controller
this.game = this.controller.game
this.keyboard = new Keyboard({
ka_l: ["ka_l"],
don_l: ["don_l"],
don_r: ["don_r"],
ka_r: ["ka_r"],
pause: ["q", "esc"],
back: ["backspace"],
previous: ["left", "up"],
next: ["right", "down"],
confirm: ["enter", "space"]
}, this.keyPress.bind(this))
this.keys = {}
this.waitKeyupScore = {}
this.waitKeyupSound = {}
this.waitKeyupMenu = {}
this.keyTime = {
"don": -Infinity,
"ka": -Infinity
}
this.keyboardEvents = 0
var layout = settings.getItem("gamepadLayout")
if(layout === "b"){
var gameBtn = {
don_l: ["d", "r", "ls"],
don_r: ["a", "x", "rs"],
ka_l: ["u", "l", "lb", "lt"],
ka_r: ["b", "y", "rb", "rt"]
}
}else if(layout === "c"){
var gameBtn = {
don_l: ["d", "l", "ls"],
don_r: ["a", "b", "rs"],
ka_l: ["u", "r", "lb", "lt"],
ka_r: ["x", "y", "rb", "rt"]
}
}else{
var gameBtn = {
don_l: ["u", "d", "l", "r", "ls"],
don_r: ["a", "b", "x", "y", "rs"],
ka_l: ["lb", "lt"],
ka_r: ["rb", "rt"]
}
}
this.gamepad = new Gamepad(gameBtn)
this.gamepadInterval = setInterval(this.gamepadKeys.bind(this), 1000 / 60 / 2)
this.gamepadMenu = new Gamepad({
cancel: ["a"],
confirm: ["b", "ls", "rs"],
previous: ["u", "l", "lb", "lt", "lsu", "lsl"],
next: ["d", "r", "rb", "rt", "lsd", "lsr"],
pause: ["start"]
})
if(controller.multiplayer === 1){
pageEvents.add(window, "beforeunload", event => {
if(p2.otherConnected){
pageEvents.send("p2-abandoned", event)
}
})
}
}
keyPress(pressed, name){
if(!this.controller.autoPlayEnabled || this.game.isPaused() || name !== "don_l" && name !== "don_r" && name !== "ka_l" && name !== "ka_r"){
this.setKey(pressed, name, this.game.getAccurateTime())
}
}
checkGameKeys(){
if(this.controller.autoPlayEnabled){
this.checkKeySound("don_l", "don")
this.checkKeySound("don_r", "don")
this.checkKeySound("ka_l", "ka")
this.checkKeySound("ka_r", "ka")
}
}
gamepadKeys(){
if(!this.game.isPaused() && !this.controller.autoPlayEnabled){
this.gamepad.play((pressed, name) => {
if(pressed){
if(this.keys[name]){
this.setKey(false, name)
}
this.setKey(true, name, this.game.getAccurateTime())
}else{
this.setKey(false, name)
}
})
}
}
checkMenuKeys(){
if(!this.controller.multiplayer && !this.locked){
var moveMenu = 0
var ms = this.game.getAccurateTime()
this.gamepadMenu.play((pressed, name) => {
if(pressed){
if(this.game.isPaused()){
if(name === "cancel"){
this.locked = true
return setTimeout(() => {
this.controller.togglePause()
this.locked = false
}, 200)
}
}
if(this.keys[name]){
this.setKey(false, name)
}
this.setKey(true, name, ms)
}else{
this.setKey(false, name)
}
})
this.checkKey("pause", "menu", () => {
this.controller.togglePause()
for(var key in this.keyTime){
this.keys[key] = null
this.keyTime[key] = -Infinity
}
})
var moveMenuMinus = () => {
moveMenu = -1
}
var moveMenuPlus = () => {
moveMenu = 1
}
var moveMenuConfirm = () => {
if(this.game.isPaused()){
this.locked = true
setTimeout(() => {
this.controller.view.pauseConfirm()
this.locked = false
}, 200)
}
}
this.checkKey("previous", "menu", moveMenuMinus)
this.checkKey("ka_l", "menu", moveMenuMinus)
this.checkKey("next", "menu", moveMenuPlus)
this.checkKey("ka_r", "menu", moveMenuPlus)
this.checkKey("confirm", "menu", moveMenuConfirm)
this.checkKey("don_l", "menu", moveMenuConfirm)
this.checkKey("don_r", "menu", moveMenuConfirm)
if(moveMenu && this.game.isPaused()){
assets.sounds["se_ka"].play()
this.controller.view.pauseMove(moveMenu)
}
}
if(this.controller.multiplayer !== 2){
this.checkKey("back", "menu", () => {
if(this.controller.multiplayer === 1 && p2.otherConnected){
p2.send("gameend")
pageEvents.send("p2-abandoned")
}
this.controller.togglePause()
this.controller.songSelection()
})
}
}
checkKey(name, type, callback){
if(this.keys[name] && !this.isWaiting(name, type)){
this.waitForKeyup(name, type)
callback()
}
}
checkKeySound(name, sound){
this.checkKey(name, "sound", () => {
var circles = this.controller.getCircles()
var circle = circles[this.controller.getCurrentCircle()]
var currentTime = this.keyTime[name]
this.keyTime[sound] = currentTime
if(circle && !circle.isPlayed){
if(circle.type === "balloon"){
if(sound === "don" && circle.requiredHits - circle.timesHit <= 1){
this.controller.playSound("se_balloon")
return
}
}
}
this.controller.playSound("neiro_1_" + sound)
})
}
getKeys(){
return this.keys
}
setKey(pressed, name, ms){
if(pressed){
this.keys[name] = true
this.waitKeyupScore[name] = false
this.waitKeyupSound[name] = false
this.waitKeyupMenu[name] = false
if(this.game.isPaused()){
return
}
this.keyTime[name] = ms
if(name == "don_l" || name == "don_r"){
this.checkKeySound(name, "don")
this.keyboardEvents++
}else if(name == "ka_l" || name == "ka_r"){
this.checkKeySound(name, "ka")
this.keyboardEvents++
}
}else{
this.keys[name] = false
this.waitKeyupScore[name] = false
this.waitKeyupSound[name] = false
this.waitKeyupMenu[name] = false
}
}
isWaiting(name, type){
if(type === "score"){
return this.waitKeyupScore[name]
}else if(type === "sound"){
return this.waitKeyupSound[name]
}else if(type === "menu"){
return this.waitKeyupMenu[name]
}
}
waitForKeyup(name, type){
if(!this.keys[name]){
return
}
if(type === "score"){
this.waitKeyupScore[name] = true
}else if(type === "sound"){
this.waitKeyupSound[name] = true
}else if(type === "menu"){
this.waitKeyupMenu[name] = true
}
}
getKeyTime(){
return this.keyTime
}
clean(){
this.keyboard.clean()
this.gamepad.clean()
this.gamepadMenu.clean()
clearInterval(this.gamepadInterval)
if(this.controller.multiplayer === 1){
pageEvents.remove(window, "beforeunload")
}
}
}

View File

@ -1,6 +1,7 @@
class Gamepad{ class Gamepad{
constructor(bindings, callback){ constructor(bindings, callback){
this.bindings = bindings this.bindings = bindings
this.callback = !!callback
this.b = { this.b = {
"a": 0, "a": 0,
"b": 1, "b": 1,
@ -87,6 +88,9 @@ class Gamepad{
for(var name in bindings[bind]){ for(var name in bindings[bind]){
var bindName = bindings[bind][name] var bindName = bindings[bind][name]
this.checkButton(gamepads, this.b[bindName], bind, callback, force[bindName]) this.checkButton(gamepads, this.b[bindName], bind, callback, force[bindName])
if(!this.b){
return
}
} }
} }
break break
@ -136,6 +140,11 @@ class Gamepad{
} }
} }
clean(){ clean(){
clearInterval(this.interval) if(this.callback){
clearInterval(this.interval)
}
delete this.bindings
delete this.b
delete this.btn
} }
} }

View File

@ -1,266 +1,105 @@
class Keyboard{ class Keyboard{
constructor(controller){ constructor(bindings, callback){
this.controller = controller this.bindings = bindings
this.game = this.controller.game this.callback = callback
this.wildcard = false
this.substitute = {
"up": "arrowup",
"right": "arrowright",
"down": "arrowdown",
"left": "arrowleft",
"space": " ",
"esc": "escape",
"ctrl": "control",
"altgr": "altgraph"
}
this.btn = {}
this.update()
pageEvents.keyAdd(this, "all", "both", this.keyEvent.bind(this))
pageEvents.blurAdd(this, this.blurEvent.bind(this))
}
update(){
var kbdSettings = settings.getItem("keyboardSettings") var kbdSettings = settings.getItem("keyboardSettings")
this.kbd = { var drumKeys = {}
"ka_l": kbdSettings.ka_l[0], for(var name in kbdSettings){
"don_l": kbdSettings.don_l[0], var keys = kbdSettings[name]
"don_r": kbdSettings.don_r[0], for(var i in keys){
"ka_r": kbdSettings.ka_r[0], drumKeys[keys[i]] = name
"pause": "q",
"back": "backspace",
"previous": "arrowleft",
"next": "arrowright",
"confirm": "enter"
}
this.kbdAlias = {
"pause": ["escape"],
"previous": ["arrowup"],
"next": ["arrowdown"],
"confirm": [" "]
}
this.keys = {}
this.waitKeyupScore = {}
this.waitKeyupSound = {}
this.waitKeyupMenu = {}
this.keyTime = {
"don": -Infinity,
"ka": -Infinity
}
this.keyboardEvents = 0
var gameBtn = {}
gameBtn[this.kbd["don_l"]] = ["u", "d", "l", "r", "ls"]
gameBtn[this.kbd["don_r"]] = ["a", "b", "x", "y", "rs"]
gameBtn[this.kbd["ka_l"]] = ["lb", "lt"]
gameBtn[this.kbd["ka_r"]] = ["rb", "rt"]
this.gamepad = new Gamepad(gameBtn)
this.gamepadInterval = setInterval(this.gamepadKeys.bind(this), 1000 / 60 / 2)
var menuBtn = {
"cancel": ["a"],
}
menuBtn[this.kbd["confirm"]] = ["b", "ls", "rs"]
menuBtn[this.kbd["previous"]] = ["u", "l", "lb", "lt", "lsu", "lsl"],
menuBtn[this.kbd["next"]] = ["d", "r", "rb", "rt", "lsd", "lsr"]
menuBtn[this.kbd["pause"]] = ["start"]
this.gamepadMenu = new Gamepad(menuBtn)
this.kbdSearch = {}
for(var name in this.kbdAlias){
var list = this.kbdAlias[name]
for(var i in list){
this.kbdSearch[list[i]] = this.kbd[name]
} }
} }
for(var name in this.kbd){ this.kbd = {}
this.kbdSearch[this.kbd[name]] = this.kbd[name] for(var name in this.bindings){
} var keys = this.bindings[name]
for(var i in keys){
pageEvents.keyAdd(this, "all", "both", event => { var key = keys[i]
if(event.keyCode === 27 || event.keyCode === 8 || event.keyCode === 9){ if(key in drumKeys){
// Escape, Backspace, Tab continue
event.preventDefault()
}
var key = this.kbdSearch[event.key.toLowerCase()]
if(key && !event.repeat && this.buttonEnabled(key)){
var ms = this.game.getAccurateTime()
this.setKey(key, event.type === "keydown", ms)
if(event.type === "keydown"){
this.keyboardEvents++
} }
} if(key in kbdSettings){
}) var keyArray = kbdSettings[key]
for(var j in keyArray){
if(controller.multiplayer === 1){ key = keyArray[j]
pageEvents.add(window, "beforeunload", event => { if(!(key in this.kbd)){
if(p2.otherConnected){ this.kbd[key] = name
pageEvents.send("p2-abandoned", event)
}
})
}
}
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.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")
}
}
gamepadKeys(){
if(!this.game.isPaused() && !this.controller.autoPlayEnabled){
this.gamepad.play((pressed, keyCode) => {
if(pressed){
if(this.keys[keyCode]){
this.setKey(keyCode, false)
}
this.setKey(keyCode, true, this.game.getAccurateTime())
}else{
this.setKey(keyCode, false)
}
})
}
}
checkMenuKeys(){
if(!this.controller.multiplayer && !this.locked){
var moveMenu = 0
var ms = this.game.getAccurateTime()
this.gamepadMenu.play((pressed, keyCode) => {
if(pressed){
if(this.game.isPaused()){
if(keyCode === "cancel"){
this.locked = true
return setTimeout(() => {
this.controller.togglePause()
this.locked = false
}, 200)
} }
} }
if(this.keys[keyCode]){
this.setKey(keyCode, false)
}
this.setKey(keyCode, true, ms)
}else{ }else{
this.setKey(keyCode, false) if(key in this.substitute){
} key = this.substitute[key]
}) }
this.checkKey(this.kbd["pause"], "menu", () => { if(!(key in this.kbd)){
this.controller.togglePause() if(key === "wildcard"){
for(var key in this.keyTime){ this.wildcard = true
this.keys[key] = null }
this.keyTime[key] = -Infinity this.kbd[key] = name
}
})
var moveMenuMinus = () => {
moveMenu = -1
}
var moveMenuPlus = () => {
moveMenu = 1
}
var moveMenuConfirm = () => {
if(this.game.isPaused()){
this.locked = true
setTimeout(() => {
this.controller.view.pauseConfirm()
this.locked = false
}, 200)
}
}
this.checkKey(this.kbd["previous"], "menu", moveMenuMinus)
this.checkKey(this.kbd["ka_l"], "menu", moveMenuMinus)
this.checkKey(this.kbd["next"], "menu", moveMenuPlus)
this.checkKey(this.kbd["ka_r"], "menu", moveMenuPlus)
this.checkKey(this.kbd["confirm"], "menu", moveMenuConfirm)
this.checkKey(this.kbd["don_l"], "menu", moveMenuConfirm)
this.checkKey(this.kbd["don_r"], "menu", moveMenuConfirm)
if(moveMenu && this.game.isPaused()){
assets.sounds["se_ka"].play()
this.controller.view.pauseMove(moveMenu)
}
}
if(this.controller.multiplayer !== 2){
this.checkKey(this.kbd["back"], "menu", () => {
if(this.controller.multiplayer === 1 && p2.otherConnected){
p2.send("gameend")
pageEvents.send("p2-abandoned")
}
this.controller.togglePause()
this.controller.songSelection()
})
}
}
checkKey(keyCode, type, callback){
if(this.keys[keyCode] && !this.isWaiting(keyCode, type)){
this.waitForKeyup(keyCode, type)
callback()
}
}
checkKeySound(keyCode, sound){
this.checkKey(keyCode, "sound", () => {
var circles = this.controller.getCircles()
var circle = circles[this.controller.getCurrentCircle()]
var currentTime = this.keyTime[keyCode]
this.keyTime[sound] = currentTime
if(circle && !circle.isPlayed){
if(circle.type === "balloon"){
if(sound === "don" && circle.requiredHits - circle.timesHit <= 1){
this.controller.playSound("se_balloon")
return
} }
} }
} }
this.controller.playSound("neiro_1_" + sound) }
})
} }
getKeys(){ keyEvent(event){
return this.keys var key = event.key.toLowerCase()
} if(key === "escape" || key === "backspace" || key === "tab"){
setKey(keyCode, down, ms){ event.preventDefault()
if(down){ }
this.keys[keyCode] = true if(!event.repeat){
if(this.game.isPaused()){ var pressed = event.type === "keydown"
return if(pressed){
this.btn[key] = true
}else{
delete this.btn[key]
if(key in this.kbd){
for(var i in this.btn){
if(this.kbd[i] === this.kbd[key]){
return
}
}
}
} }
this.keyTime[keyCode] = ms if(key in this.kbd){
if(keyCode == this.kbd.don_l || keyCode == this.kbd.don_r){ this.callback(pressed, this.kbd[key], event)
this.checkKeySound(keyCode, "don") }else if(this.wildcard){
}else if(keyCode == this.kbd.ka_l || keyCode == this.kbd.ka_r){ this.callback(pressed, this.kbd["wildcard"], event)
this.checkKeySound(keyCode, "ka")
} }
}else{
this.keys[keyCode] = false
this.waitKeyupScore[keyCode] = false
this.waitKeyupSound[keyCode] = false
this.waitKeyupMenu[keyCode] = false
} }
} }
isWaiting(keyCode, type){ blurEvent(){
if(type === "score"){ for(var key in this.btn){
return this.waitKeyupScore[keyCode] if(this.btn[key]){
}else if(type === "sound"){ delete this.btn[key]
return this.waitKeyupSound[keyCode] var name = this.kbd[key] || (this.wildcard ? "wildcard" : false)
}else if(type === "menu"){ if(name){
return this.waitKeyupMenu[keyCode] this.callback(false, name)
}
}
} }
} }
waitForKeyup(keyCode, type){
if(!this.keys[keyCode]){
return
}
if(type === "score"){
this.waitKeyupScore[keyCode] = true
}else if(type === "sound"){
this.waitKeyupSound[keyCode] = true
}else if(type === "menu"){
this.waitKeyupMenu[keyCode] = true
}
}
getKeyTime(){
return this.keyTime
}
clean(){ clean(){
pageEvents.keyRemove(this, "all") pageEvents.keyRemove(this, "all")
clearInterval(this.gamepadInterval) pageEvents.blurRemove(this)
if(this.controller.multiplayer === 1){ delete this.bindings
pageEvents.remove(window, "beforeunload") delete this.callback
} delete this.kbd
delete this.btn
} }
} }

View File

@ -50,7 +50,6 @@ class Mekadon{
} }
} }
playNow(circle, score, dai, reverse){ playNow(circle, score, dai, reverse){
var kbd = this.controller.getBindings()
var type = circle.type var type = circle.type
var keyDai = false var keyDai = false
var playDai = !dai || dai === 2 var playDai = !dai || dai === 2
@ -70,20 +69,20 @@ class Mekadon{
} }
} }
if(type === "daiDon" && playDai){ if(type === "daiDon" && playDai){
this.setKey(kbd["don_l"], ms) this.setKey("don_l", ms)
this.setKey(kbd["don_r"], ms) this.setKey("don_r", ms)
this.lr = false this.lr = false
keyDai = true keyDai = true
}else if(type === "don" || type === "daiDon" || drumrollNotes && score !== 2){ }else if(type === "don" || type === "daiDon" || drumrollNotes && score !== 2){
this.setKey(this.lr ? kbd["don_l"] : kbd["don_r"], ms) this.setKey(this.lr ? "don_l" : "don_r", ms)
this.lr = !this.lr this.lr = !this.lr
}else if(type === "daiKa" && playDai){ }else if(type === "daiKa" && playDai){
this.setKey(kbd["ka_l"], ms) this.setKey("ka_l", ms)
this.setKey(kbd["ka_r"], ms) this.setKey("ka_r", ms)
this.lr = false this.lr = false
keyDai = true keyDai = true
}else if(type === "ka" || type === "daiKa" || drumrollNotes){ }else if(type === "ka" || type === "daiKa" || drumrollNotes){
this.setKey(this.lr ? kbd["ka_l"] : kbd["ka_r"], ms) this.setKey(this.lr ? "ka_l" : "ka_r", ms)
this.lr = !this.lr this.lr = !this.lr
} }
if(type === "balloon"){ if(type === "balloon"){
@ -110,8 +109,7 @@ class Mekadon{
getMS(){ getMS(){
return this.controller.getElapsedTime() return this.controller.getElapsedTime()
} }
setKey(keyCode, ms){ setKey(name, ms){
this.controller.setKey(keyCode, false) this.controller.setKey(true, name, ms)
this.controller.setKey(keyCode, true, ms)
} }
} }

View File

@ -3,10 +3,12 @@ class PageEvents{
this.allEvents = new Map() this.allEvents = new Map()
this.keyListeners = new Map() this.keyListeners = new Map()
this.mouseListeners = new Map() this.mouseListeners = new Map()
this.blurListeners = new Map()
this.lastKeyEvent = -Infinity this.lastKeyEvent = -Infinity
this.add(window, "keydown", this.keyEvent.bind(this)) this.add(window, "keydown", this.keyEvent.bind(this))
this.add(window, "keyup", this.keyEvent.bind(this)) this.add(window, "keyup", this.keyEvent.bind(this))
this.add(window, "mousemove", this.mouseEvent.bind(this)) this.add(window, "mousemove", this.mouseEvent.bind(this))
this.add(window, "blur", this.blurEvent.bind(this))
this.kbd = [] this.kbd = []
} }
add(target, type, callback){ add(target, type, callback){
@ -142,6 +144,15 @@ class PageEvents{
mouseRemove(target){ mouseRemove(target){
this.mouseListeners.delete(target) this.mouseListeners.delete(target)
} }
blurEvent(event){
this.blurListeners.forEach(callback => callback(event))
}
blurAdd(target, callback){
this.blurListeners.set(target, callback)
}
blurRemove(target){
this.blurListeners.delete(target)
}
getMouse(){ getMouse(){
return this.lastMouse return this.lastMouse
} }
@ -149,12 +160,13 @@ class PageEvents{
dispatchEvent(new CustomEvent(name, {detail: detail})) dispatchEvent(new CustomEvent(name, {detail: detail}))
} }
setKbd(){ setKbd(){
this.kbd = []
var kbdSettings = settings.getItem("keyboardSettings") var kbdSettings = settings.getItem("keyboardSettings")
this.kbd = [ for(var name in kbdSettings){
kbdSettings.ka_l[0], var keys = kbdSettings[name]
kbdSettings.don_l[0], for(var i in keys){
kbdSettings.don_r[0], this.kbd.push(keys[i])
kbdSettings.ka_r[0] }
] }
} }
} }

View File

@ -31,13 +31,12 @@ class Scoresheet{
this.draw = new CanvasDraw() this.draw = new CanvasDraw()
this.canvasCache = new CanvasCache() this.canvasCache = new CanvasCache()
var kbdSettings = settings.getItem("keyboardSettings") this.keyboard = new Keyboard({
this.kbd = { confirm: ["enter", "space", "esc", "don_l", "don_r"]
confirm: ["enter", " ", "escape", "backspace", kbdSettings.don_l[0], kbdSettings.don_r[0]] }, this.keyDown.bind(this))
}
this.gamepad = new Gamepad({ this.gamepad = new Gamepad({
confirm: ["a", "b", "start", "ls", "rs"] confirm: ["a", "b", "start", "ls", "rs"]
}) }, this.keyDown.bind(this))
this.difficulty = { this.difficulty = {
"easy": 0, "easy": 0,
@ -76,22 +75,8 @@ class Scoresheet{
touchEvents: controller.view.touchEvents touchEvents: controller.view.touchEvents
}) })
} }
keyDown(event, key){ keyDown(pressed){
if(!key){ if(pressed && this.redrawing){
if(event.repeat){
return
}
for(var i in this.kbd){
if(this.kbd[i].indexOf(event.key.toLowerCase()) !== -1){
key = i
break
}
}
}
if(event && event.keyCode === 27 || event.keyCode === 8 || event.keyCode === 9){
event.preventDefault()
}
if(key === "confirm"){
this.toNext() this.toNext()
} }
} }
@ -140,7 +125,6 @@ class Scoresheet{
this.winW = null this.winW = null
this.winH = null this.winH = null
pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this))
pageEvents.add(this.canvas, ["mousedown", "touchstart"], this.mouseDown.bind(this)) pageEvents.add(this.canvas, ["mousedown", "touchstart"], this.mouseDown.bind(this))
if(!this.multiplayer){ if(!this.multiplayer){
@ -180,12 +164,6 @@ class Scoresheet{
} }
var ms = this.getMS() var ms = this.getMS()
this.gamepad.play((pressed, keyCode) => {
if(pressed){
this.keyDown(false, keyCode)
}
})
if(!this.redrawRunning){ if(!this.redrawRunning){
return return
} }
@ -864,12 +842,13 @@ class Scoresheet{
} }
clean(){ clean(){
this.keyboard.clean()
this.gamepad.clean()
this.draw.clean() this.draw.clean()
this.canvasCache.clean() this.canvasCache.clean()
assets.sounds["bgm_result"].stop() assets.sounds["bgm_result"].stop()
snd.buffer.loadSettings() snd.buffer.loadSettings()
this.redrawRunning = false this.redrawRunning = false
pageEvents.keyRemove(this, "all")
pageEvents.remove(this.canvas, ["mousedown", "touchstart"]) pageEvents.remove(this.canvas, ["mousedown", "touchstart"])
if(this.multiplayer !== 2 && this.touchEnabled){ if(this.multiplayer !== 2 && this.touchEnabled){
pageEvents.remove(document.getElementById("touch-full-btn"), "touchend") pageEvents.remove(document.getElementById("touch-full-btn"), "touchend")

View File

@ -2,13 +2,13 @@ class Session{
constructor(touchEnabled){ constructor(touchEnabled){
this.touchEnabled = touchEnabled this.touchEnabled = touchEnabled
loader.changePage("session", true) loader.changePage("session", true)
this.endButton = document.getElementById("tutorial-end-button") this.endButton = this.getElement("view-end-button")
if(touchEnabled){ if(touchEnabled){
document.getElementById("tutorial-outer").classList.add("touch-enabled") this.getElement("view-outer").classList.add("touch-enabled")
} }
this.sessionInvite = document.getElementById("session-invite") this.sessionInvite = document.getElementById("session-invite")
var tutorialTitle = document.getElementById("tutorial-title") var tutorialTitle = this.getElement("view-title")
tutorialTitle.innerText = strings.session.multiplayerSession tutorialTitle.innerText = strings.session.multiplayerSession
tutorialTitle.setAttribute("alt", strings.session.multiplayerSession) tutorialTitle.setAttribute("alt", strings.session.multiplayerSession)
this.sessionInvite.parentNode.insertBefore(document.createTextNode(strings.session.linkTutorial), this.sessionInvite) this.sessionInvite.parentNode.insertBefore(document.createTextNode(strings.session.linkTutorial), this.sessionInvite)
@ -16,11 +16,12 @@ class Session{
this.endButton.setAttribute("alt", strings.session.cancel) this.endButton.setAttribute("alt", strings.session.cancel)
pageEvents.add(window, ["mousedown", "touchstart"], this.mouseDown.bind(this)) pageEvents.add(window, ["mousedown", "touchstart"], this.mouseDown.bind(this))
pageEvents.keyOnce(this, 27, "down").then(this.onEnd.bind(this)) this.keyboard = new Keyboard({
confirm: ["esc"]
}, this.keyPress.bind(this))
this.gamepad = new Gamepad({ this.gamepad = new Gamepad({
"confirm": ["start", "b", "ls", "rs"] confirm: ["start", "b", "ls", "rs"]
}, this.onEnd.bind(this)) }, this.keyPress.bind(this))
p2.hashLock = true p2.hashLock = true
pageEvents.add(p2, "message", response => { pageEvents.add(p2, "message", response => {
@ -29,13 +30,16 @@ class Session{
p2.hash(response.value) p2.hash(response.value)
}else if(response.type === "songsel"){ }else if(response.type === "songsel"){
p2.clearMessage("users") p2.clearMessage("users")
this.onEnd(false, true) this.onEnd(true)
pageEvents.send("session-start", "host") pageEvents.send("session-start", "host")
} }
}) })
p2.send("invite") p2.send("invite")
pageEvents.send("session") pageEvents.send("session")
} }
getElement(name){
return loader.screen.getElementsByClassName(name)[0]
}
mouseDown(event){ mouseDown(event){
if(event.type === "mousedown" && event.which !== 1){ if(event.type === "mousedown" && event.which !== 1){
return return
@ -50,7 +54,12 @@ class Session{
this.onEnd() this.onEnd()
} }
} }
onEnd(event, fromP2){ keyPress(pressed){
if(pressed){
this.onEnd()
}
}
onEnd(fromP2){
if(!p2.session){ if(!p2.session){
p2.send("leave") p2.send("leave")
p2.hash("") p2.hash("")
@ -59,9 +68,6 @@ class Session{
}else if(!fromP2){ }else if(!fromP2){
return p2.send("songsel") return p2.send("songsel")
} }
if(event && event.type === "keydown"){
event.preventDefault()
}
this.clean() this.clean()
assets.sounds["se_don"].play() assets.sounds["se_don"].play()
setTimeout(() => { setTimeout(() => {
@ -69,9 +75,9 @@ class Session{
}, 500) }, 500)
} }
clean(){ clean(){
this.keyboard.clean()
this.gamepad.clean() this.gamepad.clean()
pageEvents.remove(window, ["mousedown", "touchstart"]) pageEvents.remove(window, ["mousedown", "touchstart"])
pageEvents.keyRemove(this, 27)
pageEvents.remove(p2, "message") pageEvents.remove(p2, "message")
delete this.endButton delete this.endButton
delete this.sessionInvite delete this.sessionInvite

View File

@ -28,6 +28,12 @@ class Settings{
ka_r: ["k"] ka_r: ["k"]
}, },
touch: false touch: false
},
gamepadLayout: {
type: "gamepad",
options: ["a", "b", "c"],
default: "a",
gamepad: true
} }
} }
@ -42,7 +48,7 @@ class Settings{
this.storage[i] = null this.storage[i] = null
} }
}else if(i in storage){ }else if(i in storage){
if(current.type === "select" && current.options.indexOf(storage[i]) === -1){ if((current.type === "select" || current.type === "gamepad") && current.options.indexOf(storage[i]) === -1){
this.storage[i] = null this.storage[i] = null
}else if(current.type === "keyboard"){ }else if(current.type === "keyboard"){
var obj = {} var obj = {}
@ -116,29 +122,50 @@ class Settings{
} }
class SettingsView{ class SettingsView{
constructor(touchEnabled, tutorial){ constructor(touchEnabled, tutorial, songId){
this.touchEnabled = touchEnabled this.touchEnabled = touchEnabled
this.tutorial = tutorial this.tutorial = tutorial
if(!tutorial){ this.songId = songId
loader.changePage("settings", tutorial)
assets.sounds["bgm_settings"].playLoop(0.1, false, 0, 1.392, 26.992) loader.changePage("settings", tutorial)
this.defaultButton = document.getElementById("settings-default") assets.sounds["bgm_settings"].playLoop(0.1, false, 0, 1.392, 26.992)
}else if(touchEnabled){ this.defaultButton = document.getElementById("settings-default")
document.getElementById("tutorial-outer").classList.add("settings-outer")
}
if(touchEnabled){ if(touchEnabled){
document.getElementById("tutorial-outer").classList.add("touch-enabled") this.getElement("view-outer").classList.add("touch-enabled")
}
var gamepadEnabled = false
if("getGamepads" in navigator){
var gamepads = navigator.getGamepads()
for(var i = 0; i < gamepads.length; i++){
if(gamepads[i]){
gamepadEnabled = true
break
}
}
} }
this.mode = "settings" this.mode = "settings"
this.tutorialTitle = document.getElementById("tutorial-title") this.keyboard = new Keyboard({
this.endButton = document.getElementById("tutorial-end-button") "confirm": ["enter", "space", "don_l", "don_r"],
if(!tutorial){ "up": ["up"],
this.setStrings() "previous": ["left", "ka_l"],
} "next": ["right", "down", "ka_r"],
"back": ["esc"],
"other": ["wildcard"]
}, this.keyPressed.bind(this))
this.gamepad = new Gamepad({
"confirm": ["b", "ls", "rs"],
"up": ["u", "lsu"],
"previous": ["l", "lb", "lt", "lsl"],
"next": ["d", "r", "rb", "rt", "lsd", "lsr"],
"back": ["start", "a"]
}, this.keyPressed.bind(this))
this.viewTitle = this.getElement("view-title")
this.endButton = this.getElement("view-end-button")
this.resolution = settings.getItem("resolution") this.resolution = settings.getItem("resolution")
var content = document.getElementById("tutorial-content") var content = this.getElement("view-content")
this.items = [] this.items = []
this.selected = tutorial ? 1 : 0 this.selected = tutorial ? 1 : 0
for(let i in settings.items){ for(let i in settings.items){
@ -146,6 +173,7 @@ class SettingsView{
if( if(
!touchEnabled && current.touch === true || !touchEnabled && current.touch === true ||
touchEnabled && current.touch === false || touchEnabled && current.touch === false ||
!gamepadEnabled && current.gamepad === true ||
tutorial && current.type !== "language" tutorial && current.type !== "language"
){ ){
continue continue
@ -166,12 +194,7 @@ class SettingsView{
if(this.items.length === this.selected){ if(this.items.length === this.selected){
settingBox.classList.add("selected") settingBox.classList.add("selected")
} }
pageEvents.add(settingBox, ["mousedown", "touchstart"], event => { this.addTouch(settingBox, event => this.setValue(i))
if(event.type !== "mousedown" || event.which === 1){
event.preventDefault()
this.setValue(i)
}
})
this.items.push({ this.items.push({
id: i, id: i,
settingBox: settingBox, settingBox: settingBox,
@ -179,58 +202,82 @@ class SettingsView{
valueDiv: valueDiv valueDiv: valueDiv
}) })
} }
if(!tutorial){ if(tutorial){
this.defaultButton.style.display = "none"
this.endButton.classList.add("selected")
}else{
this.items.push({ this.items.push({
id: "default", id: "default",
settingBox: this.defaultButton settingBox: this.defaultButton
}) })
pageEvents.add(this.defaultButton, ["mousedown", "touchstart"], this.defaultSettings.bind(this)) this.addTouch(this.defaultButton, this.defaultSettings.bind(this))
} }
this.items.push({ this.items.push({
id: "back", id: "back",
settingBox: this.endButton settingBox: this.endButton
}) })
this.addTouch(this.endButton, this.onEnd.bind(this))
this.setKbd() this.gamepadSettings = document.getElementById("settings-gamepad")
pageEvents.add(this.endButton, ["mousedown", "touchstart"], this.onEnd.bind(this)) this.addTouch(this.gamepadSettings, event => {
pageEvents.keyAdd(this, "all", "down", this.keyEvent.bind(this)) if(event.target === event.currentTarget){
this.gamepad = new Gamepad({ this.gamepadBack()
"confirm": ["b", "ls", "rs"], }
"up": ["u", "lsu"], })
"previous": ["l", "lb", "lt", "lsl"], this.gamepadTitle = this.gamepadSettings.getElementsByClassName("view-title")[0]
"next": ["d", "r", "rb", "rt", "lsd", "lsr"], this.gamepadEndButton = this.gamepadSettings.getElementsByClassName("view-end-button")[0]
"back": ["start", "a"] this.addTouch(this.gamepadEndButton, event => this.gamepadBack(true))
}, this.keyPressed.bind(this)) this.gamepadBg = document.getElementById("gamepad-bg")
if(!tutorial){ this.addTouch(this.gamepadBg, event => this.gamepadSet(1))
pageEvents.send("settings") this.gamepadButtons = document.getElementById("gamepad-buttons")
} this.gamepadValue = document.getElementById("gamepad-value")
this.setStrings()
pageEvents.send("settings")
} }
setKbd(){ getElement(name){
var kbdSettings = settings.getItem("keyboardSettings") return loader.screen.getElementsByClassName(name)[0]
this.kbd = { }
"confirm": ["enter", " ", kbdSettings.don_l[0], kbdSettings.don_r[0]], addTouch(element, callback){
"up": ["arrowup"], pageEvents.add(element, ["mousedown", "touchstart"], event => {
"previous": ["arrowleft", kbdSettings.ka_l[0]], if(event.type === "touchstart"){
"next": ["arrowright", "arrowdown", kbdSettings.ka_r[0]], event.preventDefault()
"back": ["backspace", "escape"] this.touched = true
} }else if(event.which !== 1){
return
}else{
this.touched = false
}
callback(event)
})
}
removeTouch(element){
pageEvents.remove(element, ["mousedown", "touchstart"])
} }
getValue(name, valueDiv){ getValue(name, valueDiv){
var current = settings.items[name] var current = settings.items[name]
var value = settings.getItem(name) var value = settings.getItem(name)
if(current.type === "language"){ if(current.type === "language"){
value = allStrings[value].name + " (" + value + ")" value = allStrings[value].name + " (" + value + ")"
}else if(current.type === "select"){ }else if(current.type === "select" || current.type === "gamepad"){
value = strings.settings[name][value] value = strings.settings[name][value]
}else if(current.type === "toggle"){ }else if(current.type === "toggle"){
value = value ? strings.settings.on : strings.settings.off value = value ? strings.settings.on : strings.settings.off
}else if(current.type === "keyboard"){ }else if(current.type === "keyboard"){
valueDiv.innerHTML = "" valueDiv.innerHTML = ""
for(var i in value){ for(var i in value){
var key = document.createElement("div") var keyDiv = document.createElement("div")
key.style.color = i === "ka_l" || i === "ka_r" ? "#009aa5" : "#ef2c10" keyDiv.style.color = i === "ka_l" || i === "ka_r" ? "#009aa5" : "#ef2c10"
key.innerText = value[i][0].toUpperCase() var key = value[i][0]
valueDiv.appendChild(key) for(var j in this.keyboard.substitute){
if(this.keyboard.substitute[j] === key){
key = j
break
}
}
keyDiv.innerText = key.toUpperCase()
valueDiv.appendChild(keyDiv)
} }
return return
} }
@ -264,6 +311,12 @@ class SettingsView{
this.keyboardSet() this.keyboardSet()
assets.sounds["se_don"].play() assets.sounds["se_don"].play()
return return
}else if(current.type === "gamepad"){
this.mode = "gamepad"
this.gamepadSelected = current.options.indexOf(value)
this.gamepadSet()
assets.sounds["se_don"].play()
return
} }
settings.setItem(name, value) settings.setItem(name, value)
this.getValue(name, this.items[this.selected].valueDiv) this.getValue(name, this.items[this.selected].valueDiv)
@ -272,37 +325,11 @@ class SettingsView{
this.setLang(allStrings[value]) this.setLang(allStrings[value])
} }
} }
keyEvent(event){ keyPressed(pressed, name, event){
if(event.keyCode === 27 || event.keyCode === 8 || event.keyCode === 9){
// Escape, Backspace, Tab
event.preventDefault()
}
if(!event.repeat){
for(var i in this.kbd){
if(this.kbd[i].indexOf(event.key.toLowerCase()) !== -1){
if(this.mode !== "keyboard" || i === "back"){
this.keyPressed(true, i)
return
}
}
}
if(this.mode === "keyboard"){
event.preventDefault()
var currentKey = event.key.toLowerCase()
for(var i in this.keyboardKeys){
if(this.keyboardKeys[i][0] === currentKey || !currentKey){
return
}
}
this.keyboardKeys[this.keyboardCurrent] = [currentKey]
this.keyboardSet()
}
}
}
keyPressed(pressed, name){
if(!pressed){ if(!pressed){
return return
} }
this.touched = false
var selected = this.items[this.selected] var selected = this.items[this.selected]
if(this.mode === "settings"){ if(this.mode === "settings"){
if(name === "confirm"){ if(name === "confirm"){
@ -325,9 +352,30 @@ class SettingsView{
}else if(name === "back"){ }else if(name === "back"){
this.onEnd() this.onEnd()
} }
}else if(this.mode === "gamepad"){
if(name === "confirm"){
this.gamepadBack(true)
}else if(name === "up" || name === "previous" || name === "next"){
this.gamepadSet(name === "next" ? 1 : -1)
}else if(name === "back"){
this.gamepadBack()
}
}else if(this.mode === "keyboard"){ }else if(this.mode === "keyboard"){
if(name === "back"){ if(name === "back"){
this.keyboardBack(selected) this.keyboardBack(selected)
assets.sounds["se_cancel"].play()
}else{
event.preventDefault()
var currentKey = event.key.toLowerCase()
for(var i in this.keyboardKeys){
if(this.keyboardKeys[i][0] === currentKey || !currentKey){
return
}
}
var current = this.keyboardCurrent
assets.sounds[current === "ka_l" || current === "ka_r" ? "se_ka" : "se_don"].play()
this.keyboardKeys[current] = [currentKey]
this.keyboardSet()
} }
} }
} }
@ -336,21 +384,28 @@ class SettingsView{
var current = settings.items[selected.id] var current = settings.items[selected.id]
selected.valueDiv.innerHTML = "" selected.valueDiv.innerHTML = ""
for(var i in current.default){ for(var i in current.default){
var key = document.createElement("div") var keyDiv = document.createElement("div")
key.style.color = i === "ka_l" || i === "ka_r" ? "#009aa5" : "#ef2c10" keyDiv.style.color = i === "ka_l" || i === "ka_r" ? "#009aa5" : "#ef2c10"
if(this.keyboardKeys[i]){ if(this.keyboardKeys[i]){
key.innerText = this.keyboardKeys[i][0].toUpperCase() var key = this.keyboardKeys[i][0]
selected.valueDiv.appendChild(key) for(var j in this.keyboard.substitute){
if(this.keyboard.substitute[j] === key){
key = j
break
}
}
keyDiv.innerText = key.toUpperCase()
selected.valueDiv.appendChild(keyDiv)
}else{ }else{
key.innerText = "[" + strings.settings[selected.id][i] + "]" keyDiv.innerText = "[" + strings.settings[selected.id][i] + "]"
selected.valueDiv.appendChild(key) selected.valueDiv.appendChild(keyDiv)
this.keyboardCurrent = i this.keyboardCurrent = i
return return
} }
} }
settings.setItem(selected.id, this.keyboardKeys) settings.setItem(selected.id, this.keyboardKeys)
this.keyboardBack(selected) this.keyboardBack(selected)
this.setKbd() this.keyboard.update()
pageEvents.setKbd() pageEvents.setKbd()
} }
keyboardBack(selected){ keyboardBack(selected){
@ -359,10 +414,38 @@ class SettingsView{
selected.valueDiv.classList.remove("selected") selected.valueDiv.classList.remove("selected")
this.getValue(selected.id, selected.valueDiv) this.getValue(selected.id, selected.valueDiv)
} }
defaultSettings(event){ gamepadSet(diff){
if(event && event.type === "touchstart"){ if(this.mode !== "gamepad"){
event.preventDefault() return
} }
var selected = this.items[this.selected]
var current = settings.items[selected.id]
if(diff){
this.gamepadSelected = this.mod(current.options.length, this.gamepadSelected + diff)
assets.sounds["se_ka"].play()
}
var opt = current.options[this.gamepadSelected]
this.gamepadValue.innerText = strings.settings[selected.id][opt]
this.gamepadButtons.style.backgroundPosition = "0 " + (-318 - 132 * this.gamepadSelected) + "px"
this.gamepadSettings.style.display = "block"
}
gamepadBack(save){
if(this.mode !== "gamepad"){
return
}
if(save){
var selected = this.items[this.selected]
var current = settings.items[selected.id]
settings.setItem(selected.id, current.options[this.gamepadSelected])
this.getValue(selected.id, selected.valueDiv)
assets.sounds["se_don"].play()
}else{
assets.sounds["se_cancel"].play()
}
this.gamepadSettings.style.display = ""
this.mode = "settings"
}
defaultSettings(){
if(this.mode === "keyboard"){ if(this.mode === "keyboard"){
this.keyboardBack(this.items[this.selected]) this.keyboardBack(this.items[this.selected])
} }
@ -370,27 +453,19 @@ class SettingsView{
settings.setItem(i, null) settings.setItem(i, null)
} }
this.setLang(allStrings[settings.getItem("language")]) this.setLang(allStrings[settings.getItem("language")])
this.setKbd() this.keyboard.update()
pageEvents.setKbd()
assets.sounds["se_don"].play() assets.sounds["se_don"].play()
} }
onEnd(event){ onEnd(){
if(this.tutorial){
this.clean()
return this.tutorial.onEnd(event)
}
var touched = false
if(event){
if(event.type === "touchstart"){
event.preventDefault()
touched = true
}else if(event.which !== 1){
return
}
}
this.clean() this.clean()
assets.sounds["se_don"].play() assets.sounds["se_don"].play()
setTimeout(() => { setTimeout(() => {
new SongSelect("settings", false, touched) if(this.tutorial && !this.touched){
new Tutorial(false, this.songId)
}else{
new SongSelect(this.tutorial ? false : "settings", false, this.touched, this.songId)
}
}, 500) }, 500)
} }
setLang(lang){ setLang(lang){
@ -410,33 +485,44 @@ class SettingsView{
this.setStrings() this.setStrings()
} }
setStrings(){ setStrings(){
if(this.tutorial){ this.viewTitle.innerText = strings.gameSettings
this.tutorial.setStrings() this.viewTitle.setAttribute("alt", strings.gameSettings)
}else{ this.endButton.innerText = strings.settings.ok
this.tutorialTitle.innerText = strings.gameSettings this.endButton.setAttribute("alt", strings.settings.ok)
this.tutorialTitle.setAttribute("alt", strings.gameSettings) this.gamepadTitle.innerText = strings.settings.gamepadLayout.name
this.gamepadTitle.setAttribute("alt", strings.settings.gamepadLayout.name)
this.gamepadEndButton.innerText = strings.settings.ok
this.gamepadEndButton.setAttribute("alt", strings.settings.ok)
if(!this.tutorial){
this.defaultButton.innerText = strings.settings.default this.defaultButton.innerText = strings.settings.default
this.defaultButton.setAttribute("alt", strings.settings.default) this.defaultButton.setAttribute("alt", strings.settings.default)
this.endButton.innerText = strings.settings.ok
this.endButton.setAttribute("alt", strings.settings.ok)
} }
} }
mod(length, index){ mod(length, index){
return ((index % length) + length) % length return ((index % length) + length) % length
} }
clean(){ clean(){
this.keyboard.clean()
this.gamepad.clean() this.gamepad.clean()
assets.sounds["bgm_settings"].stop() assets.sounds["bgm_settings"].stop()
pageEvents.keyRemove(this, "all")
for(var i in this.items){ for(var i in this.items){
pageEvents.remove(this.items[i].settingBox, ["mousedown", "touchstart"]) this.removeTouch(this.items[i].settingBox)
} }
if(this.defaultButton){ if(this.defaultButton){
delete this.defaultButton delete this.defaultButton
} }
this.removeTouch(this.gamepadSettings)
this.removeTouch(this.gamepadEndButton)
this.removeTouch(this.gamepadBg)
delete this.tutorialTitle delete this.tutorialTitle
delete this.endButton delete this.endButton
delete this.items delete this.items
delete this.gamepadSettings
delete this.gamepadTitle
delete this.gamepadEndButton
delete this.gamepadBg
delete this.gamepadButtons
delete this.gamepadValue
if(this.resolution !== settings.getItem("resolution")){ if(this.resolution !== settings.getItem("resolution")){
for(var i in assets.image){ for(var i in assets.image){
if(i === "touch_drum" || i.startsWith("bg_song_") || i.startsWith("bg_stage_") || i.startsWith("bg_don_")){ if(i === "touch_drum" || i.startsWith("bg_song_") || i.startsWith("bg_stage_") || i.startsWith("bg_don_")){

View File

@ -289,16 +289,17 @@ class SongSelect{
this.startPreview(true) this.startPreview(true)
this.pressedKeys = {} this.pressedKeys = {}
var kbdSettings = settings.getItem("keyboardSettings") this.keyboard = new Keyboard({
this.kbd = { confirm: ["enter", "space", "don_l", "don_r"],
confirm: ["enter", " ", kbdSettings.don_l[0], kbdSettings.don_r[0]],
back: ["escape"], back: ["escape"],
left: ["arrowleft", kbdSettings.ka_l[0]], left: ["left", "ka_l"],
right: ["arrowright", kbdSettings.ka_r[0]], right: ["right", "ka_r"],
up: ["arrowup"], up: ["up"],
down: ["arrowdown"], down: ["down"],
session: ["backspace"] session: ["backspace"],
} ctrl: ["ctrl"],
shift: ["shift"]
}, this.keyPress.bind(this))
this.gamepad = new Gamepad({ this.gamepad = new Gamepad({
confirm: ["b", "start", "ls", "rs"], confirm: ["b", "start", "ls", "rs"],
back: ["a"], back: ["a"],
@ -309,13 +310,12 @@ class SongSelect{
session: ["back"], session: ["back"],
ctrl: ["y"], ctrl: ["y"],
shift: ["x"] shift: ["x"]
}) }, this.keyPress.bind(this))
if(!assets.customSongs){ if(!assets.customSongs){
this.startP2() this.startP2()
} }
pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this))
pageEvents.add(loader.screen, "mousemove", this.mouseMove.bind(this)) pageEvents.add(loader.screen, "mousemove", this.mouseMove.bind(this))
pageEvents.add(loader.screen, "mouseleave", () => { pageEvents.add(loader.screen, "mouseleave", () => {
this.state.moveHover = null this.state.moveHover = null
@ -341,61 +341,47 @@ class SongSelect{
} }
} }
keyDown(event, key){ keyPress(pressed, name, event){
if(key){ if(pressed){
var modifiers = { if(!this.pressedKeys[name]){
shift: this.pressedKeys["shift"], this.pressedKeys[name] = this.getMS() + 300
ctrl: this.pressedKeys["ctrl"]
} }
}else{ }else{
var modifiers = { this.pressedKeys[name] = 0
shift: event.shiftKey,
ctrl: event.ctrlKey
}
for(var i in this.kbd){
if(this.kbd[i].indexOf(event.key.toLowerCase()) !== -1){
key = i
break
}
}
}
if(key === "ctrl" || key === "shift" || !this.redrawRunning){
return return
} }
if(name === "ctrl" || name === "shift" || !this.redrawRunning){
if(event && (event.keyCode === 27 || event.keyCode === 8 || event.keyCode === 9)){ return
// Escape, Backspace, Tab
event.preventDefault()
} }
if(this.state.screen === "song"){ if(this.state.screen === "song"){
if(key === "confirm"){ if(name === "confirm"){
this.toSelectDifficulty() this.toSelectDifficulty()
}else if(key === "back"){ }else if(name === "back"){
this.toTitleScreen() this.toTitleScreen()
}else if(key === "session"){ }else if(name === "session"){
this.toSession() this.toSession()
}else if(key === "left"){ }else if(name === "left"){
this.moveToSong(-1) this.moveToSong(-1)
}else if(key === "right"){ }else if(name === "right"){
this.moveToSong(1) this.moveToSong(1)
} }
}else if(this.state.screen === "difficulty"){ }else if(this.state.screen === "difficulty"){
if(key === "confirm"){ if(name === "confirm"){
if(this.selectedDiff === 0){ if(this.selectedDiff === 0){
this.toSongSelect() this.toSongSelect()
}else if(this.selectedDiff === 1){ }else if(this.selectedDiff === 1){
this.toOptions(1) this.toOptions(1)
}else{ }else{
this.toLoadSong(this.selectedDiff - this.diffOptions.length, modifiers.shift, modifiers.ctrl) this.toLoadSong(this.selectedDiff - this.diffOptions.length, this.pressedKeys["shift"], this.pressedKeys["ctrl"])
} }
}else if(key === "back" || key === "session"){ }else if(name === "back" || name === "session"){
this.toSongSelect() this.toSongSelect()
}else if(key === "left"){ }else if(name === "left"){
this.moveToDiff(-1) this.moveToDiff(-1)
}else if(key === "right"){ }else if(name === "right"){
this.moveToDiff(1) this.moveToDiff(1)
}else if(this.selectedDiff === 1 && (key === "up" || key === "down")){ }else if(this.selectedDiff === 1 && (name === "up" || name === "down")){
this.toOptions(key === "up" ? -1 : 1) this.toOptions(name === "up" ? -1 : 1)
} }
} }
} }
@ -781,20 +767,10 @@ class SongSelect{
requestAnimationFrame(this.redrawBind) requestAnimationFrame(this.redrawBind)
var ms = this.getMS() var ms = this.getMS()
this.gamepad.play((pressed, keyCode) => {
if(pressed){
if(!this.pressedKeys[keyCode]){
this.pressedKeys[keyCode] = ms + 300
this.keyDown(false, keyCode)
}
}else{
this.pressedKeys[keyCode] = 0
}
})
for(var key in this.pressedKeys){ for(var key in this.pressedKeys){
if(this.pressedKeys[key]){ if(this.pressedKeys[key]){
if(ms >= this.pressedKeys[key] + 50){ if(ms >= this.pressedKeys[key] + 50){
this.keyDown(false, key) this.keyPress(true, key)
this.pressedKeys[key] = ms this.pressedKeys[key] = ms
} }
} }
@ -1957,6 +1933,8 @@ class SongSelect{
} }
clean(){ clean(){
this.keyboard.clean()
this.gamepad.clean()
this.clearHash() this.clearHash()
this.draw.clean() this.draw.clean()
this.songTitleCache.clean() this.songTitleCache.clean()
@ -1979,7 +1957,6 @@ class SongSelect{
song.preview_sound.clean() song.preview_sound.clean()
} }
}) })
pageEvents.keyRemove(this, "all")
pageEvents.remove(loader.screen, ["mousemove", "mouseleave", "mousedown", "touchstart"]) pageEvents.remove(loader.screen, ["mousemove", "mouseleave", "mousedown", "touchstart"])
pageEvents.remove(this.canvas, "touchend") pageEvents.remove(this.canvas, "touchend")
pageEvents.remove(p2, "message") pageEvents.remove(p2, "message")

View File

@ -120,6 +120,12 @@
don_r: "面(右)", don_r: "面(右)",
ka_r: "ふち(右)" ka_r: "ふち(右)"
}, },
gamepadLayout: {
name: "そうさタイプ設定",
a: "タイプA",
b: "タイプB",
c: "タイプC"
},
on: "オン", on: "オン",
off: "オフ", off: "オフ",
default: "既定値にリセット", default: "既定値にリセット",
@ -254,6 +260,12 @@ function StringsEn(){
don_r: "Right Surface", don_r: "Right Surface",
ka_r: "Right Rim" ka_r: "Right Rim"
}, },
gamepadLayout: {
name: "Gamepad Layout",
a: "Type A",
b: "Type B",
c: "Type C"
},
on: "On", on: "On",
off: "Off", off: "Off",
default: "Reset to Defaults", default: "Reset to Defaults",
@ -383,10 +395,16 @@ function StringsCn(){
}, },
keyboardSettings: { keyboardSettings: {
name: "键盘设置", name: "键盘设置",
ka_l: "Left Rim", ka_l: "边缘(左)",
don_l: "Left Surface", don_l: "表面(左)",
don_r: "Right Surface", don_r: "表面(右)",
ka_r: "Right Rim" ka_r: "边缘(右)"
},
gamepadLayout: {
name: "操作类型设定",
a: "类型A",
b: "类型B",
c: "类型C"
}, },
on: "开", on: "开",
off: "关", off: "关",
@ -517,10 +535,16 @@ function StringsTw(){
}, },
keyboardSettings: { keyboardSettings: {
name: "鍵盤設置", name: "鍵盤設置",
ka_l: "Left Rim", ka_l: "邊緣(左)",
don_l: "Left Surface", don_l: "表面(左)",
don_r: "Right Surface", don_r: "表面(右)",
ka_r: "Right Rim" ka_r: "邊緣(右)"
},
gamepadLayout: {
name: "操作類型設定",
a: "類型A",
b: "類型B",
c: "類型C"
}, },
on: "開", on: "開",
off: "關", off: "關",
@ -651,10 +675,16 @@ function StringsKo(){
}, },
keyboardSettings: { keyboardSettings: {
name: "키보드 설정", name: "키보드 설정",
ka_l: "Left Rim", ka_l: "가장자리 (왼쪽)",
don_l: "Left Surface", don_l: "표면 (왼쪽)",
don_r: "Right Surface", don_r: "표면 (오른쪽)",
ka_r: "Right Rim" ka_r: "가장자리 (오른쪽)"
},
gamepadLayout: {
name: "조작 타입 설정",
a: "타입 A",
b: "타입 B",
c: "타입 C"
}, },
on: "온", on: "온",
off: "오프", off: "오프",

View File

@ -17,24 +17,26 @@ class Titlescreen{
if(localStorage.getItem("tutorial") === "true"){ if(localStorage.getItem("tutorial") === "true"){
new SongSelect(false, false, this.touched, this.songId) new SongSelect(false, false, this.touched, this.songId)
}else{ }else{
new Tutorial(false, this.songId) new SettingsView(false, true, this.songId)
} }
}else{ }else{
pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this)) pageEvents.add(this.titleScreen, ["mousedown", "touchstart"], event => {
pageEvents.add(this.titleScreen, ["mousedown", "touchstart"], this.onPressed.bind(this)) if(event.type === "touchstart"){
event.preventDefault()
this.touched = true
}else if(event.type === "mousedown" && event.which !== 1){
return
}
this.onPressed(true)
})
assets.sounds["v_title"].play() assets.sounds["v_title"].play()
var kbdSettings = settings.getItem("keyboardSettings") this.keyboard = new Keyboard({
this.kbd = { confirm: ["enter", "space", "don_l", "don_r"]
confirm: ["enter", " ", kbdSettings.don_l[0], kbdSettings.don_r[0]] }, this.onPressed.bind(this))
}
this.gamepad = new Gamepad({ this.gamepad = new Gamepad({
confirm: ["a", "b", "x", "y", "start", "ls", "rs"] confirm: ["a", "b", "x", "y", "start", "ls", "rs"]
}, pressed => { }, this.onPressed.bind(this))
if(pressed){
this.onPressed()
}
})
if(p2.session){ if(p2.session){
pageEvents.add(p2, "message", response => { pageEvents.add(p2, "message", response => {
if(response.type === "songsel"){ if(response.type === "songsel"){
@ -46,35 +48,13 @@ class Titlescreen{
} }
} }
keyDown(event, key){ onPressed(pressed, name){
if(!key){ if(pressed){
if(event.repeat || event.target === this.langDropdown){ this.titleScreen.style.cursor = "auto"
return this.clean()
} assets.sounds["se_don"].play()
for(var i in this.kbd){ this.goNext()
if(this.kbd[i].indexOf(event.key.toLowerCase()) !== -1){
key = i
break
}
}
} }
if(key === "confirm"){
this.onPressed()
}
}
onPressed(event){
if(event){
if(event.type === "touchstart"){
event.preventDefault()
this.touched = true
}else if(event.type === "mousedown" && event.which !== 1){
return
}
}
this.titleScreen.style.cursor = "auto"
this.clean()
assets.sounds["se_don"].play()
this.goNext()
} }
goNext(fromP2){ goNext(fromP2){
if(p2.session && !fromP2){ if(p2.session && !fromP2){
@ -89,7 +69,7 @@ class Titlescreen{
}, 500) }, 500)
}else{ }else{
setTimeout(() => { setTimeout(() => {
new Tutorial(false, this.songId, this.touched) new SettingsView(this.touched, true, this.songId)
}, 500) }, 500)
} }
} }
@ -109,10 +89,10 @@ class Titlescreen{
this.logo.updateSubtitle() this.logo.updateSubtitle()
} }
clean(){ clean(){
this.keyboard.clean()
this.gamepad.clean() this.gamepad.clean()
this.logo.clean() this.logo.clean()
assets.sounds["v_title"].stop() assets.sounds["v_title"].stop()
pageEvents.keyRemove(this, "all")
pageEvents.remove(this.titleScreen, ["mousedown", "touchstart"]) pageEvents.remove(this.titleScreen, ["mousedown", "touchstart"])
delete this.titleScreen delete this.titleScreen
delete this.proceed delete this.proceed

View File

@ -1,34 +1,37 @@
class Tutorial{ class Tutorial{
constructor(fromSongSel, songId, touchEnabled){ constructor(fromSongSel, songId){
this.fromSongSel = fromSongSel this.fromSongSel = fromSongSel
this.songId = songId this.songId = songId
this.touchEnabled = touchEnabled loader.changePage("tutorial", true)
loader.changePage("tutorial", fromSongSel || !touchEnabled)
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 = this.getElement("view-end-button")
this.tutorialTitle = document.getElementById("tutorial-title") this.tutorialTitle = this.getElement("view-title")
this.tutorialDiv = document.createElement("div") this.tutorialDiv = document.createElement("div")
document.getElementById("tutorial-content").appendChild(this.tutorialDiv) this.getElement("view-content").appendChild(this.tutorialDiv)
this.setStrings() this.setStrings()
if(fromSongSel){ pageEvents.add(this.endButton, ["mousedown", "touchstart"], event => {
pageEvents.add(this.endButton, ["mousedown", "touchstart"], this.onEnd.bind(this)) if(event.type === "touchstart"){
pageEvents.keyAdd(this, "all", "down", event => { event.preventDefault()
if(event.keyCode === 13 || event.keyCode === 27 || event.keyCode === 8){ this.touched = true
// Enter, Esc, Backspace }else if(event.type === "mousedown" && event.which !== 1){
this.onEnd.bind(this) return
} }
}) this.onEnd(true)
})
this.gamepad = new Gamepad({ this.keyboard = new Keyboard({
"confirm": ["start", "b", "ls", "rs"] confirm: ["enter", "space", "esc", "don_l", "don_r"]
}, this.onEnd.bind(this)) }, this.onEnd.bind(this))
}else{ this.gamepad = new Gamepad({
new SettingsView(touchEnabled, this) confirm: ["start", "b", "ls", "rs"]
} }, this.onEnd.bind(this))
pageEvents.send("tutorial") pageEvents.send("tutorial")
} }
getElement(name){
return loader.screen.getElementsByClassName(name)[0]
}
insertText(text, parent){ insertText(text, parent){
parent.appendChild(document.createTextNode(text)) parent.appendChild(document.createTextNode(text))
} }
@ -37,43 +40,30 @@ class Tutorial{
kbd.innerText = key kbd.innerText = key
parent.appendChild(kbd) parent.appendChild(kbd)
} }
onEnd(event){ onEnd(pressed, name){
var touched = false if(pressed){
if(event){ this.clean()
if(event.type === "touchstart"){ assets.sounds["se_don"].play()
event.preventDefault() localStorage.setItem("tutorial", "true")
touched = true setTimeout(() => {
}else if(event.which !== 1){ new SongSelect(this.fromSongSel ? "tutorial" : false, false, this.touched, this.songId)
return }, 500)
}
} }
this.clean()
assets.sounds["se_don"].play()
localStorage.setItem("tutorial", "true")
setTimeout(() => {
new SongSelect(this.fromSongSel ? "tutorial" : false, false, touched, this.songId)
}, 500)
} }
setStrings(){ setStrings(){
if(!this.fromSongSel && this.touchEnabled){
this.tutorialTitle.innerText = strings.gameSettings
this.tutorialTitle.setAttribute("alt", strings.gameSettings)
this.endButton.innerText = strings.settings.ok
this.endButton.setAttribute("alt", strings.settings.ok)
return
}
this.tutorialTitle.innerText = strings.howToPlay this.tutorialTitle.innerText = strings.howToPlay
this.tutorialTitle.setAttribute("alt", strings.howToPlay) this.tutorialTitle.setAttribute("alt", strings.howToPlay)
this.endButton.innerText = strings.tutorial.ok this.endButton.innerText = strings.tutorial.ok
this.endButton.setAttribute("alt", strings.tutorial.ok) this.endButton.setAttribute("alt", strings.tutorial.ok)
this.tutorialDiv.innerHTML = "" this.tutorialDiv.innerHTML = ""
var kbdSettings = settings.getItem("keyboardSettings") var kbdSettings = settings.getItem("keyboardSettings")
var pauseKey = pageEvents.kbd.indexOf("q") === -1 ? "Q" : "ESC"
var keys = [ var keys = [
kbdSettings.don_l[0].toUpperCase(), kbdSettings.don_l[0].toUpperCase(),
kbdSettings.don_r[0].toUpperCase(), kbdSettings.don_r[0].toUpperCase(),
kbdSettings.ka_l[0].toUpperCase(), kbdSettings.ka_l[0].toUpperCase(),
kbdSettings.ka_r[0].toUpperCase(), kbdSettings.ka_r[0].toUpperCase(),
"Q", "SHIFT", "CTRL" pauseKey, "SHIFT", "CTRL"
] ]
var keyIndex = 0 var keyIndex = 0
strings.tutorial.basics.forEach(string => { strings.tutorial.basics.forEach(string => {
@ -105,11 +95,9 @@ class Tutorial{
this.tutorialDiv.appendChild(par) this.tutorialDiv.appendChild(par)
} }
clean(){ clean(){
if(this.fromSongSel){ this.keyboard.clean()
this.gamepad.clean() this.gamepad.clean()
pageEvents.remove(this.endButton, ["mousedown", "touchstart"]) pageEvents.remove(this.endButton, ["mousedown", "touchstart"])
pageEvents.keyRemove(this, "all")
}
assets.sounds["bgm_setsume"].stop() assets.sounds["bgm_setsume"].stop()
delete this.tutorialTitle delete this.tutorialTitle
delete this.endButton delete this.endButton

View File

@ -830,11 +830,10 @@
) )
// Taiko pressed keys // Taiko pressed keys
var kbd = this.controller.getBindings()
var keys = ["ka_l", "ka_r", "don_l", "don_r"] var keys = ["ka_l", "ka_r", "don_l", "don_r"]
for(var i = 0; i < keys.length; i++){ for(var i = 0; i < keys.length; i++){
var keyMS = ms - keyTime[kbd[keys[i]]] var keyMS = ms - keyTime[keys[i]]
if(keyMS < 130){ if(keyMS < 130){
if(keyMS > 70 && !this.touchEnabled){ if(keyMS > 70 && !this.touchEnabled){
ctx.globalAlpha = this.draw.easeOut(1 - (keyMS - 70) / 60) ctx.globalAlpha = this.draw.easeOut(1 - (keyMS - 70) / 60)
@ -1769,11 +1768,10 @@
} }
touchNote(note){ touchNote(note){
var keyboard = this.controller.keyboard var keyboard = this.controller.keyboard
var kbd = keyboard.getBindings()
var ms = this.controller.game.getAccurateTime() var ms = this.controller.game.getAccurateTime()
this.touch = ms this.touch = ms
keyboard.setKey(kbd[note], false) keyboard.setKey(false, note)
keyboard.setKey(kbd[note], true, ms) keyboard.setKey(true, note, ms)
} }
mod(length, index){ mod(length, index){
return ((index % length) + length) % length return ((index % length) + length) % length

View File

@ -1,9 +1,9 @@
<div id="tutorial-outer"> <div class="view-outer">
<div id="tutorial"> <div class="view">
<div id="tutorial-title" class="stroke-sub"></div> <div class="view-title stroke-sub"></div>
<div id="tutorial-content"></div> <div class="view-content"></div>
<div id="diag-txt"></div> <div id="diag-txt"></div>
<div id="about-link-btns"> <div class="left-buttons">
<div id="link-issues" class="taibtn stroke-sub link-btn" alt="Issues"> <div id="link-issues" class="taibtn stroke-sub link-btn" alt="Issues">
<a target="_blank">Issues</a> <a target="_blank">Issues</a>
</div> </div>
@ -11,6 +11,6 @@
<a href="mailto:taiko@bui.pm">taiko@bui.pm</a> <a href="mailto:taiko@bui.pm">taiko@bui.pm</a>
</div> </div>
</div> </div>
<div id="tutorial-end-button" class="taibtn stroke-sub selected"></div> <div class="view-end-button taibtn stroke-sub selected"></div>
</div> </div>
</div> </div>

View File

@ -1,9 +1,9 @@
<div id="tutorial-outer"> <div class="view-outer">
<div id="tutorial"> <div class="view">
<div id="tutorial-title" class="stroke-sub"></div> <div class="view-title stroke-sub"></div>
<div id="tutorial-content"> <div class="view-content">
<div id="session-invite"></div> <div id="session-invite"></div>
</div> </div>
<div id="tutorial-end-button" class="taibtn stroke-sub"></div> <div class="view-end-button taibtn stroke-sub"></div>
</div> </div>
</div> </div>

View File

@ -1,10 +1,20 @@
<div id="tutorial-outer" class="settings-outer"> <div class="view-outer settings-outer">
<div id="tutorial"> <div class="view">
<div id="tutorial-title" class="stroke-sub"></div> <div class="view-title stroke-sub"></div>
<div id="tutorial-content"></div> <div class="view-content"></div>
<div id="about-link-btns"> <div class="left-buttons">
<div id="settings-default" class="taibtn stroke-sub"></div> <div id="settings-default" class="taibtn stroke-sub"></div>
</div> </div>
<div id="tutorial-end-button" class="taibtn stroke-sub"></div> <div class="view-end-button taibtn stroke-sub"></div>
<div class="view-outer shadow-outer" id="settings-gamepad">
<div class="view">
<div class="view-title stroke-sub"></div>
<div id="gamepad-bg" class="view-content">
<span id="gamepad-value"></span>
<div id="gamepad-buttons"></div>
</div>
<div class="view-end-button taibtn stroke-sub selected"></div>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
<div id="tutorial-outer"> <div class="view-outer">
<div id="tutorial"> <div class="view">
<div id="tutorial-title" class="stroke-sub"></div> <div class="view-title" class="stroke-sub"></div>
<div id="tutorial-content"></div> <div class="view-content"></div>
<div id="tutorial-end-button" class="taibtn stroke-sub selected"></div> <div class="view-end-button taibtn stroke-sub selected"></div>
</div> </div>
</div> </div>