Commit 13ca5e36 authored by Bui's avatar Bui Committed by GitHub

Merge pull request #136 from bui/parsetja-add-branches

ParseTja: Add branches
parents 440436b3 92510c30
...@@ -44,7 +44,8 @@ ...@@ -44,7 +44,8 @@
box-sizing: border-box; box-sizing: border-box;
} }
#debug .input-slider{ #debug .input-slider,
#debug .select{
display: flex; display: flex;
width: 100%; width: 100%;
height: 30px; height: 30px;
...@@ -59,7 +60,8 @@ ...@@ -59,7 +60,8 @@
padding: 2px 4px; padding: 2px 4px;
text-align: center; text-align: center;
} }
#debug .input-slider>span{ #debug .input-slider>span,
#debug .select>span{
display: block; display: block;
width: 10%; width: 10%;
height: 100%; height: 100%;
...@@ -70,10 +72,19 @@ ...@@ -70,10 +72,19 @@
line-height: 2em; line-height: 2em;
cursor: pointer; cursor: pointer;
} }
#debug .input-slider>span:hover{ #debug .input-slider>span:hover,
#debug .select>span:hover{
opacity: 1; opacity: 1;
background: #333; background: #333;
} }
#debug .select select{
width: 90%;
height: 100%;
box-sizing: border-box;
font-size: 18px;
font-family: sans-serif;
padding: 2px 4px;
}
#debug label{ #debug label{
display: block; display: block;
...@@ -111,6 +122,7 @@ ...@@ -111,6 +122,7 @@
margin-left: 3px; margin-left: 3px;
} }
#debug .autoplay-label{ #debug .autoplay-label,
#debug .branch-hide{
display: none; display: none;
} }
...@@ -268,6 +268,9 @@ ...@@ -268,6 +268,9 @@
easeOut(pos){ easeOut(pos){
return Math.sin(Math.PI / 2 * pos) return Math.sin(Math.PI / 2 * pos)
} }
easeOutBack(pos){
return Math.sin(Math.PI / 1.74 * pos) * 1.03
}
easeInOut(pos){ easeInOut(pos){
return (Math.cos(Math.PI * pos) - 1) / -2 return (Math.cos(Math.PI * pos) - 1) / -2
} }
...@@ -572,7 +575,7 @@ ...@@ -572,7 +575,7 @@
} }
if(symbol.ura){ if(symbol.ura){
ctx.font = (30 * mul) + "px Meiryo, sans-serif" ctx.font = (30 * mul) + "px Meiryo, sans-serif"
ctx.textBaseline = "center" ctx.textBaseline = "middle"
ctx.beginPath() ctx.beginPath()
ctx.arc(currentX, currentY + (17 * mul), (18 * mul), 0, Math.PI * 2) ctx.arc(currentX, currentY + (17 * mul), (18 * mul), 0, Math.PI * 2)
if(action === "stroke"){ if(action === "stroke"){
...@@ -581,7 +584,7 @@ ...@@ -581,7 +584,7 @@
}else if(action === "fill"){ }else if(action === "fill"){
ctx.strokeStyle = config.fill ctx.strokeStyle = config.fill
ctx.lineWidth = 2.5 * mul ctx.lineWidth = 2.5 * mul
ctx.fillText(symbol.text, currentX, currentY) ctx.fillText(symbol.text, currentX, currentY + (17 * mul))
} }
ctx.stroke() ctx.stroke()
}else{ }else{
...@@ -788,7 +791,7 @@ ...@@ -788,7 +791,7 @@
} }
if(symbol.ura){ if(symbol.ura){
ctx.font = (30 * mul) + "px Meiryo, sans-serif" ctx.font = (30 * mul) + "px Meiryo, sans-serif"
ctx.textBaseline = "center" ctx.textBaseline = "middle"
ctx.beginPath() ctx.beginPath()
ctx.arc(currentX, currentY + (17 * mul), (18 * mul), 0, Math.PI * 2) ctx.arc(currentX, currentY + (17 * mul), (18 * mul), 0, Math.PI * 2)
if(action === "strokeText"){ if(action === "strokeText"){
...@@ -797,7 +800,7 @@ ...@@ -797,7 +800,7 @@
}else if(action === "fillText"){ }else if(action === "fillText"){
ctx.strokeStyle = layer.fill ctx.strokeStyle = layer.fill
ctx.lineWidth = 2.5 * mul ctx.lineWidth = 2.5 * mul
ctx.fillText(symbol.text, currentX, currentY) ctx.fillText(symbol.text, currentX, currentY + (17 * mul))
} }
ctx.stroke() ctx.stroke()
}else{ }else{
...@@ -1167,6 +1170,7 @@ ...@@ -1167,6 +1170,7 @@
var firstTop = config.multiplayer ? 0 : 30 var firstTop = config.multiplayer ? 0 : 30
var secondTop = config.multiplayer ? 0 : 8 var secondTop = config.multiplayer ? 0 : 8
config.percentage = Math.max(0, Math.min(1, config.percentage))
var cleared = config.percentage - 1 / 50 >= config.clear var cleared = config.percentage - 1 / 50 >= config.clear
var gaugeW = 14 * 50 var gaugeW = 14 * 50
......
class Circle{ class Circle{
constructor(config){ constructor(config){
// id, ms, type, text, speed, endTime, requiredHits
this.id = config.id this.id = config.id
this.ms = config.start this.ms = config.start
this.originalMS = this.ms this.originalMS = this.ms
...@@ -23,38 +22,13 @@ class Circle{ ...@@ -23,38 +22,13 @@ class Circle{
this.gogoChecked = false this.gogoChecked = false
this.beatMS = config.beatMS this.beatMS = config.beatMS
this.fixedPos = config.fixedPos this.fixedPos = config.fixedPos
} this.branch = config.branch
getMS(){ this.section = config.section
return this.ms
}
getEndTime(){
return this.endTime
}
getType(){
return this.type
}
getLastFrame(){
return this.lastFrame
} }
animate(ms){ animate(ms){
this.animating = true this.animating = true
this.animT = ms this.animT = ms
} }
isAnimated(){
return this.animating
}
getAnimT(){
return this.animT
}
getPlayed(){
return this.isPlayed
}
isAnimationFinished(){
return this.animationEnded
}
endAnimation(){
this.animationEnded = true
}
played(score, big){ played(score, big){
this.score = score this.score = score
this.isPlayed = score <= 0 ? score - 1 : (big ? 2 : 1) this.isPlayed = score <= 0 ? score - 1 : (big ? 2 : 1)
...@@ -65,16 +39,4 @@ class Circle{ ...@@ -65,16 +39,4 @@ class Circle{
this.timesKa++ this.timesKa++
} }
} }
getScore(){
return this.score
}
getID(){
return this.id
}
getText(){
return this.text
}
getSpeed(){
return this.speed
}
} }
\ No newline at end of file
...@@ -8,15 +8,19 @@ class Debug{ ...@@ -8,15 +8,19 @@ class Debug{
this.debugDiv.innerHTML = assets.pages["debug"] this.debugDiv.innerHTML = assets.pages["debug"]
document.body.appendChild(this.debugDiv) document.body.appendChild(this.debugDiv)
this.titleDiv = this.debugDiv.getElementsByClassName("title")[0] this.titleDiv = this.byClass("title")
this.minimiseDiv = this.debugDiv.getElementsByClassName("minimise")[0] this.minimiseDiv = this.byClass("minimise")
this.offsetDiv = this.debugDiv.getElementsByClassName("offset")[0] this.offsetDiv = this.byClass("offset")
this.measureNumDiv = this.debugDiv.getElementsByClassName("measure-num")[0] this.measureNumDiv = this.byClass("measure-num")
this.restartCheckbox = this.debugDiv.getElementsByClassName("change-restart")[0] this.branchHideDiv = this.byClass("branch-hide")
this.autoplayLabel = this.debugDiv.getElementsByClassName("autoplay-label")[0] this.branchSelectDiv = this.byClass("branch-select")
this.autoplayCheckbox = this.debugDiv.getElementsByClassName("autoplay")[0] this.branchSelect = this.branchSelectDiv.getElementsByTagName("select")[0]
this.restartBtn = this.debugDiv.getElementsByClassName("restart-btn")[0] this.branchResetBtn = this.branchSelectDiv.getElementsByClassName("reset")[0]
this.exitBtn = this.debugDiv.getElementsByClassName("exit-btn")[0] this.restartCheckbox = this.byClass("change-restart")
this.autoplayLabel = this.byClass("autoplay-label")
this.autoplayCheckbox = this.byClass("autoplay")
this.restartBtn = this.byClass("restart-btn")
this.exitBtn = this.byClass("exit-btn")
this.moving = false this.moving = false
pageEvents.add(window, ["mousedown", "mouseup", "blur"], this.stopMove.bind(this)) pageEvents.add(window, ["mousedown", "mouseup", "blur"], this.stopMove.bind(this))
...@@ -26,6 +30,8 @@ class Debug{ ...@@ -26,6 +30,8 @@ class Debug{
pageEvents.add(this.restartBtn, "click", this.restartSong.bind(this)) pageEvents.add(this.restartBtn, "click", this.restartSong.bind(this))
pageEvents.add(this.exitBtn, "click", this.clean.bind(this)) pageEvents.add(this.exitBtn, "click", this.clean.bind(this))
pageEvents.add(this.autoplayCheckbox, "change", this.toggleAutoplay.bind(this)) pageEvents.add(this.autoplayCheckbox, "change", this.toggleAutoplay.bind(this))
pageEvents.add(this.branchSelect, "change", this.branchChange.bind(this))
pageEvents.add(this.branchResetBtn, "click", this.branchReset.bind(this))
this.offsetSlider = new InputSlider(this.offsetDiv, -60, 60, 3) this.offsetSlider = new InputSlider(this.offsetDiv, -60, 60, 3)
this.offsetSlider.onchange(this.offsetChange.bind(this)) this.offsetSlider.onchange(this.offsetChange.bind(this))
...@@ -39,6 +45,9 @@ class Debug{ ...@@ -39,6 +45,9 @@ class Debug{
this.updateStatus() this.updateStatus()
pageEvents.send("debug") pageEvents.send("debug")
} }
byClass(name){
return this.debugDiv.getElementsByClassName(name)[0]
}
startMove(event){ startMove(event){
if(event.which === 1){ if(event.which === 1){
event.stopPropagation() event.stopPropagation()
...@@ -88,20 +97,28 @@ class Debug{ ...@@ -88,20 +97,28 @@ class Debug{
} }
updateStatus(){ updateStatus(){
if(debugObj.controller && !this.controller){ if(debugObj.controller && !this.controller){
this.controller = debugObj.controller
this.restartBtn.style.display = "block" this.restartBtn.style.display = "block"
this.autoplayLabel.style.display = "block" this.autoplayLabel.style.display = "block"
if(this.controller.parsedSongData.branches){
this.branchHideDiv.style.display = "block"
}
this.controller = debugObj.controller
var selectedSong = this.controller.selectedSong var selectedSong = this.controller.selectedSong
this.defaultOffset = selectedSong.offset || 0 this.defaultOffset = selectedSong.offset || 0
if(this.songFolder === selectedSong.folder){ if(this.songFolder === selectedSong.folder){
this.offsetChange(this.offsetSlider.get(), true) this.offsetChange(this.offsetSlider.get(), true)
this.branchChange(null, true)
}else{ }else{
this.songFolder = selectedSong.folder this.songFolder = selectedSong.folder
this.offsetSlider.set(this.defaultOffset) this.offsetSlider.set(this.defaultOffset)
this.branchReset(null, true)
} }
var measures = this.controller.parsedSongData.measures var measures = this.controller.parsedSongData.measures.filter((measure, i, array) => {
return i === 0 || Math.abs(measure.ms - array[i - 1].ms) > 0.01
})
this.measureNumSlider.setMinMax(0, measures.length - 1) this.measureNumSlider.setMinMax(0, measures.length - 1)
if(this.measureNum && measures.length > this.measureNum){ if(this.measureNum && measures.length > this.measureNum){
var measureMS = measures[this.measureNum].ms var measureMS = measures[this.measureNum].ms
...@@ -128,6 +145,7 @@ class Debug{ ...@@ -128,6 +145,7 @@ class Debug{
if(this.controller && !debugObj.controller){ if(this.controller && !debugObj.controller){
this.restartBtn.style.display = "" this.restartBtn.style.display = ""
this.autoplayLabel.style.display = "" this.autoplayLabel.style.display = ""
this.branchHideDiv.style.display = ""
this.controller = null this.controller = null
} }
} }
...@@ -142,6 +160,11 @@ class Debug{ ...@@ -142,6 +160,11 @@ class Debug{
songData.measures.forEach(measure => { songData.measures.forEach(measure => {
measure.ms = measure.originalMS + offset measure.ms = measure.originalMS + offset
}) })
if(songData.branches){
songData.branches.forEach(branch => {
branch.ms = branch.originalMS + offset
})
}
if(this.restartCheckbox.checked && !noRestart){ if(this.restartCheckbox.checked && !noRestart){
this.restartSong() this.restartSong()
} }
...@@ -171,21 +194,46 @@ class Debug{ ...@@ -171,21 +194,46 @@ class Debug{
} }
} }
} }
branchChange(event, noRestart){
if(this.controller){
var game = this.controller.game
var name = this.branchSelect.value
game.branch = name === "auto" ? false : name
game.branchSet = name === "auto"
var selectedOption = this.branchSelect.selectedOptions[0]
this.branchSelect.style.background = selectedOption.style.background
if(this.restartCheckbox.checked && !noRestart){
this.restartSong()
}
}
}
branchReset(event, noRestart){
this.branchSelect.value = "auto"
this.branchChange(null, noRestart)
}
clean(){ clean(){
this.offsetSlider.clean() this.offsetSlider.clean()
this.measureNumSlider.clean()
pageEvents.remove(window, ["mousedown", "mouseup", "blur"]) pageEvents.remove(window, ["mousedown", "mouseup", "blur"])
pageEvents.mouseRemove(this) pageEvents.mouseRemove(this)
pageEvents.remove(this.titleDiv, "mousedown")
pageEvents.remove(this.title, "mousedown") pageEvents.remove(this.title, "mousedown")
pageEvents.remove(this.minimiseDiv, "click") pageEvents.remove(this.minimiseDiv, "click")
pageEvents.remove(this.restartBtn, "click") pageEvents.remove(this.restartBtn, "click")
pageEvents.remove(this.exitBtn, "click") pageEvents.remove(this.exitBtn, "click")
pageEvents.remove(this.autoplayCheckbox, "change") pageEvents.remove(this.autoplayCheckbox, "change")
pageEvents.remove(this.branchSelect, "change")
pageEvents.remove(this.branchResetBtn, "click")
delete this.titleDiv delete this.titleDiv
delete this.minimiseDiv delete this.minimiseDiv
delete this.offsetDiv delete this.offsetDiv
delete this.measureNumDiv delete this.measureNumDiv
delete this.branchHideDiv
delete this.branchSelectDiv
delete this.branchSelect
delete this.branchResetBtn
delete this.restartCheckbox delete this.restartCheckbox
delete this.autoplayLabel delete this.autoplayLabel
delete this.autoplayCheckbox delete this.autoplayCheckbox
......
This diff is collapsed.
...@@ -199,7 +199,7 @@ ...@@ -199,7 +199,7 @@
songObj.subtitle = songObj.subtitle_en = subtitle songObj.subtitle = songObj.subtitle_en = subtitle
songObj.preview = meta.demostart ? Math.floor(meta.demostart * 1000) : 0 songObj.preview = meta.demostart ? Math.floor(meta.demostart * 1000) : 0
if(meta.level){ if(meta.level){
songObj.stars[this.courseTypes[diff]] = meta.level songObj.stars[this.courseTypes[diff]] = meta.level + (meta.branch ? " B" : "")
} }
if(meta.wave){ if(meta.wave){
songObj.music = this.otherFiles[dir + meta.wave.toLowerCase()] songObj.music = this.otherFiles[dir + meta.wave.toLowerCase()]
......
...@@ -199,8 +199,8 @@ class Keyboard{ ...@@ -199,8 +199,8 @@ class Keyboard{
if( if(
sound === "don" sound === "don"
&& circle && circle
&& !circle.getPlayed() && !circle.isPlayed
&& circle.getType() === "balloon" && circle.type === "balloon"
&& circle.requiredHits - circle.timesHit <= 1 && circle.requiredHits - circle.timesHit <= 1
){ ){
this.controller.playSound("se_balloon") this.controller.playSound("se_balloon")
......
...@@ -106,7 +106,9 @@ pageEvents.keyAdd(debugObj, "all", "down", event => { ...@@ -106,7 +106,9 @@ pageEvents.keyAdd(debugObj, "all", "down", event => {
}else if(debugObj.state === "minimised"){ }else if(debugObj.state === "minimised"){
debugObj.debug.restore() debugObj.debug.restore()
}else{ }else{
debugObj.debug = new Debug() try{
debugObj.debug = new Debug()
}catch(e){}
} }
} }
if(event.keyCode === 82 && debugObj.debug && debugObj.controller){ if(event.keyCode === 82 && debugObj.debug && debugObj.controller){
......
...@@ -6,12 +6,15 @@ class Mekadon{ ...@@ -6,12 +6,15 @@ class Mekadon{
this.lastHit = -Infinity this.lastHit = -Infinity
} }
play(circle){ play(circle){
var type = circle.getType() var type = circle.type
if((type === "balloon" || type === "drumroll" || type === "daiDrumroll") && this.getMS() > circle.getEndTime()){ if((type === "balloon" || type === "drumroll" || type === "daiDrumroll") && this.getMS() > circle.endTime){
if(circle.section && circle.timesHit === 0){
this.game.resetSection()
}
circle.played(-1, false) circle.played(-1, false)
this.game.updateCurrentCircle() this.game.updateCurrentCircle()
} }
type = circle.getType() type = circle.type
if(type === "balloon"){ if(type === "balloon"){
this.playDrumrollAt(circle, 0, 30) this.playDrumrollAt(circle, 0, 30)
}else if(type === "drumroll" || type === "daiDrumroll"){ }else if(type === "drumroll" || type === "daiDrumroll"){
...@@ -21,7 +24,7 @@ class Mekadon{ ...@@ -21,7 +24,7 @@ class Mekadon{
} }
} }
playAt(circle, ms, score, dai, reverse){ playAt(circle, ms, score, dai, reverse){
var currentMs = circle.getMS() - this.getMS() var currentMs = circle.ms - this.getMS()
if(ms > currentMs - 10){ if(ms > currentMs - 10){
return this.playNow(circle, score, dai, reverse) return this.playNow(circle, score, dai, reverse)
} }
...@@ -36,18 +39,19 @@ class Mekadon{ ...@@ -36,18 +39,19 @@ class Mekadon{
} }
} }
miss(circle){ miss(circle){
var currentMs = circle.getMS() - this.getMS() var currentMs = circle.ms - this.getMS()
if(0 >= currentMs - 10){ if(0 >= currentMs - 10){
this.controller.displayScore(0, true) this.controller.displayScore(0, true)
this.game.updateCurrentCircle() this.game.updateCurrentCircle()
this.game.updateCombo(0) this.game.updateCombo(0)
this.game.updateGlobalScore(0, 1, circle.gogoTime) this.game.updateGlobalScore(0, 1, circle.gogoTime)
this.game.sectionNotes.push(0)
return true return true
} }
} }
playNow(circle, score, dai, reverse){ playNow(circle, score, dai, reverse){
var kbd = this.controller.getBindings() var kbd = this.controller.getBindings()
var type = circle.getType() var type = circle.type
var keyDai = false var keyDai = false
var playDai = !dai || dai === 2 var playDai = !dai || dai === 2
var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll" var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll"
...@@ -55,7 +59,7 @@ class Mekadon{ ...@@ -55,7 +59,7 @@ class Mekadon{
if(drumrollNotes){ if(drumrollNotes){
var ms = this.getMS() var ms = this.getMS()
}else{ }else{
var ms = circle.getMS() var ms = circle.ms
} }
if(reverse){ if(reverse){
...@@ -95,6 +99,10 @@ class Mekadon{ ...@@ -95,6 +99,10 @@ class Mekadon{
this.game.updateGlobalScore(score, keyDai ? 2 : 1, circle.gogoTime) this.game.updateGlobalScore(score, keyDai ? 2 : 1, circle.gogoTime)
this.game.updateCurrentCircle() this.game.updateCurrentCircle()
circle.played(score, keyDai) circle.played(score, keyDai)
if(circle.section){
this.game.resetSection()
}
this.game.sectionNotes.push(score === 450 ? 1 : (score === 230 ? 0.5 : 0))
} }
this.lastHit = ms this.lastHit = ms
return true return true
......
...@@ -109,6 +109,7 @@ class P2Connection{ ...@@ -109,6 +109,7 @@ class P2Connection{
this.dai = 2 this.dai = 2
this.kaAmount = 0 this.kaAmount = 0
this.results = false this.results = false
this.branch = "normal"
break break
case "gameend": case "gameend":
this.otherConnected = false this.otherConnected = false
...@@ -141,6 +142,10 @@ class P2Connection{ ...@@ -141,6 +142,10 @@ class P2Connection{
this.kaAmount = response.value.kaAmount this.kaAmount = response.value.kaAmount
} }
break break
case "branch":
this.branch = response.value
this.branchSet = false
break
case "session": case "session":
this.clearMessage("users") this.clearMessage("users")
this.otherConnected = true this.otherConnected = true
...@@ -161,10 +166,10 @@ class P2Connection{ ...@@ -161,10 +166,10 @@ class P2Connection{
} }
play(circle, mekadon){ play(circle, mekadon){
if(this.otherConnected || this.notes.length > 0){ if(this.otherConnected || this.notes.length > 0){
var type = circle.getType() var type = circle.type
var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll" var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll"
if(drumrollNotes && mekadon.getMS() > circle.getEndTime()){ if(drumrollNotes && mekadon.getMS() > circle.endTime){
circle.played(-1, false) circle.played(-1, false)
mekadon.game.updateCurrentCircle() mekadon.game.updateCurrentCircle()
} }
...@@ -177,7 +182,7 @@ class P2Connection{ ...@@ -177,7 +182,7 @@ class P2Connection{
var note = this.notes[0] var note = this.notes[0]
if(note.score >= 0){ if(note.score >= 0){
var dai = 1 var dai = 1
if(circle.getType() === "daiDon" || circle.getType() === "daiKa"){ if(circle.type === "daiDon" || circle.type === "daiKa"){
dai = this.dai dai = this.dai
} }
if(mekadon.playAt(circle, note.ms, note.score, dai, note.reverse)){ if(mekadon.playAt(circle, note.ms, note.score, dai, note.reverse)){
......
...@@ -59,7 +59,9 @@ ...@@ -59,7 +59,9 @@
if(!(courseName in courses)){ if(!(courseName in courses)){
courses[courseName] = {} courses[courseName] = {}
} }
courses[courseName][name] = currentCourse[name] if(name !== "branch"){
courses[courseName][name] = currentCourse[name]
}
} }
courses[courseName].start = lineNum + 1 courses[courseName].start = lineNum + 1
courses[courseName].end = this.data.length courses[courseName].end = this.data.length
...@@ -70,6 +72,8 @@ ...@@ -70,6 +72,8 @@
hasSong = true hasSong = true
courses[courseName].end = lineNum courses[courseName].end = lineNum
} }
}else if(name.startsWith("branchstart") && inSong){
courses[courseName].branch = true
} }
}else if(!inSong){ }else if(!inSong){
...@@ -128,9 +132,13 @@ ...@@ -128,9 +132,13 @@
var balloons = meta.balloon || [] var balloons = meta.balloon || []
var lastDrumroll = false var lastDrumroll = false
var branch = false var branch = false
var branchType var branchObj = {}
var branchPreference = "m" var currentBranch = false
var branchSettings = {}
var branchFirstMeasure = false
var sectionBegin = true
var currentMeasure = [] var currentMeasure = []
var firstNote = true var firstNote = true
...@@ -138,19 +146,21 @@ ...@@ -138,19 +146,21 @@
var circleID = 0 var circleID = 0
var pushMeasure = () => { var pushMeasure = () => {
if(barLine){ var note = currentMeasure[0]
var note = currentMeasure[0] if(note){
if(note){ var speed = note.bpm * note.scroll / 60
var speed = note.bpm * note.scroll / 60 }else{
}else{ var speed = bpm * scroll / 60
var speed = bpm * scroll / 60
}
this.measures.push({
ms: ms,
originalMS: ms,
speed: speed
})
} }
this.measures.push({
ms: ms,
originalMS: ms,
speed: speed,
visible: barLine,
branch: currentBranch,
branchFirst: branchFirstMeasure
})
branchFirstMeasure = false
if(currentMeasure.length){ if(currentMeasure.length){
for(var i = 0; i < currentMeasure.length; i++){ for(var i = 0; i < currentMeasure.length; i++){
var note = currentMeasure[i] var note = currentMeasure[i]
...@@ -182,7 +192,9 @@ ...@@ -182,7 +192,9 @@
gogoTime: note.gogo, gogoTime: note.gogo,
endTime: note.endTime, endTime: note.endTime,
requiredHits: note.requiredHits, requiredHits: note.requiredHits,
beatMS: 60000 / note.bpm beatMS: 60000 / note.bpm,
branch: currentBranch,
section: note.section
}) })
if(lastDrumroll === note){ if(lastDrumroll === note){
lastDrumroll = circleObj lastDrumroll = circleObj
...@@ -204,59 +216,113 @@ ...@@ -204,59 +216,113 @@
var line = line.slice(1).toLowerCase() var line = line.slice(1).toLowerCase()
var [name, value] = this.split(line, " ") var [name, value] = this.split(line, " ")
if(!branch || branch && branchType === branchPreference){
switch(name){
case "gogostart":
gogo = true
break
case "gogoend":
gogo = false
break
case "bpmchange":
bpm = parseFloat(value)
break
case "scroll":
scroll = parseFloat(value)
break
case "measure":
var [numerator, denominator] = value.split("/")
measure = numerator / denominator * 4
break
case "delay":
ms += (parseFloat(value) || 0) * 1000
break
case "barlineon":
barLine = true
break
case "barlineoff":
barLine = false
break
}
}
switch(name){ switch(name){
case "gogostart":
gogo = true
break
case "gogoend":
gogo = false
break
case "bpmchange":
bpm = parseFloat(value) || bpm
break
case "scroll":
scroll = parseFloat(value) || scroll
break
case "measure":
var [numerator, denominator] = value.split("/")
measure = numerator / denominator * 4 || measure
break
case "delay":
ms += (parseFloat(value) || 0) * 1000
break
case "barlineon":
barLine = true
break
case "barlineoff":
barLine = false
break
case "branchstart": case "branchstart":
branch = true branch = true
branchType = "" currentBranch = false
branchFirstMeasure = true
branchSettings = {
ms: ms,
gogo: gogo,
bpm: bpm,
scroll: scroll,
sectionBegin: sectionBegin
}
value = value.split(",") value = value.split(",")
var forkType = value[0].toLowerCase() if(!this.branches){
if(forkType === "r" || parseFloat(value[2]) <= 100){ this.branches = []
branchPreference = "m" }
}else if(parseFloat(value[1]) <= 100){ var req = {
branchPreference = "e" advanced: parseFloat(value[1]) || 0,
master: parseFloat(value[2]) || 0
}
if(req.advanced > 0){
var active = req.master > 0 ? "normal" : "master"
}else{ }else{
branchPreference = "n" var active = req.master > 0 ? "advanced" : "master"
}
branchObj = {
ms: ms,
originalMS: ms,
active: active,
type: value[0].trim().toLowerCase() === "r" ? "drumroll" : "accuracy",
requirement: req
}
this.branches.push(branchObj)
if(this.measures.length === 1 && branchObj.type === "drumroll"){
for(var i = circles.length; i--;){
var circle = circles[i]
if(circle.endTime && circle.type === "drumroll" || circle.type === "daiDrumroll" || circle.type === "balloon"){
this.measures.push({
ms: circle.endTime,
originalMS: circle.endTime,
speed: circle.bpm * circle.scroll / 60,
visible: false,
branch: circle.branch
})
break
}
}
}
if(this.measures.length !== 0){
this.measures[this.measures.length - 1].nextBranch = branchObj
} }
break break
case "branchend": case "branchend":
case "section":
branch = false branch = false
currentBranch = false
break
case "section":
sectionBegin = true
if(branch && !currentBranch){
branchSettings.sectionBegin = true
}
break break
case "n": case "e": case "m": case "n": case "e": case "m":
branchType = name if(!branch){
break
}
ms = branchSettings.ms
gogo = branchSettings.gogo
bpm = branchSettings.bpm
scroll = branchSettings.scroll
sectionBegin = branchSettings.sectionBegin
branchFirstMeasure = true
var branchName = name === "m" ? "master" : (name === "e" ? "advanced" : "normal")
currentBranch = {
name: branchName,
active: branchName === branchObj.active
}
branchObj[branchName] = currentBranch
break break
} }
}else if(!branch || branch && branchType === branchPreference){ }else{
var string = line.split("") var string = line.split("")
...@@ -278,8 +344,10 @@ ...@@ -278,8 +344,10 @@
txt: type.txt, txt: type.txt,
gogo: gogo, gogo: gogo,
bpm: bpm, bpm: bpm,
scroll: scroll scroll: scroll,
section: sectionBegin
} }
sectionBegin = false
if(lastDrumroll){ if(lastDrumroll){
circleObj.endDrumroll = lastDrumroll circleObj.endDrumroll = lastDrumroll
lastDrumroll = false lastDrumroll = false
...@@ -293,15 +361,19 @@ ...@@ -293,15 +361,19 @@
txt: type.txt, txt: type.txt,
gogo: gogo, gogo: gogo,
bpm: bpm, bpm: bpm,
scroll: scroll scroll: scroll,
section: sectionBegin
} }
sectionBegin = false
if(lastDrumroll){ if(lastDrumroll){
if(symbol === "9"){ if(symbol === "9"){
currentMeasure.push({ currentMeasure.push({
endDrumroll: lastDrumroll, endDrumroll: lastDrumroll,
bpm: bpm, bpm: bpm,
scroll: scroll scroll: scroll,
section: sectionBegin
}) })
sectionBegin = false
lastDrumroll = false lastDrumroll = false
}else{ }else{
currentMeasure.push({ currentMeasure.push({
...@@ -327,8 +399,10 @@ ...@@ -327,8 +399,10 @@
currentMeasure.push({ currentMeasure.push({
endDrumroll: lastDrumroll, endDrumroll: lastDrumroll,
bpm: bpm, bpm: bpm,
scroll: scroll scroll: scroll,
section: sectionBegin
}) })
sectionBegin = false
lastDrumroll = false lastDrumroll = false
}else{ }else{
currentMeasure.push({ currentMeasure.push({
...@@ -359,6 +433,11 @@ ...@@ -359,6 +433,11 @@
lastDrumroll.originalEndTime = ms lastDrumroll.originalEndTime = ms
} }
if(this.branches){
circles.sort((a, b) => a.ms > b.ms ? 1 : -1)
this.measures.sort((a, b) => a.ms > b.ms ? 1 : -1)
circles.forEach((circle, i) => circle.id = i + 1)
}
return circles return circles
} }
} }
...@@ -351,7 +351,7 @@ class SongSelect{ ...@@ -351,7 +351,7 @@ class SongSelect{
down: code == 40 down: code == 40
// Down // Down
} }
if(key.cancel && event){ if(event && (code == 27 || code == 8)){
event.preventDefault() event.preventDefault()
} }
if(this.state.screen === "song"){ if(this.state.screen === "song"){
...@@ -1322,27 +1322,47 @@ class SongSelect{ ...@@ -1322,27 +1322,47 @@ class SongSelect{
outlineSize: currentUra ? this.songAsset.letterBorder : 0 outlineSize: currentUra ? this.songAsset.letterBorder : 0
}) })
}) })
var songStars = currentUra ? currentSong.stars[4] : currentSong.stars[i] var songStarsArray = (currentUra ? currentSong.stars[4] : currentSong.stars[i]).toString().split(" ")
for(var j = 0; j < 10; j++){ var songStars = songStarsArray[0]
if(songSel){ var songBranch = songStarsArray[1] === "B"
var yPos = _y + 113 + j * 17 var elapsedMS = this.state.screenMS > this.state.moveMS || !songSel ? this.state.screenMS : this.state.moveMS
}else{ var fade = ((ms - elapsedMS) % 2000) / 2000
var yPos = _y + 178 + j * 19.5 if(songBranch && fade > 0.25 && fade < 0.75){
} this.draw.verticalText({
if(10 - j > songStars){ ctx: ctx,
ctx.fillStyle = currentUra ? "#187085" : (songSel ? "#e97526" : "#e7e7e7") text: strings.songBranch,
ctx.beginPath() x: _x,
ctx.arc(_x, yPos, songSel ? 4.5 : 5, 0, Math.PI * 2) y: _y + (songSel ? 110 : 185),
ctx.fill() width: songSel ? 44 : 56,
}else{ height: songSel ? 160 : 170,
this.draw.diffStar({ fill: songSel && !currentUra ? "#c85200" : "#fff",
ctx: ctx, fontSize: songSel ? 25 : 27,
songSel: songSel, fontFamily: songSel ? "Meiryo, Microsoft YaHei, sans-serif" : this.font,
ura: currentUra, outline: songSel ? false : "#f22666",
x: _x, outlineSize: songSel ? 0 : this.songAsset.letterBorder
y: yPos, })
ratio: ratio }else{
}) for(var j = 0; j < 10; j++){
if(songSel){
var yPos = _y + 113 + j * 17
}else{
var yPos = _y + 178 + j * 19.5
}
if(10 - j > songStars){
ctx.fillStyle = currentUra ? "#187085" : (songSel ? "#e97526" : "#e7e7e7")
ctx.beginPath()
ctx.arc(_x, yPos, songSel ? 4.5 : 5, 0, Math.PI * 2)
ctx.fill()
}else{
this.draw.diffStar({
ctx: ctx,
songSel: songSel,
ura: currentUra,
x: _x,
y: yPos,
ratio: ratio
})
}
} }
} }
var currentDiff = this.selectedDiff - this.diffOptions.length var currentDiff = this.selectedDiff - this.diffOptions.length
......
...@@ -86,7 +86,7 @@ class SoundGain{ ...@@ -86,7 +86,7 @@ class SoundGain{
this.volume = amount this.volume = amount
} }
setCrossfade(amount){ setCrossfade(amount){
this.setVolume(Math.pow(Math.sin(Math.PI / 2 * amount), 1 / 4)) this.setVolume(Math.sqrt(Math.sin(Math.PI / 2 * amount)))
} }
fadeIn(duration, time, absolute){ fadeIn(duration, time, absolute){
this.fadeVolume(0, this.volume * this.volume, duration, time, absolute) this.fadeVolume(0, this.volume * this.volume, duration, time, absolute)
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
this.normal = "ふつう" this.normal = "ふつう"
this.hard = "むずかしい" this.hard = "むずかしい"
this.oni = "おに" this.oni = "おに"
this.songBranch = "譜面分岐あり"
this.sessionStart = "オンラインセッションを開始する!" this.sessionStart = "オンラインセッションを開始する!"
this.sessionEnd = "オンラインセッションを終了する" this.sessionEnd = "オンラインセッションを終了する"
this.loading = "ロード中..." this.loading = "ロード中..."
...@@ -53,6 +54,11 @@ ...@@ -53,6 +54,11 @@
this.good = "" this.good = ""
this.ok = "" this.ok = ""
this.bad = "不可" this.bad = "不可"
this.branch = {
"normal": "普通譜面",
"advanced": "玄人譜面",
"master": "達人譜面"
}
this.pauseOptions = [ this.pauseOptions = [
"演奏をつづける", "演奏をつづける",
"はじめからやりなおす", "はじめからやりなおす",
...@@ -135,6 +141,7 @@ function StringsEn(){ ...@@ -135,6 +141,7 @@ function StringsEn(){
this.normal = "Normal" this.normal = "Normal"
this.hard = "Hard" this.hard = "Hard"
this.oni = "Extreme" this.oni = "Extreme"
this.songBranch = "Diverge Notes"
this.sessionStart = "Begin an Online Session!" this.sessionStart = "Begin an Online Session!"
this.sessionEnd = "End Online Session" this.sessionEnd = "End Online Session"
this.loading = "Loading..." this.loading = "Loading..."
...@@ -154,6 +161,11 @@ function StringsEn(){ ...@@ -154,6 +161,11 @@ function StringsEn(){
this.good = "GOOD" this.good = "GOOD"
this.ok = "OK" this.ok = "OK"
this.bad = "BAD" this.bad = "BAD"
this.branch = {
"normal": "Normal",
"advanced": "Professional",
"master": "Master"
}
this.pauseOptions = [ this.pauseOptions = [
"Continue", "Continue",
"Retry", "Retry",
...@@ -236,6 +248,7 @@ function StringsCn(){ ...@@ -236,6 +248,7 @@ function StringsCn(){
this.normal = "普通" this.normal = "普通"
this.hard = "困难" this.hard = "困难"
this.oni = "魔王" this.oni = "魔王"
this.songBranch = "有谱面分歧"
this.sessionStart = "开始在线会话!" this.sessionStart = "开始在线会话!"
this.sessionEnd = "结束在线会话" this.sessionEnd = "结束在线会话"
this.loading = "加载中..." this.loading = "加载中..."
...@@ -255,6 +268,11 @@ function StringsCn(){ ...@@ -255,6 +268,11 @@ function StringsCn(){
this.good = "" this.good = ""
this.ok = "" this.ok = ""
this.bad = "不可" this.bad = "不可"
this.branch = {
"normal": "一般谱面",
"advanced": "进阶谱面",
"master": "达人谱面"
}
this.pauseOptions = [ this.pauseOptions = [
"继续演奏", "继续演奏",
"从头开始", "从头开始",
...@@ -337,6 +355,7 @@ function StringsTw(){ ...@@ -337,6 +355,7 @@ function StringsTw(){
this.normal = "普通" this.normal = "普通"
this.hard = "困難" this.hard = "困難"
this.oni = "魔王" this.oni = "魔王"
this.songBranch = "有譜面分歧"
this.sessionStart = "開始多人模式!" this.sessionStart = "開始多人模式!"
this.sessionEnd = "結束多人模式" this.sessionEnd = "結束多人模式"
this.loading = "讀取中..." this.loading = "讀取中..."
...@@ -356,6 +375,11 @@ function StringsTw(){ ...@@ -356,6 +375,11 @@ function StringsTw(){
this.good = "" this.good = ""
this.ok = "" this.ok = ""
this.bad = "不可" this.bad = "不可"
this.branch = {
"normal": "一般譜面",
"advanced": "進階譜面",
"master": "達人譜面"
}
this.pauseOptions = [ this.pauseOptions = [
"繼續演奏", "繼續演奏",
"從頭開始", "從頭開始",
...@@ -438,6 +462,7 @@ function StringsKo(){ ...@@ -438,6 +462,7 @@ function StringsKo(){
this.normal = "보통" this.normal = "보통"
this.hard = "어려움" this.hard = "어려움"
this.oni = "귀신" this.oni = "귀신"
this.songBranch = "악보 분기 있습니다"
this.sessionStart = "온라인 세션 시작!" this.sessionStart = "온라인 세션 시작!"
this.sessionEnd = "온라인 세션 끝내기" this.sessionEnd = "온라인 세션 끝내기"
this.loading = "로딩 중..." this.loading = "로딩 중..."
...@@ -457,6 +482,11 @@ function StringsKo(){ ...@@ -457,6 +482,11 @@ function StringsKo(){
this.good = "얼쑤" this.good = "얼쑤"
this.ok = "좋다" this.ok = "좋다"
this.bad = "에구" this.bad = "에구"
this.branch = {
"normal": "보통 악보",
"advanced": "현인 악보",
"master": "달인 악보"
}
this.pauseOptions = [ this.pauseOptions = [
"연주 계속하기", "연주 계속하기",
"처음부터 다시", "처음부터 다시",
......
...@@ -18,7 +18,11 @@ class Titlescreen{ ...@@ -18,7 +18,11 @@ class Titlescreen{
this.setLang(allStrings[this.lang], true) this.setLang(allStrings[this.lang], true)
if(songId){ if(songId){
this.goNext() if(localStorage.getItem("tutorial") === "true"){
new SongSelect(false, false, this.touched, this.songId)
}else{
new Tutorial(false, this.songId)
}
}else{ }else{
this.addLangs() this.addLangs()
......
This diff is collapsed.
...@@ -9,6 +9,17 @@ ...@@ -9,6 +9,17 @@
<div class="measure-num input-slider"> <div class="measure-num input-slider">
<span class="reset">x</span><input type="text" value="" readonly><span class="minus">-</span><span class="plus">+</span> <span class="reset">x</span><input type="text" value="" readonly><span class="minus">-</span><span class="plus">+</span>
</div> </div>
<div class="branch-hide">
<div>Branch:</div>
<div class="branch-select select">
<span class="reset">x</span><select>
<option value="auto" selected style="background:#fff">Auto</option>
<option value="normal" style="background:#ccc">Normal</option>
<option value="advanced" style="background:#bdf">Professional</option>
<option value="master" style="background:#ebf">Master</option>
</select>
</div>
</div>
<label><input class="change-restart" type="checkbox">Restart on change</label> <label><input class="change-restart" type="checkbox">Restart on change</label>
<label class="autoplay-label"><input class="autoplay" type="checkbox">Auto play</label> <label class="autoplay-label"><input class="autoplay" type="checkbox">Auto play</label>
<div class="bottom-btns"> <div class="bottom-btns">
......
...@@ -185,6 +185,7 @@ async def connection(ws, path): ...@@ -185,6 +185,7 @@ async def connection(ws, path):
if "other_user" in user and "ws" in user["other_user"]: if "other_user" in user and "ws" in user["other_user"]:
if type == "note"\ if type == "note"\
or type == "drumroll"\ or type == "drumroll"\
or type == "branch"\
or type == "gameresults": or type == "gameresults":
await user["other_user"]["ws"].send(msgobj(type, value)) await user["other_user"]["ws"].send(msgobj(type, value))
elif type == "songsel" and user["session"]: elif type == "songsel" and user["session"]:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment