diff --git a/public/index.html b/public/index.html
index 44beb4f..b34e7a9 100644
--- a/public/index.html
+++ b/public/index.html
@@ -10,10 +10,11 @@
-
+
太鼓の達人ウェブ - Taiko no Tatsujin Web
+
@@ -46,6 +47,7 @@
+
diff --git a/public/src/js/circle.js b/public/src/js/circle.js
index 84039d0..4ca8b9b 100644
--- a/public/src/js/circle.js
+++ b/public/src/js/circle.js
@@ -6,14 +6,13 @@ class Circle{
this.type = config.type
this.text = config.txt
this.speed = config.speed
- this.endTime = config.endTime || this.ms + 150
+ this.endTime = config.endTime || this.ms
this.isPlayed = 0
this.animating = false
this.animT = 0
this.score = 0
this.lastFrame = this.ms + 100
this.animationEnded = false
- this.status = -1
this.timesHit = 0
this.requiredHits = config.requiredHits || 0
this.rendaPlayed = false
@@ -47,12 +46,6 @@ class Circle{
incAnimT(){
this.animT += 0.05
}
- updateStatus(status){
- this.status = status
- }
- getStatus(){
- return this.status
- }
getPlayed(){
return this.isPlayed
}
@@ -64,7 +57,7 @@ class Circle{
}
played(score, big){
this.score = score
- this.isPlayed = big ? 2 : 1
+ this.isPlayed = score <= 0 ? score - 1 : (big ? 2 : 1)
}
hit(){
this.timesHit++
diff --git a/public/src/js/controller.js b/public/src/js/controller.js
index 43cb03a..e276f9d 100644
--- a/public/src/js/controller.js
+++ b/public/src/js/controller.js
@@ -80,7 +80,10 @@ class Controller{
})
}
var ms = this.game.getElapsedTime().ms
+
if(!this.game.isPaused()){
+ this.keyboard.checkGameKeys()
+
if(ms >= 0 && !this.mainLoopStarted){
this.mainLoopStarted = true
}
@@ -95,7 +98,6 @@ class Controller{
this.game.playMainMusic()
}
this.view.refresh()
- this.keyboard.checkGameKeys()
}
this.keyboard.checkMenuKeys()
}
@@ -156,8 +158,8 @@ class Controller{
getKeys(){
return this.keyboard.getKeys()
}
- setKey(keyCode, down){
- return this.keyboard.setKey(keyCode, down)
+ setKey(keyCode, down, ms){
+ return this.keyboard.setKey(keyCode, down, ms)
}
getBindings(){
return this.keyboard.getBindings()
diff --git a/public/src/js/game.js b/public/src/js/game.js
index 0be543e..d208b1e 100644
--- a/public/src/js/game.js
+++ b/public/src/js/game.js
@@ -28,6 +28,8 @@ class Game{
this.fadeOutStarted = false
this.currentTimingPoint = 0
this.offsetTime = 0
+ this.rules = new GameRules(this)
+
assets.songs.forEach(song => {
if(song.id == selectedSong.folder){
this.mainAsset = song.sound
@@ -64,45 +66,33 @@ class Game{
var circles = this.songData.circles
circles.forEach(circle => {
if(!circle.getPlayed()){
- var currentTime = this.getElapsedTime().ms
- var startingTime = circle.getMS() - this.timeForDistanceCircle
- // At circle.getMS(), the circle fits the slot
- var hitTime = circle.getMS()
- var endTime = circle.getEndTime()
+ var ms = this.getElapsedTime().ms
var type = circle.getType()
var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll"
+ var endTime = circle.getEndTime() + (drumrollNotes ? 0 : this.rules.bad)
- if(currentTime >= startingTime && currentTime <= endTime){
-
- if(currentTime>= hitTime - 50 && currentTime < hitTime - 30){
- circle.updateStatus(0)
- }else if(currentTime >= hitTime - 30 && currentTime < hitTime){
- circle.updateStatus(230)
- }else if(currentTime >= hitTime && currentTime < endTime){
- circle.updateStatus(450)
- if(drumrollNotes && !circle.rendaPlayed){
- circle.rendaPlayed = true
- if(this.controller.selectedSong.difficulty === "easy"){
- assets.sounds["renda"].stop()
- assets.sounds["renda"].play()
- }
+ if(ms >= circle.getMS()){
+ if(drumrollNotes && !circle.rendaPlayed){
+ circle.rendaPlayed = true
+ if(this.rules.difficulty === "easy"){
+ assets.sounds["renda"].stop()
+ assets.sounds["renda"].play()
}
}
- }else if(currentTime > endTime){
+ }
+ if(ms > endTime){
if(!this.controller.autoPlayEnabled){
if(drumrollNotes){
- circle.updateStatus(-1)
- circle.played(0, false)
+ circle.played(-1, false)
this.updateCurrentCircle()
if(this.controller.multiplayer === 1){
p2.send("drumroll", {
- pace: (this.getElapsedTime().ms - circle.getMS()) / circle.timesHit
+ pace: (ms - circle.getMS()) / circle.timesHit
})
}
}else{
- circle.updateStatus(-1)
var currentScore = 0
- circle.played(currentScore, type === "daiDon" || type === "daiKa")
+ circle.played(-1, type === "daiDon" || type === "daiKa")
this.controller.displayScore(currentScore, true)
this.updateCurrentCircle()
this.updateCombo(currentScore)
@@ -152,7 +142,7 @@ class Game{
}
}
checkKey(keyCodes, circle, check){
- if(circle && !circle.getPlayed() && circle.getStatus() != -1){
+ if(circle && !circle.getPlayed()){
if(!this.checkScore(circle, check)){
return
}
@@ -172,18 +162,33 @@ class Game{
var typeKa = type === "ka" || type === "daiKa"
var typeDai = type === "daiDon" || type === "daiKa"
+ var keyTime = this.controller.getKeyTime()
+ var currentTime = keysDon ? keyTime["don"] : keyTime["ka"]
+ var relative = currentTime - circle.getMS()
+
if(typeDon || typeKa){
+ if(-this.rules.bad >= relative || relative >= this.rules.bad){
+ return true
+ }
var score = 0
if(keysDon && typeDon || keysKa && typeKa){
if(typeDai && !keyDai){
if(!circle.daiFailed){
circle.daiFailed = ms
return false
- }else if(ms < circle.daiFailed + 2000 / 60){
+ }else if(ms < circle.daiFailed + this.rules.daiLeniency){
return false
}
}
- var circleStatus = circle.getStatus()
+ var circleStatus = -1
+ relative = Math.abs(relative)
+ if(relative < this.rules.good){
+ circleStatus = 450
+ }else if(relative < this.rules.ok){
+ circleStatus = 230
+ }else if(relative < this.rules.bad){
+ circleStatus = 0
+ }
if(circleStatus === 230 || circleStatus === 450){
score = circleStatus
}
@@ -198,19 +203,24 @@ class Game{
if(this.controller.multiplayer == 1){
p2.send("note", {
score: score,
- ms: circle.getMS() - ms,
+ ms: circle.getMS() - currentTime,
dai: typeDai ? keyDai ? 2 : 1 : 0
})
}
- }else if(keysDon && type == "balloon"){
- this.checkBalloon(circle)
- if(check === "daiDon" && !circle.getPlayed()){
- this.checkBalloon(circle)
+ }else{
+ if(circle.getMS() > currentTime || currentTime > circle.getEndTime()){
+ return true
}
- }else if((keysDon || keysKa) && (type === "drumroll" || type === "daiDrumroll")){
- this.checkDrumroll(circle)
- if(keyDai){
+ if(keysDon && type === "balloon"){
+ this.checkBalloon(circle)
+ if(check === "daiDon" && !circle.getPlayed()){
+ this.checkBalloon(circle)
+ }
+ }else if((keysDon || keysKa) && (type === "drumroll" || type === "daiDrumroll")){
this.checkDrumroll(circle)
+ if(keyDai){
+ this.checkDrumroll(circle)
+ }
}
}
return true
@@ -261,7 +271,7 @@ class Game{
var circles = this.songData.circles
var lastCircle = circles[circles.length - 1]
var ms = this.getElapsedTime().ms
- if(!this.fadeOutStarted && ms >= lastCircle.getEndTime() + 1900){
+ if(!this.fadeOutStarted && ms >= lastCircle.getEndTime() + 2000){
this.fadeOutStarted = ms
}
}
@@ -329,17 +339,21 @@ class Game{
}
updateTime(){
// Refreshed date
- this.currentDate = new Date()
+ var currentDate = new Date()
var ms = this.getElapsedTime().ms
if(ms >= 0 && !this.started){
this.startDate = new Date()
this.elapsedTimeSincePause = 0
- this.setElapsedTime(this.currentDate.getTime() - this.startDate.getTime())
+ this.setElapsedTime(this.getAccurateTime())
this.started = true
}else if(ms < 0 || ms >= 0 && this.started){
- this.setElapsedTime(this.currentDate.getTime() - this.startDate.getTime() - this.elapsedTimeSincePause)
+ this.setElapsedTime(this.getAccurateTime())
}
}
+ getAccurateTime(){
+ var currentDate = new Date()
+ return currentDate.getTime() - this.startDate.getTime() - this.elapsedTimeSincePause
+ }
getCircles(){
return this.songData.circles
}
diff --git a/public/src/js/gamepad.js b/public/src/js/gamepad.js
index 35b634b..ceb0a98 100644
--- a/public/src/js/gamepad.js
+++ b/public/src/js/gamepad.js
@@ -1,5 +1,8 @@
class Gamepad{
constructor(keyboard){
+ this.keyboard = keyboard
+ this.game = this.keyboard.controller.game
+
var kbd = keyboard.getBindings()
this.gameBtn = {}
this.gameBtn[kbd["don_l"]] = ["u", "d", "l", "r"]
@@ -28,9 +31,9 @@ class Gamepad{
"guide": 16
}
this.btn = {}
- this.keyboard = keyboard
}
play(menuPlay){
+ var ms = this.game.getAccurateTime()
if("getGamepads" in navigator){
var gamepads = navigator.getGamepads()
}else{
@@ -48,7 +51,7 @@ class Gamepad{
for(var bind in bindings){
for(var name in bindings[bind]){
if(btnName === this.b[bindings[bind][name]]){
- this.checkButton(gamepads, btnName, bind)
+ this.checkButton(gamepads, btnName, bind, ms)
break buttonSearch
}
}
@@ -59,8 +62,9 @@ class Gamepad{
}
}
}
- checkButton(gamepads, btnName, keyCode){
+ checkButton(gamepads, btnName, keyCode, ms){
var button = false
+
for(var i = 0; i < gamepads.length; i++){
if(gamepads[i]){
var btn = gamepads[i].buttons[btnName]
@@ -72,19 +76,24 @@ class Gamepad{
}
}
}
+
+ var keys = this.keyboard.getKeys()
var pressed = !this.btn[btnName] && button
var released = this.btn[btnName] && !button
+
if(pressed){
this.btn[btnName] = true
}else if(released){
delete this.btn[btnName]
}
+
if(pressed){
- if(this.keyboard.getKeys()[keyCode]){
+ if(keys[keyCode]){
this.keyboard.setKey(keyCode, false)
}
- this.keyboard.setKey(keyCode, true)
- }else if(!button && this.keyboard.getKeys()[keyCode]){
+ this.keyboard.setKey(keyCode, true, ms)
+
+ }else if(!button && keys[keyCode]){
if(released){
this.toRelease[keyCode + "released"] = true
}
diff --git a/public/src/js/gamerules.js b/public/src/js/gamerules.js
new file mode 100644
index 0000000..95dd6b3
--- /dev/null
+++ b/public/src/js/gamerules.js
@@ -0,0 +1,23 @@
+class GameRules{
+ constructor(game){
+ this.difficulty = game.controller.selectedSong.difficulty
+ var frame = 1000 / 60
+
+ switch(this.difficulty){
+ case "easy":
+ case "normal":
+ this.good = 5 / 2 * frame
+ this.ok = 13 / 2 * frame
+ this.bad = 15 / 2 * frame
+ break
+ case "hard":
+ case "oni":
+ this.good = 3 / 2 * frame
+ this.ok = 9 / 2 * frame
+ this.bad = 13 / 2 * frame
+ break
+ }
+
+ this.daiLeniency = 2 * frame
+ }
+}
diff --git a/public/src/js/keyboard.js b/public/src/js/keyboard.js
index dc50d65..36d799a 100644
--- a/public/src/js/keyboard.js
+++ b/public/src/js/keyboard.js
@@ -1,6 +1,8 @@
class Keyboard{
constructor(controller){
this.controller = controller
+ this.game = this.controller.game
+
this.kbd = {
"don_l": 86, // V
"don_r": 66, // B
@@ -19,12 +21,13 @@ class Keyboard{
}
this.gamepad = new Gamepad(this)
pageEvents.keyAdd(this, "all", "both", event => {
- if (event.keyCode === 8){
+ if(event.keyCode === 8){
// Disable back navigation when pressing backspace
event.preventDefault()
}
- if(this.buttonEnabled(event.keyCode)){
- this.setKey(event.keyCode, event.type === "keydown")
+ if(!event.repeat && this.buttonEnabled(event.keyCode)){
+ var ms = this.game.getAccurateTime()
+ this.setKey(event.keyCode, event.type === "keydown", ms)
}
})
}
@@ -69,21 +72,20 @@ class Keyboard{
})
}
}
- checkKey(keyCode, keyup, callback){
- if(this.keys[keyCode] && !this.isWaiting(keyCode, keyup)){
- this.waitForKeyup(keyCode, keyup)
+ checkKey(keyCode, type, callback){
+ if(this.keys[keyCode] && !this.isWaiting(keyCode, type)){
+ this.waitForKeyup(keyCode, type)
callback()
}
}
checkKeySound(keyCode, sound){
this.checkKey(keyCode, "sound", () => {
- var circles = this.controller.parsedSongData.circles
- var circle = circles[this.controller.game.getCurrentCircle()]
+ var circles = this.controller.getCircles()
+ var circle = circles[this.controller.getCurrentCircle()]
if(
(keyCode === this.kbd["don_l"] || keyCode === this.kbd["don_r"])
&& circle
&& !circle.getPlayed()
- && circle.getStatus() !== -1
&& circle.getType() === "balloon"
&& circle.requiredHits - circle.timesHit <= 1
){
@@ -91,40 +93,39 @@ class Keyboard{
}else{
assets.sounds["note_" + sound].play()
}
- var ms = this.controller.getElapsedTime().ms
- this.keyTime[keyCode] = ms
- this.keyTime[sound] = ms
+ this.keyTime[sound] = this.keyTime[keyCode]
})
}
getKeys(){
return this.keys
}
- setKey(keyCode, down){
+ setKey(keyCode, down, ms){
if(down){
this.keys[keyCode] = true
+ this.keyTime[keyCode] = ms
}else{
- delete this.keys[keyCode]
- delete this.waitKeyupScore[keyCode]
- delete this.waitKeyupSound[keyCode]
- delete this.waitKeyupMenu[keyCode]
+ this.keys[keyCode] = false
+ this.waitKeyupScore[keyCode] = false
+ this.waitKeyupSound[keyCode] = false
+ this.waitKeyupMenu[keyCode] = false
}
}
- isWaiting(key, type){
+ isWaiting(keyCode, type){
if(type === "score"){
- return this.waitKeyupScore[key]
+ return this.waitKeyupScore[keyCode]
}else if(type === "sound"){
- return this.waitKeyupSound[key]
+ return this.waitKeyupSound[keyCode]
}else if(type === "menu"){
- return this.waitKeyupMenu[key]
+ return this.waitKeyupMenu[keyCode]
}
}
- waitForKeyup(key, type){
+ waitForKeyup(keyCode, type){
if(type === "score"){
- this.waitKeyupScore[key] = true
+ this.waitKeyupScore[keyCode] = true
}else if(type === "sound"){
- this.waitKeyupSound[key] = true
+ this.waitKeyupSound[keyCode] = true
}else if(type === "menu"){
- this.waitKeyupMenu[key] = true
+ this.waitKeyupMenu[keyCode] = true
}
}
getKeyTime(){
diff --git a/public/src/js/mekadon.js b/public/src/js/mekadon.js
index 91b319f..2864a82 100644
--- a/public/src/js/mekadon.js
+++ b/public/src/js/mekadon.js
@@ -3,13 +3,11 @@ class Mekadon{
this.controller = controller
this.game = game
this.lr = false
- this.keys = {}
this.lastHit = -Infinity
}
play(circle){
var type = circle.getType()
if((type === "balloon" || type === "drumroll" || type === "daiDrumroll") && this.getMS() > circle.getEndTime()){
- circle.updateStatus(-1)
circle.played(0, false)
this.game.updateCurrentCircle()
}
@@ -48,21 +46,29 @@ class Mekadon{
var type = circle.getType()
var keyDai = false
var playDai = !dai || dai === 2
+ var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll"
+
+ if(drumrollNotes){
+ var ms = this.getMS()
+ }else{
+ var ms = circle.getMS()
+ }
+
if(type == "daiDon" && playDai){
- this.setKey(kbd["don_l"])
- this.setKey(kbd["don_r"])
+ this.setKey(kbd["don_l"], ms)
+ this.setKey(kbd["don_r"], ms)
this.lr = false
keyDai = true
- }else if(type == "don" || type == "daiDon" || type == "balloon" || type == "drumroll" || type == "daiDrumroll"){
- this.setKey(this.lr ? kbd["don_l"] : kbd["don_r"])
+ }else if(type == "don" || type == "daiDon" || drumrollNotes){
+ this.setKey(this.lr ? kbd["don_l"] : kbd["don_r"], ms)
this.lr = !this.lr
}else if(type == "daiKa" && playDai){
- this.setKey(kbd["ka_l"])
- this.setKey(kbd["ka_r"])
+ this.setKey(kbd["ka_l"], ms)
+ this.setKey(kbd["ka_r"], ms)
this.lr = false
keyDai = true
}else if(type == "ka" || type == "daiKa"){
- this.setKey(this.lr ? kbd["ka_l"] : kbd["ka_r"])
+ this.setKey(this.lr ? kbd["ka_l"] : kbd["ka_r"], ms)
this.lr = !this.lr
}
if(type === "balloon"){
@@ -73,36 +79,20 @@ class Mekadon{
}else if(type === "drumroll" || type === "daiDrumroll"){
this.game.checkDrumroll(circle)
}else{
- if(typeof score == "undefined"){
- score = this.game.checkScore(circle)
- }else{
- this.controller.displayScore(score)
- this.game.updateCombo(score)
- this.game.updateGlobalScore(score, keyDai ? 2 : 1, circle.gogoTime)
- this.game.updateCurrentCircle()
- }
- circle.updateStatus(score)
+ this.controller.displayScore(score)
+ this.game.updateCombo(score)
+ this.game.updateGlobalScore(score, keyDai ? 2 : 1, circle.gogoTime)
+ this.game.updateCurrentCircle()
circle.played(score, keyDai)
}
- this.lastHit = this.getMS()
+ this.lastHit = ms
return true
}
getMS(){
return this.controller.getElapsedTime().ms
}
- setKey(keyCode){
- var self = this
- if(this.keys[keyCode]){
- clearTimeout(this.keys[keyCode])
- self.clearKey(keyCode)
- }
- this.controller.setKey(keyCode, true)
- this.keys[keyCode] = setTimeout(function(){
- self.clearKey(keyCode)
- }, 100)
- }
- clearKey(keyCode){
+ setKey(keyCode, ms){
this.controller.setKey(keyCode, false)
- delete this.keys[keyCode]
+ this.controller.setKey(keyCode, true, ms)
}
}
diff --git a/public/src/js/p2.js b/public/src/js/p2.js
index 03a3925..1f932be 100644
--- a/public/src/js/p2.js
+++ b/public/src/js/p2.js
@@ -116,7 +116,14 @@ class P2Connection{
play(circle, mekadon){
if(this.otherConnected || this.notes.length > 0){
var type = circle.getType()
- if(type === "balloon"|| type === "drumroll" || type === "daiDrumroll"){
+ var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll"
+
+ if(drumrollNotes && mekadon.getMS() > circle.getEndTime()){
+ circle.played(-1, false)
+ mekadon.game.updateCurrentCircle()
+ }
+
+ if(drumrollNotes){
mekadon.playDrumrollAt(circle, 0, this.drumrollPace)
}else if(this.notes.length === 0){
mekadon.play(circle)
diff --git a/public/src/js/view.js b/public/src/js/view.js
index d744afb..ac32dec 100644
--- a/public/src/js/view.js
+++ b/public/src/js/view.js
@@ -420,8 +420,8 @@ class View{
var startingTime = circle.getMS() - timeForDistance
var finishTime = circle.getEndTime() + this.posToMs(this.slotX - this.taikoSquareW + this.bigCircleSize * 3, speed)
- if(!circle.getPlayed() || circle.getScore() === 0){
- if(ms >= startingTime && ms <= finishTime){
+ if(circle.getPlayed() <= 0 || circle.getScore() === 0){
+ if(ms >= startingTime && ms <= finishTime && circle.getPlayed() !== -1){
this.drawCircle(circle)
}
}else if(!circle.isAnimated()){
diff --git a/public/src/views/titlescreen.html b/public/src/views/titlescreen.html
index 82dedc0..b582db7 100644
--- a/public/src/views/titlescreen.html
+++ b/public/src/views/titlescreen.html
@@ -1,4 +1,4 @@
-
Click or Press Enter!
+
Click or Press Enter!