From f90f6fe6e156d5dc13a2484a5328846c33463857 Mon Sep 17 00:00:00 2001 From: LoveEevee Date: Thu, 25 Oct 2018 17:18:41 +0300 Subject: [PATCH] View: Rewrite --- public/src/css/game.css | 11 +- public/src/js/assets.js | 15 +- public/src/js/canvasasset.js | 5 +- public/src/js/canvascache.js | 23 +- public/src/js/canvasdraw.js | 297 +++++- public/src/js/controller.js | 31 +- public/src/js/debug.js | 4 + public/src/js/element.js | 49 - public/src/js/game.js | 10 +- public/src/js/keyboard.js | 2 +- public/src/js/loadsong.js | 2 +- public/src/js/scalablecanvas.js | 42 - public/src/js/scoresheet.js | 35 +- public/src/js/songselect.js | 233 +++-- public/src/js/view.js | 1667 +++++++++++++++++++------------ public/src/js/viewassets.js | 60 +- public/src/views/game.html | 1 - templates/index.html | 2 - 18 files changed, 1511 insertions(+), 978 deletions(-) delete mode 100644 public/src/js/element.js delete mode 100644 public/src/js/scalablecanvas.js diff --git a/public/src/css/game.css b/public/src/css/game.css index 848c24a..1d3a518 100644 --- a/public/src/css/game.css +++ b/public/src/css/game.css @@ -1,9 +1,10 @@ #game{ width: 100%; height: 100%; - position: asbolute; + position: absolute; overflow: hidden; background-size: cover; + background-position: center; } #game.default-bg{ background-size: calc(100vh / 720 * 512); @@ -70,7 +71,7 @@ #touch-buttons{ display: none; position: absolute; - top: 6.5vh; + top: 8vh; right: 2vh; opacity: 0.5; z-index: 5; @@ -79,6 +80,12 @@ width: 12.5vmin; height: 12.5vmin; } +.portrait #touch-buttons{ + top: 11vh; +} +.touchp2 #touch-buttons{ + top: -1.9vh; +} .touch-visible #touch-drum, .touch-visible #touch-buttons{ display: block; diff --git a/public/src/js/assets.js b/public/src/js/assets.js index 3fa9dc8..9880625 100644 --- a/public/src/js/assets.js +++ b/public/src/js/assets.js @@ -2,20 +2,11 @@ var assets = { "img": [ "title-screen.png", "logo-big.png", - "don-0.png", - "don-1.png", - "big-don-0.png", - "big-don-1.png", + "notes.png", + "notes_drumroll.png", + "notes_hit.png", "balloon.png", "taiko.png", - "taiko-key-blue.png", - "taiko-key-red.png", - "hp-bar-bg.png", - "hp-bar-colour.png", - "score-0.png", - "score-0-b.png", - "score-230.png", - "score-450.png", "dancing-don.gif", "bg-pattern-1.png", "muzu_easy.png", diff --git a/public/src/js/canvasasset.js b/public/src/js/canvasasset.js index 9008e0f..0e9fd1b 100644 --- a/public/src/js/canvasasset.js +++ b/public/src/js/canvasasset.js @@ -27,6 +27,7 @@ class CanvasAsset{ }else{ frame = this.mod(this.animation, index) } + this.ctx.save() var pos = this.position(frame) if(this.image){ this.ctx.drawImage(this.image, @@ -35,9 +36,7 @@ class CanvasAsset{ pos.x, pos.y, pos.w, pos.h ) } - if(pos.callback){ - pos.callback() - } + this.ctx.restore() } } mod(length, index){ diff --git a/public/src/js/canvascache.js b/public/src/js/canvascache.js index 4ebae13..622fae8 100644 --- a/public/src/js/canvascache.js +++ b/public/src/js/canvascache.js @@ -1,14 +1,17 @@ class CanvasCache{ constructor(w, h, scale){ - this.canvas = document.createElement("canvas") - this.ctx = this.canvas.getContext("2d") - this.map = new Map() if(w){ this.resize(w, h, scale) } } resize(w, h, scale){ - this.map.clear() + if(this.canvas){ + this.map.clear() + }else{ + this.map = new Map() + this.canvas = document.createElement("canvas") + this.ctx = this.canvas.getContext("2d") + } this.scale = scale this.x = 0 this.y = 0 @@ -20,8 +23,11 @@ class CanvasCache{ this.canvas.height = this.h * this.scale this.ctx.scale(this.scale, this.scale) } - get(config, callback){ + get(config, callback, setOnly){ var img = this.map.get(config.id) + if(img && setOnly || !img && !callback){ + return + } var saved = false if(!img){ var w = config.w @@ -50,6 +56,10 @@ class CanvasCache{ callback(this.ctx) } + if(setOnly){ + this.ctx.restore() + return + } var z = this.scale config.ctx.drawImage(this.canvas, img.x * z |0, img.y * z |0, img.w * z |0, img.h * z |0, @@ -59,6 +69,9 @@ class CanvasCache{ this.ctx.restore() } } + set(config, callback){ + return this.get(config, callback, true) + } clean(){ delete this.map delete this.ctx diff --git a/public/src/js/canvasdraw.js b/public/src/js/canvasdraw.js index 429b59b..7d4ebe7 100644 --- a/public/src/js/canvasdraw.js +++ b/public/src/js/canvasdraw.js @@ -39,6 +39,13 @@ this.crownPath = new Path2D("m82 21c0-4 3-6 5.5-6 2.5 0 5.5 2 5.5 6 0 4-3 6-5.5 6C85 27 82 25 82 21ZM41.5 6c0-4 3-6 5.5-6 2.5 0 5.5 2 5.5 6 0 4-3 6-5.5 6-2.5 0-5.5-2-5.5-6zM1 21C1 17 4 15 6.5 15 9 15 12 17 12 21 12 25 9 27 6.5 27 4 27 1 25 1 21Zm12 46h68l2 11H11ZM13 62 5 18 29 34 47 6 65 34 89 18 81 62Z") + this.soulPath = new Path2D("m37 29c1-4 7 2 7 4 0 1-2 2-4 2-1 0-1-4-3-6zm-4-7c3 1 5 3 4 5-1 2-3 3-3 4 3-2 5-2 5-2 0 0-1 3-5 5-4 3-5-1-3-4 2-3 3-6 0-7zm-3 8c1 3-5 10 8 7 6-1 2-4 2-4 5 1 7 3 7 5 0 3-8 4-12 4-4 0-9-2-9-5 0 0 0-6-1-8 0-3 3-3 5 1zM20 23h8C27 27 20 44 9 42 18 36 23 28 21 26 19 24 20 23 20 23Zm0-6c4-2 9-4 14-2v2c-5 0-9 1-14 2zm8-7v12h-4c2-1 1-9-1-10zm-6 12c3 0 10-2 10-2 0 0 1-10 0-10-5 1-8 3-12 3 0 0 2 5 2 9zm0-12c0 0 6-1 9-3 3-2 9 3 8 6-1 3-2 6-4 9-2 2-15 2-15 2-1 0-3-7-2-11zM21 0c8 0 10 3 8 5 0 0-6 7-15 10C22 8 23 3 23 3 23 1 21 0 21 0ZM5 9c-1 3 2 6 4 6 5-1 13-6 4-7-3 0-5 5-8 1zm7 17c2-1 4-1 6 1 2 2 1 6-2 6-1 0-2-2-2-2-1-2-3-4-2-5zm2 4c-3 2-4 5-5 6-1 1-4 2-6-2-1-2 0-3 2-5l4-4c0-1-1 0-4 1-2 1-5-2-4-4 2-5 1 0 3-1 6-4 9-5 11-3 2 2 0 3-2 5-1 1-3 4-4 6 0 1 3-1 4-2") + + this.optionsPath = { + shadow: new Path2D("M4-1V8H9V0l1-1 3 6v4l-4 5v10l4 5v4l-2 4-2 1V30H4L5 37 3 38 0 33V29L4 24V14L0 9V5L3 0Z"), + main: new Path2D("M4 0V8H9V0h1l3 5v4l-4 5v10l4 5v4l-3 5H9V30H4v8H3L0 33V29L4 24V14L0 9V5L3 0Z") + } + this.regex = { comma: /[,.]/, ideographicComma: /[、。]/, @@ -76,11 +83,25 @@ var h = config.h var r = config.radius ctx.beginPath() - ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5) - ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, 0) - ctx.arc(x + w - r, y + h - r, r, 0, Math.PI / 2) - ctx.arc(x + r, y + h - r, r, Math.PI / 2, Math.PI) - ctx.lineTo(x, y + r) + this.roundedCorner(ctx, x, y, r, 0) + this.roundedCorner(ctx, x + w, y, r, 1) + this.roundedCorner(ctx, x + w, y + h, r, 2) + this.roundedCorner(ctx, x, y + h, r, 3) + ctx.closePath() + } + + roundedCorner(ctx, x, y, r, rotation){ + var pi = Math.PI + switch(rotation){ + case 0: + return ctx.arc(x + r, y + r, r, pi, pi / -2) + case 1: + return ctx.arc(x - r, y + r, r, pi / -2, 0) + case 2: + return ctx.arc(x - r, y - r, r, 0, pi / 2) + case 3: + return ctx.arc(x + r, y - r, r, pi / 2, pi) + } } songFrame(config){ @@ -428,6 +449,9 @@ } ctx.translate(config.x, config.y) + if(config.scale){ + ctx.scale(config.scale[0], config.scale[1]) + } var scale = 1 if(config.width && drawnWidth > config.width){ scale = config.width / drawnWidth @@ -438,7 +462,13 @@ ctx.textAlign = "center" for(let layer of layers){ + var savedLayer = false var action = "strokeText" + if(layer.scale){ + savedLayer = true + ctx.save() + ctx.scale(layer.scale[0], layer.scale[1]) + } if(layer.outline){ ctx.strokeStyle = layer.outline ctx.lineJoin = "round" @@ -452,7 +482,10 @@ action = "fillText" } if(layer.shadow){ - ctx.save() + if(!savedLayer){ + savedLayer = true + ctx.save() + } this.shadow({ ctx: ctx, fill: "rgba(0, 0, 0, " + (1 / (layer.shadow[3] || 2)) + ")", @@ -501,7 +534,7 @@ } offsetX += symbol.w * mul } - if(layer.shadow){ + if(savedLayer){ ctx.restore() } } @@ -538,42 +571,59 @@ diffOptionsIcon(config){ var ctx = config.ctx ctx.save() - ctx.translate(config.x - 21, config.y - 21) - var drawLine = y => { - ctx.beginPath() - ctx.moveTo(12, y) - ctx.arc(20.5, 25, 8.5, Math.PI, Math.PI * 2, true) - ctx.lineTo(29, 18) - ctx.stroke() - } - var drawTriangle = noFill => { - ctx.beginPath() - ctx.moveTo(29, 5) - ctx.lineTo(21, 19) - ctx.lineTo(37, 19) - ctx.closePath() - if(!noFill){ - ctx.fill() + if(config.iconName === "back"){ + ctx.translate(config.x - 21, config.y - 21) + + var drawLine = y => { + ctx.beginPath() + ctx.moveTo(12, y) + ctx.arc(20.5, 25, 8.5, Math.PI, Math.PI * 2, true) + ctx.lineTo(29, 18) + ctx.stroke() } + var drawTriangle = noFill => { + ctx.beginPath() + ctx.moveTo(29, 5) + ctx.lineTo(21, 19) + ctx.lineTo(37, 19) + ctx.closePath() + if(!noFill){ + ctx.fill() + } + } + ctx.strokeStyle = "#000" + ctx.lineWidth = 12 + drawLine(9) + ctx.lineWidth = 5 + drawTriangle(true) + ctx.stroke() + ctx.lineWidth = 7 + ctx.fillStyle = "#fff" + ctx.strokeStyle = "#fff" + drawLine(11) + drawTriangle() + ctx.translate(-1.5, -0.5) + ctx.fillStyle = "#23a6e1" + ctx.strokeStyle = "#23a6e1" + ctx.globalCompositeOperation = "darken" + drawLine(11) + drawTriangle() + }else if(config.iconName === "options"){ + ctx.translate(config.x, config.y) + ctx.rotate(-55 * Math.PI / 180) + ctx.translate(-6, -20) + ctx.strokeStyle = "#000" + ctx.lineWidth = 6 + ctx.stroke(this.optionsPath.main) + ctx.translate(-2, 2) + ctx.stroke(this.optionsPath.main) + ctx.fillStyle = "#7e7c76" + ctx.fill(this.optionsPath.shadow) + ctx.translate(2, -2) + ctx.fillStyle = "#d9d6ce" + ctx.fill(this.optionsPath.main) } - ctx.strokeStyle = "#000" - ctx.lineWidth = 12 - drawLine(9) - ctx.lineWidth = 5 - drawTriangle(true) - ctx.stroke() - ctx.lineWidth = 7 - ctx.fillStyle = "#fff" - ctx.strokeStyle = "#fff" - drawLine(11) - drawTriangle() - ctx.translate(-1.5, -0.5) - ctx.fillStyle = "#23a6e1" - ctx.strokeStyle = "#23a6e1" - ctx.globalCompositeOperation = "darken" - drawLine(11) - drawTriangle() ctx.restore() } @@ -676,9 +726,13 @@ ctx.scale(1 / mul, 1 / mul) } ctx.fillStyle = ctx.createPattern(config.img, "repeat") - ctx.beginPath() - ctx.rect(config.x * mul, config.y * mul, config.w * mul, config.h * mul) - ctx.translate(config.dx, config.dy) + if(config.shape){ + config.shape(ctx, mul) + }else{ + ctx.beginPath() + ctx.rect(config.x * mul, config.y * mul, config.w * mul, config.h * mul) + } + ctx.translate(config.dx * mul, config.dy * mul) ctx.fill() ctx.restore() @@ -692,6 +746,9 @@ if(config.scale){ ctx.scale(config.scale, config.scale) } + if(config.align === "center"){ + ctx.translate(config.score === "bad" ? -49 / 2 : -23 / 2, 0) + } ctx.strokeStyle = "#000" ctx.lineWidth = 7 if(config.score === "good"){ @@ -790,6 +847,160 @@ ctx.restore() } + gauge(config){ + var ctx = config.ctx + ctx.save() + + ctx.translate(config.x, config.y) + if(config.scale){ + ctx.scale(config.scale, config.scale) + } + ctx.translate(-788, 0) + + var firstTop = config.multiplayer ? 0 : 30 + var secondTop = config.multiplayer ? 0 : 8 + + var cleared = config.percentage - 1 / 50 >= config.clear + + var gaugeW = 14 * 50 + var gaugeClear = gaugeW * config.clear + var gaugeFilled = gaugeW * config.percentage + + ctx.fillStyle = "#000" + ctx.beginPath() + if(config.scoresheet){ + ctx.moveTo(-4, 26) + ctx.lineTo(gaugeClear - 4, 26) + this.roundedCorner(ctx, gaugeClear - 4, 4, 13, 0) + this.roundedCorner(ctx, 760, 4, 13, 1) + ctx.lineTo(760, 56) + ctx.lineTo(-4, 56) + }else if(config.multiplayer){ + ctx.moveTo(gaugeClear - 7, 27) + ctx.lineTo(788, 27) + ctx.lineTo(788, 52) + this.roundedCorner(ctx, gaugeClear - 7, 52, 18, 3) + }else{ + ctx.moveTo(gaugeClear - 7, 24) + this.roundedCorner(ctx, gaugeClear - 7, 0, 18, 0) + ctx.lineTo(788, 0) + ctx.lineTo(788, 24) + } + ctx.fill() + + if(gaugeFilled <= gaugeClear){ + ctx.fillStyle = "#680000" + var x = Math.max(0, gaugeFilled - 5) + ctx.fillRect(x, firstTop, gaugeClear - x + 2, 22) + } + if(gaugeFilled > 0){ + var w = Math.min(gaugeClear + 1, gaugeFilled - 4) + ctx.fillStyle = "#ff3508" + ctx.fillRect(0, firstTop + 2, w, 20) + ctx.fillStyle = "#ff9e94" + ctx.fillRect(0, firstTop, w, 3) + } + if(gaugeFilled < gaugeW - 4){ + ctx.fillStyle = "#684c00" + var x = Math.max(gaugeClear + 9, gaugeFilled - gaugeClear + 9) + ctx.fillRect(x, secondTop, gaugeW - 4 - x, 44) + } + if(gaugeFilled > gaugeClear + 14){ + var w = Math.min(gaugeW - 4, gaugeFilled - gaugeClear - 14) + ctx.fillStyle = "#ff0" + ctx.fillRect(gaugeClear + 9, secondTop + 2, w, 42) + ctx.fillStyle = "#fff" + ctx.fillRect(gaugeClear + 9, secondTop, w, 3) + } + ctx.fillStyle = cleared ? "#ff0" : "#684c00" + ctx.beginPath() + if(config.multiplayer){ + this.roundedCorner(ctx, gaugeClear, secondTop + 44, 10, 3) + ctx.lineTo(gaugeClear, secondTop) + ctx.lineTo(gaugeClear + 10, secondTop) + }else{ + ctx.moveTo(gaugeClear, secondTop + 44) + this.roundedCorner(ctx, gaugeClear, secondTop, 10, 0) + ctx.lineTo(gaugeClear + 10, secondTop + 44) + } + ctx.fill() + if(cleared){ + ctx.save() + ctx.clip() + ctx.fillStyle = "#fff" + ctx.fillRect(gaugeClear, secondTop, 10, 3) + ctx.restore() + } + + ctx.strokeStyle = "rgba(0, 0, 0, 0.16)" + ctx.beginPath() + ctx.lineWidth = 5 + for(var i = 0; i < 49; i++){ + var x = 14 + i * 14 - ctx.lineWidth / 2 + if(i === 26){ + ctx.stroke() + ctx.beginPath() + ctx.lineWidth = 4 + } + ctx.moveTo(x, x < gaugeClear ? firstTop : secondTop) + ctx.lineTo(x, x < gaugeClear ? firstTop + 22 : secondTop + 44) + } + ctx.stroke() + this.layeredText({ + ctx: ctx, + text: "クリア", + fontSize: 18, + fontFamily: config.font, + x: gaugeClear - 6, + y: config.multiplayer ? 22 : 11, + letterSpacing: -2 + }, [ + {scale: [1.1, 1.01], outline: "#000", letterBorder: 6}, + {scale: [1.11, 1], fill: cleared ? "#fff" : "#737373"} + ]) + + ctx.restore() + } + + soul(config){ + var ctx = config.ctx + ctx.save() + + ctx.translate(config.x, config.y) + if(config.scale){ + ctx.scale(config.scale, config.scale) + } + ctx.translate(-23, -21) + + ctx.fillStyle = config.cleared ? "#fff" : "#737373" + ctx.fill(this.soulPath) + + ctx.restore() + } + + slot(ctx, x, y, size){ + var mul = size / 106 + + ctx.save() + ctx.globalAlpha = 0.7 + ctx.globalCompositeOperation = "screen" + ctx.fillStyle = "#444544" + ctx.beginPath() + ctx.arc(x, y, 26 * mul, 0, Math.PI * 2) + ctx.fill() + ctx.lineWidth = 3 + ctx.strokeStyle = "#9c9e9c" + ctx.beginPath() + ctx.arc(x, y, 33.5 * mul, 0, Math.PI * 2) + ctx.stroke() + ctx.lineWidth = 3.5 + ctx.strokeStyle = "#5d5e5d" + ctx.beginPath() + ctx.arc(x, y, 51.5 * mul, 0, Math.PI * 2) + ctx.stroke() + ctx.restore() + } + alpha(amount, ctx, callback){ if(amount >= 1){ return callback(ctx) diff --git a/public/src/js/controller.js b/public/src/js/controller.js index 5c1c316..51b61a3 100644 --- a/public/src/js/controller.js +++ b/public/src/js/controller.js @@ -81,6 +81,17 @@ class Controller{ if(this.syncWith){ this.syncWith.mainLoop() } + + 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() + } + } }) } var ms = this.game.elapsedTime @@ -104,10 +115,6 @@ class Controller{ this.view.refresh() } this.keyboard.checkMenuKeys() - - if(this.scoresheet){ - this.scoresheet.redraw() - } } } togglePauseMenu(){ @@ -117,11 +124,13 @@ class Controller{ gameEnded(){ var score = this.getGlobalScore() var vp - if(score.bad === 0){ - vp = "fullcombo" - this.playSoundMeka("fullcombo", 1.350) - }else if(score.gauge >= 50){ - vp = "clear" + if(Math.round(score.gauge / 2) - 1 >= 25){ + if(score.bad === 0){ + vp = "fullcombo" + this.playSoundMeka("fullcombo", 1.350) + }else{ + vp = "clear" + } }else{ vp = "fail" } @@ -132,8 +141,8 @@ class Controller{ this.scoresheet = new Scoresheet(this, this.getGlobalScore(), this.multiplayer) } } - displayScore(score, notPlayed){ - this.view.displayScore(score, notPlayed) + displayScore(score, notPlayed, bigNote){ + this.view.displayScore(score, notPlayed, bigNote) } songSelection(fadeIn){ if(!fadeIn){ diff --git a/public/src/js/debug.js b/public/src/js/debug.js index 0c566ee..7118836 100644 --- a/public/src/js/debug.js +++ b/public/src/js/debug.js @@ -117,6 +117,10 @@ class Debug{ break } } + if(game.mainMusicPlaying){ + game.mainMusicPlaying = false + game.mainAsset.stop() + } } this.autoplayCheckbox.checked = this.controller.autoPlayEnabled } diff --git a/public/src/js/element.js b/public/src/js/element.js deleted file mode 100644 index e38a7e6..0000000 --- a/public/src/js/element.js +++ /dev/null @@ -1,49 +0,0 @@ -function element(){ - var parent - var lasttag - var createdtag - var toreturn={} - for(var i=0;i { diff --git a/public/src/js/loadsong.js b/public/src/js/loadsong.js index b90b2d1..3af964e 100644 --- a/public/src/js/loadsong.js +++ b/public/src/js/loadsong.js @@ -94,7 +94,7 @@ class loadSong{ this.clean() loader.changePage("game") var taikoGame1 = new Controller(this.selectedSong, this.songData, false, 1, this.touchEnabled) - var taikoGame2 = new Controller(this.selectedSong2, this.song2Data, true, 2) + var taikoGame2 = new Controller(this.selectedSong2, this.song2Data, true, 2, this.touchEnabled) taikoGame1.run(taikoGame2) } }) diff --git a/public/src/js/scalablecanvas.js b/public/src/js/scalablecanvas.js deleted file mode 100644 index afa27ad..0000000 --- a/public/src/js/scalablecanvas.js +++ /dev/null @@ -1,42 +0,0 @@ -class ScalableCanvas{ - constructor(id, width, height, noStyle){ - var oldCanvas = document.getElementById(id) - if(oldCanvas){ - this.canvas = oldCanvas - }else{ - this.canvas = document.createElement("canvas") - this.canvas.id = id - } - this.ctx = this.canvas.getContext("2d") - this.rescale() - this.resize(width, height, noStyle) - } - resize(width, height, noStyle){ - if(width != this.width || height != this.height){ - this.width = width - this.height = height - this.scaledWidth = width * this.scale - this.canvas.width = this.scaledWidth - this.scaledHeight = height * this.scale - this.canvas.height = this.scaledHeight - if(noStyle || this.scale == 1){ - if(this.canvas.style.width){ - this.canvas.style.width = "" - } - if(this.canvas.style.height){ - this.canvas.style.height = "" - } - }else{ - this.canvas.style.width = width + "px" - this.canvas.style.height = height + "px" - } - } - } - rescale(){ - var scale = window.devicePixelRatio || 1 - if(scale != this.scale){ - this.ctx.scale(scale, scale) - this.scale = scale - } - } -} \ No newline at end of file diff --git a/public/src/js/scoresheet.js b/public/src/js/scoresheet.js index a13c2cd..18169c0 100644 --- a/public/src/js/scoresheet.js +++ b/public/src/js/scoresheet.js @@ -416,16 +416,25 @@ class Scoresheet{ results = p2.results ctx.translate(0, p2Offset) } - ctx.drawImage(assets.image["hp-bar-bg"], - 552, 120, 688, 48 - ) - var gauge = results.gauge / 100 - if(gauge > 0){ - ctx.drawImage(assets.image["hp-bar-colour"], - 0, 0, 650 * gauge, 40, - 557, 127, 635 * gauge, 37, - ) - } + var gaugePercent = Math.round(results.gauge / 2) / 50 + var w = 712 + this.draw.gauge({ + ctx: ctx, + x: 558 + w, + y: 116, + clear: 25 / 50, + percentage: gaugePercent, + font: this.font, + scale: w / 788, + scoresheet: true + }) + this.draw.soul({ + ctx: ctx, + x: 1215, + y: 144, + scale: 36 / 42, + cleared: gaugePercent - 1 / 50 >= 25 / 50 + }) } ctx.restore() } @@ -441,10 +450,8 @@ class Scoresheet{ results = p2.results } var crownType = null - if(results.bad === "0"){ - crownType = "gold" - }else if(results.gauge >= 50){ - crownType = "silver" + if(Math.round(results.gauge / 2) - 1 >= 25){ + crownType = results.bad === "0" ? "gold" : "silver" } if(crownType !== null){ noCrownResultWait = 0; diff --git a/public/src/js/songselect.js b/public/src/js/songselect.js index dcdc259..b3d290d 100644 --- a/public/src/js/songselect.js +++ b/public/src/js/songselect.js @@ -156,6 +156,21 @@ class SongSelect{ letterBorder: 12 } + this.diffOptions = [{ + text: "もどる", + fill: "#efb058", + iconName: "back", + iconFill: "#f7d39c", + letterSpacing: 4 + }, { + text: "演奏オプション", + fill: "#b2e442", + iconName: "options", + iconFill: "#d9f19f", + letterSpacing: 0 + }] + this.optionsList = ["なし", "オート", "ネットプレイ"] + this.draw = new CanvasDraw() this.songTitleCache = new CanvasCache() this.selectTextCache = new CanvasCache() @@ -185,7 +200,7 @@ class SongSelect{ this.playBgm(false) } if("selectedDiff" in localStorage){ - this.selectedDiff = Math.min(Math.max(0, localStorage["selectedDiff"] |0), 4) + this.selectedDiff = Math.min(Math.max(0, localStorage["selectedDiff"] |0), this.diffOptions.length + 3) } this.songSelect = document.getElementById("song-select") @@ -202,7 +217,8 @@ class SongSelect{ ura: 0, moveHover: null, locked: true, - hasPointer: false + hasPointer: false, + options: 0 } this.songSelecting = { speed: 800, @@ -218,6 +234,8 @@ class SongSelect{ "8": ["a"], "37": ["l", "lb", "lt", "lsl"], "39": ["r", "rb", "rt", "lsr"], + "38": ["u", "lsu"], + "40": ["d", "lsd"], "ctrl": ["y"], "shift": ["x"] }) @@ -259,10 +277,14 @@ class SongSelect{ // Enter, Space, F, J cancel: code == 27 || code == 8, // Esc, Backspace - left: code == 68, + left: code == 37 || code == 68, // Left, D - right: code == 75 + right: code == 39 || code == 75, // Right, K + up: code == 38, + // Up + down: code == 40 + // Down } if(key.cancel && event){ event.preventDefault() @@ -281,8 +303,10 @@ class SongSelect{ if(key.confirm){ if(this.selectedDiff === 0){ this.toSongSelect() + }else if(this.selectedDiff === 1){ + this.toOptions(1) }else{ - this.toLoadSong(this.selectedDiff - 1, modifiers.shift, modifiers.ctrl) + this.toLoadSong(this.selectedDiff - this.diffOptions.length, modifiers.shift, modifiers.ctrl) } }else if(key.cancel){ this.toSongSelect() @@ -290,6 +314,8 @@ class SongSelect{ this.moveToDiff(-1) }else if(key.right){ this.moveToDiff(1) + }else if(this.selectedDiff === 1 && (key.up || key.down)){ + this.toOptions(key.up ? -1 : 1) } } } @@ -319,20 +345,21 @@ class SongSelect{ } }else if(this.state.screen === "difficulty"){ var moveBy = this.diffSelMouse(mouse.x, mouse.y) - if( - moveBy === 0 - || mouse.x < 55 || mouse.x > 967 - || mouse.y < 40 || mouse.y > 540 - ){ + if(mouse.x < 55 || mouse.x > 967 || mouse.y < 40 || mouse.y > 540){ this.toSongSelect() - }else if(moveBy === 5){ + }else if(moveBy === 0){ + this.selectedDiff = 0 + this.toSongSelect() + }else if(moveBy === 1){ + this.toOptions(1) + }else if(moveBy === this.diffOptions.length + 4){ this.state.ura = !this.state.ura assets.sounds["ka"].play() - if(this.selectedDiff === 5 && !this.state.ura){ + if(this.selectedDiff === this.diffOptions.length + 4 && !this.state.ura){ this.state.move = -1 } }else if(moveBy !== null){ - this.toLoadSong(moveBy - 1, shift, ctrl, touch) + this.toLoadSong(moveBy - this.diffOptions.length, shift, ctrl, touch) } } } @@ -393,12 +420,12 @@ class SongSelect{ } diffSelMouse(x, y){ if(this.state.locked === 0){ - if(100 < x && x < 160 && 120 < y && y < 420){ - return 0 + if(95 < x && x < 239 && 118 < y && y < 422){ + return Math.floor((x - 95) / ((239 - 95) / 2)) }else if(422 < x && x < 922 && 95 < y && y < 524){ - var moveBy = Math.floor((x - 422) / ((922 - 422) / 5)) + 1 + var moveBy = Math.floor((x - 422) / ((922 - 422) / 5)) + this.diffOptions.length var currentSong = this.songs[this.selectedSong] - if(this.state.ura && moveBy === 4 || currentSong.stars[moveBy - 1]){ + if(this.state.ura && moveBy === this.diffOptions + 3 || currentSong.stars[moveBy - this.diffOptions.length]){ return moveBy } } @@ -451,8 +478,8 @@ class SongSelect{ this.state.locked = true this.state.moveHover = null this.state.ura = 0 - if(this.selectedDiff === 5){ - this.selectedDiff = 4 + if(this.selectedDiff === this.diffOptions.length + 4){ + this.selectedDiff = this.diffOptions.length + 3 } assets.sounds["don"].play() @@ -497,11 +524,22 @@ class SongSelect{ assets.sounds["don"].play() localStorage["selectedSong"] = this.selectedSong - localStorage["selectedDiff"] = difficulty + 1 + localStorage["selectedDiff"] = difficulty + this.diffOptions.length if(difficulty === 3 && this.state.ura){ difficulty = 4 } + var autoplay = false + var multiplayer = false + if(this.state.options === 1){ + autoplay = true + }else if(this.state.options === 2){ + multiplayer = true + }else if(shift){ + autoplay = shift + }else{ + multiplayer = ctrl + } new loadSong({ "title": selectedSong.title, @@ -510,7 +548,12 @@ class SongSelect{ "category": selectedSong.category, "type": selectedSong.type, "offset": selectedSong.offset - }, shift, ctrl, touch) + }, autoplay, multiplayer, touch) + } + toOptions(moveBy){ + assets.sounds["ka"].play() + this.selectedDiff = 1 + this.state.options = this.mod(this.optionsList.length, this.state.options + moveBy) } toTitleScreen(){ assets.sounds["cancel"].play() @@ -745,25 +788,25 @@ class SongSelect{ do{ if(hasUra && this.state.move > 0){ this.selectedDiff += this.state.move - if(this.selectedDiff > 5){ + if(this.selectedDiff > this.diffOptions.length + 4){ this.state.ura = !this.state.ura if(this.state.ura){ - this.selectedDiff = previousSelection === 4 ? 5 : previousSelection + this.selectedDiff = previousSelection === this.diffOptions.length + 3 ? this.diffOptions.length + 4 : previousSelection break }else{ this.state.move = -1 } } }else{ - this.selectedDiff = this.mod(6, this.selectedDiff + this.state.move) + this.selectedDiff = this.mod(this.diffOptions.length + 5, this.selectedDiff + this.state.move) } }while( - this.selectedDiff !== 0 && !currentSong.stars[this.selectedDiff - 1] - || this.selectedDiff === 4 && this.state.ura - || this.selectedDiff === 5 && !this.state.ura + this.selectedDiff >= this.diffOptions.length && !currentSong.stars[this.selectedDiff - this.diffOptions.length] + || this.selectedDiff === this.diffOptions.length + 3 && this.state.ura + || this.selectedDiff === this.diffOptions.length + 4 && !this.state.ura ) this.state.move = 0 - }else if(!currentSong.stars[this.selectedDiff - 1]){ + }else if(this.selectedDiff < 0 || this.selectedDiff >= this.diffOptions.length && !currentSong.stars[this.selectedDiff - this.diffOptions.length]){ this.selectedDiff = 0 } } @@ -897,70 +940,80 @@ class SongSelect{ }) var opened = 1 var songSel = false - var _x = x + 62 - var _y = y + 67 - ctx.fillStyle = "#efb058" - ctx.lineWidth = 5 - this.draw.roundedRect({ - ctx: ctx, - x: _x - 28, - y: _y, - w: 56, - h: 298, - radius: 24 - }) - ctx.fill() - ctx.stroke() - ctx.fillStyle = "#f7d39c" - ctx.beginPath() - ctx.arc(_x, _y + 28, 20, 0, Math.PI * 2) - ctx.fill() - this.draw.diffOptionsIcon({ - ctx: ctx, - x: _x, - y: _y + 28 - }) - this.draw.verticalText({ - ctx: ctx, - text: "もどる", - x: _x, - y: _y + 57, - width: 56, - height: 220, - fill: "#fff", - outline: "#000", - outlineSize: this.songAsset.letterBorder, - letterBorder: 4, - fontSize: 28, - fontFamily: this.font, - letterSpacing: 4 - }) - var highlight = 0 - if(this.state.moveHover === 0){ - highlight = 2 - }else if(this.selectedDiff === 0){ - highlight = 1 - } - if(highlight){ - this.draw.highlight({ + for(var i = 0; i < this.diffOptions.length; i++){ + var _x = x + 62 + i * 72 + var _y = y + 67 + ctx.fillStyle = this.diffOptions[i].fill + ctx.lineWidth = 5 + this.draw.roundedRect({ ctx: ctx, - x: _x - 32, - y: _y - 3, - w: 64, - h: 304, - animate: highlight === 1, - animateMS: this.state.moveMS, - opacity: highlight === 2 ? 0.8 : 1, + x: _x - 28, + y: _y, + w: 56, + h: 298, radius: 24 }) - if(this.selectedDiff === 0){ - this.draw.diffCursor({ + ctx.fill() + ctx.stroke() + ctx.fillStyle = this.diffOptions[i].iconFill + ctx.beginPath() + ctx.arc(_x, _y + 28, 20, 0, Math.PI * 2) + ctx.fill() + this.draw.diffOptionsIcon({ + ctx: ctx, + x: _x, + y: _y + 28, + iconName: this.diffOptions[i].iconName + }) + + var text = this.diffOptions[i].text + if(this.diffOptions[i].iconName === "options" && (this.selectedDiff === i || this.state.options !== 0)){ + text = this.optionsList[this.state.options] + } + + this.draw.verticalText({ + ctx: ctx, + text: text, + x: _x, + y: _y + 57, + width: 56, + height: 220, + fill: "#fff", + outline: "#000", + outlineSize: this.songAsset.letterBorder, + letterBorder: 4, + fontSize: 28, + fontFamily: this.font, + letterSpacing: this.diffOptions[i].letterSpacing + }) + + var highlight = 0 + if(this.state.moveHover === i){ + highlight = 2 + }else if(this.selectedDiff === i){ + highlight = 1 + } + if(highlight){ + this.draw.highlight({ ctx: ctx, - font: this.font, - x: _x, - y: _y - 45 + x: _x - 32, + y: _y - 3, + w: 64, + h: 304, + animate: highlight === 1, + animateMS: this.state.moveMS, + opacity: highlight === 2 ? 0.8 : 1, + radius: 24 }) + if(this.selectedDiff === i && !this.touchEnabled){ + this.draw.diffCursor({ + ctx: ctx, + font: this.font, + x: _x, + y: _y - 45 + }) + } } } } @@ -1057,8 +1110,8 @@ class SongSelect{ }) } } - var currentDiff = this.selectedDiff - 1 - if(this.selectedDiff === 5){ + var currentDiff = this.selectedDiff - this.diffOptions.length + if(this.selectedDiff === 4 + this.diffOptions.length){ currentDiff = 3 } if(i === currentSong.p2Cursor){ @@ -1074,12 +1127,12 @@ class SongSelect{ } if(!songSel){ var highlight = 0 - if(this.state.moveHover - 1 === i){ + if(this.state.moveHover - this.diffOptions.length === i){ highlight = 2 }else if(currentDiff === i){ highlight = 1 } - if(currentDiff === i){ + if(currentDiff === i && !this.touchEnabled){ this.draw.diffCursor({ ctx: ctx, font: this.font, diff --git a/public/src/js/view.js b/public/src/js/view.js index a9f5dcf..fc216ed 100644 --- a/public/src/js/view.js +++ b/public/src/js/view.js @@ -1,97 +1,752 @@ -class View{ - constructor(controller, bg, songTitle, songDifficulty){ +class View{ + constructor(controller){ this.controller = controller - this.bg = bg - this.songTitle = songTitle - this.songDifficulty = songDifficulty + + this.canvas = document.getElementById("canvas") + this.ctx = this.canvas.getContext("2d") this.pauseMenu = document.getElementById("pause-menu") this.cursor = document.getElementById("cursor") this.gameDiv = document.getElementById("game") - var docW = document.body.offsetWidth - var docH = document.body.offsetHeight - if(this.controller.multiplayer === 2){ - this.canvas = new ScalableCanvas("canvas-p2", docW, docH / 3 * 2) - this.canvas.canvas.style.position = "absolute" - this.canvas.canvas.style.top = "33%" - this.gameDiv.appendChild(this.canvas.canvas) - }else{ - this.canvas = new ScalableCanvas("canvas", docW, docH) + this.portraitClass = false + this.touchp2Class = false + + this.currentScore = { + ms: -Infinity, + type: 0 } - this.winW = this.canvas.scaledWidth - this.winH = this.canvas.scaledHeight - if(this.controller.multiplayer === 2){ - this.winH = this.winH / 2 * 3 + this.noteFace = { + small: 0, + big: 3 } - this.ctx = this.canvas.ctx - - this.taikoSquareW = this.winW / 4 - this.slotX = this.taikoSquareW + 100 - - this.currentScore = 0 - this.special = "" - this.scoreDispCount = -1 - this.scoreOpacity = 1 - - this.lastMeasure = 0 - this.currentTimingPoint = 0 - //Distance to be done by the circle - this.distanceForCircle = this.winW - this.slotX - - this.currentCircleFace = 0 - this.currentDonFace = 0 - this.currentBigDonFace = 1 this.nextBeat = 0 this.gogoTime = 0 - this.gogoTimeStarted = -Infinity - this.drumroll = [] this.beatInterval = this.controller.parsedSongData.beatInfo.beatInterval + this.font = "TnT, Meiryo, sans-serif" + + this.draw = new CanvasDraw() this.assets = new ViewAssets(this) + this.titleCache = new CanvasCache() + this.comboCache = new CanvasCache() + + this.multiplayer = this.controller.multiplayer + + this.touchEnabled = this.controller.touchEnabled this.touch = -Infinity - if(this.controller.touchEnabled){ - this.touchEnabled = true - - this.touchDrumDiv = document.getElementById("touch-drum") - this.touchDrumImg = document.getElementById("touch-drum-img") - this.gameDiv.classList.add("touch-visible") - document.getElementById("version").classList.add("version-hide") - - pageEvents.add(this.canvas.canvas, "touchstart", this.ontouch.bind(this)) - - this.touchFullBtn = document.getElementById("touch-full-btn") - pageEvents.add(this.touchFullBtn, "touchend", toggleFullscreen) - if(!fullScreenSupported){ - this.touchFullBtn.style.display = "none" - } - - this.touchPauseBtn = document.getElementById("touch-pause-btn") - pageEvents.add(this.touchPauseBtn, "touchend", () => { - this.controller.togglePauseMenu() + if(this.multiplayer !== 2){ + pageEvents.add(window, "resize", () => { + if(this.controller.game.isPaused()){ + this.refresh() + setTimeout(this.refresh.bind(this), 100) + } }) + + if(this.controller.touchEnabled){ + this.touchDrumDiv = document.getElementById("touch-drum") + this.touchDrumImg = document.getElementById("touch-drum-img") + this.gameDiv.classList.add("touch-visible") + document.getElementById("version").classList.add("version-hide") + + pageEvents.add(this.canvas, "touchstart", this.ontouch.bind(this)) + + this.touchFullBtn = document.getElementById("touch-full-btn") + pageEvents.add(this.touchFullBtn, "touchend", toggleFullscreen) + if(!fullScreenSupported){ + this.touchFullBtn.style.display = "none" + } + + this.touchPauseBtn = document.getElementById("touch-pause-btn") + pageEvents.add(this.touchPauseBtn, "touchend", () => { + this.controller.togglePauseMenu() + }) + if(this.multiplayer){ + this.touchPauseBtn.style.display = "none" + } + } } } run(){ - this.ctx.font = "normal 14pt TnT, Meiryo, sans-serif" this.setBackground() - if(this.controller.multiplayer !== 2){ - var gameSong = document.getElementsByClassName("game-song")[0] - gameSong.appendChild(document.createTextNode(this.songTitle)) - gameSong.setAttribute("alt", this.songTitle) - } this.lastMousemove = this.controller.getElapsedTime() pageEvents.mouseAdd(this, this.onmousemove.bind(this)) this.refresh() } + refresh(){ + var ctx = this.ctx + + var winW = innerWidth + var winH = lastHeight + + if(winW / 32 > winH / 9){ + winW = winH / 9 * 32 + } + + this.portrait = winW < winH + var touchMultiplayer = this.touchEnabled && this.multiplayer && !this.portrait + + this.pixelRatio = window.devicePixelRatio || 1 + winW *= this.pixelRatio + winH *= this.pixelRatio + if(this.portrait){ + var ratioX = winW / 720 + var ratioY = winH / 1280 + }else{ + var ratioX = winW / 1280 + var ratioY = winH / 720 + } + var ratio = (ratioX < ratioY ? ratioX : ratioY) + + if(this.winW !== winW || this.winH !== winH){ + this.winW = winW + this.winH = winH + this.ratio = ratio + + if(this.multiplayer !== 2){ + this.canvas.width = winW + this.canvas.height = winH + ctx.scale(ratio, ratio) + this.canvas.style.width = (winW / this.pixelRatio) + "px" + this.canvas.style.height = (winH / this.pixelRatio) + "px" + + this.titleCache.resize(640, 80, ratio) + } + this.fillComboCache() + }else if(this.multiplayer !== 2){ + ctx.clearRect(0, 0, winW / ratio, winH / ratio) + } + winW /= ratio + winH /= ratio + var ms = this.getMS() + + if(this.portrait){ + var frameTop = winH / 2 - 1280 / 2 + var frameLeft = winW / 2 - 720 / 2 + }else{ + var frameTop = winH / 2 - 720 / 2 + var frameLeft = winW / 2 - 1280 / 2 + } + if(this.multiplayer === 2){ + frameTop += this.multiplayer === 2 ? 165 : 176 + } + if(touchMultiplayer){ + if(!this.touchp2Class){ + this.touchp2Class = true + this.gameDiv.classList.add("touchp2") + } + frameTop -= 90 + }else if(this.touchp2Class){ + this.touchp2Class = false + this.gameDiv.classList.remove("touchp2") + } + + ctx.save() + ctx.translate(0, frameTop) + + this.drawGogoTime() + + if(!touchMultiplayer){ + this.assets.drawAssets("background") + } + + if(this.multiplayer !== 2){ + this.titleCache.get({ + ctx: ctx, + x: winW - (touchMultiplayer && fullScreenSupported ? 750 : 650), + y: touchMultiplayer ? 75 : 10, + w: 640, + h: 80, + id: "title" + }, ctx => { + this.draw.layeredText({ + ctx: ctx, + text: this.controller.selectedSong.title, + fontSize: 40, + fontFamily: this.font, + x: 620, + y: 20, + width: 600, + align: "right" + }, [ + {outline: "#000", letterBorder: 10}, + {fill: "#fff"} + ]) + }) + } + + var score = this.controller.getGlobalScore() + var gaugePercent = Math.round(score.gauge / 2) / 50 + + if(this.multiplayer === 2){ + var scoreImg = "bg_score_p2" + var scoreFill = "#6bbec0" + }else{ + var scoreImg = "bg_score_p1" + var scoreFill = "#fa4529" + } + + if(this.portrait){ + // Portrait + + if(!this.portraitClass){ + this.portraitClass = true + this.gameDiv.classList.add("portrait") + } + + this.slotPos = { + x: 66, + y: frameTop + 375, + size: 100, + paddingLeft: 0 + } + this.scorePos = {x: 363, y: frameTop + (this.multiplayer === 2 ? 520 : 227)} + + var animPos = { + x1: this.slotPos.x + 13, + y1: this.slotPos.y + (this.multiplayer === 2 ? 27 : -27), + x2: winW - 38, + y2: frameTop + (this.multiplayer === 2 ? 484 : 293) + } + var taikoPos = { + x: 19, + y: frameTop + (this.multiplayer === 2 ? 464 : 184), + w: 111, + h: 130 + } + + ctx.fillStyle = "#000" + ctx.fillRect( + 0, + this.multiplayer === 2 ? 306 : 288, + winW, + this.multiplayer === 1 ? 184 : 183 + ) + ctx.beginPath() + if(this.multiplayer === 2){ + ctx.moveTo(0, 467) + ctx.lineTo(384, 467) + ctx.lineTo(384, 512) + ctx.lineTo(184, 560) + ctx.lineTo(0, 560) + }else{ + ctx.moveTo(0, 217) + ctx.lineTo(184, 217) + ctx.lineTo(384, 265) + ctx.lineTo(384, 309) + ctx.lineTo(0, 309) + } + ctx.fill() + + // Left side + ctx.fillStyle = scoreFill + var leftSide = (ctx, mul) => { + ctx.beginPath() + if(this.multiplayer === 2){ + ctx.moveTo(0, 468 * mul) + ctx.lineTo(380 * mul, 468 * mul) + ctx.lineTo(380 * mul, 512 * mul) + ctx.lineTo(184 * mul, 556 * mul) + ctx.lineTo(0, 556 * mul) + }else{ + ctx.moveTo(0, 221 * mul) + ctx.lineTo(184 * mul, 221 * mul) + ctx.lineTo(380 * mul, 265 * mul) + ctx.lineTo(380 * mul, 309 * mul) + ctx.lineTo(0, 309 * mul) + } + } + leftSide(ctx, 1) + ctx.fill() + ctx.globalAlpha = 0.5 + this.draw.pattern({ + ctx: ctx, + img: assets.image[scoreImg], + shape: leftSide, + dx: 0, + dy: 45, + scale: 1.55 + }) + ctx.globalAlpha = 1 + + // Score background + ctx.fillStyle = "#000" + ctx.beginPath() + if(this.multiplayer === 2){ + this.draw.roundedCorner(ctx, 184, 512, 20, 0) + ctx.lineTo(384, 512) + this.draw.roundedCorner(ctx, 384, 560, 12, 2) + ctx.lineTo(184, 560) + }else{ + ctx.moveTo(184, 217) + this.draw.roundedCorner(ctx, 384, 217, 12, 1) + ctx.lineTo(384, 265) + this.draw.roundedCorner(ctx, 184, 265, 20, 3) + } + ctx.fill() + + // Difficulty + var badgeImg = assets.image["muzu_" + this.controller.selectedSong.difficulty] + var badgeW = badgeImg.width / badgeImg.height * 53 + ctx.drawImage(badgeImg, + 157 - badgeW / 2, + this.multiplayer === 2 ? 497 : 228, + badgeW, + 53 + ) + + // Badges + if(this.controller.autoPlayEnabled && !this.controller.multiplayer){ + this.ctx.drawImage(assets.image["badge_auto"], + 183, + this.multiplayer === 2 ? 490 : 265, + 23, + 23 + ) + } + + // Gauge + ctx.fillStyle = "#000" + ctx.beginPath() + var gaugeX = winW - 788 * 0.7 - 32 + if(this.multiplayer === 2){ + ctx.moveTo(gaugeX, 464) + ctx.lineTo(winW, 464) + ctx.lineTo(winW, 489) + this.draw.roundedCorner(ctx, gaugeX, 489, 12, 3) + }else{ + this.draw.roundedCorner(ctx, gaugeX, 288, 12, 0) + ctx.lineTo(winW, 288) + ctx.lineTo(winW, 314) + ctx.lineTo(gaugeX, 314) + } + ctx.fill() + this.draw.gauge({ + ctx: ctx, + x: winW, + y: this.multiplayer === 2 ? 468 : 273, + clear: 25 / 50, + percentage: gaugePercent, + font: this.font, + scale: 0.7, + multiplayer: this.multiplayer === 2 + }) + this.draw.soul({ + ctx: ctx, + x: winW - 40, + y: this.multiplayer === 2 ? 484 : 293, + scale: 0.75, + cleared: gaugePercent - 1 / 50 >= 25 / 50 + }) + + // Note bar + ctx.fillStyle = "#2c2a2c" + ctx.fillRect(0, 314, winW, 122) + ctx.fillStyle = "#847f84" + ctx.fillRect(0, 440, winW, 24) + + }else{ + // Landscape + + if(this.portraitClass){ + this.portraitClass = false + this.gameDiv.classList.remove("portrait") + } + + this.slotPos = { + x: 413, + y: frameTop + 257, + size: 106, + paddingLeft: 332 + } + this.scorePos = { + x: 155, + y: frameTop + (this.multiplayer === 2 ? 318 : 193) + } + + var animPos = { + x1: this.slotPos.x + 14, + y1: this.slotPos.y + (this.multiplayer === 2 ? 29 : -29), + x2: winW - 55, + y2: frameTop + (this.multiplayer === 2 ? 378 : 165) + } + var taikoPos = {x: 179, y: frameTop + 190, w: 138, h: 162} + + ctx.fillStyle = "#000" + ctx.fillRect( + 0, + 184, + winW, + this.multiplayer === 1 ? 177 : 176 + ) + ctx.beginPath() + if(this.multiplayer === 2){ + ctx.moveTo(328, 351) + ctx.lineTo(winW, 351) + ctx.lineTo(winW, 385) + this.draw.roundedCorner(ctx, 328, 385, 10, 3) + }else{ + ctx.moveTo(328, 192) + this.draw.roundedCorner(ctx, 328, 158, 10, 0) + ctx.lineTo(winW, 158) + ctx.lineTo(winW, 192) + } + ctx.fill() + + // Gauge + this.draw.gauge({ + ctx: ctx, + x: winW, + y: this.multiplayer === 2 ? 357 : 135, + clear: 25 / 50, + percentage: gaugePercent, + font: this.font, + multiplayer: this.multiplayer === 2 + }) + this.draw.soul({ + ctx: ctx, + x: winW - 57, + y: this.multiplayer === 2 ? 378 : 165, + cleared: gaugePercent - 1 / 50 >= 25 / 50 + }) + + // Note bar + ctx.fillStyle = "#2c2a2c" + ctx.fillRect(332, 192, winW - 332, 130) + ctx.fillStyle = "#847f84" + ctx.fillRect(332, 326, winW - 332, 26) + + // Left side + ctx.fillStyle = scoreFill + ctx.fillRect(0, 192, 328, 160) + ctx.globalAlpha = 0.5 + this.draw.pattern({ + ctx: ctx, + img: assets.image[scoreImg], + x: 0, + y: 192, + w: 328, + h: 160, + dx: 0, + dy: 45, + scale: 1.55 + }) + ctx.globalAlpha = 1 + + // Difficulty + var badgeImg = assets.image["muzu_" + this.controller.selectedSong.difficulty] + var badgeW = badgeImg.width / badgeImg.height * 120 + ctx.drawImage(badgeImg, + 87 - badgeW / 2, this.multiplayer === 2 ? 194 : 232, + badgeW, 120 + ) + + // Badges + if(this.controller.autoPlayEnabled && !this.controller.multiplayer){ + this.ctx.drawImage(assets.image["badge_auto"], + 125, 235, 34, 34 + ) + } + + // Score background + ctx.fillStyle = "#000" + ctx.beginPath() + if(this.multiplayer === 2){ + ctx.moveTo(0, 312) + this.draw.roundedCorner(ctx, 176, 312, 20, 1) + ctx.lineTo(176, 353) + ctx.lineTo(0, 353) + }else{ + ctx.moveTo(0, 191) + ctx.lineTo(176, 191) + this.draw.roundedCorner(ctx, 176, 232, 20, 2) + ctx.lineTo(0, 232) + } + ctx.fill() + } + + ctx.restore() + + animPos.w = animPos.x2 - animPos.x1 + animPos.h = animPos.y1 - animPos.y2 + this.animateBezier = [{ + // 427, 228 + x: animPos.x1, + y: animPos.y1 + }, { + // 560, 10 + x: animPos.x1 + animPos.w / 6, + y: animPos.y1 - animPos.h * (this.multiplayer === 2 ? 2.5 : 3.5) + }, { + // 940, -150 + x: animPos.x2 - animPos.w / 3, + y: animPos.y2 - animPos.h * (this.multiplayer === 2 ? 3.5 : 5) + }, { + // 1225, 165 + x: animPos.x2, + y: animPos.y2 + }] + + var touchTop = frameTop + (touchMultiplayer ? 135 : 0) + this.touchDrum = (() => { + var sw = 842 + var sh = 340 + var x = 0 + var y = this.portrait ? touchTop + 477 : touchTop + 365 + var paddingTop = 13 + var w = winW + var maxH = winH - y + var h = maxH - paddingTop + if(w / h >= sw / sh){ + w = h / sh * sw + x = (winW - w) / 2 + y += paddingTop + }else{ + h = w / sw * sh + y = y + (maxH - h) + } + return { + x: x, y: y, w: w, h: h + } + })() + this.touchCircle = { + x: winW / 2, + y: winH + this.touchDrum.h * 0.1, + rx: this.touchDrum.w / 2 - this.touchDrum.h * 0.03, + ry: this.touchDrum.h * 1.07 + } + + if(this.multiplayer !== 2){ + this.mouseIdle() + this.drawTouch() + } + + // Score + ctx.save() + ctx.font = "30px " + this.font + ctx.fillStyle = "#fff" + ctx.strokeStyle = "#fff" + ctx.lineWidth = 0.3 + ctx.textAlign = "center" + ctx.textBaseline = "top" + var glyph = 29 + var pointsText = score.points.toString().split("") + ctx.translate(this.scorePos.x, this.scorePos.y) + ctx.scale(0.7, 1) + for(var i in pointsText){ + var x = glyph * (i - pointsText.length + 1) + ctx.strokeText(pointsText[i], x, 0) + ctx.fillText(pointsText[i], x, 0) + } + ctx.restore() + + // Bar pressed keys + var keyTime = this.controller.getKeyTime() + var sound = keyTime["don"] > keyTime["ka"] ? "don" : "ka" + var padding = this.slotPos.paddingLeft + var mul = this.slotPos.size / 106 + var barY = this.slotPos.y - 65 * mul + var barH = 130 * mul + + if(this.gogoTime || ms <= this.gogoTimeStarted + 100){ + var grd = ctx.createLinearGradient(0, 0, this.winW, 0) + grd.addColorStop(0, "#512a2c") + grd.addColorStop(0.46, "#6f2a2d") + grd.addColorStop(0.76, "#8a4763") + grd.addColorStop(1, "#2c2a2c") + ctx.fillStyle = grd + if(!this.touchEnabled){ + var alpha = Math.min(100, ms - this.gogoTimeStarted) / 100 + if(!this.gogoTime){ + alpha = 1 - alpha + } + ctx.globalAlpha = alpha + } + ctx.fillRect(padding, barY, winW - padding, barH) + } + if(keyTime[sound] > ms - 200){ + var gradients = { + "don": ["#f54c25", "#232323"], + "ka": ["#75cee9", "#232323"] + } + var grd = ctx.createLinearGradient(0, 0, this.winW, 0) + grd.addColorStop(0, gradients[sound][0]) + grd.addColorStop(1, gradients[sound][1]) + ctx.fillStyle = grd + ctx.globalAlpha = 1 - (ms - keyTime[sound]) / 200 + ctx.fillRect(padding, barY, winW - padding, barH) + } + ctx.globalAlpha = 1 + + // Taiko + ctx.drawImage(assets.image["taiko"], + 0, 0, 138, 162, + taikoPos.x, taikoPos.y, taikoPos.w, taikoPos.h + ) + + // Taiko pressed keys + var kbd = this.controller.getBindings() + var keys = ["ka_l", "ka_r", "don_l", "don_r"] + + for(var i = 0; i < keys.length; i++){ + var keyMS = ms - keyTime[kbd[keys[i]]] + if(keyMS < 130){ + if(keyMS > 70 && !this.touchEnabled){ + ctx.globalAlpha = this.draw.easeOut(1 - (keyMS - 70) / 60) + } + ctx.drawImage(assets.image["taiko"], + 0, 162 * (i + 1), 138, 162, + taikoPos.x, taikoPos.y, taikoPos.w, taikoPos.h + ) + } + } + ctx.globalAlpha = 1 + + // Combo + var scoreMS = ms - this.currentScore.ms + + var comboCount = this.controller.getCombo() + if(comboCount >= 10){ + var comboText = comboCount.toString().split("") + var mul = this.portrait ? 0.8 : 1 + var comboX = taikoPos.x + taikoPos.w / 2 + var comboY = taikoPos.y + taikoPos.h * 0.09 + var comboScale = 0 + if(this.currentScore !== 0 && scoreMS < 100){ + comboScale = this.draw.fade(scoreMS / 100) + } + var glyphW = 51 + var glyphH = 64 + var letterSpacing = (comboText.length >= 4 ? 38 : 42) * mul + var orange = comboCount >= 100 ? "1" : "0" + + var w = glyphW * mul + var h = glyphH * mul * (1 + comboScale / 8) + + for(var i in comboText){ + var textX = comboX + letterSpacing * (i - (comboText.length - 1) / 2) + this.comboCache.get({ + ctx: ctx, + x: textX - w / 2, + y: comboY + glyphH * mul - h, + w: w, + h: h, + id: orange + "combo" + comboText[i] + }) + } + + var fontSize = 24 * mul + var comboTextY = taikoPos.y + taikoPos.h * 0.63 + if(orange === "1"){ + var grd = ctx.createLinearGradient( + 0, + comboTextY - fontSize * 0.6, + 0, + comboTextY + fontSize * 0.1 + ) + grd.addColorStop(0, "#ff2000") + grd.addColorStop(0.5, "#ffc321") + grd.addColorStop(1, "#ffedb7") + ctx.fillStyle = grd + }else{ + ctx.fillStyle = "#fff" + } + ctx.font = fontSize + "px " + this.font + ctx.lineWidth = 7 * mul + ctx.textAlign = "center" + ctx.strokeText("コンボ", comboX, comboTextY) + ctx.fillText("コンボ", comboX, comboTextY) + } + + // Slot + this.draw.slot(ctx, this.slotPos.x, this.slotPos.y, this.slotPos.size) + + // Measures + ctx.save() + ctx.rect(this.slotPos.paddingLeft, 0, winW - this.slotPos.paddingLeft, winH) + ctx.clip() + this.drawMeasures() + ctx.restore() + + // Go go time fire + this.assets.drawAssets("bar") + + // Hit notes shadow + if(scoreMS < 300 && this.currentScore.type){ + var fadeOut = scoreMS > 120 && !this.touchEnabled + if(fadeOut){ + ctx.globalAlpha = 1 - (scoreMS - 120) / 180 + } + var scoreId = this.currentScore.type === 230 ? 0 : 1 + if(this.currentScore.bigNote){ + scoreId += 2 + } + ctx.drawImage(assets.image["notes_hit"], + 0, 128 * scoreId, 128, 128, + this.slotPos.x - 64, this.slotPos.y - 64, + 128, 128 + ) + if(fadeOut){ + ctx.globalAlpha = 1 + } + } + + // Future notes + this.updateNoteFaces() + ctx.save() + ctx.rect(this.slotPos.paddingLeft, 0, winW - this.slotPos.paddingLeft, winH) + ctx.clip() + + this.drawCircles(this.controller.getCircles()) + ctx.restore() + + // Hit notes explosion + + + // Good, OK, Bad + if(scoreMS < 300){ + var mul = this.slotPos.size / 106 + var scores = { + "0": "bad", + "230": "ok", + "450": "good" + } + var yOffset = scoreMS < 70 ? scoreMS * (13 / 70) : 0 + var fadeOut = scoreMS > 250 && !this.touchEnabled + if(fadeOut){ + ctx.globalAlpha = 1 - (scoreMS - 250) / 50 + } + this.draw.score({ + ctx: ctx, + score: scores[this.currentScore.type], + x: this.slotPos.x, + y: this.slotPos.y - 98 * mul - yOffset, + scale: 1.35 * mul, + align: "center" + }) + if(fadeOut){ + ctx.globalAlpha = 1 + } + } + + // Animating notes + this.drawAnimatedCircles(this.controller.getCircles()) + this.drawAnimatedCircles(this.drumroll) + + // Go-go time fireworks + if(!this.touchEnabled && !this.portrait && !this.multiplayer){ + this.assets.drawAssets("foreground") + } + } setBackground(){ var gameDiv = document.getElementById("game") var selectedSong = this.controller.selectedSong + var bg = "/songs/" + selectedSong.folder + "/bg.png" if(selectedSong.defaultBg){ var categories = { "J-POP": 0, @@ -106,399 +761,69 @@ class View{ if(selectedSong.category in categories){ catId = categories[selectedSong.category] } - this.bg = assets.image["bg_genre_" + catId].src + bg = assets.image["bg_genre_" + catId].src gameDiv.classList.add("default-bg") } - gameDiv.style.backgroundImage = "url('" + this.bg + "')" + gameDiv.style.backgroundImage = "url('" + bg + "')" } - positionning(){ - var docW = document.body.offsetWidth - var docH = document.body.offsetHeight - this.canvas.rescale() - if(this.controller.multiplayer === 2){ - docH = docH / 3 * 2 - } - this.canvas.resize(docW, docH) - this.winW = this.canvas.scaledWidth - this.winH = this.canvas.scaledHeight - if(this.controller.multiplayer === 2){ - this.winH = this.winH / 2 * 3 - } - 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.slotX = this.taikoSquareW + this.barH * 0.5 - this.scoreSquareW = this.taikoSquareW * 0.55 - this.scoreSquareH = 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 - this.HPBarW = this.taikoSquareW * 2.475 - this.HPBarH = this.barH * 0.35 - if(this.HPBarW/this.HPBarH > HPBarRatio){ - this.HPBarW = this.HPBarH * HPBarRatio - }else{ - this.HPBarH = this.HPBarW / HPBarRatio - } - this.HPBarX = this.winW - this.HPBarW - this.HPBarY = this.barY - this.HPBarH - this.HPbarColX = this.HPBarX + this.HPBarW * 0.008 - this.HPbarColY = this.HPBarY + this.HPBarH * 0.14 - this.HPBarColMaxW = this.HPBarW * 0.925 - this.HPBarColH = this.HPBarH * 0.8 - var diffRatio = 176 / 120 - this.diffH = this.winH * 0.16 - this.diffW = this.diffH * diffRatio - this.diffX = this.taikoX * 0.10 - this.diffY = this.taikoY * 1.05 + this.taikoH * 0.19 - this.touchDrum = (() => { - var sw = 842 - var sh = 340 - var x = 0 - var y = this.barY + this.barH + 5 - var paddingTop = this.barH * 0.1 - var w = this.winW - var maxH = this.winH - (this.barY + this.barH + 5) - var h = maxH - paddingTop - if(w / h >= sw / sh){ - w = h / sh * sw - x = (this.winW - w) / 2 - y += paddingTop - }else{ - h = w / sw * sh - y = y + (maxH - h) - } - return { - x: x, y: y, w: w, h: h - } - })() - this.touchCircle = (() => { - return { - x: this.winW / 2, - y: this.winH + this.touchDrum.h * 0.1, - rx: this.touchDrum.w / 2 - this.touchDrum.h * 0.03, - ry: this.touchDrum.h * 1.07 - } - })() - } - refresh(){ - this.positionning() - this.distanceForCircle = this.winW - this.slotX + + drawMeasures(){ + var measures = this.controller.parsedSongData.measures + var ms = this.getMS() + var mul = this.slotPos.size / 106 + var distanceForCircle = this.winW / this.ratio - this.slotPos.x + var measureY = this.slotPos.y - 65 * mul + var measureH = 130 * mul - this.ctx.clearRect(0, 0, this.canvas.scaledWidth, this.canvas.scaledHeight) - - // Draw - this.assets.drawAssets("background") - this.drawBar() - this.drawSlot() - this.drawHPBar() - this.assets.drawAssets("bar") - this.drawMeasures() - this.drawScore() - this.drawCircles(this.controller.getCircles()) - this.drawCircles(this.drumroll) - this.drawTaikoSquare() - this.drawDifficulty() - this.drawPressedKeys() - this.drawCombo() - this.drawGlobalScore() - this.updateDonFaces() - this.drawGogoTime() - this.mouseIdle() - if(!this.touchEnabled){ - this.assets.drawAssets("foreground") - } - this.drawTouch() - //this.drawTime() + measures.forEach(measure => { + var timeForDistance = this.posToMs(distanceForCircle, measure.speed) + if(ms >= measure.ms - timeForDistance && ms <= measure.ms + 350){ + var measureX = this.slotPos.x + this.msToPos(measure.ms - ms, measure.speed) + this.ctx.strokeStyle = "#bdbdbd" + this.ctx.lineWidth = 3 + this.ctx.beginPath() + this.ctx.moveTo(measureX, measureY) + this.ctx.lineTo(measureX, measureY + measureH) + this.ctx.stroke() + } + }) } - updateDonFaces(){ - var ms = this.controller.getElapsedTime() + updateNoteFaces(){ + var ms = this.getMS() while(ms >= this.nextBeat){ this.nextBeat += this.beatInterval if(this.controller.getCombo() >= 50){ var face = Math.floor(ms / this.beatInterval) % 2 - this.currentBigDonFace = face - this.currentDonFace = face - }else{ - this.currentBigDonFace = 1 - this.currentDonFace = 0 - } - } - } - drawHPBar(){ - var z = this.canvas.scale - - var bottomSquareX = this.taikoSquareW - var borderSize = this.HPBarH * 0.2 - this.ctx.fillStyle = "#000" - this.ctx.beginPath() - // Right hand black square - this.ctx.fillRect( - this.HPBarX + this.HPBarW - this.HPBarY * 0.2, - this.HPBarY, - this.HPBarW * 0.2, - this.HPBarH - ) - this.ctx.fillRect( - bottomSquareX + borderSize, - this.HPBarY + 0.435 * this.HPBarH, - this.winW - bottomSquareX - borderSize, - this.HPBarH / 2 + 2 * z - ) - this.ctx.fillRect( - bottomSquareX, - this.HPBarY + 0.68 * this.HPBarH, - this.HPBarW * 0.8, - this.HPBarH / 4 + 2 * z - ) - this.ctx.arc( - bottomSquareX+borderSize, - this.HPBarY+ 0.435 * this.HPBarH + borderSize, - borderSize, - 0, - Math.PI * 2 - ) - this.ctx.fill() - this.ctx.closePath() - - this.ctx.fillOpacity = 0.5 - this.ctx.drawImage(assets.image["hp-bar-bg"], - this.HPBarX, this.HPBarY, - this.HPBarW, this.HPBarH - ) - this.ctx.fillOpacity = 1 - var hpBar = this.getHP() - this.ctx.drawImage(assets.image["hp-bar-colour"], - 0, 0, - Math.max(1, hpBar.imgW), 40, - this.HPbarColX, this.HPbarColY, - hpBar.canvasW, this.HPBarColH - ) - } - getHP(){ - var circles = this.controller.getCircles() - var currentCircle = this.controller.getCurrentCircle() - var gauge = this.controller.getGlobalScore().gauge - var width = Math.floor(gauge * 650 / 1000) * 10 - return { - imgW: width, - canvasW: width / 650 * this.HPBarColMaxW - } - } - drawMeasures(){ - var measures = this.controller.parsedSongData.measures - var currentTime = this.controller.getElapsedTime() - - measures.forEach((measure, index)=>{ - var timeForDistance = this.posToMs(this.distanceForCircle, measure.speed) - if(currentTime >= measure.ms - timeForDistance && currentTime <= measure.ms + 350){ - this.drawMeasure(measure) - } - }) - } - drawMeasure(measure){ - var z = this.canvas.scale - var currentTime = this.controller.getElapsedTime() - var measureX = this.slotX + this.msToPos(measure.ms - currentTime, measure.speed) - this.ctx.strokeStyle = "#bab8b8" - this.ctx.lineWidth = 2 - this.ctx.beginPath() - this.ctx.moveTo(measureX, this.barY + 5 * z) - this.ctx.lineTo(measureX, this.barY + this.barH - this.lyricsBarH - 5 * z) - this.ctx.closePath() - this.ctx.stroke() - } - drawCombo(){ - var comboCount = this.controller.getCombo() - if(comboCount >= 10){ - var comboX = this.taikoX + this.taikoW / 2 - var comboY = this.barY + this.barH / 2 - var fontSize = this.taikoH * 0.4 - this.ctx.font = "normal " + fontSize + "px TnT, Meiryo, sans-serif" - this.ctx.textAlign = "center" - this.ctx.strokeStyle = "#000" - this.ctx.lineWidth = fontSize / 10 - var glyph = this.ctx.measureText("0").width - var comboText = comboCount.toString().split("") - for(var i in comboText){ - var textX = comboX + glyph * (i - (comboText.length - 1) / 2) - if(comboCount >= 100){ - var grd = this.ctx.createLinearGradient( - textX - glyph * 0.2, - comboY - fontSize * 0.8, - textX + glyph * 0.2, - comboY - fontSize * 0.2 - ) - grd.addColorStop(0, "#f00") - grd.addColorStop(1, "#fe0") - this.ctx.fillStyle = grd - }else{ - this.ctx.fillStyle = "#fff" + this.noteFace = { + small: face, + big: face + 2 } - this.strokeFillText(comboText[i], - textX, - comboY - ) - } - - var fontSize = this.taikoH * 0.12 - if(comboCount >= 100){ - var grd = this.ctx.createLinearGradient(0, comboY + fontSize * 0.5, 0, comboY + fontSize * 1.5) - grd.addColorStop(0, "#f00") - grd.addColorStop(1, "#fe0") - this.ctx.fillStyle = grd }else{ - this.ctx.fillStyle = "#fff" + this.noteFace = { + small: 0, + big: 3 + } } - this.ctx.font = "normal " + fontSize + "px TnT, Meiryo, sans-serif" - this.ctx.lineWidth = fontSize / 5 - this.strokeFillText("コンボ", - comboX, - comboY + fontSize * 1.5 - ) - - this.scoreDispCount++ } } - strokeFillText(text, x, y){ - this.ctx.strokeText(text, x, y) - this.ctx.fillText(text, x, y) - } - drawGlobalScore(){ - // Draw score square - this.ctx.fillStyle="#000" - this.ctx.beginPath() - this.ctx.fillRect(0, this.barY, this.scoreSquareW, this.scoreSquareH - 10) - this.ctx.fillRect(0, this.barY, this.scoreSquareW - 10, this.scoreSquareH) - this.ctx.arc( - this.scoreSquareW - 10, - this.barY + this.scoreSquareH - 10, - 10, - 0, - Math.PI * 2 - ) - this.ctx.fill() - this.ctx.closePath() - - var fontSize = 0.7 * this.scoreSquareH - // Draw score text - this.ctx.font = "normal " + fontSize + "px TnT, Meiryo, sans-serif" - this.ctx.fillStyle = "#fff" - this.ctx.textAlign = "center" - var glyph = this.ctx.measureText("0").width - var pointsText = this.controller.getGlobalScore().points.toString().split("") - for(var i in pointsText){ - this.ctx.fillText(pointsText[i], - this.scoreSquareW - 30 + glyph * (i - pointsText.length + 1), - this.barY + this.scoreSquareH * 0.7 - ) - } - } - drawPressedKeys(){ - var ms = this.controller.getElapsedTime() - var keyTime = this.controller.getKeyTime() - var kbd = this.controller.getBindings() - - if(keyTime[kbd["ka_l"]] > ms - 150){ - var elemW = 0.45 * this.taikoW - this.ctx.globalAlpha = Math.min(1, 4 - (ms - keyTime[kbd["ka_l"]]) / 37.5) - this.ctx.drawImage(assets.image["taiko-key-blue"], - 0, 0, 68, 124, - this.taikoX + this.taikoW * 0.05, - this.taikoY + this.taikoH * 0.03, - elemW, - 124 / 68 * elemW - ) - } - if(keyTime[kbd["don_l"]] > ms - 150){ - var elemW = 0.35 * this.taikoW - this.ctx.globalAlpha = Math.min(1, 4 - (ms - keyTime[kbd["don_l"]]) / 37.5) - this.ctx.drawImage(assets.image["taiko-key-red"], - 0, 0, 53, 100, - this.taikoX + this.taikoW * 0.15, - this.taikoY + this.taikoH * 0.09, - elemW, - 100 / 53 * elemW - ) - } - if(keyTime[kbd["don_r"]] > ms - 150){ - var elemW = 0.35 * this.taikoW - this.ctx.globalAlpha = Math.min(1, 4 - (ms - keyTime[kbd["don_r"]]) / 37.5) - this.ctx.drawImage(assets.image["taiko-key-red"], - 53, 0, 53, 100, - this.taikoX + this.taikoW * 0.15 + elemW, - this.taikoY + this.taikoH * 0.09, - elemW, - 100 / 53 * elemW - ) - } - if(keyTime[kbd["ka_r"]] > ms - 150){ - var elemW = 0.45 * this.taikoW - this.ctx.globalAlpha = Math.min(1, 4 - (ms - keyTime[kbd["ka_r"]]) / 37.5) - this.ctx.drawImage(assets.image["taiko-key-blue"], - 68, 0, 68, 124, - this.taikoX + this.taikoW * 0.05 + elemW, - this.taikoY + this.taikoH * 0.03, - elemW, - 124 / 68 * elemW - ) - } - this.ctx.globalAlpha = 1 - } - displayScore(score, notPlayed){ - this.currentScore = score - this.special = notPlayed ? "-b" : "" - this.scoreDispCount = 0 - this.scoreOpacity = 1 - } - drawScore(){ - if(this.scoreDispCount >= 0 && this.scoreDispCount <= 20){ - this.ctx.globalAlpha = this.scoreOpacity - var scoreIMG = assets.image["score-" + this.currentScore + this.special] - this.ctx.drawImage(scoreIMG, - this.slotX - this.barH / 2, - this.barY + (this.barH - this.lyricsBarH) / 2 - this.barH / 2, - this.barH, - this.barH - ) - this.scoreDispCount++ - if(this.scoreOpacity - 0.1 >= 0 && this.currentScore != 0){ - this.scoreOpacity -= 0.1 - } - }else if(this.scoreDispCount === 21){ - this.scoreDispCount = -1 - } - this.ctx.globalAlpha = 1 - } - posToMs(pos, speed){ - return 140 / this.circleSize * pos / speed - } - msToPos(ms, speed){ - return speed / (140 / this.circleSize) * ms - } drawCircles(circles){ + var distanceForCircle = this.winW / this.ratio - this.slotPos.x + var ms = this.controller.getElapsedTime() + for(var i = circles.length; i--;){ var circle = circles[i] - var ms = this.controller.getElapsedTime() var speed = circle.getSpeed() - var timeForDistance = this.posToMs(this.distanceForCircle + this.bigCircleSize / 2, speed) + var timeForDistance = this.posToMs(distanceForCircle + this.slotPos.size / 2, speed) var startingTime = circle.getMS() - timeForDistance - var finishTime = circle.getEndTime() + this.posToMs(this.slotX - this.taikoSquareW + this.bigCircleSize * 3, speed) + var finishTime = circle.getEndTime() + this.posToMs(this.slotPos.x - this.slotPos.paddingLeft + this.slotPos.size * 2, speed) if(circle.getPlayed() <= 0 || circle.getScore() === 0){ if(ms >= startingTime && ms <= finishTime && circle.getPlayed() !== -1){ this.drawCircle(circle) } }else if(!circle.isAnimated()){ - // Start animation to HP bar + // Start animation to gauge circle.animate(ms) } if(ms >= circle.ms && !circle.gogoChecked){ @@ -507,28 +832,27 @@ class View{ } circle.gogoChecked = true } + } + } + drawAnimatedCircles(circles){ + var ms = this.controller.getElapsedTime() + + for(var i = 0; i < circles.length; i++){ + var circle = circles[i] + if(circle.isAnimated()){ + var animT = circle.getAnimT() - var animationDuration = 400 - if(ms <= animT + animationDuration){ - var curveDistance = this.HPBarX + this.HPBarW - this.slotX - this.HPBarColH / 2 - var animPoint = (ms - animT) / animationDuration - var bezierPoint = this.calcBezierPoint(this.easeOut(animPoint), [{ - x: this.slotX + this.circleSize * 0.4, - y: this.circleY - this.circleSize * 0.8 - }, { - x: this.slotX + curveDistance * 0.15, - y: this.barH * 0.5 - }, { - x: this.slotX + curveDistance * 0.35, - y: 0 - }, { - x: this.slotX + curveDistance, - y: this.HPbarColY + this.HPBarColH / 2 - }]) + if(ms < animT + 490){ + + var animPoint = (ms - animT) / 490 + var bezierPoint = this.calcBezierPoint(this.draw.easeOut(animPoint), this.animateBezier) this.drawCircle(circle, {x: bezierPoint.x, y: bezierPoint.y}) - } - else{ + + }else if(ms < animT + 810){ + var pos = this.animateBezier[3] + this.drawCircle(circle, pos, (ms - animT - 490) / 160) + }else{ circle.endAnimation() } } @@ -536,6 +860,7 @@ class View{ } calcBezierPoint(t, data){ var at = 1 - t + data = data.slice() for(var i = 1; i < data.length; i++){ for(var k = 0; k < data.length - i; k++){ @@ -547,11 +872,14 @@ class View{ } return data[0] } - easeOut(pos){ - return Math.sin(Math.PI / 2 * pos) - } - drawCircle(circle, circlePos){ - var z = this.canvas.scale + drawCircle(circle, circlePos, fade){ + var ctx = this.ctx + var mul = this.slotPos.size / 106 + + var bigCircleSize = 106 * mul / 2 + var circleSize = 70 * mul / 2 + var lyricsSize = 20 * mul + var fill, size, faceID var type = circle.getType() var ms = this.controller.getElapsedTime() @@ -560,54 +888,57 @@ class View{ var animated = circle.isAnimated() var speed = circle.getSpeed() var played = circle.getPlayed() + var drumroll = 0 + var endX = 0 if(!circlePos){ circlePos = { - x: this.slotX + this.msToPos(circleMs - ms, speed), - y: this.circleY + x: this.slotPos.x + this.msToPos(circleMs - ms, speed), + y: this.slotPos.y } } if(animated){ - var currentDonFace = 0 - var currentBigDonFace = 1 + var noteFace = { + small: 0, + big: 3 + } }else{ - var currentDonFace = this.currentDonFace - var currentBigDonFace = this.currentBigDonFace + var noteFace = this.noteFace } if(type === "don" || type === "daiDon" && played === 1){ fill = "#f34728" - size = this.circleSize - faceID = "don-" + currentDonFace + size = circleSize + faceID = noteFace.small }else if(type === "ka" || type === "daiKa" && played === 1){ fill = "#65bdbb" - size = this.circleSize - faceID = "don-" + currentDonFace + size = circleSize + faceID = noteFace.small }else if(type === "daiDon"){ fill = "#f34728" - size = this.bigCircleSize - faceID = "big-don-" + currentBigDonFace + size = bigCircleSize + faceID = noteFace.big }else if(type === "daiKa"){ fill = "#65bdbb" - size = this.bigCircleSize - faceID = "big-don-" + currentBigDonFace + size = bigCircleSize + faceID = noteFace.big }else if(type === "balloon"){ if(animated){ fill = "#f34728" - size = this.bigCircleSize * 0.8 - faceID = "big-don-" + currentBigDonFace + size = bigCircleSize * 0.8 + faceID = noteFace.big }else{ fill = "#f87700" - size = this.circleSize - faceID = "don-" + currentDonFace + size = circleSize + faceID = noteFace.small var h = size * 1.8 if(circleMs < ms && ms <= endTime){ - circlePos.x = this.slotX + circlePos.x = this.slotPos.x }else if(ms > endTime){ - circlePos.x = this.slotX + this.msToPos(endTime - ms, speed) + circlePos.x = this.slotPos.x + this.msToPos(endTime - ms, speed) } - this.ctx.drawImage(assets.image["balloon"], - circlePos.x + size - 3, - circlePos.y - h / 2, + ctx.drawImage(assets.image["balloon"], + circlePos.x + size - 4, + circlePos.y - h / 2 + 2, h / 61 * 115, h ) @@ -615,188 +946,165 @@ class View{ }else if(type === "drumroll" || type === "daiDrumroll"){ fill = "#f3b500" if(type == "drumroll"){ - size = this.circleSize - faceID = "don-" + currentDonFace + size = circleSize + faceID = noteFace.small }else{ - size = this.bigCircleSize - faceID = "big-don-" + currentBigDonFace + size = bigCircleSize + faceID = noteFace.big } - var endX = this.msToPos(endTime - circleMs, speed) - this.ctx.fillStyle = fill - this.ctx.strokeStyle = "#1f1a17" - this.ctx.lineWidth = this.lyricsSize / 10 - this.ctx.beginPath() - this.ctx.moveTo(circlePos.x, circlePos.y - size) - this.ctx.lineTo(circlePos.x + endX, circlePos.y - size) - this.ctx.arc(circlePos.x + endX, circlePos.y, size, -Math.PI / 2, Math.PI / 2) - this.ctx.lineTo(circlePos.x, circlePos.y + size) - this.ctx.fill() - this.ctx.stroke() + endX = this.msToPos(endTime - circleMs, speed) + drumroll = endX > 50 ? 2 : 1 + + ctx.fillStyle = fill + ctx.strokeStyle = "#000" + ctx.lineWidth = 3 + ctx.beginPath() + ctx.moveTo(circlePos.x, circlePos.y - size + 1.5) + ctx.arc(circlePos.x + endX, circlePos.y, size - 1.5, Math.PI / -2, Math.PI / 2) + ctx.lineTo(circlePos.x, circlePos.y + size - 1.5) + ctx.fill() + ctx.stroke() + } + if(!fade || fade < 1){ + // Main circle + ctx.fillStyle = fill + ctx.beginPath() + ctx.arc(circlePos.x, circlePos.y, size - 1, 0, Math.PI * 2) + ctx.fill() + // Face on circle + var drawSize = size + if(faceID < 2){ + drawSize *= bigCircleSize / circleSize + } + ctx.drawImage(assets.image[drumroll ? "notes_drumroll" : "notes"], + 0, 172 * faceID, + 172, 172, + circlePos.x - drawSize - 4, + circlePos.y - drawSize - 4, + drawSize * 2 + 8, + drawSize * 2 + 8 + ) + } + if(fade && !this.touchEnabled){ + ctx.globalAlpha = this.draw.easeOut(fade < 1 ? fade : 2 - fade) + ctx.fillStyle = "#fff" + ctx.beginPath() + ctx.arc(circlePos.x, circlePos.y, size - 1, 0, Math.PI * 2) + ctx.fill() + ctx.globalAlpha = 1 } - // Main circle - this.ctx.fillStyle = fill - this.ctx.beginPath() - this.ctx.arc(circlePos.x, circlePos.y, size, 0, Math.PI * 2) - this.ctx.closePath() - this.ctx.fill() - // Face on circle - this.ctx.drawImage(assets.image[faceID], - circlePos.x - size - 2, - circlePos.y - size - 4, - size * 2 + 5, - size * 2 + 6 - ) if(!circle.isAnimated()){ // Text - this.ctx.font = "normal bold " + this.lyricsSize + "px Kozuka" - this.ctx.textAlign = "center" - this.ctx.strokeStyle = "#000" - this.ctx.lineWidth = this.lyricsSize / 5 - this.ctx.fillStyle = "#fff" - this.strokeFillText(circle.getText(), - circlePos.x, - this.barY + this.barH - this.lyricsBarH * 0.3 - ) - } - } - togglePauseMenu(){ - if(this.controller.game.isPaused()){ - this.pauseMenu.style.display = "block" - this.lastMousemove = this.controller.getElapsedTime() - this.cursorHidden = false - this.mouseIdle() - }else{ - this.pauseMenu.style.display = "" - } - } - drawDifficulty(){ - this.ctx.drawImage(assets.image["muzu_" + this.songDifficulty], - this.diffX, this.diffY, - this.diffW, this.diffH - ) - if(this.controller.autoPlayEnabled && !this.controller.multiplayer){ - this.ctx.drawImage(assets.image["badge_auto"], - this.diffX + this.diffW * 0.71, this.diffY + this.diffH * 0.01, - this.diffH * 0.3, this.diffH * 0.3 - ) - } - this.ctx.drawImage(assets.image.taiko, - this.taikoX, this.taikoY, - this.taikoW, this.taikoH - ) - } - drawTime(){ - var z = this.canvas.scale - var ms = this.controller.getElapsedTime() - var sign = Math.sign(ms) < 0 ? "-" : "" - ms = Math.abs(ms) + (sign === "-" ? 1000 : 0) - var time = { - sec: Math.floor(ms / 1000) % 60, - min: Math.floor(ms / 1000 / 60) % 60, - hour: Math.floor(ms / 1000 / 60 / 60) % 60 - } - - this.ctx.globalAlpha = 0.7 - this.ctx.fillStyle = "#000" - this.ctx.fillRect(this.winW - 110 * z, this.winH - 60 * z, this.winW, this.winH) - - this.ctx.globalAlpha = 1 - this.ctx.fillStyle = "#fff" - - var formatedH = ("0" + time.hour).slice(-2) - var formatedM = ("0" + time.min).slice(-2) - var formatedS = ("0" + time.sec).slice(-2) - - this.ctx.font = "normal " + (this.barH / 12) + "px Kozuka" - this.ctx.textAlign = "right" - this.ctx.fillText(sign + formatedH + ":" + formatedM + ":" + formatedS, - this.winW - 10 * z, this.winH - 30 * z - ) - this.ctx.fillText(sign + Math.floor(ms), this.winW - 10 * z, this.winH - 10 * z) - } - drawBar(){ - this.ctx.strokeStyle = "#000" - this.ctx.fillStyle = "#232323" - this.ctx.lineWidth = 10 - this.ctx.beginPath() - this.ctx.rect(0, this.barY, this.winW, this.barH) - this.ctx.closePath() - this.ctx.fill() - - var ms = this.controller.getElapsedTime() - var keyTime = this.controller.getKeyTime() - var sound = keyTime["don"] > keyTime["ka"] ? "don" : "ka" - if(this.gogoTime || ms <= this.gogoTimeStarted + 100){ - var grd = this.ctx.createLinearGradient(0, this.barY, this.winW, this.barH) - grd.addColorStop(0, "#512a2c") - grd.addColorStop(0.46, "#6f2a2d") - grd.addColorStop(0.76, "#8a4763") - grd.addColorStop(1, "#2c2a2c") - this.ctx.fillStyle = grd - this.ctx.rect(0, this.barY, this.winW, this.barH) - var alpha = Math.min(100, this.controller.getElapsedTime() - this.gogoTimeStarted) / 100 - if(!this.gogoTime){ - alpha = 1 - alpha + var text = circle.getText() + var textX = circlePos.x + var textY = circlePos.y + 83 * mul + ctx.font = lyricsSize + "px Kozuka" + ctx.textBaseline = "middle" + ctx.textAlign = "center" + + if(drumroll === 2){ + var longText = text.split("ー") + text = longText[0] + var text0Width = ctx.measureText(longText[0]).width + var text1Width = ctx.measureText(longText[1]).width } - this.ctx.globalAlpha = alpha - this.ctx.fill() - this.ctx.globalAlpha = 1 - } - if(keyTime[sound] > ms - 200){ - var gradients = { - "don": ["#f54c25", "#232323"], - "ka": ["#75cee9", "#232323"] + + ctx.fillStyle = "#fff" + ctx.strokeStyle = "#000" + ctx.lineWidth = 5 + ctx.strokeText(text, textX, textY) + + if(drumroll === 2){ + ctx.strokeText(longText[1], textX + endX, textY) + + ctx.lineWidth = 4 + var x1 = textX + text0Width / 2 + var x2 = textX + endX - text1Width / 2 + ctx.beginPath() + ctx.moveTo(x1, textY - 2) + ctx.lineTo(x2, textY - 2) + ctx.lineTo(x2, textY + 1) + ctx.lineTo(x1, textY + 1) + ctx.closePath() + ctx.stroke() + ctx.fill() + } + + ctx.strokeStyle = "#fff" + ctx.lineWidth = 0.5 + + ctx.strokeText(text, textX, textY) + ctx.fillText(text, textX, textY) + + if(drumroll){ + ctx.strokeText(longText[1], textX + endX, textY) + ctx.fillText(longText[1], textX + endX, textY) } - var grd = this.ctx.createLinearGradient(0, this.barY, this.winW, this.barH) - grd.addColorStop(0, gradients[sound][0]) - grd.addColorStop(1, gradients[sound][1]) - this.ctx.fillStyle = grd - this.ctx.rect(0, this.barY, this.winW, this.barH) - this.ctx.globalAlpha = 1 - (ms - keyTime[sound]) / 200 - this.ctx.fill() - this.ctx.globalAlpha = 1 } - this.ctx.stroke() - // Lyrics bar - this.ctx.fillStyle = "#888888" - this.ctx.beginPath() - this.ctx.rect(0, this.barY + this.barH - this.lyricsBarH, this.winW, this.lyricsBarH) - this.ctx.closePath() - this.ctx.fill() - this.ctx.stroke() } - drawSlot(){ - // Main circle - this.ctx.fillStyle = "#6f6f6e" - this.ctx.beginPath() - this.ctx.arc(this.slotX, this.circleY, this.circleSize - 0.2 * this.circleSize, 0, 2 * Math.PI) - this.ctx.closePath() - this.ctx.fill() - // Big stroke circle - this.ctx.strokeStyle = "#9e9f9f" - this.ctx.lineWidth = 3 - this.ctx.beginPath() - this.ctx.arc(this.slotX, this.circleY, this.circleSize, 0, 2 * Math.PI) - this.ctx.closePath() - this.ctx.stroke() - // Bigger stroke circle - this.ctx.strokeStyle = "#6f6f6e" - this.ctx.lineWidth = 3 - this.ctx.beginPath() - this.ctx.arc(this.slotX, this.circleY, this.bigCircleSize, 0, 2 * Math.PI) - this.ctx.closePath() - this.ctx.stroke() - } - drawTaikoSquare(){ - // Taiko square - this.ctx.lineWidth = 7 - this.ctx.fillStyle = "#ff3c00" - this.ctx.strokeStyle = "#000" - this.ctx.beginPath() - this.ctx.rect(0,this.barY, this.taikoSquareW,this.barH) - this.ctx.fill() - this.ctx.closePath() - this.ctx.stroke() + fillComboCache(){ + var fontSize = 58 + var letterSpacing = fontSize * 0.67 + var glyphW = 50 + var glyphH = 64 + var textX = 11 + var textY = 5 + var letterBorder = fontSize * 0.15 + + this.comboCache.resize((glyphW + 1) * 20, glyphH + 1, this.ratio) + for(var orange = 0; orange < 2; orange++){ + for(var i = 0; i < 10; i++){ + this.comboCache.set({ + w: glyphW, + h: glyphH, + id: orange + "combo" + i + }, ctx => { + ctx.scale(0.9, 1) + if(orange){ + var grd = ctx.createLinearGradient( + (glyphW - glyphH) / 2, + 0, + (glyphW + glyphH) / 2, + glyphH + ) + grd.addColorStop(0.3, "#ff2000") + grd.addColorStop(0.5, "#ffc321") + grd.addColorStop(0.6, "#ffedb7") + grd.addColorStop(0.8, "#ffffce") + var fill = grd + }else{ + var fill = "#fff" + } + this.draw.layeredText({ + ctx: ctx, + text: i.toString(), + fontSize: fontSize, + fontFamily: this.font, + x: textX, + y: textY + }, [ + {x: -2, y: -1, outline: "#000", letterBorder: letterBorder}, + {x: 3.5, y: 1.5}, + {x: 3, y: 1}, + {}, + {x: -2, y: -1, fill: "#fff"}, + {x: 3.5, y: 1.5, fill: fill}, + {x: 3, y: 1, fill: "rgba(0, 0, 0, 0.5)"}, + {fill: fill} + ]) + }) + } + } + this.globalAlpha = 0 + this.comboCache.get({ + ctx: this.ctx, + x: 0, + y: 0, + w: 54, + h: 77, + id: "combo0" + }) + this.globalAlpha = 1 } toggleGogoTime(circle){ this.gogoTime = circle.gogoTime @@ -823,7 +1131,7 @@ class View{ } } drawGogoTime(){ - var ms = this.controller.getElapsedTime() + var ms = this.getMS() if(this.gogoTime){ var circles = this.controller.parsedSongData.circles @@ -837,7 +1145,9 @@ class View{ } }else{ var animation = this.assets.don.getAnimation() - if(animation === "gogo" || this.controller.getGlobalScore().gauge >= 50 && animation === "normal"){ + var gauge = this.controller.getGlobalScore().gauge + var cleared = Math.round(gauge / 2) - 1 >= 25 + if(animation === "gogo" || cleared && animation === "normal" || !cleared && animation === "clear"){ this.assets.don.normalAnimation() } if(ms >= this.gogoTimeStarted + 100){ @@ -864,12 +1174,38 @@ class View{ don.setAnimationEnd(length, don.normalAnimation) } } + displayScore(score, notPlayed, bigNote){ + if(!notPlayed){ + this.currentScore.ms = this.getMS() + this.currentScore.type = score + this.currentScore.bigNote = bigNote + } + } + posToMs(pos, speed){ + var circleSize = 70 * this.slotPos.size / 106 / 2 + return 140 / circleSize * pos / speed + } + msToPos(ms, speed){ + var circleSize = 70 * this.slotPos.size / 106 / 2 + return speed / (140 / circleSize) * ms + } + togglePauseMenu(){ + if(this.controller.game.isPaused()){ + this.pauseMenu.style.display = "block" + this.lastMousemove = this.controller.getElapsedTime() + this.cursorHidden = false + this.mouseIdle() + }else{ + this.pauseMenu.style.display = "" + } + } drawTouch(){ if(this.touchEnabled){ - var ms = this.controller.getElapsedTime() + var ms = this.getMS() + var mul = this.ratio / this.pixelRatio - var drumWidth = this.touchDrum.w / this.canvas.scale - var drumHeight = this.touchDrum.h / this.canvas.scale + var drumWidth = this.touchDrum.w * mul + var drumHeight = this.touchDrum.h * mul if(drumHeight !== this.touchDrumHeight || drumWidth !== this.touchDrumWidth){ this.touchDrumWidth = drumWidth this.touchDrumHeight = drumHeight @@ -890,9 +1226,8 @@ class View{ ontouch(event){ for(let touch of event.changedTouches){ event.preventDefault() - var scale = this.canvas.scale - var pageX = touch.pageX * scale - var pageY = touch.pageY * scale + var pageX = touch.pageX * this.pixelRatio + var pageY = touch.pageY * this.pixelRatio var c = this.touchCircle var pi = Math.PI @@ -947,17 +1282,17 @@ class View{ this.beatInterval = beatMS this.assets.changeBeatInterval(beatMS) } + getMS(){ + return this.controller.getElapsedTime() + } clean(){ - pageEvents.mouseRemove(this) - if(this.controller.multiplayer === 2){ - if(this.canvas){ - this.canvas.canvas.parentNode.removeChild(this.canvas.canvas) - } - }else{ - this.cursor.parentNode.removeChild(this.cursor) + this.comboCache.clean() + + if(this.multiplayer !== 2){ + pageEvents.remove(window, "resize") } if(this.touchEnabled){ - pageEvents.remove(this.canvas.canvas, "touchstart") + pageEvents.remove(this.canvas, "touchstart") pageEvents.remove(this.touchFullBtn, "touchend") pageEvents.remove(this.touchPauseBtn, "touchend") this.gameDiv.classList.remove("touch-visible") diff --git a/public/src/js/viewassets.js b/public/src/js/viewassets.js index c1af46e..14b26bd 100644 --- a/public/src/js/viewassets.js +++ b/public/src/js/viewassets.js @@ -9,17 +9,17 @@ class ViewAssets{ var imgw = 360 var imgh = 184 var scale = 165 - var w = (this.view.barH * imgw) / scale - var h = (this.view.barH * imgh) / scale + var w = imgw + var h = imgh return { sx: Math.floor(frame / 10) * imgw, - sy: (frame % 10) * imgh, + sy: (frame % 10) * imgh + 1, sw: imgw, - sh: imgh, - x: this.view.taikoSquareW - w + this.view.barH * 0.2, - y: this.view.barY - h, + sh: imgh - 1, + x: view.portrait ? -60 : 0, + y: view.portrait ? (view.multiplayer === 2 ? 560 : 35) : (view.multiplayer === 2 ? 360 : 2), w: w, - h: h + h: h - 1 } }) this.don.addFrames("normal", [ @@ -41,7 +41,7 @@ class ViewAssets{ var length = this.don.getAnimationLength("gogo") this.don.setUpdateSpeed(4 / length) this.don.setAnimation("gogo") - }else if(this.controller.getGlobalScore().gauge >= 50){ + }else if(Math.round(this.controller.getGlobalScore().gauge / 2) - 1 >= 25){ this.don.setAnimationStart(0) var length = this.don.getAnimationLength("clear") this.don.setUpdateSpeed(2 / length) @@ -58,31 +58,31 @@ class ViewAssets{ this.fire = this.createAsset("bar", frame => { var imgw = 360 var imgh = 370 - var scale = 175 - var ms = this.controller.getElapsedTime() + var scale = 130 + var ms = this.view.getMS() var elapsed = ms - this.view.gogoTimeStarted + + var mul = this.view.slotPos.size / 106 + var barH = 130 * mul + if(this.view.gogoTime){ var grow = 3 - Math.min(200, elapsed) / 100 this.ctx.globalAlpha = Math.min(200, elapsed) / 200 }else{ var grow = 1 - Math.min(100, elapsed) / 100 } - var w = (this.view.barH * imgw) / scale * grow - var h = (this.view.barH * imgh) / scale * grow + var w = (barH * imgw) / scale * grow + var h = (barH * imgh) / scale * grow this.ctx.globalCompositeOperation = "lighter" return { sx: frame * imgw, sy: 0, sw: imgw, sh: imgh, - x: this.view.slotX - w / 2, - y: this.view.circleY - h / 2, + x: this.view.slotPos.x - w / 2, + y: this.view.slotPos.y - h / 2, w: w, - h: h, - callback: () => { - this.ctx.globalCompositeOperation = "source-over" - this.ctx.globalAlpha = 1 - } + h: h } }) this.fire.addFrames("normal", 7, "fire_anim") @@ -93,15 +93,17 @@ class ViewAssets{ var imgw = 230 var imgh = 460 var scale = 165 - var w = (this.view.barH * imgw) / scale - var h = (this.view.barH * imgh) / scale + var w = imgw + var h = imgh + var winW = this.view.winW / this.view.ratio + var winH = this.view.winH / this.view.ratio return { sx: Math.floor(frame / 4) * imgw, sy: (frame % 4) * imgh, sw: imgw, sh: imgh, - x: this.view.winW / 4 * i - w / 2 * (i / 2), - y: this.view.winH - h, + x: winW / 4 * i - w / 2 * (i / 2), + y: winH - h, w: w, h: h } @@ -118,13 +120,11 @@ class ViewAssets{ return asset } drawAssets(layer){ - if(this.controller.multiplayer !== 2 || layer === "bar"){ - this.allAssets.forEach(asset => { - if(layer === asset.layer){ - asset.draw() - } - }) - } + this.allAssets.forEach(asset => { + if(layer === asset.layer){ + asset.draw() + } + }) } changeBeatInterval(beatMS, initial){ this.allAssets.forEach(asset => { diff --git a/public/src/views/game.html b/public/src/views/game.html index 2763175..3061e9a 100644 --- a/public/src/views/game.html +++ b/public/src/views/game.html @@ -1,5 +1,4 @@
-

diff --git a/templates/index.html b/templates/index.html index b733fa0..df040f1 100644 --- a/templates/index.html +++ b/templates/index.html @@ -39,8 +39,6 @@ - -