japanese-drum-game/public/src/js/settings.js

427 lines
12 KiB
JavaScript
Raw Normal View History

class Settings{
constructor(){
var ios = /iPhone|iPad/.test(navigator.userAgent)
var phone = /Android|iPhone|iPad/.test(navigator.userAgent)
this.items = {
2019-04-06 18:19:10 +08:00
language: {
type: "language",
options: ["ja", "en", "cn", "tw", "ko"],
default: this.getLang()
},
resolution: {
type: "select",
options: ["high", "medium", "low", "lowest"],
default: phone ? "medium" : "high"
},
touchAnimation: {
type: "toggle",
default: !ios,
touch: true
2019-04-06 03:53:51 +08:00
},
keyboardSettings: {
type: "keyboard",
default: {
ka_l: ["d"],
don_l: ["f"],
don_r: ["j"],
ka_r: ["k"]
},
touch: false
}
}
this.storage = {}
try{
var storage = JSON.parse(localStorage.getItem("settings") || "{}")
for(var i in this.items){
var current = this.items[i]
2019-04-06 18:19:10 +08:00
if(current.type === "language"){
this.storage[i] = localStorage.getItem("lang")
if(current.options.indexOf(this.storage[i]) === -1){
this.storage[i] = null
}
}else if(i in storage){
if(current.type === "select" && current.options.indexOf(storage[i]) === -1){
this.storage[i] = null
2019-04-06 03:53:51 +08:00
}else if(current.type === "keyboard"){
var obj = {}
for(var j in current.default){
2019-04-06 18:19:10 +08:00
if(storage[i] && storage[i][j] && storage[i][j][0]){
2019-04-06 03:53:51 +08:00
obj[j] = storage[i][j]
}else{
obj = null
break
}
}
this.storage[i] = obj
}else{
this.storage[i] = storage[i]
}
}else{
this.storage[i] = null
}
}
}catch(e){
for(var i in this.items){
this.storage[i] = null
}
}
}
getItem(name){
var value = this.storage[name]
return value === null ? this.items[name].default : value
}
setItem(name, value){
this.storage[name] = value
try{
2019-04-06 18:19:10 +08:00
if(name === "language"){
if(value){
localStorage.setItem("lang", value)
}else{
localStorage.removeItem("lang")
}
}else{
var language = this.storage.language
delete this.storage.language
localStorage.setItem("settings", JSON.stringify(this.storage))
this.storage.language = language
}
}catch(e){}
}
2019-04-06 18:19:10 +08:00
getLang(){
if("languages" in navigator){
var userLang = navigator.languages.slice()
userLang.unshift(navigator.language)
for(var i in userLang){
for(var j in allStrings){
if(allStrings[j].regex.test(userLang[i])){
return j
}
}
}
}
return "ja"
}
setLang(lang, noEvent){
strings = lang
var boldFonts = strings.font === "Microsoft YaHei, sans-serif"
loader.screen.style.fontFamily = strings.font
loader.screen.style.fontWeight = boldFonts ? "bold" : ""
loader.screen.classList[boldFonts ? "add" : "remove"]("bold-fonts")
if(!noEvent){
pageEvents.send("language-change", lang.id)
}
}
}
class SettingsView{
constructor(touchEnabled){
this.touchEnabled = touchEnabled
2019-04-06 03:53:51 +08:00
loader.changePage("settings", false)
2019-04-05 17:36:14 +08:00
assets.sounds["bgm_settings"].playLoop(0.1, false, 0, 1.392, 26.992)
if(touchEnabled){
document.getElementById("tutorial-outer").classList.add("touch-enabled")
}
2019-04-06 03:53:51 +08:00
this.mode = "settings"
2019-04-06 18:19:10 +08:00
this.tutorialTitle = document.getElementById("tutorial-title")
2019-04-06 05:10:15 +08:00
this.defaultButton = document.getElementById("settings-default")
this.endButton = document.getElementById("tutorial-end-button")
2019-04-06 18:19:10 +08:00
this.setStrings()
this.resolution = settings.getItem("resolution")
var content = document.getElementById("tutorial-content")
this.items = []
this.selected = 0
for(let i in settings.items){
2019-04-06 03:53:51 +08:00
var current = settings.items[i]
if(
!touchEnabled && current.touch === true ||
2019-04-06 05:10:15 +08:00
touchEnabled && current.touch === false
2019-04-06 03:53:51 +08:00
){
continue
}
var settingBox = document.createElement("div")
settingBox.classList.add("setting-box")
var nameDiv = document.createElement("div")
nameDiv.classList.add("setting-name", "stroke-sub")
var name = strings.settings[i].name
nameDiv.innerText = name
nameDiv.setAttribute("alt", name)
settingBox.appendChild(nameDiv)
var valueDiv = document.createElement("div")
valueDiv.classList.add("setting-value")
2019-04-06 03:53:51 +08:00
this.getValue(i, valueDiv)
settingBox.appendChild(valueDiv)
content.appendChild(settingBox)
if(this.items.length === this.selected){
settingBox.classList.add("selected")
}
pageEvents.add(settingBox, ["mousedown", "touchstart"], event => {
2019-04-06 04:21:22 +08:00
if(event.type !== "mousedown" || event.which === 1){
2019-04-06 03:53:51 +08:00
event.preventDefault()
this.setValue(i)
}
})
this.items.push({
id: i,
settingBox: settingBox,
2019-04-06 18:19:10 +08:00
nameDiv: nameDiv,
valueDiv: valueDiv
})
}
2019-04-06 05:10:15 +08:00
this.items.push({
id: "default",
settingBox: this.defaultButton
})
this.items.push({
id: "back",
settingBox: this.endButton
})
2019-04-06 03:53:51 +08:00
this.setKbd()
2019-04-06 05:10:15 +08:00
pageEvents.add(this.defaultButton, ["mousedown", "touchstart"], this.defaultSettings.bind(this))
2019-04-06 03:53:51 +08:00
pageEvents.add(this.endButton, ["mousedown", "touchstart"], this.onEnd.bind(this))
pageEvents.keyAdd(this, "all", "down", this.keyEvent.bind(this))
this.gamepad = new Gamepad({
"confirm": ["b", "ls", "rs"],
2019-04-06 05:10:15 +08:00
"up": ["u", "lsu"],
"previous": ["l", "lb", "lt", "lsl"],
"next": ["d", "r", "rb", "rt", "lsd", "lsr"],
"back": ["start", "a"]
}, this.keyPressed.bind(this))
pageEvents.send("settings")
}
2019-04-06 03:53:51 +08:00
setKbd(){
var kbdSettings = settings.getItem("keyboardSettings")
this.kbd = {
"confirm": ["enter", " ", kbdSettings.don_l[0], kbdSettings.don_r[0]],
2019-04-06 05:10:15 +08:00
"up": ["arrowup"],
"previous": ["arrowleft", kbdSettings.ka_l[0]],
2019-04-06 03:53:51 +08:00
"next": ["arrowright", "arrowdown", kbdSettings.ka_r[0]],
"back": ["backspace", "escape"]
}
}
getValue(name, valueDiv){
var current = settings.items[name]
var value = settings.getItem(name)
2019-04-06 18:19:10 +08:00
if(current.type === "language"){
value = allStrings[value].name + " (" + value + ")"
}else if(current.type === "select"){
value = strings.settings[name][value]
}else if(current.type === "toggle"){
value = value ? strings.settings.on : strings.settings.off
2019-04-06 03:53:51 +08:00
}else if(current.type === "keyboard"){
valueDiv.innerHTML = ""
for(var i in value){
var key = document.createElement("div")
key.style.color = i === "ka_l" || i === "ka_r" ? "#009aa5" : "#ef2c10"
key.innerText = value[i][0].toUpperCase()
valueDiv.appendChild(key)
}
return
}
2019-04-06 03:53:51 +08:00
valueDiv.innerText = value
}
setValue(name){
var current = settings.items[name]
var value = settings.getItem(name)
2019-04-06 03:53:51 +08:00
var selectedIndex = this.items.findIndex(item => item.id === name)
var selected = this.items[selectedIndex]
if(this.mode !== "settings"){
if(this.selected === selectedIndex){
this.keyboardBack(selected)
}
return
}
if(this.selected !== selectedIndex){
this.items[this.selected].settingBox.classList.remove("selected")
this.selected = selectedIndex
selected.settingBox.classList.add("selected")
}
2019-04-06 18:19:10 +08:00
if(current.type === "language" || current.type === "select"){
value = current.options[this.mod(current.options.length, current.options.indexOf(value) + 1)]
}else if(current.type === "toggle"){
value = !value
2019-04-06 03:53:51 +08:00
}else if(current.type === "keyboard"){
this.mode = "keyboard"
selected.settingBox.style.animation = "none"
selected.valueDiv.classList.add("selected")
this.keyboardKeys = {}
this.keyboardSet()
assets.sounds["se_don"].play()
return
}
settings.setItem(name, value)
2019-04-06 03:53:51 +08:00
this.getValue(name, this.items[this.selected].valueDiv)
2019-04-05 17:36:14 +08:00
assets.sounds["se_ka"].play()
2019-04-06 18:19:10 +08:00
if(current.type === "language"){
this.setLang(allStrings[value])
}
}
keyEvent(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){
2019-04-06 03:53:51 +08:00
if(this.kbd[i].indexOf(event.key.toLowerCase()) !== -1){
if(this.mode !== "keyboard" || i === "back"){
this.keyPressed(true, i)
return
}
}
}
2019-04-06 03:53:51 +08:00
if(this.mode === "keyboard"){
2019-04-06 18:19:10 +08:00
event.preventDefault()
2019-04-06 03:53:51 +08:00
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){
return
}
var selected = this.items[this.selected]
2019-04-06 03:53:51 +08:00
if(this.mode === "settings"){
if(name === "confirm"){
if(selected.id === "back"){
this.onEnd()
2019-04-06 05:10:15 +08:00
}else if(selected.id === "default"){
this.defaultSettings()
2019-04-06 03:53:51 +08:00
}else{
this.setValue(selected.id)
}
2019-04-06 05:10:15 +08:00
}else if(name === "up" || name === "previous" || name === "next"){
2019-04-06 03:53:51 +08:00
selected.settingBox.classList.remove("selected")
2019-04-06 05:10:15 +08:00
do{
this.selected = this.mod(this.items.length, this.selected + (name === "next" ? 1 : -1))
}while(this.items[this.selected].id === "default" && name !== "previous")
2019-04-06 03:53:51 +08:00
this.items[this.selected].settingBox.classList.add("selected")
assets.sounds["se_ka"].play()
}else if(name === "back"){
this.onEnd()
2019-04-06 03:53:51 +08:00
}
}else if(this.mode === "keyboard"){
if(name === "back"){
this.keyboardBack(selected)
}
}
}
keyboardSet(){
var selected = this.items[this.selected]
var current = settings.items[selected.id]
selected.valueDiv.innerHTML = ""
for(var i in current.default){
var key = document.createElement("div")
key.style.color = i === "ka_l" || i === "ka_r" ? "#009aa5" : "#ef2c10"
if(this.keyboardKeys[i]){
key.innerText = this.keyboardKeys[i][0].toUpperCase()
selected.valueDiv.appendChild(key)
}else{
2019-04-06 03:53:51 +08:00
key.innerText = "[" + strings.settings[selected.id][i] + "]"
selected.valueDiv.appendChild(key)
this.keyboardCurrent = i
return
}
}
2019-04-06 03:53:51 +08:00
settings.setItem(selected.id, this.keyboardKeys)
this.keyboardBack(selected)
this.setKbd()
pageEvents.setKbd()
}
keyboardBack(selected){
this.mode = "settings"
selected.settingBox.style.animation = ""
selected.valueDiv.classList.remove("selected")
this.getValue(selected.id, selected.valueDiv)
}
2019-04-06 05:10:15 +08:00
defaultSettings(event){
if(event && event.type === "touchstart"){
event.preventDefault()
}
2019-04-06 18:19:10 +08:00
if(this.mode === "keyboard"){
this.keyboardBack(this.items[this.selected])
2019-04-06 05:10:15 +08:00
}
for(var i in settings.items){
settings.setItem(i, null)
}
2019-04-06 18:19:10 +08:00
this.setLang(allStrings[settings.getItem("language")])
2019-04-06 05:10:15 +08:00
assets.sounds["se_don"].play()
}
onEnd(event){
var touched = false
2019-04-06 03:53:51 +08:00
if(event){
if(event.type === "touchstart"){
event.preventDefault()
touched = true
}else if(event.which !== 1){
return
}
}
this.clean()
assets.sounds["se_don"].play()
setTimeout(() => {
new SongSelect("settings", false, touched)
}, 500)
}
2019-04-06 18:19:10 +08:00
setLang(lang){
settings.setLang(lang)
if(failedTests.length !== 0){
showUnsupported(strings)
}
for(var i in this.items){
var item = this.items[i]
if(item.valueDiv){
var name = strings.settings[item.id].name
item.nameDiv.innerText = name
item.nameDiv.setAttribute("alt", name)
this.getValue(item.id, item.valueDiv)
}
}
this.setStrings()
}
setStrings(){
this.tutorialTitle.innerText = strings.gameSettings
this.tutorialTitle.setAttribute("alt", strings.gameSettings)
this.defaultButton.innerText = 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){
return ((index % length) + length) % length
}
clean(){
this.gamepad.clean()
2019-04-05 17:36:14 +08:00
assets.sounds["bgm_settings"].stop()
pageEvents.keyRemove(this, "all")
for(var i in this.items){
pageEvents.remove(this.items[i].settingBox, ["mousedown", "touchstart"])
}
2019-04-06 18:19:10 +08:00
delete this.tutorialTitle
2019-04-06 05:10:15 +08:00
delete this.defaultButton
delete this.endButton
delete this.items
if(this.resolution !== settings.getItem("resolution")){
for(var i in assets.image){
2019-04-05 05:21:08 +08:00
if(i === "touch_drum" || i.startsWith("bg_song_") || i.startsWith("bg_stage_") || i.startsWith("bg_don_")){
URL.revokeObjectURL(assets.image[i].src)
delete assets.image[i]
}
}
}
}
}