Add Go-Go Time

This commit is contained in:
LoveEevee 2018-09-20 02:20:26 +03:00
parent bba6ad525b
commit e3af27f23c
9 changed files with 293 additions and 88 deletions

View File

@ -45,6 +45,7 @@
<script src="/src/js/p2.js"></script>
<script src="/src/js/canvasasset.js"></script>
<script src="/src/js/pageevents.js"></script>
<script src="/src/js/viewassets.js"></script>
</head>
<body>

View File

@ -7,6 +7,7 @@ var assets = {
"don-1.png",
"big-don-0.png",
"big-don-1.png",
"balloon.png",
"taiko.png",
"taiko-key-blue.png",
"taiko-key-red.png",
@ -28,7 +29,10 @@ var assets = {
"muzu_oni.png",
"don_anim_normal.png",
"don_anim_10combo.png",
"balloon.png"
"don_anim_gogo.png",
"don_anim_gogostart.png",
"fire_anim.png",
"fireworks_anim.png"
],
"audioSfx": [
"start.wav",

View File

@ -1,19 +1,17 @@
class CanvasAsset{
constructor(view, position, image){
constructor(view, layer, position){
this.ctx = view.ctx
this.controller = view.controller
if(image){
this.image = assets.image[image]
}
this.position = position
this.animationFrames = {}
this.speed = 1000 / 60
this.animationStart = 0
this.layer = layer
}
draw(){
var u = (a, b) => typeof a === "undefined" ? b : a
var frame = 0
if(this.animation){
var u = (a, b) => typeof a === "undefined" ? b : a
var frame = 0
var ms = this.controller.getElapsedTime().ms
if(this.animationEnd){
if(ms > this.animationEnd.ms){
@ -28,14 +26,17 @@ class CanvasAsset{
}else{
frame = this.mod(this.animation, index)
}
}
var pos = this.position(frame)
if(this.image){
this.ctx.drawImage(this.image,
u(pos.sx, pos.x), u(pos.sy, pos.y),
u(pos.sw, pos.w), u(pos.sh, pos.h),
pos.x, pos.y, pos.w, pos.h
)
var pos = this.position(frame)
if(this.image){
this.ctx.drawImage(this.image,
u(pos.sx, pos.x), u(pos.sy, pos.y),
u(pos.sw, pos.w), u(pos.sh, pos.h),
pos.x, pos.y, pos.w, pos.h
)
}
if(pos.callback){
pos.callback()
}
}
}
mod(length, index){
@ -52,17 +53,21 @@ class CanvasAsset{
}
setAnimation(name){
var framesObj = this.animationFrames[name]
this.animation = framesObj.frames
this.animationName = name
if(framesObj.image){
this.image = framesObj.image
if(framesObj){
this.animation = framesObj.frames
if(framesObj.image){
this.image = framesObj.image
}
}else{
this.animation = false
}
}
getAnimation(){
return this.animationName
}
getAnimationLength(){
var frames = this.animationFrames["10combo"].frames
getAnimationLength(name){
var frames = this.animationFrames[name].frames
if(Array.isArray(frames)){
return frames.length
}else{

View File

@ -1,21 +1,24 @@
class Circle{
constructor(id, ms, type, text, speed, endTime, requiredHits){
this.id = id
this.ms = ms
this.type = type
this.text = text
this.speed = speed
this.endTime = endTime ? endTime : ms + 150
constructor(config){
// id, ms, type, text, speed, endTime, requiredHits
this.id = config.id
this.ms = config.start
this.type = config.type
this.text = config.txt
this.speed = config.speed
this.endTime = config.endTime || this.ms + 150
this.isPlayed = 0
this.animating = false
this.animT = 0
this.score = 0
this.lastFrame = ms + 100
this.lastFrame = this.ms + 100
this.animationEnded = false
this.status = -1
this.timesHit = 0
this.requiredHits = requiredHits ? requiredHits : 0
this.requiredHits = config.requiredHits || 0
this.rendaPlayed = false
this.gogoTime = config.gogoTime
this.gogoChecked = false
}
getMS(){
return this.ms

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 = Math.max(0, this.timeForDistanceCircle - this.songData.circles[0].ms) |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()
@ -192,9 +192,9 @@ class Game{
this.controller.displayScore(score, true)
}
this.updateCombo(score)
this.updateGlobalScore(score, typeDai && keyDai ? 2 : 1)
this.updateGlobalScore(score, typeDai && keyDai ? 2 : 1, circle.gogoTime)
this.updateCurrentCircle()
circle.played(score, keyDai)
circle.played(score, score === 0 ? typeDai : keyDai)
if(this.controller.multiplayer == 1){
p2.send("note", {
score: score,
@ -243,7 +243,14 @@ class Game{
}else{
var sound = keyTime["don"] > keyTime["ka"] ? "daiDon" : "daiKa"
}
var circleAnim = new Circle(0, this.getElapsedTime().ms, sound, "", circle.speed)
var circleAnim = new Circle({
id: 0,
start: this.getElapsedTime().ms,
type: sound,
txt: "",
speed: circle.speed,
gogoTime: circle.gogoTime
})
circleAnim.played(score, dai)
circleAnim.animate()
this.controller.view.drumroll.push(circleAnim)
@ -252,7 +259,7 @@ class Game{
}
whenLastCirclePlayed(){
var circles = this.songData.circles
var lastCircle = circles[this.songData.circles.length - 1]
var lastCircle = circles[circles.length - 1]
var ms = this.getElapsedTime().ms
if(!this.fadeOutStarted && ms >= lastCircle.getEndTime() + 1900){
this.fadeOutStarted = ms
@ -365,7 +372,7 @@ class Game{
getGlobalScore(){
return this.globalScore
}
updateGlobalScore(score, multiplier){
updateGlobalScore(score, multiplier, gogoTime){
// Circle score
switch(score){
case 450:
@ -389,6 +396,9 @@ class Game{
// Points update
score += Math.max(0, Math.floor((Math.min(this.combo, 100) - 1) / 10) * 100)
this.globalScore.points += score * multiplier
if(gogoTime){
multiplier *= 1.2
}
this.globalScore.points += Math.floor(score * multiplier / 10) * 10
}
}

View File

@ -33,7 +33,7 @@ class Mekadon{
this.controller.displayScore(0, true)
this.game.updateCurrentCircle()
this.game.updateCombo(0)
this.game.updateGlobalScore(0, 1)
this.game.updateGlobalScore(0, 1, circle.gogoTime)
return true
}
}
@ -72,7 +72,7 @@ class Mekadon{
}else{
this.controller.displayScore(score)
this.game.updateCombo(score)
this.game.updateGlobalScore(score, keyDai ? 2 : 1)
this.game.updateGlobalScore(score, keyDai ? 2 : 1, circle.gogoTime)
this.game.updateCurrentCircle()
}
circle.updateStatus(score)

View File

@ -121,7 +121,8 @@ class ParseSong{
timingPoints.push({
start: start,
sliderMultiplier: sliderMultiplier,
measure: parseInt(values[this.osu.METER])
measure: parseInt(values[this.osu.METER]),
gogoTime: parseInt(values[this.osu.KIAIMODE])
})
}
return timingPoints
@ -142,7 +143,7 @@ class ParseSong{
speed: this.timingPoints[i].sliderMultiplier
})
measureNumber++
if(measureNumber == this.timingPoints[i].measure + 1){
if(measureNumber === this.timingPoints[i].measure + 1){
measureNumber = 0
}
}
@ -229,6 +230,7 @@ class ParseSong{
var emptyValue = false
var start = parseInt(values[this.osu.TIME])
var speed = this.difficulty.originalMultiplier
var gogoTime = false
var osuType = parseInt(values[this.osu.TYPE])
var hitSound = parseInt(values[this.osu.HITSOUND])
@ -237,6 +239,7 @@ class ParseSong{
break
}
speed = this.timingPoints[j].sliderMultiplier
gogoTime = this.timingPoints[j].gogoTime
}
if(osuType & this.osu.SPINNER){
@ -244,7 +247,16 @@ class ParseSong{
var endTime = parseInt(values[this.osu.ENDTIME])
var hitMultiplier = this.difficultyRange(this.difficulty.overallDifficulty, 3, 5, 7.5) * 1.65
var requiredHits = Math.floor(Math.max(1, (endTime - start) / 1000 * hitMultiplier))
circles.push(new Circle(circleID, start, "balloon", "ふうせん", speed, endTime, requiredHits))
circles.push(new Circle({
id: circleID,
start: start,
type: "balloon",
txt: "ふうせん",
speed: speed,
endTime: endTime,
requiredHits: requiredHits,
gogoTime: gogoTime
}))
}else if(osuType & this.osu.SLIDER){
@ -258,7 +270,15 @@ class ParseSong{
type = "drumroll"
txt = "連打ーっ!!"
}
circles.push(new Circle(circleID, start, type, txt, speed, endTime))
circles.push(new Circle({
id: circleID,
start: start,
type: type,
txt: txt,
speed: speed,
endTime: endTime,
gogoTime: gogoTime
}))
}else if(osuType & this.osu.CIRCLE){
var type
@ -284,7 +304,14 @@ class ParseSong{
emptyValue = true
}
if(!emptyValue){
circles.push(new Circle(circleID, start, type, txt, speed))
circles.push(new Circle({
id: circleID,
start: start,
type: type,
txt: txt,
speed: speed,
gogoTime: gogoTime
}))
}
}else{
emptyValue = true

View File

@ -42,37 +42,13 @@ class View{
this.currentDonFace = 0
this.currentBigDonFace = 1
this.nextBeat = 0
this.gogoTime = 0
this.gogoTimeStarted = -Infinity
this.drumroll = []
this.beatInterval = this.controller.getSongData().beatInfo.beatInterval
this.assets = []
this.don = this.createAsset(frame => {
var imgw = 360
var imgh = 184
var scale = 165
var w = (this.barH * imgw) / scale
var h = (this.barH * imgh) / scale
return {
sx: 0,
sy: frame * imgh,
sw: imgw,
sh: imgh,
x: this.taikoSquareW - w + this.barH * 0.2,
y: this.barY - h,
w: w,
h: h
}
})
this.don.addFrames("normal", [
0 ,0 ,0 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,6 ,5 ,4 ,3 ,2 ,1 ,
0 ,0 ,0 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,6 ,5 ,4 ,3 ,2 ,1 ,
0 ,0 ,0 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,6 ,5 ,7 ,8 ,9 ,10,
11,11,11,11,10,9 ,8 ,7 ,13,12,12,13,14,15,16,17
], "don_anim_normal")
this.don.addFrames("10combo", 22, "don_anim_10combo")
this.don.setAnimation("normal")
this.don.setUpdateSpeed(this.beatInterval / 16)
this.assets = new ViewAssets(this)
}
run(){
this.ctx.font = "normal 14pt TnT"
@ -146,11 +122,12 @@ class View{
this.ctx.clearRect(0, 0, this.canvas.scaledWidth, this.canvas.scaledHeight)
// Draw
this.drawAssets()
this.assets.drawAssets("background")
this.drawBar()
this.drawSlot()
this.drawMeasures()
this.drawHPBar()
this.assets.drawAssets("bar")
this.drawMeasures()
this.drawScore()
this.drawCircles(this.controller.getCircles())
this.drawCircles(this.drumroll)
@ -160,7 +137,9 @@ class View{
this.drawCombo()
this.drawGlobalScore()
this.updateDonFaces()
this.drawGogoTime()
this.mouseIdle()
this.assets.drawAssets("foreground")
//this.drawTime()
}
updateDonFaces(){
@ -449,6 +428,12 @@ class View{
// Start animation to HP bar
circle.animate()
}
if(ms >= circle.ms && !circle.gogoChecked){
if(this.gogoTime != circle.gogoTime){
this.toggleGogoTime(circle)
}
circle.gogoChecked = true
}
if(circle.isAnimated()){
var animationDuration = 470
if(ms <= finishTime + animationDuration){
@ -654,6 +639,22 @@ class View{
var ms = this.controller.getElapsedTime().ms
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().ms - this.gogoTimeStarted) / 100
if(!this.gogoTime){
alpha = 1 - alpha
}
this.ctx.globalAlpha = alpha
this.ctx.fill()
this.ctx.globalAlpha = 1
}
if(keyTime[sound] > ms - 200){
var gradients = {
"don": ["#f54c25", "#232323"],
@ -710,27 +711,78 @@ class View{
this.ctx.closePath()
this.ctx.stroke()
}
createAsset(image, position){
var asset = new CanvasAsset(this, image, position)
this.assets.push(asset)
return asset
}
drawAssets(){
if(this.controller.multiplayer !== 2){
this.assets.forEach(asset => {
asset.draw()
toggleGogoTime(circle){
this.gogoTime = circle.gogoTime
this.gogoTimeStarted = circle.ms
if(this.gogoTime){
this.assets.fireworks.forEach(fireworksAsset => {
fireworksAsset.setAnimation("normal")
fireworksAsset.setAnimationStart(circle.ms)
var length = fireworksAsset.getAnimationLength("normal")
fireworksAsset.setAnimationEnd(circle.ms + length * fireworksAsset.speed, () => {
fireworksAsset.setAnimation(false)
})
})
this.assets.fire.setAnimation("normal")
var don = this.assets.don
don.setAnimation("gogostart")
don.setAnimationStart(circle.ms)
var length = don.getAnimationLength("gogostart")
don.setAnimationEnd(circle.ms + length * don.speed, () => {
don.setAnimationStart(0)
if(this.gogoTime){
don.setAnimation("gogo")
}else{
don.setAnimation("normal")
}
})
}
}
drawGogoTime(){
var ms = this.controller.getElapsedTime().ms
if(this.gogoTime){
if(this.gogoTimeStarted){
}
var circles = this.controller.parsedSongData.circles
var lastCircle = circles[circles.length - 1]
var endTime = lastCircle.getEndTime() + 3000
if(ms >= endTime){
this.toggleGogoTime({
gogoTime: 0,
ms: endTime
})
}
}else{
if(this.assets.don.getAnimation() === "gogo"){
this.assets.don.setAnimation("normal")
}
if(ms >= this.gogoTimeStarted + 100){
this.assets.fire.setAnimation(false)
}
}
}
updateCombo(combo){
if(combo > 0 && combo % 10 === 0 && this.don.getAnimation() != "10combo"){
this.don.setAnimation("10combo")
var don = this.assets.don
var animation = don.getAnimation()
if(
combo > 0
&& combo % 10 === 0
&& animation !== "10combo"
&& animation !== "gogostart"
&& animation !== "gogo"
){
don.setAnimation("10combo")
var ms = this.controller.getElapsedTime().ms
this.don.setAnimationStart(ms)
var length = this.don.getAnimationLength("10combo")
this.don.setAnimationEnd(ms + length * this.don.speed, () => {
this.don.setAnimationStart(0)
this.don.setAnimation("normal")
don.setAnimationStart(ms)
var length = don.getAnimationLength("10combo")
don.setAnimationEnd(ms + length * don.speed, () => {
don.setAnimationStart(0)
if(this.gogoTime){
don.setAnimation("gogo")
}else{
don.setAnimation("normal")
}
})
}
}

103
public/src/js/viewassets.js Normal file
View File

@ -0,0 +1,103 @@
class ViewAssets{
constructor(view){
this.view = view
this.controller = this.view.controller
this.allAssets = []
this.beatInterval = this.view.beatInterval
this.ctx = this.view.ctx
this.don = this.createAsset("background", frame => {
var imgw = 360
var imgh = 184
var scale = 165
var w = (this.view.barH * imgw) / scale
var h = (this.view.barH * imgh) / scale
return {
sx: Math.floor(frame / 10) * imgw,
sy: (frame % 10) * imgh,
sw: imgw,
sh: imgh,
x: this.view.taikoSquareW - w + this.view.barH * 0.2,
y: this.view.barY - h,
w: w,
h: h
}
})
this.don.addFrames("normal", [
0 ,0 ,0 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,6 ,5 ,4 ,3 ,2 ,1 ,
0 ,0 ,0 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,6 ,5 ,4 ,3 ,2 ,1 ,
0 ,0 ,0 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,6 ,5 ,7 ,8 ,9 ,10,
11,11,11,11,10,9 ,8 ,7 ,13,12,12,13,14,15,16,17
], "don_anim_normal")
this.don.addFrames("10combo", 22, "don_anim_10combo")
this.don.addFrames("gogo", 56, "don_anim_gogo")
this.don.addFrames("gogostart", 27, "don_anim_gogostart")
this.don.setAnimation("normal")
this.don.setUpdateSpeed(this.beatInterval / 16)
this.fire = this.createAsset("bar", frame => {
var imgw = 360
var imgh = 370
var scale = 175
var ms = this.controller.getElapsedTime().ms
var grow = Math.min(100, ms - this.view.gogoTimeStarted) / 100
if(!this.view.gogoTime){
grow = 1 - grow
}
var w = (this.view.barH * imgw) / scale * grow
var h = (this.view.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,
w: w,
h: h,
callback: () => {
this.ctx.globalCompositeOperation = "source-over"
}
}
})
this.fire.addFrames("normal", 7, "fire_anim")
this.fire.setUpdateSpeed(this.beatInterval / 8)
this.fireworks = []
for(let i = 0; i < 5 ; i++){
var fireworksAsset = this.createAsset("foreground", frame => {
var imgw = 230
var imgh = 460
var scale = 165
var w = (this.view.barH * imgw) / scale
var h = (this.view.barH * imgh) / scale
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,
w: w,
h: h
}
})
fireworksAsset.addFrames("normal", 30, "fireworks_anim")
fireworksAsset.setUpdateSpeed(this.beatInterval / 16)
this.fireworks.push(fireworksAsset)
}
}
createAsset(layer, position){
var asset = new CanvasAsset(this.view, layer, position)
this.allAssets.push(asset)
return asset
}
drawAssets(layer){
if(this.controller.multiplayer !== 2){
this.allAssets.forEach(asset => {
if(layer === asset.layer){
asset.draw()
}
})
}
}
}