japanese-drum-game/public/src/js/controller.js
LoveEevee 9248a52194 Lots of bug fixes
- Toggling autoplay checkbox in debug now disallows saving the score
- Fix crown of the song that was previously selected rendering above the genre
- Outline of empty crowns is slightly darker
- Fix rendering when there is a crown on oni and no crown on ura
- Fix crowns overlapping the netplay 2P icon
- Fix gauge in latency calibration
- Fix debug to work on mobile, can be toggled with ctrl+alt+`;` on hacker's keyboard with permanent notification
- Fix being unable to scroll the settings list without toggling something
- Handle KeyboardInterrupt in server.py
- Fix category jumping not working in session mode
- Fix mouse cursor being hidden at results screen in session mode
- Make "Issues" on the about screen and "An error occurred, please refresh" on loading screens translateable
- CanvasCache uses integer increments for comparison instead of Date.now()
- For imported songs, exclude song titles from genre comparisons if they appear in the name of the folder
- Fix tja files with spaces in the notation
- Fix second player's score on the results screen to have upside down appearance
- Add fixed chinese strings
2020-03-09 15:36:57 +03:00

311 lines
7.9 KiB
JavaScript

class Controller{
constructor(selectedSong, songData, autoPlayEnabled, multiplayer, touchEnabled){
this.selectedSong = selectedSong
this.songData = songData
this.autoPlayEnabled = autoPlayEnabled
this.saveScore = !autoPlayEnabled
this.multiplayer = multiplayer
this.touchEnabled = touchEnabled
this.snd = this.multiplayer ? "_p" + this.multiplayer : ""
this.calibrationMode = selectedSong.folder === "calibration"
this.audioLatency = 0
this.videoLatency = 0
if(!this.calibrationMode){
var latency = settings.getItem("latency")
if(!autoPlayEnabled){
this.audioLatency = Math.round(latency.audio) || 0
}
this.videoLatency = Math.round(latency.video) || 0 + this.audioLatency
}
if(this.multiplayer !== 2){
loader.changePage("game", false)
}
if(selectedSong.type === "tja"){
this.parsedSongData = new ParseTja(songData, selectedSong.difficulty, selectedSong.stars, selectedSong.offset)
}else{
this.parsedSongData = new ParseOsu(songData, selectedSong.difficulty, selectedSong.stars, selectedSong.offset)
}
this.offset = this.parsedSongData.soundOffset
var maxCombo = this.parsedSongData.circles.filter(circle => ["don", "ka", "daiDon", "daiKa"].indexOf(circle.type) > -1 && (!circle.branch || circle.branch.name == "master")).length
if (maxCombo >= 50) {
var comboVoices = ["v_combo_50"].concat([...Array(Math.floor(maxCombo/100)).keys()].map(i => "v_combo_" + (i + 1)*100))
var promises = []
comboVoices.forEach(name => {
if (!assets.sounds[name + "_p1"]) {
promises.push(loader.loadSound(name + ".wav", snd.sfxGain).then(sound => {
assets.sounds[name + "_p1"] = assets.sounds[name].copy(snd.sfxGainL)
assets.sounds[name + "_p2"] = assets.sounds[name].copy(snd.sfxGainR)
}))
}
})
Promise.all(promises)
}
if(this.calibrationMode){
this.volume = 1
}else{
assets.songs.forEach(song => {
if(song.id == this.selectedSong.folder){
this.mainAsset = song.sound
this.volume = song.volume || 1
}
})
}
this.game = new Game(this, this.selectedSong, this.parsedSongData)
this.view = new View(this)
this.mekadon = new Mekadon(this, this.game)
this.keyboard = new GameInput(this)
if(!autoPlayEnabled && this.multiplayer !== 2){
this.easierBigNotes = settings.getItem("easierBigNotes") || this.keyboard.keyboard.TaikoForceLv5
}else{
this.easierBigNotes = false
}
this.drumSounds = settings.getItem("latency").drumSounds
this.playedSounds = {}
}
run(syncWith){
if(syncWith){
this.syncWith = syncWith
}
if(this.multiplayer !== 2){
snd.musicGain.setVolumeMul(this.volume)
}
this.game.run()
this.view.run()
if(this.multiplayer === 1){
syncWith.run(this)
syncWith.game.elapsedTime = this.game.elapsedTime
syncWith.game.startDate = this.game.startDate
}
requestAnimationFrame(() => {
this.startMainLoop()
if(!this.multiplayer){
debugObj.controller = this
if(debugObj.debug){
debugObj.debug.updateStatus()
}
}
})
}
startMainLoop(){
this.mainLoopRunning = true
this.gameLoop()
this.viewLoop()
if(this.multiplayer !== 2){
this.gameInterval = setInterval(this.gameLoop.bind(this), 1000 / 60)
pageEvents.send("game-start", {
selectedSong: this.selectedSong,
autoPlayEnabled: this.autoPlayEnabled,
multiplayer: this.multiplayer,
touchEnabled: this.touchEnabled
})
}
}
stopMainLoop(){
this.mainLoopRunning = false
if(this.game.mainAsset){
this.game.mainAsset.stop()
}
if(this.multiplayer !== 2){
clearInterval(this.gameInterval)
}
}
gameLoop(){
if(this.mainLoopRunning){
if(this.multiplayer === 1){
this.syncWith.game.elapsedTime = this.game.elapsedTime
this.syncWith.game.startDate = this.game.startDate
}
var ms = this.game.elapsedTime
if(this.game.musicFadeOut < 3){
this.keyboard.checkMenuKeys()
}
if(this.calibrationMode){
this.game.calibration()
}
if(!this.game.isPaused()){
this.keyboard.checkGameKeys()
if(ms < 0){
this.game.updateTime()
}else{
if(!this.calibrationMode){
this.game.update()
}
if(!this.mainLoopRunning){
return
}
this.game.playMainMusic()
}
}
if(this.multiplayer === 1){
this.syncWith.gameLoop()
}
}
}
viewLoop(){
if(this.mainLoopRunning){
if(this.multiplayer !== 2){
requestAnimationFrame(() => {
this.viewLoop()
if(this.multiplayer === 1){
this.syncWith.viewLoop()
}
if(this.scoresheet){
if(this.view.ctx){
this.view.ctx.save()
this.view.ctx.setTransform(1, 0, 0, 1, 0, 0)
}
this.scoresheet.redraw()
if(this.view.ctx){
this.view.ctx.restore()
}
}
})
}
this.view.refresh()
}
}
gameEnded(){
var score = this.getGlobalScore()
var vp
if(this.game.rules.clearReached(score.gauge)){
if(score.bad === 0){
vp = "fullcombo"
this.playSound("v_fullcombo", 1.350)
}else{
vp = "clear"
}
}else{
vp = "fail"
}
this.playSound("se_game" + vp)
}
displayResults(){
if(this.multiplayer !== 2){
this.scoresheet = new Scoresheet(this, this.getGlobalScore(), this.multiplayer, this.touchEnabled)
}
}
displayScore(score, notPlayed, bigNote){
this.view.displayScore(score, notPlayed, bigNote)
}
songSelection(fadeIn){
if(!fadeIn){
this.clean()
}
if(this.calibrationMode){
new SettingsView(this.touchEnabled, false, null, "latency")
}else{
new SongSelect(false, fadeIn, this.touchEnabled)
}
}
restartSong(){
this.clean()
if(this.multiplayer){
new LoadSong(this.selectedSong, false, true, this.touchEnabled)
}else{
new Promise(resolve => {
if(this.calibrationMode){
resolve()
}else{
var songObj = assets.songs.find(song => song.id === this.selectedSong.folder)
if(songObj.chart && songObj.chart !== "blank"){
var reader = new FileReader()
var promise = pageEvents.load(reader).then(event => {
this.songData = event.target.result.replace(/\0/g, "").split("\n")
resolve()
})
if(this.selectedSong.type === "tja"){
reader.readAsText(songObj.chart, "sjis")
}else{
reader.readAsText(songObj.chart)
}
}else{
resolve()
}
}
}).then(() => {
var taikoGame = new Controller(this.selectedSong, this.songData, this.autoPlayEnabled, false, this.touchEnabled)
taikoGame.run()
})
}
}
playSound(id, time, noSnd){
if(!this.drumSounds && (id === "neiro_1_don" || id === "neiro_1_ka" || id === "se_don" || id === "se_ka")){
return
}
var ms = Date.now() + (time || 0) * 1000
if(!(id in this.playedSounds) || ms > this.playedSounds[id] + 30){
assets.sounds[id + (noSnd ? "" : this.snd)].play(time)
this.playedSounds[id] = ms
}
}
togglePause(forcePause, pauseMove, noSound){
if(this.multiplayer === 1){
this.syncWith.game.togglePause(forcePause, pauseMove, noSound)
}
this.game.togglePause(forcePause, pauseMove, noSound)
}
getKeys(){
return this.keyboard.getKeys()
}
setKey(pressed, name, ms){
return this.keyboard.setKey(pressed, name, ms)
}
getElapsedTime(){
return this.game.elapsedTime
}
getCircles(){
return this.game.getCircles()
}
getCurrentCircle(){
return this.game.getCurrentCircle()
}
isWaiting(key, type){
return this.keyboard.isWaiting(key, type)
}
waitForKeyup(key, type){
this.keyboard.waitForKeyup(key, type)
}
getKeyTime(){
return this.keyboard.getKeyTime()
}
getCombo(){
return this.game.getCombo()
}
getGlobalScore(){
return this.game.getGlobalScore()
}
autoPlay(circle){
if(this.multiplayer){
p2.play(circle, this.mekadon)
}else{
return this.mekadon.play(circle)
}
}
clean(){
if(this.multiplayer === 1){
this.syncWith.clean()
}
this.stopMainLoop()
this.keyboard.clean()
this.view.clean()
snd.buffer.loadSettings()
if(!this.multiplayer){
debugObj.controller = null
if(debugObj.debug){
debugObj.debug.updateStatus()
}
}
}
}