Add renda sound, dai notes scoring, fix music timing

This commit is contained in:
LoveEevee 2018-09-18 20:33:18 +03:00
parent 0ee627db9d
commit a49cc6a3c4
10 changed files with 181 additions and 145 deletions

View File

@ -82,7 +82,8 @@ var assets = {
"note_don.ogg",
"note_ka.ogg",
"balloon.ogg"
"balloon.ogg",
"renda.ogg"
],
"audioMusic": [
"bgm_songsel.ogg",

View File

@ -6,7 +6,7 @@ class Circle{
this.text = text
this.speed = speed
this.endTime = endTime ? endTime : ms + 150
this.isPlayed = false
this.isPlayed = 0
this.animating = false
this.animT = 0
this.score = 0
@ -15,6 +15,7 @@ class Circle{
this.status = -1
this.timesHit = 0
this.requiredHits = requiredHits ? requiredHits : 0
this.rendaPlayed = false
}
getMS(){
return this.ms
@ -58,9 +59,9 @@ class Circle{
endAnimation(){
this.animationEnded = true
}
played(score){
played(score, big){
this.score = score
this.isPlayed = true
this.isPlayed = big ? 2 : 1
}
hit(){
this.timesHit++

View File

@ -174,8 +174,8 @@ class Controller{
getCurrentCircle(){
return this.game.getCurrentCircle()
}
isWaitingForKeyup(key, type){
return this.keyboard.isWaitingForKeyup(key, type)
isWaiting(key, type){
return this.keyboard.isWaiting(key, type)
}
waitForKeyup(key, type){
this.keyboard.waitForKeyup(key, type)

View File

@ -41,7 +41,7 @@ class Game{
initTiming(){
// Date when the chrono is started (before the game begins)
this.offsetDate = new Date()
this.offsetTime = this.timeForDistanceCircle |0
this.offsetTime = Math.max(0, this.timeForDistanceCircle - this.songData.circles[0].ms) |0
this.setElapsedTime(-this.offsetTime)
// The real start for the game will start when chrono will reach 0
this.startDate = new Date()
@ -70,20 +70,26 @@ class Game{
var hitTime = circle.getMS()
var endTime = circle.getEndTime()
var type = circle.getType()
var normalNotes = type == "don" || type == "daiDon" || type == "ka" || type == "daiKa"
var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll"
if(currentTime >= startingTime && currentTime <= endTime){
if(currentTime>= hitTime - 50 && currentTime < hitTime - 30){
circle.updateStatus(0)
}else if(currentTime>= hitTime - 30 && currentTime < hitTime){
}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()
}
}
}
}else if(currentTime>endTime){
if(type == "balloon" || type == "drumroll" || type == "daiDrumroll"){
}else if(currentTime > endTime){
if(drumrollNotes){
circle.updateStatus(-1)
circle.played(0)
this.updateCurrentCircle()
@ -100,9 +106,9 @@ class Game{
this.controller.displayScore(currentScore, true)
this.updateCurrentCircle()
this.updateCombo(currentScore)
this.updateGlobalScore(currentScore)
this.updateGlobalScore(currentScore, 1)
}
if(this.controller.multiplayer == 1){
if(this.controller.multiplayer === 1){
p2.send("note", {
score: -1
})
@ -124,42 +130,61 @@ class Game{
}
var keys = this.controller.getKeys()
var kbd = this.controller.getBindings()
if(keys[kbd["don_l"]]){
this.checkKey(kbd["don_l"], circle)
}
if(keys[kbd["don_r"]]){
this.checkKey(kbd["don_r"], circle)
}
if(keys[kbd["ka_l"]]){
this.checkKey(kbd["ka_l"], circle)
}
if(keys[kbd["ka_r"]]){
this.checkKey(kbd["ka_r"], circle)
}
}
checkKey(keyCode, circle){
if(!this.controller.isWaitingForKeyup(keyCode, "score")){
if(circle && !circle.getPlayed() && circle.getStatus() != -1){
this.checkScore(circle)
}
this.controller.waitForKeyup(keyCode, "score")
}
}
checkScore(circle){
var keys = this.controller.getKeys()
var kbd = this.controller.getBindings()
var keysDon = keys[kbd["don_l"]] || keys[kbd["don_r"]]
var keysKa = keys[kbd["ka_l"]] || keys[kbd["ka_r"]]
var don_l = keys[kbd["don_l"]] && !this.controller.isWaiting(kbd["don_l"], "score")
var don_r = keys[kbd["don_r"]] && !this.controller.isWaiting(kbd["don_r"], "score")
var ka_l = keys[kbd["ka_l"]] && !this.controller.isWaiting(kbd["ka_l"], "score")
var ka_r = keys[kbd["ka_r"]] && !this.controller.isWaiting(kbd["ka_r"], "score")
if(don_l && don_r){
this.checkKey([kbd["don_l"], kbd["don_r"]], circle, "daiDon")
}else if(don_l){
this.checkKey([kbd["don_l"]], circle, "don")
}else if(don_r){
this.checkKey([kbd["don_r"]], circle, "don")
}
if(ka_l && ka_r){
this.checkKey([kbd["ka_l"], kbd["ka_r"]], circle, "daiKa")
}else if(ka_l){
this.checkKey([kbd["ka_l"]], circle, "ka")
}else if(ka_r){
this.checkKey([kbd["ka_r"]], circle, "ka")
}
}
checkKey(keyCodes, circle, check){
if(circle && !circle.getPlayed() && circle.getStatus() != -1){
if(!this.checkScore(circle, check)){
return
}
}
keyCodes.forEach(keyCode => {
this.controller.waitForKeyup(keyCode, "score")
})
}
checkScore(circle, check){
var ms = this.getElapsedTime().ms
var type = circle.getType()
var typeDon = type == "don" || type == "daiDon"
var typeKa = type == "ka" || type == "daiKa"
var keysDon = check === "don" || check === "daiDon"
var keysKa = check === "ka" || check === "daiKa"
var keyDai = check === "daiDon" || check === "daiKa"
var typeDon = type === "don" || type === "daiDon"
var typeKa = type === "ka" || type === "daiKa"
var typeDai = type === "daiDon" || type === "daiKa"
if(typeDon || typeKa){
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){
return false
}
}
var circleStatus = circle.getStatus()
if(circleStatus == 230 || circleStatus == 450){
if(circleStatus === 230 || circleStatus === 450){
score = circleStatus
}
this.controller.displayScore(score)
@ -167,20 +192,28 @@ class Game{
this.controller.displayScore(score, true)
}
this.updateCombo(score)
this.updateGlobalScore(score)
this.updateGlobalScore(score, typeDai && keyDai ? 2 : 1)
this.updateCurrentCircle()
circle.played(score)
circle.played(score, keyDai)
if(this.controller.multiplayer == 1){
p2.send("note", {
score: score,
ms: circle.getMS() - this.getElapsedTime().ms
ms: circle.getMS() - ms,
dai: typeDai ? keyDai ? 2 : 1 : 0
})
}
}else if(keysDon && type == "balloon"){
this.checkBalloon(circle)
}else if((keysDon || keysKa) && (type == "drumroll" || type == "daiDrumroll")){
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
}
checkBalloon(circle){
if(circle.timesHit >= circle.requiredHits - 1){
@ -201,20 +234,21 @@ class Game{
this.globalScore.points += score
}
checkDrumroll(circle){
var dai = circle.getType() === "daiDrumroll"
var score = 100
circle.hit()
var keyTime = this.controller.getKeyTime()
if(circle.getType() == "drumroll"){
if(circle.getType() === "drumroll"){
var sound = keyTime["don"] > keyTime["ka"] ? "don" : "ka"
}else{
var sound = keyTime["don"] > keyTime["ka"] ? "daiDon" : "daiKa"
}
var circleAnim = new Circle(0, this.getElapsedTime().ms, sound, "", circle.speed)
circleAnim.played(score)
circleAnim.played(score, dai)
circleAnim.animate()
this.controller.view.drumroll.push(circleAnim)
this.globalScore.drumroll ++
this.globalScore.points += score
this.globalScore.drumroll++
this.globalScore.points += score * (dai ? 2 : 1)
}
whenLastCirclePlayed(){
var circles = this.songData.circles
@ -229,21 +263,15 @@ class Game{
if(started){
var ms = this.getElapsedTime().ms
if(this.musicFadeOut === 0){
snd.musicGain.fadeOut(1.6)
if(this.controller.multiplayer === 1){
p2.send("gameresults", this.controller.getGlobalScore())
}
this.musicFadeOut++
}else if(this.musicFadeOut === 1 && ms >= started + 1600){
this.controller.gameEnded()
this.mainAsset.stop()
p2.send("gameend")
this.musicFadeOut++
}else if(this.musicFadeOut === 2 && ms >= started + 2600){
snd.musicGain.fadeIn()
snd.musicGain.unmute()
this.musicFadeOut++
}else if(this.musicFadeOut === 3 && ms >= started + 8600){
}else if(this.musicFadeOut === 2 && (ms >= started + 8600 && ms >= this.controller.mainAsset.duration * 1000 + 250)){
this.controller.displayResults()
this.musicFadeOut++
}
@ -259,7 +287,7 @@ class Game{
playMainMusic(){
var ms = this.getElapsedTime().ms
if(!this.mainMusicPlaying && (!this.fadeOutStarted || ms<this.fadeOutStarted + 1600)){
if(this.controller.multiplayer != 2){
if(this.controller.multiplayer !== 2){
this.mainAsset.play((ms < 0 ? -ms : 0) / 1000, false, Math.max(0, ms / 1000))
}
this.mainMusicPlaying = true
@ -318,7 +346,7 @@ class Game{
return this.currentCircle
}
updateCombo(score){
if(score != 0){
if(score !== 0){
this.combo++
}else{
this.combo = 0
@ -326,7 +354,7 @@ class Game{
if(this.combo > this.globalScore.maxCombo){
this.globalScore.maxCombo = this.combo
}
if(this.combo == 50 || this.combo > 0 && this.combo % 100 == 0 && this.combo <= 1400){
if(this.combo === 50 || this.combo > 0 && this.combo % 100 === 0 && this.combo <= 1400){
this.controller.playSoundMeka("combo-" + this.combo)
}
this.controller.view.updateCombo(this.combo)
@ -337,7 +365,7 @@ class Game{
getGlobalScore(){
return this.globalScore
}
updateGlobalScore(score){
updateGlobalScore(score, multiplier){
// Circle score
switch(score){
case 450:
@ -351,7 +379,7 @@ class Game{
break
}
// HP Update
if(score != 0){
if(score !== 0){
this.globalScore.hp += this.HPGain
}else if(this.globalScore.hp - this.HPGain > 0){
this.globalScore.hp -= this.HPGain
@ -361,6 +389,6 @@ class Game{
// Points update
score += Math.max(0, Math.floor((Math.min(this.combo, 100) - 1) / 10) * 100)
this.globalScore.points+=score
this.globalScore.points += score * multiplier
}
}

View File

@ -70,7 +70,7 @@ class Keyboard{
}
}
checkKey(keyCode, keyup, callback){
if(this.keys[keyCode] && !this.isWaitingForKeyup(keyCode, keyup)){
if(this.keys[keyCode] && !this.isWaiting(keyCode, keyup)){
this.waitForKeyup(keyCode, keyup)
callback()
}
@ -109,7 +109,7 @@ class Keyboard{
delete this.waitKeyupMenu[keyCode]
}
}
isWaitingForKeyup(key, type){
isWaiting(key, type){
if(type === "score"){
return this.waitKeyupScore[key]
}else if(type === "sound"){

View File

@ -3,8 +3,6 @@ class loadSong{
this.selectedSong = selectedSong
this.multiplayer = multiplayer
this.autoPlayEnabled = autoPlayEnabled
this.diff = this.selectedSong.difficulty.slice(0, -4)
this.songFilePath = "/songs/" + this.selectedSong.folder + "/" + this.selectedSong.difficulty
loader.changePage("loadsong")
this.run()
}
@ -36,7 +34,7 @@ class loadSong{
}, reject)
}
}))
promises.push(loader.ajax(this.songFilePath).then(data => {
promises.push(loader.ajax(this.getOsuPath(this.selectedSong)).then(data => {
this.songData = data.replace(/\0/g, "").split("\n")
}))
Promise.all(promises).then(() => {
@ -46,6 +44,9 @@ class loadSong{
alert("An error occurred, please refresh")
})
}
getOsuPath(selectedSong){
return "/songs/" + selectedSong.folder + "/" + selectedSong.difficulty + ".osu"
}
setupMultiplayer(){
if(this.multiplayer){
var loadingText = document.getElementsByClassName("loading-text")[0]
@ -57,15 +58,15 @@ class loadSong{
this.selectedSong2 = this.selectedSong
pageEvents.add(p2, "message", event => {
if(event.type === "gameload"){
if(event.value === this.diff){
if(event.value === this.selectedSong.difficulty){
p2.send("gamestart")
}else{
this.selectedSong2 = {
title: this.selectedSong.title,
folder: this.selectedSong.folder,
difficulty: event.value + ".osu"
difficulty: event.value
}
loader.ajax("/songs/" + this.selectedSong2.folder + "/" + this.selectedSong2.difficulty).then(data => {
loader.ajax(this.getOsuPath(this.selectedSong2)).then(data => {
this.song2Data = data.replace(/\0/g, "").split("\n")
p2.send("gamestart")
}, () => {
@ -82,7 +83,7 @@ class loadSong{
})
p2.send("join", {
id: this.selectedSong.folder,
diff: this.diff
diff: this.selectedSong.difficulty
})
}else{
this.clean()

View File

@ -16,10 +16,10 @@ class Mekadon{
this.playAt(circle, 0, 450)
}
}
playAt(circle, ms, score){
playAt(circle, ms, score, dai){
var currentMs = circle.getMS() - this.getMS()
if(ms > currentMs - 10){
return this.playNow(circle, score)
return this.playNow(circle, score, dai)
}
}
playDrumrollAt(circle, ms, pace){
@ -33,27 +33,31 @@ class Mekadon{
this.controller.displayScore(0, true)
this.game.updateCurrentCircle()
this.game.updateCombo(0)
this.game.updateGlobalScore(0)
this.game.updateGlobalScore(0, 1)
return true
}
}
playNow(circle, score){
playNow(circle, score, dai){
var kbd = this.controller.getBindings()
var type = circle.getType()
if(type == "don" || type == "balloon" || type == "drumroll" || type == "daiDrumroll"){
this.setKey(this.lr ? kbd["don_l"] : kbd["don_r"])
this.lr = !this.lr
}else if(type == "daiDon"){
var keyDai = false
var playDai = !dai || dai === 2
if(type == "daiDon" && playDai){
this.setKey(kbd["don_l"])
this.setKey(kbd["don_r"])
this.lr = false
}else if(type == "ka"){
this.setKey(this.lr ? kbd["ka_l"] : kbd["ka_r"])
keyDai = true
}else if(type == "don" || type == "daiDon" || type == "balloon" || type == "drumroll" || type == "daiDrumroll"){
this.setKey(this.lr ? kbd["don_l"] : kbd["don_r"])
this.lr = !this.lr
}else if(type == "daiKa"){
}else if(type == "daiKa" && playDai){
this.setKey(kbd["ka_l"])
this.setKey(kbd["ka_r"])
this.lr = false
keyDai = true
}else if(type == "ka" || type == "daiKa"){
this.setKey(this.lr ? kbd["ka_l"] : kbd["ka_r"])
this.lr = !this.lr
}
if(type == "balloon"){
if(circle.requiredHits == 1){
@ -68,11 +72,11 @@ class Mekadon{
}else{
this.controller.displayScore(score)
this.game.updateCombo(score)
this.game.updateGlobalScore(score)
this.game.updateGlobalScore(score, keyDai ? 2 : 1)
this.game.updateCurrentCircle()
}
circle.updateStatus(score)
circle.played(score)
circle.played(score, keyDai)
}
this.lastHit = this.getMS()
return true

View File

@ -93,6 +93,7 @@ class P2Connection{
this.otherConnected = true
this.notes = []
this.drumrollPace = 45
this.dai = 2
this.results = false
break
case "gameend":
@ -103,6 +104,9 @@ class P2Connection{
break
case "note":
this.notes.push(response.value)
if(response.value.dai){
this.dai = response.value.dai
}
break
case "drumroll":
this.drumrollPace = response.value.pace
@ -119,7 +123,11 @@ class P2Connection{
}else{
var note = this.notes[0]
if(note.score >= 0){
if(mekadon.playAt(circle, note.ms, note.score)){
var dai = 1
if(circle.getType() === "daiDon" || circle.getType() === "daiKa"){
dai = this.dai
}
if(mekadon.playAt(circle, note.ms, note.score, dai)){
this.notes.shift()
}
}else{

View File

@ -77,7 +77,7 @@ class SongSelect{
var song = target.parentNode.parentNode
assets.sounds["don"].play()
this.selectedSong.difficulty = target.classList[1] + ".osu"
this.selectedSong.difficulty = target.classList[1]
this.selectedSong.title = song.dataset.title
this.selectedSong.folder = song.dataset.songId

View File

@ -1,8 +1,9 @@
class View{
constructor(controller, bg, title, diff){
constructor(controller, bg, songTitle, songDifficulty){
this.controller = controller
this.bg = bg
this.diff = diff
this.songTitle = songTitle
this.songDifficulty = songDifficulty
this.pauseMenu = document.getElementById("pause-menu")
this.cursor = document.getElementById("cursor")
@ -42,9 +43,6 @@ class View{
this.currentBigDonFace = 1
this.nextBeat = 0
this.songTitle = title
this.songDifficulty = this.diff.split(".").slice(0, -1).join(".")
this.drumroll = []
this.beatInterval = this.controller.getSongData().beatInfo.beatInterval
@ -79,10 +77,12 @@ class View{
run(){
this.ctx.font = "normal 14pt TnT"
this.setBackground()
var gameSong = document.getElementsByClassName("game-song")[0]
gameSong.appendChild(document.createTextNode(this.songTitle))
gameSong.setAttribute("alt", this.songTitle)
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().ms
pageEvents.mouseAdd(this, this.onmousemove.bind(this))
@ -500,6 +500,7 @@ class View{
var endTime = circle.getEndTime()
var animated = circle.isAnimated()
var speed = circle.getSpeed()
var played = circle.getPlayed()
if(!circlePos){
circlePos = {
@ -514,34 +515,28 @@ class View{
var currentDonFace = this.currentDonFace
var currentBigDonFace = this.currentBigDonFace
}
switch(type){
case "don":
if(type === "don" || type === "daiDon" && played === 1){
fill = "#f34728"
size = this.circleSize
faceID = "don-" + currentDonFace
}else if(type === "ka" || type === "daiKa" && played === 1){
fill = "#65bdbb"
size = this.circleSize
faceID = "don-" + currentDonFace
}else if(type === "daiDon"){
fill = "#f34728"
size = this.bigCircleSize
faceID = "big-don-" + currentBigDonFace
}else if(type === "daiKa"){
fill = "#65bdbb"
size = this.bigCircleSize
faceID = "big-don-" + currentBigDonFace
}else if(type === "balloon"){
if(animated){
fill = "#f34728"
size = this.circleSize
faceID = "don-" + currentDonFace
break
case "ka":
fill = "#65bdbb"
size = this.circleSize
faceID = "don-" + currentDonFace
break
case "daiDon":
fill = "#f34728"
size = this.bigCircleSize
size = this.bigCircleSize * 0.8
faceID = "big-don-" + currentBigDonFace
break
case "daiKa":
fill = "#65bdbb"
size = this.bigCircleSize
faceID = "big-don-" + currentBigDonFace
break
case "balloon":
if(animated){
fill = "#f34728"
size = this.bigCircleSize * 0.8
faceID = "big-don-" + currentBigDonFace
break
}
}else{
fill = "#f87700"
size = this.circleSize
faceID = "don-" + currentDonFace
@ -557,29 +552,27 @@ class View{
h / 61 * 115,
h
)
break
case "drumroll":
case "daiDrumroll":
fill = "#f3b500"
if(type == "drumroll"){
size = this.circleSize
faceID = "don-" + currentDonFace
}else{
size = this.bigCircleSize
faceID = "big-don-" + currentBigDonFace
}
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()
break
}
}else if(type === "drumroll" || type === "daiDrumroll"){
fill = "#f3b500"
if(type == "drumroll"){
size = this.circleSize
faceID = "don-" + currentDonFace
}else{
size = this.bigCircleSize
faceID = "big-don-" + currentBigDonFace
}
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()
}
// Main circle
this.ctx.fillStyle = fill