diff --git a/public/index.html b/public/index.html index 8fdeb7f..6c35a2f 100644 --- a/public/index.html +++ b/public/index.html @@ -46,6 +46,7 @@ + diff --git a/public/src/js/assets.js b/public/src/js/assets.js index 4d74296..2fa85d6 100644 --- a/public/src/js/assets.js +++ b/public/src/js/assets.js @@ -27,7 +27,8 @@ var assets = { 'muzu_normal.png', 'muzu_hard.png', 'muzu_oni.png', - 'don_anim_normal.png' + 'don_anim_normal.png', + 'don_anim_10combo.png' ], audioSfx: [ diff --git a/public/src/js/canvasasset.js b/public/src/js/canvasasset.js new file mode 100644 index 0000000..4c4f989 --- /dev/null +++ b/public/src/js/canvasasset.js @@ -0,0 +1,94 @@ +class CanvasAsset{ + constructor(view, position, image){ + this.ctx = view.ctx + this.controller = view.controller + if(image){ + this.image = assets.image[image] + } + this.position = position + this.animationFrames = {} + this.speed = 1000 / 60 + this.animationStart = 0 + } + draw(){ + var u = (a, b) => typeof a == "undefined" ? b : a + var frame = 0 + if(this.animation){ + var ms = this.controller.getElapsedTime().ms + if(this.animationEnd){ + if(ms > this.animationEnd.ms){ + this.animationEnd.callback() + delete this.animationEnd + return this.draw() + } + } + var index = Math.floor((ms - this.animationStart) / this.speed) + if(Array.isArray(this.animation)){ + frame = this.animation[this.boundedIndex(this.animation.length, index)] + }else{ + frame = this.boundedIndex(this.animation, index) + } + } + var pos = this.position(frame) + if(this.image){ + this.ctx.drawImage(this.image, + u(pos.sx, pos.x), u(pos.sy, pos.y), + u(pos.sw, pos.w), u(pos.sh, pos.h), + pos.x, pos.y, pos.w, pos.h + ) + } + } + boundedIndex(length, index){ + if(length == 0){ + return + } + while(index < length){ + index += length + } + return index % length + } + addFrames(name, frames, image){ + var framesObj = { + frames: frames + } + if(image){ + framesObj.image = assets.image[image] + } + this.animationFrames[name] = framesObj + } + setAnimation(name){ + var framesObj = this.animationFrames[name] + this.animation = framesObj.frames + this.animationName = name + if(framesObj.image){ + this.image = framesObj.image + } + } + getAnimation(){ + return this.animationName + } + getAnimationLength(){ + var frames = this.animationFrames["10combo"].frames + if(Array.isArray(frames)){ + return frames.length + }else{ + return frames + } + } + setUpdateSpeed(speed){ + this.speed = speed + } + setAnimationStart(ms){ + this.animationStart = ms + } + setAnimationEnd(ms, callback){ + if(typeof ms == "undefined"){ + delete this.animationEnd + }else{ + this.animationEnd = { + ms: ms, + callback: callback + } + } + } +} diff --git a/public/src/js/game.js b/public/src/js/game.js index 24fcc68..fbfe763 100644 --- a/public/src/js/game.js +++ b/public/src/js/game.js @@ -372,6 +372,8 @@ function Game(controller, selectedSong, songData){ controller.playSoundMeka("combo-1400"); break; } + + controller.view.updateCombo(_combo) } this.getCombo = function(){ diff --git a/public/src/js/mekadon.js b/public/src/js/mekadon.js index 3ef38d9..ecbd330 100644 --- a/public/src/js/mekadon.js +++ b/public/src/js/mekadon.js @@ -19,8 +19,6 @@ class Mekadon{ miss(circle){ var currentMs = circle.getMS() - this.controller.getElapsedTime().ms if(0 > currentMs - 10){ - circle.updateStatus(-1) - circle.played(0) this.controller.displayScore(0, true) this.game.updateCurrentCircle() this.game.updateCombo(0) diff --git a/public/src/js/p2.js b/public/src/js/p2.js index 137c595..ee346d1 100644 --- a/public/src/js/p2.js +++ b/public/src/js/p2.js @@ -112,7 +112,7 @@ class P2Connection{ } } play(circle, mekadon){ - if(this.otherConnected){ + if(this.otherConnected || this.notes.length > 0){ if(this.notes.length == 0){ mekadon.play(circle) }else{ @@ -127,6 +127,8 @@ class P2Connection{ } } } + }else if(mekadon.miss(circle)){ + this.notes.shift() } } } diff --git a/public/src/js/view.js b/public/src/js/view.js index 02cceae..b7fc73c 100644 --- a/public/src/js/view.js +++ b/public/src/js/view.js @@ -14,6 +14,9 @@ class View{ } this.winW = this.canvas.scaledWidth this.winH = this.canvas.scaledHeight + if(this.controller.multiplayer == 2){ + this.winH = this.winH / 2 * 3 + } this.ctx = this.canvas.ctx this.taikoSquareW = this.winW / 4 @@ -36,14 +39,41 @@ class View{ this.songTitle = title this.songDifficulty = this.diff.split(".").slice(0, -1).join(".") + + this.beatInterval = this.controller.getSongData().beatInfo.beatInterval + this.assets = [] + this.don = this.createAsset(frame => { + var imgw = 360 + var imgh = 184 + var scale = 165 + var w = (this.barH * imgw) / scale + var h = (this.barH * imgh) / scale + return { + sx: 0, + sy: frame * imgh, + sw: imgw, + sh: imgh, + x: this.taikoSquareW - w + this.barH * 0.2, + y: this.barY - h, + w: w, + h: h + } + }) + this.don.addFrames("normal", [ + 0 ,0 ,0 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,6 ,5 ,4 ,3 ,2 ,1 , + 0 ,0 ,0 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,6 ,5 ,4 ,3 ,2 ,1 , + 0 ,0 ,0 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,6 ,5 ,7 ,8 ,9 ,10, + 11,11,11,11,10,9 ,8 ,7 ,13,12,12,13,14,15,16,17 + ], "don_anim_normal") + this.don.addFrames("10combo", 22, "don_anim_10combo") + this.don.setAnimation("normal") + this.don.setUpdateSpeed(this.beatInterval / 16) } run(){ this.ctx.font = "normal 14pt TnT" this.setBackground() - $(".game-song").attr("alt", this.songTitle).html(this.songTitle) - this.refresh() } @@ -71,16 +101,16 @@ class View{ this.barY = 0.25 * this.winH this.barH = 0.23 * this.winH this.lyricsBarH = 0.2 * this.barH + this.taikoSquareW = this.winW / 4 this.taikoH = this.barH this.taikoW = this.taikoH / 1.2 this.taikoX = this.taikoSquareW * 0.76 - this.taikoW / 2 this.taikoY = this.barY + 5 - this.taikoSquareW = this.winW / 4 - this.slotX = this.taikoSquareW + this.barH * 0.45 + this.slotX = this.taikoSquareW + this.barH * 0.5 this.scoreSquareW = this.taikoSquareW * 0.55 this.scoreSquareH = this.barH * 0.25 - this.circleSize = this.barH * 0.15 - this.bigCircleSize = this.barH * 0.25 + this.circleSize = this.barH * 0.18 + this.bigCircleSize = this.circleSize * (5 / 3) this.circleY = this.barY + (this.barH - this.lyricsBarH) / 2 this.lyricsSize = this.lyricsBarH * 0.6 var HPBarRatio = 703 / 51 @@ -111,6 +141,7 @@ class View{ this.ctx.clearRect(0, 0, this.canvas.scaledWidth, this.canvas.scaledHeight) // Draw + this.drawAssets() this.drawBar() this.drawSlot() this.drawMeasures() @@ -128,7 +159,7 @@ class View{ updateDonFaces(){ if(this.controller.getElapsedTime().ms >= this.nextBeat){ - this.nextBeat += this.controller.getSongData().beatInfo.beatInterval + this.nextBeat += this.beatInterval if(this.controller.getCombo() >= 50){ this.currentBigDonFace = (this.currentBigDonFace + 1) % 2 this.currentDonFace = (this.currentDonFace + 1) % 2 @@ -657,4 +688,31 @@ class View{ this.ctx.closePath() this.ctx.stroke() } + + createAsset(image, position){ + var asset = new CanvasAsset(this, image, position) + this.assets.push(asset) + return asset + } + + drawAssets(){ + if(this.controller.multiplayer != 2){ + this.assets.forEach(asset => { + asset.draw() + }) + } + } + + updateCombo(combo){ + if(combo > 0 && combo % 10 == 0 && this.don.getAnimation() != "10combo"){ + this.don.setAnimation("10combo") + var ms = this.controller.getElapsedTime().ms + this.don.setAnimationStart(ms) + var length = this.don.getAnimationLength("10combo") + this.don.setAnimationEnd(ms + length * this.don.speed, () => { + this.don.setAnimationStart(0) + this.don.setAnimation("normal") + }) + } + } }