diff --git a/public/index.html b/public/index.html
index 742ea9a..dc78b49 100644
--- a/public/index.html
+++ b/public/index.html
@@ -14,7 +14,7 @@
太鼓の達人ウェブ - Taiko no Tatsujin Web
-
+
diff --git a/public/src/css/game.css b/public/src/css/game.css
index 8416bbe..7853dc4 100644
--- a/public/src/css/game.css
+++ b/public/src/css/game.css
@@ -51,3 +51,62 @@
pointer-events: none;
z-index: 1;
}
+#touch-bg{
+ display: none;
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ height: 50%;
+ background: url(/assets/img/touch_bg.png) center bottom;
+ background-size: cover;
+ overflow: hidden;
+}
+#touch-bg-blue{
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background: url(/assets/img/touch_bg_blue.png) center bottom;
+ background-size: cover;
+ opacity: 0;
+}
+#touch-drum{
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ text-align: center;
+ margin: auto;
+}
+#touch-drum img{
+ width: 100%;
+}
+#touch-buttons{
+ display: none;
+ position: absolute;
+ top: 7vh;
+ right: 2vh;
+ opacity: 0.5;
+ z-index: 5;
+}
+#touch-buttons img{
+ width: 12vh;
+}
+.touch-visible #touch-bg,
+.touch-visible #touch-buttons{
+ display: block;
+}
+.touch-visible .window{
+ width: 80vmin;
+ height: 53vmin;
+}
+.touch-visible #pause-menu .window button{
+ font-size: 5vmin;
+}
+.touch-visible #pause-menu .window button.selected{
+ color: #000;
+ background: #fff;
+ border-color: #ae7a26;
+}
diff --git a/public/src/js/assets.js b/public/src/js/assets.js
index 6f1c873..2ec1a5d 100644
--- a/public/src/js/assets.js
+++ b/public/src/js/assets.js
@@ -39,7 +39,12 @@ var assets = {
"bg_genre_7.png",
"bg_score_p1.png",
"bg_score_p2.png",
- "badge_auto.png"
+ "badge_auto.png",
+ "touch_bg.png",
+ "touch_bg_blue.png",
+ "touch_drum.png",
+ "touch_pause.png",
+ "touch_fullscreen.png"
],
"audioSfx": [
"don.wav",
diff --git a/public/src/js/controller.js b/public/src/js/controller.js
index da8ec3c..4e013db 100644
--- a/public/src/js/controller.js
+++ b/public/src/js/controller.js
@@ -1,9 +1,10 @@
class Controller{
- constructor(selectedSong, songData, autoPlayEnabled, multiplayer){
+ constructor(selectedSong, songData, autoPlayEnabled, multiplayer, touchEnabled){
this.selectedSong = selectedSong
this.songData = songData
this.autoPlayEnabled = autoPlayEnabled
this.multiplayer = multiplayer
+ this.touchEnabled = touchEnabled
this.snd = this.multiplayer ? "_p" + this.multiplayer : ""
var backgroundURL = "/songs/" + this.selectedSong.folder + "/bg.png"
@@ -202,6 +203,9 @@ class Controller{
}
}
clean(){
+ if(this.syncWith){
+ this.syncWith.clean()
+ }
this.stopMainLoop()
this.keyboard.clean()
this.view.clean()
diff --git a/public/src/js/game.js b/public/src/js/game.js
index 5498ac9..1b0d657 100644
--- a/public/src/js/game.js
+++ b/public/src/js/game.js
@@ -289,10 +289,10 @@ class Game{
this.controller.displayResults()
this.musicFadeOut++
}else if(this.musicFadeOut === 3 && (ms >= started + 9600 && ms >= this.controller.mainAsset.duration * 1000 + 1250)){
+ this.controller.clean()
if(this.controller.scoresheet){
this.controller.scoresheet.startRedraw()
}
- this.controller.clean()
}
}
}
diff --git a/public/src/js/keyboard.js b/public/src/js/keyboard.js
index 67f6494..30871d1 100644
--- a/public/src/js/keyboard.js
+++ b/public/src/js/keyboard.js
@@ -79,11 +79,12 @@ class Keyboard{
this.setKey(keyCode, false)
}
})
+ }else{
+ this.checkKeySound(this.kbd["don_l"], "don")
+ this.checkKeySound(this.kbd["don_r"], "don")
+ this.checkKeySound(this.kbd["ka_l"], "ka")
+ this.checkKeySound(this.kbd["ka_r"], "ka")
}
- this.checkKeySound(this.kbd["don_l"], "don")
- this.checkKeySound(this.kbd["don_r"], "don")
- this.checkKeySound(this.kbd["ka_l"], "ka")
- this.checkKeySound(this.kbd["ka_r"], "ka")
}
checkMenuKeys(){
if(!this.controller.multiplayer){
@@ -171,7 +172,7 @@ class Keyboard{
var circles = this.controller.getCircles()
var circle = circles[this.controller.getCurrentCircle()]
if(
- (keyCode === this.kbd["don_l"] || keyCode === this.kbd["don_r"])
+ sound === "don"
&& circle
&& !circle.getPlayed()
&& circle.getType() === "balloon"
@@ -191,6 +192,11 @@ class Keyboard{
if(down){
this.keys[keyCode] = true
this.keyTime[keyCode] = ms
+ if(keyCode == this.kbd.don_l || keyCode == this.kbd.don_r){
+ this.checkKeySound(keyCode, "don")
+ }else if(keyCode == this.kbd.ka_l || keyCode == this.kbd.ka_r){
+ this.checkKeySound(keyCode, "ka")
+ }
}else{
this.keys[keyCode] = false
this.waitKeyupScore[keyCode] = false
diff --git a/public/src/js/loadsong.js b/public/src/js/loadsong.js
index 0d58857..3ae4ebf 100644
--- a/public/src/js/loadsong.js
+++ b/public/src/js/loadsong.js
@@ -1,8 +1,9 @@
class loadSong{
- constructor(selectedSong, autoPlayEnabled, multiplayer){
+ constructor(selectedSong, autoPlayEnabled, multiplayer, touchEnabled){
this.selectedSong = selectedSong
- this.multiplayer = multiplayer
this.autoPlayEnabled = autoPlayEnabled
+ this.multiplayer = multiplayer
+ this.touchEnabled = touchEnabled
loader.changePage("loadsong")
this.run()
}
@@ -81,7 +82,7 @@ class loadSong{
}else if(event.type === "gamestart"){
this.clean()
loader.changePage("game")
- var taikoGame1 = new Controller(this.selectedSong, this.songData, false, 1)
+ var taikoGame1 = new Controller(this.selectedSong, this.songData, false, 1, this.touchEnabled)
var taikoGame2 = new Controller(this.selectedSong2, this.song2Data, true, 2)
taikoGame1.run(taikoGame2)
}
@@ -93,7 +94,7 @@ class loadSong{
}else{
this.clean()
loader.changePage("game")
- var taikoGame = new Controller(this.selectedSong, this.songData, this.autoPlayEnabled)
+ var taikoGame = new Controller(this.selectedSong, this.songData, this.autoPlayEnabled, false, this.touchEnabled)
taikoGame.run()
}
}
diff --git a/public/src/js/scoresheet.js b/public/src/js/scoresheet.js
index 8acd94c..5c2c7e4 100644
--- a/public/src/js/scoresheet.js
+++ b/public/src/js/scoresheet.js
@@ -29,8 +29,6 @@ class Scoresheet{
this.redrawRunning = true
this.redrawBind = this.redraw.bind(this)
this.redraw()
- pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this))
- pageEvents.add(this.canvas, "mousedown", this.mouseDown.bind(this))
assets.sounds["results"].play()
assets.sounds["bgm_result"].playLoop(3, false, 0, 0.847, 17.689)
@@ -56,7 +54,11 @@ class Scoresheet{
}
}
mouseDown(event){
- if(event.which !== 1){
+ if(event.type === "touchstart"){
+ event.preventDefault()
+ this.canvas.style.cursor = ""
+ this.state.pointerLocked = true
+ }else if(event.which !== 1){
return
}
this.toNext()
@@ -81,6 +83,10 @@ class Scoresheet{
requestAnimationFrame(this.redrawBind)
this.winW = null
this.winH = null
+
+ pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this))
+ pageEvents.add(this.canvas, "mousedown", this.mouseDown.bind(this))
+ pageEvents.add(this.canvas, "touchstart", this.mouseDown.bind(this))
}
redraw(){
@@ -218,7 +224,9 @@ class Scoresheet{
if(elapsed >= 0){
if(this.state.hasPointer === 0){
this.state.hasPointer = 1
- this.canvas.style.cursor = "pointer"
+ if(!this.state.pointerLocked){
+ this.canvas.style.cursor = "pointer"
+ }
}
ctx.save()
ctx.setTransform(1, 0, 0, 1, 0, 0)
@@ -643,6 +651,7 @@ class Scoresheet{
this.redrawRunning = false
pageEvents.keyRemove(this, "all")
pageEvents.remove(this.canvas, "mousedown")
+ pageEvents.remove(this.canvas, "touchstart")
delete this.ctx
delete this.canvas
}
diff --git a/public/src/js/songselect.js b/public/src/js/songselect.js
index 75dbfe1..33a0f83 100644
--- a/public/src/js/songselect.js
+++ b/public/src/js/songselect.js
@@ -197,6 +197,7 @@ class SongSelect{
pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this))
pageEvents.add(this.canvas, "mousemove", this.mouseMove.bind(this))
pageEvents.add(this.canvas, "mousedown", this.mouseDown.bind(this))
+ pageEvents.add(this.canvas, "touchstart", this.mouseDown.bind(this))
}
keyDown(event, code){
@@ -256,10 +257,21 @@ class SongSelect{
}
mouseDown(event){
- if(event.which !== 1){
- return
+ if(event.type === "mousedown"){
+ if(event.which !== 1){
+ return
+ }
+ var mouse = this.mouseOffset(event.offsetX, event.offsetY)
+ var shift = event.shiftKey
+ var ctrl = event.ctrlKey
+ var touch = false
+ }else{
+ event.preventDefault()
+ var mouse = this.mouseOffset(event.touches[0].pageX, event.touches[0].pageY)
+ var shift = false
+ var ctrl = false
+ var touch = true
}
- var mouse = this.mouseOffset(event)
if(this.state.screen === "song"){
var moveBy = this.songSelMouse(mouse.x, mouse.y)
if(moveBy === 0){
@@ -276,12 +288,12 @@ class SongSelect{
){
this.toSongSelect()
}else if(moveBy !== null){
- this.toLoadSong(moveBy - 1, event.shiftKey, event.ctrlKey)
+ this.toLoadSong(moveBy - 1, shift, ctrl, touch)
}
}
}
mouseMove(event){
- var mouse = this.mouseOffset(event)
+ var mouse = this.mouseOffset(event.offsetX, event.offsetY)
var moveTo = null
if(this.state.screen === "song"){
var moveTo = this.songSelMouse(mouse.x, mouse.y)
@@ -298,10 +310,10 @@ class SongSelect{
}
this.pointer(moveTo !== null)
}
- mouseOffset(event){
+ mouseOffset(offsetX, offsetY){
return {
- x: (event.offsetX * this.pixelRatio - this.winW / 2) / this.ratio + 1024 / 2,
- y: (event.offsetY * this.pixelRatio - this.winH / 2) / this.ratio + 720 / 2
+ x: (offsetX * this.pixelRatio - this.winW / 2) / this.ratio + 1024 / 2,
+ y: (offsetY * this.pixelRatio - this.winH / 2) / this.ratio + 720 / 2
}
}
pointer(enabled){
@@ -425,7 +437,7 @@ class SongSelect{
assets.sounds["cancel"].play()
}
}
- toLoadSong(difficulty, shift, ctrl){
+ toLoadSong(difficulty, shift, ctrl, touch){
this.clean()
var selectedSong = this.songs[this.selectedSong]
assets.sounds["diffsel"].stop()
@@ -439,7 +451,7 @@ class SongSelect{
"folder": selectedSong.id,
"difficulty": this.difficultyId[difficulty],
"category": selectedSong.category
- }, shift, ctrl)
+ }, shift, ctrl, touch)
}
toTitleScreen(){
assets.sounds["cancel"].play()
diff --git a/public/src/js/titlescreen.js b/public/src/js/titlescreen.js
index 905d8d4..d5cdfa9 100644
--- a/public/src/js/titlescreen.js
+++ b/public/src/js/titlescreen.js
@@ -3,7 +3,8 @@ class Titlescreen{
loader.changePage("titlescreen")
this.titleScreen = document.getElementById("title-screen")
pageEvents.keyOnce(this, 13, "down").then(this.onPressed.bind(this))
- pageEvents.once(this.titleScreen, "click").then(this.onPressed.bind(this))
+ pageEvents.once(this.titleScreen, "mousedown").then(this.onPressed.bind(this))
+ pageEvents.once(this.titleScreen, "touchstart").then(this.onPressed.bind(this))
assets.sounds["title"].play()
this.gamepad = new Gamepad({
"start": ["b", "x", "y", "start"],
@@ -15,6 +16,7 @@ class Titlescreen{
})
}
onPressed(){
+ this.titleScreen.style.cursor = "auto"
this.clean()
assets.sounds["don"].play()
setTimeout(this.goNext.bind(this), 500)
@@ -22,7 +24,7 @@ class Titlescreen{
goNext(){
if(localStorage.getItem("tutorial") !== "true"){
new Tutorial()
- } else {
+ }else{
new SongSelect()
}
}
@@ -30,7 +32,8 @@ class Titlescreen{
this.gamepad.clean()
assets.sounds["title"].stop()
pageEvents.keyRemove(this, 13)
- pageEvents.remove(this.titleScreen, "click")
+ pageEvents.remove(this.titleScreen, "mousedown")
+ pageEvents.remove(this.titleScreen, "touchstart")
delete this.titleScreen
}
}
diff --git a/public/src/js/view.js b/public/src/js/view.js
index cdba97b..22e5aec 100644
--- a/public/src/js/view.js
+++ b/public/src/js/view.js
@@ -7,6 +7,7 @@ class View{
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
@@ -14,7 +15,7 @@ class View{
this.canvas = new ScalableCanvas("canvas-p2", docW, docH / 3 * 2)
this.canvas.canvas.style.position = "absolute"
this.canvas.canvas.style.top = "33%"
- document.getElementById("game").appendChild(this.canvas.canvas)
+ this.gameDiv.appendChild(this.canvas.canvas)
}else{
this.canvas = new ScalableCanvas("canvas", docW, docH)
}
@@ -49,6 +50,39 @@ class View{
this.beatInterval = this.controller.getSongData().beatInfo.beatInterval
this.assets = new ViewAssets(this)
+
+ this.touch = {
+ don_l: -Infinity,
+ don_r: -Infinity,
+ don_c: -Infinity,
+ ka_l: -Infinity,
+ ka_r: -Infinity,
+ ka_c: -Infinity,
+ cursor: {
+ ms: -Infinity,
+ x: 0,
+ y: 0
+ }
+ }
+
+ if(this.controller.touchEnabled){
+ this.touchEnabled = true
+
+ this.touchBgDiv = document.getElementById("touch-bg")
+ this.touchBgBlueDiv = document.getElementById("touch-bg-blue")
+ this.touchDrumDiv = document.getElementById("touch-drum")
+ this.gameDiv.classList.add("touch-visible")
+
+ pageEvents.add(this.canvas.canvas, "touchstart", this.ontouch.bind(this))
+
+ this.touchFullBtn = document.getElementById("touch-full-btn")
+ pageEvents.add(this.touchFullBtn, "click", this.toggleFullscreen)
+
+ this.touchPauseBtn = document.getElementById("touch-pause-btn")
+ pageEvents.add(this.touchPauseBtn, "click", () => {
+ this.controller.togglePauseMenu()
+ })
+ }
}
run(){
this.ctx.font = "normal 14pt TnT"
@@ -133,6 +167,37 @@ class View{
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 = (() => {
+ var padTop = this.touchDrum.h * 0.062
+ var padLeft = this.touchDrum.h * 0.05
+ return {
+ x: this.winW / 2,
+ y: this.winH + padTop,
+ rx: this.touchDrum.w / 2 - padLeft * 2,
+ ry: this.touchDrum.h
+ }
+ })()
}
refresh(){
this.positionning()
@@ -158,7 +223,10 @@ class View{
this.updateDonFaces()
this.drawGogoTime()
this.mouseIdle()
- this.assets.drawAssets("foreground")
+ if(!this.touchEnabled){
+ this.assets.drawAssets("foreground")
+ }
+ this.drawTouch()
//this.drawTime()
}
updateDonFaces(){
@@ -809,6 +877,147 @@ class View{
don.setAnimationEnd(ms + length * don.speed, don.normalAnimation)
}
}
+ drawTouch(){
+ if(this.touchEnabled){
+ var ms = this.controller.getElapsedTime()
+ this.ctx.save()
+
+ var bgHeight = (this.winH - (this.barY + this.barH + 5)) / this.canvas.scale
+ if(bgHeight !== this.touchBgHeight){
+ this.touchBgHeight = bgHeight
+ this.touchBgDiv.style.height = bgHeight + "px"
+ }
+ var drumWidth = this.touchDrum.w / this.canvas.scale
+ var drumHeight = this.touchDrum.h / this.canvas.scale
+ if(drumHeight !== this.touchDrumHeight || drumWidth !== this.touchDrumWidth){
+ this.touchDrumWidth = drumWidth
+ this.touchDrumHeight = drumHeight
+ this.touchDrumDiv.style.width = drumWidth + "px"
+ this.touchDrumDiv.style.height = drumHeight + "px"
+ }
+
+ var lastKa = this.touch.ka_l > this.touch.ka_r ? this.touch.ka_l : this.touch.ka_r
+ if(ms < lastKa + 150){
+ if(!this.blueBgShown){
+ this.blueBgShown = true
+ this.touchBgBlueDiv.style.opacity = 0.5
+ }
+ }else if(this.blueBgShown){
+ this.blueBgShown = false
+ this.touchBgBlueDiv.style.opacity = 0
+ }
+
+ var c = this.touchCircle
+ var pi = Math.PI
+ var lastDon = this.touch.don_l > this.touch.don_r ? this.touch.don_l : this.touch.don_r
+ if(lastDon > ms - 150){
+ this.ctx.fillStyle = "rgba(239, 86, 51, 0.5)"
+ this.ctx.beginPath()
+ this.ctx.ellipse(c.x, c.y, c.rx * 0.9, c.ry * 0.9, 0, pi, 0)
+ this.ctx.fill()
+ }
+ if(this.touch.don_c > ms - 150){
+ this.ctx.beginPath()
+ this.ctx.ellipse(c.x, c.y, c.rx * 0.6, c.ry * 0.6, 0, pi, 0)
+ this.ctx.fill()
+ }
+ if(this.touch.ka_c > ms - 150){
+ this.ctx.fillStyle = "rgba(33, 191, 211, 0.5)"
+ this.ctx.beginPath()
+ this.ctx.ellipse(c.x, c.y, c.rx * 1.3, c.ry * 1.3, 0, pi, 0)
+ this.ctx.ellipse(c.x, c.y, c.rx * 0.9, c.ry * 0.9, 0, 0, pi, true)
+ this.ctx.fill()
+ }
+
+ this.ctx.restore()
+ }
+ }
+ ontouch(event){
+ for(let touch of event.touches){
+ event.preventDefault()
+ var scale = this.canvas.scale
+ var pageX = touch.pageX * scale
+ var pageY = touch.pageY * scale
+
+ this.touch.cursor = {
+ ms: this.controller.getElapsedTime(),
+ x: pageX,
+ y: pageY
+ }
+
+ var c = this.touchCircle
+ var pi = Math.PI
+ var inPath = () => this.ctx.isPointInPath(pageX, pageY)
+
+ this.ctx.beginPath()
+ this.ctx.ellipse(c.x, c.y, c.rx * 0.6, c.ry * 0.6, 0, pi, 0)
+
+ if(inPath()){
+ this.touchNote("don_c")
+ }else{
+ this.ctx.beginPath()
+ this.ctx.ellipse(c.x, c.y, c.rx * 0.9, c.ry * 0.9, 0, pi, 0)
+
+ if(inPath()){
+ if(pageX < this.winW / 2){
+ this.touchNote("don_l")
+ }else{
+ this.touchNote("don_r")
+ }
+ }else{
+
+ this.ctx.beginPath()
+ this.ctx.ellipse(c.x, c.y, c.rx * 1.3, c.ry * 1.3, 0, pi, 0)
+
+ if(inPath()){
+ this.touchNote("ka_c")
+ }else if(pageX < this.winW / 2){
+ this.touchNote("ka_l")
+ }else{
+ this.touchNote("ka_r")
+ }
+ }
+ }
+ }
+ }
+ touchNote(note){
+ var keyboard = this.controller.keyboard
+ var kbd = keyboard.getBindings()
+ var ms = this.controller.game.getAccurateTime()
+ this.touch[note] = ms
+ if(note === "don_c"){
+ this.touchNote("don_l")
+ this.touchNote("don_r")
+ }else if(note === "ka_c"){
+ this.touchNote("ka_l")
+ this.touchNote("ka_r")
+ }else{
+ keyboard.setKey(kbd[note], false)
+ keyboard.setKey(kbd[note], true, ms)
+ }
+ }
+ toggleFullscreen(){
+ var root = document.documentElement
+ if("requestFullscreen" in root){
+ if(document.fullscreenElement){
+ document.exitFullscreen()
+ }else{
+ root.requestFullscreen()
+ }
+ }else if("webkitRequestFullscreen" in root){
+ if(document.webkitFullscreenElement){
+ document.webkitExitFullscreen()
+ }else{
+ root.webkitRequestFullscreen()
+ }
+ }else if("mozRequestFullScreen" in root){
+ if(document.mozFullScreenElement){
+ document.mozCancelFullScreen()
+ }else{
+ root.mozRequestFullScreen()
+ }
+ }
+ }
onmousemove(event){
this.lastMousemove = this.controller.getElapsedTime()
this.cursorHidden = false
@@ -832,10 +1041,22 @@ class View{
pageEvents.mouseRemove(this)
if(this.controller.multiplayer === 2){
this.canvas.canvas.parentNode.removeChild(this.canvas.canvas)
+ }else{
+ this.cursor.parentNode.removeChild(this.cursor)
+ }
+ if(this.touchEnabled){
+ pageEvents.remove(this.canvas.canvas, "touchstart")
+ pageEvents.remove(this.touchFullBtn, "click")
+ pageEvents.remove(this.touchPauseBtn, "click")
+ this.gameDiv.classList.remove("touch-visible")
+ delete this.touchBgDiv
+ delete this.touchFullBtn
+ delete this.touchPauseBtn
+ delete this.touchBgBlueDiv
}
- this.cursor.parentNode.removeChild(this.cursor)
delete this.pauseMenu
delete this.cursor
+ delete this.gameDiv
delete this.canvas
delete this.ctx
}
diff --git a/public/src/views/game.html b/public/src/views/game.html
index fe5ef6f..c6e44e8 100644
--- a/public/src/views/game.html
+++ b/public/src/views/game.html
@@ -1,5 +1,11 @@
+
+
+
+
+
+
+