Merge branch 'master' into cat-jump
This commit is contained in:
@@ -29,23 +29,30 @@
|
||||
this.endButton.innerText = strings.tutorial.ok
|
||||
this.endButton.setAttribute("alt", strings.tutorial.ok)
|
||||
|
||||
this.items = []
|
||||
|
||||
var versionUrl = gameConfig._version.url
|
||||
this.getLink(this.linkIssues).href = versionUrl + "issues"
|
||||
|
||||
this.items.push(this.linkIssues)
|
||||
|
||||
var contactEmail = gameConfig.email
|
||||
if (typeof contactEmail === 'string') {
|
||||
this.hasEmail = typeof contactEmail === "string"
|
||||
if(this.hasEmail){
|
||||
this.linkEmail.setAttribute("alt", contactEmail)
|
||||
this.getLink(this.linkEmail).href = "mailto:" + contactEmail
|
||||
this.getLink(this.linkEmail).text = contactEmail
|
||||
} else {
|
||||
this.linkEmail.style.display = "none"
|
||||
this.getLink(this.linkEmail).innerText = contactEmail
|
||||
this.items.push(this.linkEmail)
|
||||
}else{
|
||||
this.linkEmail.parentNode.removeChild(this.linkEmail)
|
||||
}
|
||||
|
||||
|
||||
pageEvents.add(this.linkIssues, ["click", "touchend"], this.linkButton.bind(this))
|
||||
pageEvents.add(this.linkEmail, ["click", "touchend"], this.linkButton.bind(this))
|
||||
if(this.hasEmail){
|
||||
pageEvents.add(this.linkEmail, ["click", "touchend"], this.linkButton.bind(this))
|
||||
}
|
||||
pageEvents.add(this.endButton, ["mousedown", "touchstart"], this.onEnd.bind(this))
|
||||
this.items = [this.linkIssues, this.linkEmail, this.endButton]
|
||||
this.selected = 2
|
||||
this.items.push(this.endButton)
|
||||
this.selected = this.items.length - 1
|
||||
|
||||
this.keyboard = new Keyboard({
|
||||
confirm: ["enter", "space", "don_l", "don_r"],
|
||||
@@ -146,6 +153,8 @@
|
||||
}
|
||||
}
|
||||
diag.push("Language: " + strings.id + userLangStr)
|
||||
var latency = settings.getItem("latency")
|
||||
diag.push("Audio Latency: " + (latency.audio > 0 ? "+" : "") + latency.audio.toString() + "ms, Video Latency: " + (latency.video > 0 ? "+" : "") + latency.video.toString() + "ms")
|
||||
var errorObj = {}
|
||||
if(localStorage["lastError"]){
|
||||
try{
|
||||
@@ -195,7 +204,9 @@
|
||||
}
|
||||
|
||||
var issueBody = strings.about.issueTemplate + "\n\n\n\n" + diag
|
||||
this.getLink(this.linkEmail).href += "?body=" + encodeURIComponent(issueBody.replace(/\n/g, "<br>\r\n"))
|
||||
if(this.hasEmail){
|
||||
this.getLink(this.linkEmail).href += "?body=" + encodeURIComponent(issueBody.replace(/\n/g, "<br>\r\n"))
|
||||
}
|
||||
|
||||
return diag
|
||||
}
|
||||
@@ -214,7 +225,9 @@
|
||||
this.keyboard.clean()
|
||||
this.gamepad.clean()
|
||||
pageEvents.remove(this.linkIssues, ["click", "touchend"])
|
||||
pageEvents.remove(this.linkEmail, ["click", "touchend"])
|
||||
if(this.hasEmail){
|
||||
pageEvents.remove(this.linkEmail, ["click", "touchend"])
|
||||
}
|
||||
pageEvents.remove(this.endButton, ["mousedown", "touchstart"])
|
||||
if(this.textarea){
|
||||
pageEvents.remove(this.textarea, ["focus", "blur"])
|
||||
|
||||
@@ -91,26 +91,8 @@ var assets = {
|
||||
"se_ka.wav",
|
||||
"se_pause.wav",
|
||||
"se_jump.wav",
|
||||
|
||||
"v_combo_50_meka.wav",
|
||||
"v_combo_100_meka.wav",
|
||||
"v_combo_200_meka.wav",
|
||||
"v_combo_300_meka.wav",
|
||||
"v_combo_400_meka.wav",
|
||||
"v_combo_500_meka.wav",
|
||||
"v_combo_600_meka.wav",
|
||||
"v_combo_700_meka.wav",
|
||||
"v_combo_800_meka.wav",
|
||||
"v_combo_900_meka.wav",
|
||||
"v_combo_1000_meka.wav",
|
||||
"v_combo_1100_meka.wav",
|
||||
"v_combo_1200_meka.wav",
|
||||
"v_combo_1300_meka.wav",
|
||||
"v_combo_1400_meka.wav",
|
||||
"v_combo_over1500_meka.wav",
|
||||
"se_calibration.wav",
|
||||
|
||||
"v_fullcombo_meka.wav",
|
||||
"v_renda_meka.wav",
|
||||
"v_results.wav",
|
||||
"v_sanka.wav",
|
||||
"v_songsel.wav",
|
||||
@@ -128,23 +110,6 @@ var assets = {
|
||||
"se_results_countup.wav",
|
||||
"se_results_crown.wav",
|
||||
|
||||
"v_combo_50.wav",
|
||||
"v_combo_100.wav",
|
||||
"v_combo_200.wav",
|
||||
"v_combo_300.wav",
|
||||
"v_combo_400.wav",
|
||||
"v_combo_500.wav",
|
||||
"v_combo_600.wav",
|
||||
"v_combo_700.wav",
|
||||
"v_combo_800.wav",
|
||||
"v_combo_900.wav",
|
||||
"v_combo_1000.wav",
|
||||
"v_combo_1100.wav",
|
||||
"v_combo_1200.wav",
|
||||
"v_combo_1300.wav",
|
||||
"v_combo_1400.wav",
|
||||
"v_combo_over1500.wav",
|
||||
|
||||
"v_fullcombo.wav",
|
||||
"v_renda.wav",
|
||||
"v_results_fullcombo.wav",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
class CanvasCache{
|
||||
constructor(w, h, scale){
|
||||
constructor(noSmoothing, w, h, scale){
|
||||
this.noSmoothing = noSmoothing
|
||||
if(w){
|
||||
this.resize(w, h, scale)
|
||||
}
|
||||
@@ -11,6 +12,9 @@ class CanvasCache{
|
||||
this.map = new Map()
|
||||
this.canvas = document.createElement("canvas")
|
||||
this.ctx = this.canvas.getContext("2d")
|
||||
if(this.noSmoothing){
|
||||
this.ctx.imageSmoothingEnabled = false
|
||||
}
|
||||
}
|
||||
this.scale = scale
|
||||
this.x = 0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class CanvasDraw{
|
||||
constructor(){
|
||||
constructor(noSmoothing){
|
||||
this.diffStarPath = new Path2D(vectors.diffStar)
|
||||
this.longVowelMark = new Path2D(vectors.longVowelMark)
|
||||
|
||||
@@ -68,7 +68,8 @@
|
||||
emCap: /[MWMW]/,
|
||||
rWidth: /[abdfIjo-rtvabdfIjo-rtv]/,
|
||||
lWidth: /[ilil]/,
|
||||
ura: /\s*[\((]裏[\))]$/
|
||||
ura: /\s*[\((]裏[\))]$/,
|
||||
cjk: /[\u3040-ゞ゠-ヾ一-\u9ffe]/
|
||||
}
|
||||
|
||||
var numbersFull = "0123456789"
|
||||
@@ -78,10 +79,12 @@
|
||||
this.numbersFullToHalf[numbersFull[i]] = numbersHalf[i]
|
||||
this.numbersFullToHalf[numbersHalf[i]] = numbersHalf[i]
|
||||
}
|
||||
this.wrapOn = [" ", "\n", "%s"]
|
||||
this.stickySymbols = "!,.:;?~‐–‼、。々〜ぁぃぅぇぉっゃゅょァィゥェォッャュョ・ーヽヾ!:;?"
|
||||
|
||||
this.songFrameCache = new CanvasCache()
|
||||
this.diffStarCache = new CanvasCache()
|
||||
this.crownCache = new CanvasCache()
|
||||
this.songFrameCache = new CanvasCache(noSmoothing)
|
||||
this.diffStarCache = new CanvasCache(noSmoothing)
|
||||
this.crownCache = new CanvasCache(noSmoothing)
|
||||
|
||||
this.tmpCanvas = document.createElement("canvas")
|
||||
this.tmpCtx = this.tmpCanvas.getContext("2d")
|
||||
@@ -818,6 +821,163 @@
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
wrappingText(config){
|
||||
var ctx = config.ctx
|
||||
var inputText = config.text.toString()
|
||||
var words = []
|
||||
var start = 0
|
||||
var substituteIndex = 0
|
||||
while(start < inputText.length){
|
||||
var character = inputText.slice(start, start + 1)
|
||||
if(words.length !== 0){
|
||||
var previous = words[words.length - 1]
|
||||
if(!previous.substitute && previous !== "\n" && this.stickySymbols.indexOf(character) !== -1){
|
||||
words[words.length - 1] += character
|
||||
start++
|
||||
continue
|
||||
}
|
||||
}
|
||||
var index = Infinity
|
||||
var currentIndex = inputText.slice(start).search(this.regex.cjk)
|
||||
if(currentIndex !== -1){
|
||||
index = start + currentIndex
|
||||
var on = inputText.charAt(index)
|
||||
}
|
||||
for(var i = 0; i < this.wrapOn.length; i++){
|
||||
var currentIndex = inputText.indexOf(this.wrapOn[i], start)
|
||||
if(currentIndex !== -1 && currentIndex < index){
|
||||
var on = this.wrapOn[i]
|
||||
index = currentIndex
|
||||
}
|
||||
}
|
||||
if(index === Infinity){
|
||||
if(start !== inputText.length){
|
||||
words.push(inputText.slice(start, inputText.length))
|
||||
}
|
||||
break
|
||||
}
|
||||
var end = index + (on === " " ? 1 : 0)
|
||||
if(start !== end){
|
||||
words.push(inputText.slice(start, end))
|
||||
}
|
||||
if(on === "%s" && config.substitute){
|
||||
words.push({
|
||||
substitute: true,
|
||||
index: substituteIndex,
|
||||
width: config.substitute(config, substituteIndex, true) || 0
|
||||
})
|
||||
substituteIndex++
|
||||
}else if(on !== " "){
|
||||
words.push(on)
|
||||
}
|
||||
start = index + on.length
|
||||
}
|
||||
|
||||
ctx.save()
|
||||
|
||||
var bold = this.bold(config.fontFamily)
|
||||
ctx.font = bold + config.fontSize + "px " + config.fontFamily
|
||||
ctx.textBaseline = config.baseline || "top"
|
||||
ctx.textAlign = "left"
|
||||
ctx.fillStyle = config.fill
|
||||
var lineHeight = config.lineHeight || config.fontSize
|
||||
|
||||
var x = 0
|
||||
var y = 0
|
||||
var totalW = 0
|
||||
var totalH = 0
|
||||
var line = ""
|
||||
var toDraw = []
|
||||
var lastWidth = 0
|
||||
|
||||
var addToDraw = obj => {
|
||||
toDraw.push(obj)
|
||||
if(x + lastWidth > totalW){
|
||||
totalW = x + lastWidth
|
||||
}
|
||||
if(y + lineHeight > totalH){
|
||||
totalH = y + lineHeight
|
||||
}
|
||||
}
|
||||
var recenter = () => {
|
||||
if(config.textAlign === "center"){
|
||||
for(var j in toDraw){
|
||||
if(toDraw[j].y === y){
|
||||
toDraw[j].x += (config.width - x - lastWidth) / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(var i in words){
|
||||
var skip = words[i].substitute || words[i] === "\n"
|
||||
if(!skip){
|
||||
var currentWidth = ctx.measureText(line + words[i]).width
|
||||
}
|
||||
if(skip || (x !== 0 || line) && x + currentWidth > config.width){
|
||||
if(line){
|
||||
addToDraw({
|
||||
text: line,
|
||||
x: x, y: y
|
||||
})
|
||||
}
|
||||
if(words[i].substitute){
|
||||
line = ""
|
||||
var currentWidth = words[i].width
|
||||
if(x + lastWidth + currentWidth > config.width){
|
||||
recenter()
|
||||
x = 0
|
||||
y += lineHeight
|
||||
lastWidth = 0
|
||||
}
|
||||
addToDraw({
|
||||
substitute: true,
|
||||
index: words[i].index,
|
||||
x: x + lastWidth, y: y
|
||||
})
|
||||
x += lastWidth + currentWidth
|
||||
lastWidth = currentWidth
|
||||
}else{
|
||||
recenter()
|
||||
x = 0
|
||||
y += lineHeight
|
||||
line = words[i] === "\n" ? "" : words[i]
|
||||
lastWidth = ctx.measureText(line).width
|
||||
}
|
||||
}else{
|
||||
line += words[i]
|
||||
lastWidth = currentWidth
|
||||
}
|
||||
}
|
||||
if(line){
|
||||
addToDraw({
|
||||
text: line,
|
||||
x: x, y: y
|
||||
})
|
||||
recenter()
|
||||
}
|
||||
|
||||
var addX = 0
|
||||
var addY = 0
|
||||
if(config.verticalAlign === "middle"){
|
||||
addY = ((config.height || 0) - totalH) / 2
|
||||
}
|
||||
for(var i in toDraw){
|
||||
var x = config.x + toDraw[i].x + addX
|
||||
var y = config.y + toDraw[i].y + addY
|
||||
if(toDraw[i].text){
|
||||
ctx.fillText(toDraw[i].text, x, y)
|
||||
}else if(toDraw[i].substitute){
|
||||
ctx.save()
|
||||
ctx.translate(x, y)
|
||||
config.substitute(config, toDraw[i].index)
|
||||
ctx.restore()
|
||||
}
|
||||
}
|
||||
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
diffIcon(config){
|
||||
var ctx = config.ctx
|
||||
var scale = config.scale
|
||||
|
||||
@@ -7,6 +7,16 @@ class Controller{
|
||||
this.touchEnabled = touchEnabled
|
||||
this.snd = this.multiplayer ? "_p" + this.multiplayer : ""
|
||||
|
||||
this.calibrationMode = selectedSong.folder === "calibration"
|
||||
this.audioLatency = 0
|
||||
this.videoLatency = 0
|
||||
if(!this.calibrationMode){
|
||||
var latency = settings.getItem("latency")
|
||||
if(!autoPlayEnabled){
|
||||
this.audioLatency = Math.round(latency.audio) || 0
|
||||
}
|
||||
this.videoLatency = Math.round(latency.video) || 0 + this.audioLatency
|
||||
}
|
||||
if(this.multiplayer !== 2){
|
||||
loader.changePage("game", false)
|
||||
}
|
||||
@@ -17,19 +27,41 @@ class Controller{
|
||||
this.parsedSongData = new ParseOsu(songData, selectedSong.difficulty, selectedSong.stars, selectedSong.offset)
|
||||
}
|
||||
this.offset = this.parsedSongData.soundOffset
|
||||
|
||||
var maxCombo = this.parsedSongData.circles.filter(circle => ["don", "ka", "daiDon", "daiKa"].indexOf(circle.type) > -1 && (!circle.branch || circle.branch.name == "master")).length
|
||||
if (maxCombo >= 50) {
|
||||
var comboVoices = ["v_combo_50"].concat([...Array(Math.floor(maxCombo/100)).keys()].map(i => "v_combo_" + (i + 1)*100))
|
||||
var promises = []
|
||||
|
||||
comboVoices.forEach(name => {
|
||||
if (!assets.sounds[name + "_p1"]) {
|
||||
promises.push(loader.loadSound(name + ".wav", snd.sfxGain).then(sound => {
|
||||
assets.sounds[name + "_p1"] = assets.sounds[name].copy(snd.sfxGainL)
|
||||
assets.sounds[name + "_p2"] = assets.sounds[name].copy(snd.sfxGainR)
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
Promise.all(promises)
|
||||
}
|
||||
|
||||
assets.songs.forEach(song => {
|
||||
if(song.id == this.selectedSong.folder){
|
||||
this.mainAsset = song.sound
|
||||
this.volume = song.volume || 1
|
||||
}
|
||||
})
|
||||
if(this.calibrationMode){
|
||||
this.volume = 1
|
||||
}else{
|
||||
assets.songs.forEach(song => {
|
||||
if(song.id == this.selectedSong.folder){
|
||||
this.mainAsset = song.sound
|
||||
this.volume = song.volume || 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.game = new Game(this, this.selectedSong, this.parsedSongData)
|
||||
this.view = new View(this)
|
||||
this.mekadon = new Mekadon(this, this.game)
|
||||
this.keyboard = new GameInput(this)
|
||||
|
||||
this.drumSounds = settings.getItem("latency").drumSounds
|
||||
this.playedSounds = {}
|
||||
}
|
||||
run(syncWith){
|
||||
@@ -72,8 +104,8 @@ class Controller{
|
||||
}
|
||||
stopMainLoop(){
|
||||
this.mainLoopRunning = false
|
||||
if(this.mainAsset){
|
||||
this.mainAsset.stop()
|
||||
if(this.game.mainAsset){
|
||||
this.game.mainAsset.stop()
|
||||
}
|
||||
if(this.multiplayer !== 2){
|
||||
clearInterval(this.gameInterval)
|
||||
@@ -90,13 +122,18 @@ class Controller{
|
||||
if(this.game.musicFadeOut < 3){
|
||||
this.keyboard.checkMenuKeys()
|
||||
}
|
||||
if(this.calibrationMode){
|
||||
this.game.calibration()
|
||||
}
|
||||
if(!this.game.isPaused()){
|
||||
this.keyboard.checkGameKeys()
|
||||
|
||||
if(ms < 0){
|
||||
this.game.updateTime()
|
||||
}else{
|
||||
this.game.update()
|
||||
if(!this.calibrationMode){
|
||||
this.game.update()
|
||||
}
|
||||
if(!this.mainLoopRunning){
|
||||
return
|
||||
}
|
||||
@@ -137,7 +174,7 @@ class Controller{
|
||||
if(Math.round(score.gauge / 2) - 1 >= 25){
|
||||
if(score.bad === 0){
|
||||
vp = "fullcombo"
|
||||
this.playSoundMeka("v_fullcombo", 1.350)
|
||||
this.playSound("v_fullcombo", 1.350)
|
||||
}else{
|
||||
vp = "clear"
|
||||
}
|
||||
@@ -158,7 +195,11 @@ class Controller{
|
||||
if(!fadeIn){
|
||||
this.clean()
|
||||
}
|
||||
new SongSelect(false, fadeIn, this.touchEnabled)
|
||||
if(this.calibrationMode){
|
||||
new SettingsView(this.touchEnabled, false, null, "latency")
|
||||
}else{
|
||||
new SongSelect(false, fadeIn, this.touchEnabled)
|
||||
}
|
||||
}
|
||||
restartSong(){
|
||||
this.clean()
|
||||
@@ -166,20 +207,24 @@ class Controller{
|
||||
new LoadSong(this.selectedSong, false, true, this.touchEnabled)
|
||||
}else{
|
||||
new Promise(resolve => {
|
||||
var songObj = assets.songs.find(song => song.id === this.selectedSong.folder)
|
||||
if(songObj.chart){
|
||||
var reader = new FileReader()
|
||||
var promise = pageEvents.load(reader).then(event => {
|
||||
this.songData = event.target.result.replace(/\0/g, "").split("\n")
|
||||
resolve()
|
||||
})
|
||||
if(this.selectedSong.type === "tja"){
|
||||
reader.readAsText(songObj.chart, "sjis")
|
||||
}else{
|
||||
reader.readAsText(songObj.chart)
|
||||
}
|
||||
}else{
|
||||
if(this.calibrationMode){
|
||||
resolve()
|
||||
}else{
|
||||
var songObj = assets.songs.find(song => song.id === this.selectedSong.folder)
|
||||
if(songObj.chart && songObj.chart !== "blank"){
|
||||
var reader = new FileReader()
|
||||
var promise = pageEvents.load(reader).then(event => {
|
||||
this.songData = event.target.result.replace(/\0/g, "").split("\n")
|
||||
resolve()
|
||||
})
|
||||
if(this.selectedSong.type === "tja"){
|
||||
reader.readAsText(songObj.chart, "sjis")
|
||||
}else{
|
||||
reader.readAsText(songObj.chart)
|
||||
}
|
||||
}else{
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
var taikoGame = new Controller(this.selectedSong, this.songData, this.autoPlayEnabled, false, this.touchEnabled)
|
||||
@@ -187,25 +232,21 @@ class Controller{
|
||||
})
|
||||
}
|
||||
}
|
||||
playSound(id, time){
|
||||
playSound(id, time, noSnd){
|
||||
if(!this.drumSounds && (id === "neiro_1_don" || id === "neiro_1_ka" || id === "se_don" || id === "se_ka")){
|
||||
return
|
||||
}
|
||||
var ms = Date.now() + (time || 0) * 1000
|
||||
if(!(id in this.playedSounds) || ms > this.playedSounds[id] + 30){
|
||||
assets.sounds[id + this.snd].play(time)
|
||||
assets.sounds[id + (noSnd ? "" : this.snd)].play(time)
|
||||
this.playedSounds[id] = ms
|
||||
}
|
||||
}
|
||||
playSoundMeka(soundID, time){
|
||||
var meka = ""
|
||||
if(this.autoPlayEnabled && !this.multiplayer){
|
||||
meka = "_meka"
|
||||
}
|
||||
this.playSound(soundID + meka, time)
|
||||
}
|
||||
togglePause(){
|
||||
togglePause(forcePause, pauseMove, noSound){
|
||||
if(this.multiplayer === 1){
|
||||
this.syncWith.game.togglePause()
|
||||
this.syncWith.game.togglePause(forcePause, pauseMove, noSound)
|
||||
}
|
||||
this.game.togglePause()
|
||||
this.game.togglePause(forcePause, pauseMove, noSound)
|
||||
}
|
||||
getKeys(){
|
||||
return this.keyboard.getKeys()
|
||||
|
||||
@@ -45,7 +45,12 @@ class Game{
|
||||
}
|
||||
initTiming(){
|
||||
// Date when the chrono is started (before the game begins)
|
||||
var offsetTime = Math.max(0, this.timeForDistanceCircle - this.songData.circles[0].ms) |0
|
||||
var firstCircle = this.songData.circles[0]
|
||||
if(this.controller.calibrationMode){
|
||||
var offsetTime = 0
|
||||
}else{
|
||||
var offsetTime = Math.max(0, this.timeForDistanceCircle - (firstCircle ? firstCircle.ms : 0)) |0
|
||||
}
|
||||
if(this.controller.multiplayer){
|
||||
var syncWith = this.controller.syncWith
|
||||
var syncCircles = syncWith.game.songData.circles
|
||||
@@ -57,8 +62,8 @@ class Game{
|
||||
this.startDate = Date.now() + offsetTime
|
||||
}
|
||||
update(){
|
||||
// Main operations
|
||||
this.updateTime()
|
||||
// Main operations
|
||||
this.updateCirclesStatus()
|
||||
this.checkPlays()
|
||||
// Event operations
|
||||
@@ -82,14 +87,14 @@ class Game{
|
||||
if(circle && (!circle.branch || circle.branch.active) && !circle.isPlayed){
|
||||
var type = circle.type
|
||||
var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll"
|
||||
var endTime = circle.endTime + (drumrollNotes ? 0 : this.rules.bad)
|
||||
var endTime = circle.endTime + (drumrollNotes ? 0 : this.rules.bad) + this.controller.audioLatency
|
||||
|
||||
if(ms >= circle.ms){
|
||||
if(drumrollNotes && !circle.rendaPlayed && ms < endTime){
|
||||
if(ms >= circle.ms + this.controller.audioLatency){
|
||||
if(drumrollNotes && !circle.rendaPlayed && ms < endTime + this.controller.audioLatency){
|
||||
circle.rendaPlayed = true
|
||||
if(this.rules.difficulty === "easy"){
|
||||
assets.sounds["v_renda" + this.controller.snd].stop()
|
||||
this.controller.playSoundMeka("v_renda")
|
||||
this.controller.playSound("v_renda")
|
||||
}
|
||||
}
|
||||
if(!circle.beatMSCopied){
|
||||
@@ -109,7 +114,7 @@ class Game{
|
||||
this.updateCurrentCircle()
|
||||
if(this.controller.multiplayer === 1){
|
||||
var value = {
|
||||
pace: (ms - circle.ms) / circle.timesHit
|
||||
pace: (ms - circle.ms - this.controller.audioLatency) / circle.timesHit
|
||||
}
|
||||
if(type === "drumroll" || type === "daiDrumroll"){
|
||||
value.kaAmount = circle.timesKa / circle.timesHit
|
||||
@@ -211,7 +216,7 @@ class Game{
|
||||
|
||||
for(var i = this.currentCircle + 1; i < circles.length; i++){
|
||||
var circle = circles[i]
|
||||
var relative = ms - circle.ms
|
||||
var relative = ms - circle.ms - this.controller.audioLatency
|
||||
if(!circle.branch || circle.branch.active){
|
||||
if((!circleIsNote(circle) || relative < -this.rules.bad)){
|
||||
break
|
||||
@@ -310,7 +315,7 @@ class Game{
|
||||
|
||||
var keyTime = this.controller.getKeyTime()
|
||||
var currentTime = keysDon ? keyTime["don"] : keyTime["ka"]
|
||||
var relative = currentTime - circle.ms
|
||||
var relative = currentTime - circle.ms - this.controller.audioLatency
|
||||
|
||||
if(relative >= this.rules.ok){
|
||||
var fixedNote = this.fixNoteStream(keysDon)
|
||||
@@ -366,7 +371,7 @@ class Game{
|
||||
if(this.controller.multiplayer === 1){
|
||||
var value = {
|
||||
score: score,
|
||||
ms: circle.ms - currentTime,
|
||||
ms: circle.ms - currentTime - this.controller.audioLatency,
|
||||
dai: typeDai ? (keyDai ? 2 : 1) : 0
|
||||
}
|
||||
if((!keysDon || !typeDon) && (!keysKa || !typeKa)){
|
||||
@@ -375,7 +380,7 @@ class Game{
|
||||
p2.send("note", value)
|
||||
}
|
||||
}else{
|
||||
if(circle.ms > currentTime || currentTime > circle.endTime){
|
||||
if(circle.ms + this.controller.audioLatency > currentTime || currentTime > circle.endTime + this.controller.audioLatency){
|
||||
return true
|
||||
}
|
||||
if(keysDon && type === "balloon"){
|
||||
@@ -400,7 +405,7 @@ class Game{
|
||||
circle.played(score)
|
||||
if(this.controller.multiplayer == 1){
|
||||
p2.send("drumroll", {
|
||||
pace: (this.elapsedTime - circle.ms) / circle.timesHit
|
||||
pace: (this.elapsedTime - circle.ms + this.controller.audioLatency) / circle.timesHit
|
||||
})
|
||||
}
|
||||
}else{
|
||||
@@ -447,17 +452,19 @@ class Game{
|
||||
var ms = this.elapsedTime
|
||||
if(!this.lastCircle){
|
||||
var circles = this.songData.circles
|
||||
this.lastCircle = circles[circles.length - 1].endTime
|
||||
var circle = circles[circles.length - 1]
|
||||
this.lastCircle = circle ? circle.endTime : 0
|
||||
if(this.controller.multiplayer){
|
||||
var syncWith = this.controller.syncWith
|
||||
var syncCircles = syncWith.game.songData.circles
|
||||
var syncLastCircle = syncCircles[syncCircles.length - 1].endTime
|
||||
circle = syncCircles[syncCircles.length - 1]
|
||||
var syncLastCircle = circle ? circle.endTime : 0
|
||||
if(syncLastCircle > this.lastCircle){
|
||||
this.lastCircle = syncLastCircle
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!this.fadeOutStarted && ms >= this.lastCircle + 2000){
|
||||
if(!this.fadeOutStarted && ms >= this.lastCircle + 2000 + this.controller.audioLatency){
|
||||
this.fadeOutStarted = ms
|
||||
if(this.controller.multiplayer){
|
||||
this.controller.syncWith.game.fadeOutStarted = ms
|
||||
@@ -495,28 +502,51 @@ class Game{
|
||||
playMainMusic(){
|
||||
var ms = this.elapsedTime + this.controller.offset
|
||||
if(!this.mainMusicPlaying && (!this.fadeOutStarted || ms < this.fadeOutStarted + 1600)){
|
||||
if(this.controller.multiplayer !== 2 && this.mainAsset){
|
||||
if(this.calibrationState === "audio"){
|
||||
var beatInterval = this.controller.view.beatInterval
|
||||
var startAt = ms % beatInterval
|
||||
var duration = this.mainAsset.duration * 1000
|
||||
if(startAt < duration){
|
||||
this.mainAsset.playLoop(0, false, startAt / 1000, 0, beatInterval / 1000)
|
||||
}else{
|
||||
this.mainAsset.playLoop((startAt - duration) / 1000, false, 0, 0, beatInterval / 1000)
|
||||
}
|
||||
}else if(this.controller.multiplayer !== 2 && this.mainAsset){
|
||||
this.mainAsset.play((ms < 0 ? -ms : 0) / 1000, false, Math.max(0, ms / 1000))
|
||||
}
|
||||
this.mainMusicPlaying = true
|
||||
}
|
||||
}
|
||||
togglePause(){
|
||||
togglePause(forcePause, pauseMove, noSound){
|
||||
if(!this.paused){
|
||||
assets.sounds["se_pause"].play()
|
||||
if(forcePause === false){
|
||||
return
|
||||
}
|
||||
if(!noSound){
|
||||
this.controller.playSound("se_pause", 0, true)
|
||||
}
|
||||
this.paused = true
|
||||
this.latestDate = Date.now()
|
||||
if(this.mainAsset){
|
||||
this.mainAsset.stop()
|
||||
}
|
||||
this.mainMusicPlaying = false
|
||||
this.view.pauseMove(0, true)
|
||||
this.view.pauseMove(pauseMove || 0, true)
|
||||
this.view.gameDiv.classList.add("game-paused")
|
||||
this.view.lastMousemove = this.view.getMS()
|
||||
this.view.cursorHidden = false
|
||||
pageEvents.send("pause")
|
||||
}else{
|
||||
assets.sounds["se_cancel"].play()
|
||||
}else if(!forcePause){
|
||||
if(forcePause !== false && this.calibrationState && ["audioHelp", "audioComplete", "videoHelp", "videoComplete", "results"].indexOf(this.calibrationState) !== -1){
|
||||
return
|
||||
}
|
||||
if(this.calibrationState === "audioHelp" || this.calibrationState === "videoHelp"){
|
||||
this.calibrationState = this.calibrationState === "audioHelp" ? "audio" : "video"
|
||||
this.controller.view.pauseOptions = strings.pauseOptions
|
||||
this.controller.playSound("se_don", 0, true)
|
||||
}else if(!noSound){
|
||||
this.controller.playSound("se_cancel", 0, true)
|
||||
}
|
||||
this.paused = false
|
||||
var currentDate = Date.now()
|
||||
this.startDate += currentDate - this.latestDate
|
||||
@@ -579,8 +609,8 @@ 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 < 1500 || this.combo > 0 && this.combo % 500 === 0){
|
||||
this.controller.playSoundMeka("v_combo_" + (this.combo <= 1400 ? this.combo : "over1500"))
|
||||
if(this.combo === 50 || this.combo > 0 && this.combo % 100 === 0 && this.combo <= 5000){
|
||||
this.controller.playSound("v_combo_" + this.combo)
|
||||
}
|
||||
if (this.songData.scoremode == 2 && this.combo > 0 && this.combo % 100 == 0) {
|
||||
this.globalScore.points += 10000;
|
||||
@@ -683,7 +713,7 @@ class Game{
|
||||
if(!circle || circle.branch === currentBranch[pastActive]){
|
||||
var ms = this.elapsedTime
|
||||
var closestCircle = circles.findIndex(circle => {
|
||||
return (!circle.branch || circle.branch.active) && circle.endTime >= ms
|
||||
return (!circle.branch || circle.branch.active) && circle.endTime + this.controller.audioLatency >= ms
|
||||
})
|
||||
if(closestCircle !== -1){
|
||||
this.currentCircle = closestCircle
|
||||
@@ -701,4 +731,104 @@ class Game{
|
||||
this.sectionNotes = []
|
||||
this.sectionDrumroll = 0
|
||||
}
|
||||
clearKeyTime(){
|
||||
var keyboard = this.controller.keyboard
|
||||
for(var key in keyboard.keyTime){
|
||||
keyboard.keys[key] = null
|
||||
keyboard.keyTime[key] = -Infinity
|
||||
}
|
||||
}
|
||||
calibration(){
|
||||
var view = this.controller.view
|
||||
if(!this.calibrationState){
|
||||
this.controller.parsedSongData.measures = []
|
||||
this.calibrationProgress = {
|
||||
audio: 0,
|
||||
video: 0,
|
||||
requirement: 40
|
||||
}
|
||||
this.calibrationReset("audio", true)
|
||||
}
|
||||
var progress = this.calibrationProgress
|
||||
var state = this.calibrationState
|
||||
switch(state){
|
||||
case "audio":
|
||||
case "video":
|
||||
if(state === "audio" && !this.mainAsset){
|
||||
this.mainAsset = assets.sounds["se_calibration"]
|
||||
this.mainMusicPlaying = false
|
||||
}
|
||||
if(progress.hit >= progress.requirement){
|
||||
var reduced = 0
|
||||
for(var i = 2; i < progress.offsets.length; i++){
|
||||
reduced += progress.offsets[i]
|
||||
}
|
||||
progress[state] = Math.max(0, Math.round(reduced / progress.offsets.length - 2))
|
||||
this.calibrationState += "Complete"
|
||||
view.pauseOptions = []
|
||||
this.clearKeyTime()
|
||||
this.togglePause(true, 1)
|
||||
this.mainAsset = null
|
||||
}
|
||||
break
|
||||
case "audioComplete":
|
||||
case "videoComplete":
|
||||
if(Date.now() - this.latestDate > 3000){
|
||||
var audioComplete = this.calibrationState === "audioComplete"
|
||||
this.controller.playSound("se_pause", 0, true)
|
||||
if(audioComplete){
|
||||
this.calibrationReset("video")
|
||||
}else{
|
||||
view.pauseOptions = [
|
||||
strings.calibration.retryPrevious,
|
||||
strings.calibration.finish
|
||||
]
|
||||
}
|
||||
this.calibrationState = audioComplete ? "videoHelp" : "results"
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
calibrationHit(ms){
|
||||
var progress = this.calibrationProgress
|
||||
var beatInterval = this.controller.view.beatInterval
|
||||
var current = Math.floor((ms + 100) / beatInterval)
|
||||
if(current !== progress.last){
|
||||
var offset = ((ms + 100) % beatInterval) - 100
|
||||
var offsets = progress.offsets
|
||||
if(offsets.length >= progress.requirement){
|
||||
offsets.shift()
|
||||
}
|
||||
offsets.push(offset)
|
||||
progress.hit++
|
||||
progress.last = current
|
||||
this.globalScore.gauge = 100 / (progress.requirement / progress.hit)
|
||||
}
|
||||
}
|
||||
calibrationReset(to, togglePause){
|
||||
var view = this.controller.view
|
||||
this.songData.circles = []
|
||||
view.pauseOptions = [
|
||||
to === "audio" ? strings.calibration.back : strings.calibration.retryPrevious,
|
||||
strings.calibration.start
|
||||
]
|
||||
this.calibrationState = to + "Help"
|
||||
var progress = this.calibrationProgress
|
||||
progress.offsets = []
|
||||
progress.hit = 0
|
||||
progress.last = null
|
||||
this.globalScore.gauge = 0
|
||||
if(to === "video"){
|
||||
this.clearKeyTime()
|
||||
this.initTiming()
|
||||
this.latestDate = this.startDate
|
||||
this.elapsedTime = 0
|
||||
view.ms = 0
|
||||
}
|
||||
if(togglePause){
|
||||
this.togglePause(true, 1, true)
|
||||
}else{
|
||||
view.pauseMove(1, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ class GameInput{
|
||||
}
|
||||
}
|
||||
checkMenuKeys(){
|
||||
if(!this.controller.multiplayer && !this.locked){
|
||||
if(!this.controller.multiplayer && !this.locked && this.controller.view.pauseOptions.length !== 0){
|
||||
var moveMenu = 0
|
||||
var ms = this.game.getAccurateTime()
|
||||
this.gamepadMenu.play((pressed, name) => {
|
||||
@@ -146,7 +146,7 @@ class GameInput{
|
||||
this.checkKey("don_l", "menu", moveMenuConfirm)
|
||||
this.checkKey("don_r", "menu", moveMenuConfirm)
|
||||
if(moveMenu && this.game.isPaused()){
|
||||
assets.sounds["se_ka"].play()
|
||||
this.controller.playSound("se_ka", 0, true)
|
||||
this.controller.view.pauseMove(moveMenu)
|
||||
}
|
||||
}
|
||||
@@ -197,11 +197,19 @@ class GameInput{
|
||||
return
|
||||
}
|
||||
this.keyTime[name] = ms
|
||||
var calibrationState = this.game.calibrationState
|
||||
var calibration = calibrationState && !this.game.paused
|
||||
if(name == "don_l" || name == "don_r"){
|
||||
this.checkKeySound(name, "don")
|
||||
if(calibration){
|
||||
this.game.calibrationHit(ms)
|
||||
}else{
|
||||
this.checkKeySound(name, "don")
|
||||
}
|
||||
this.keyboardEvents++
|
||||
}else if(name == "ka_l" || name == "ka_r"){
|
||||
this.checkKeySound(name, "ka")
|
||||
if(!calibration){
|
||||
this.checkKeySound(name, "ka")
|
||||
}
|
||||
this.keyboardEvents++
|
||||
}
|
||||
}else{
|
||||
|
||||
@@ -35,14 +35,20 @@ class LoadSong{
|
||||
var song = this.selectedSong
|
||||
var id = song.folder
|
||||
var promises = []
|
||||
assets.sounds["v_start"].play()
|
||||
if(song.folder !== "calibration"){
|
||||
assets.sounds["v_start"].play()
|
||||
var songObj = assets.songs.find(song => song.id === id)
|
||||
}else{
|
||||
var songObj = {
|
||||
"music": "muted",
|
||||
"chart": "blank"
|
||||
}
|
||||
}
|
||||
|
||||
song.songBg = this.randInt(1, 5)
|
||||
song.songStage = this.randInt(1, 3)
|
||||
song.donBg = this.randInt(1, 6)
|
||||
|
||||
var songObj = assets.songs.find(song => song.id === id)
|
||||
|
||||
if(song.songSkin && song.songSkin.name){
|
||||
var imgLoad = []
|
||||
for(var type in song.songSkin){
|
||||
@@ -117,14 +123,18 @@ class LoadSong{
|
||||
}
|
||||
}))
|
||||
if(songObj.chart){
|
||||
var reader = new FileReader()
|
||||
promises.push(pageEvents.load(reader).then(event => {
|
||||
this.songData = event.target.result.replace(/\0/g, "").split("\n")
|
||||
}))
|
||||
if(song.type === "tja"){
|
||||
reader.readAsText(songObj.chart, "sjis")
|
||||
if(songObj.chart === "blank"){
|
||||
this.songData = ""
|
||||
}else{
|
||||
reader.readAsText(songObj.chart)
|
||||
var reader = new FileReader()
|
||||
promises.push(pageEvents.load(reader).then(event => {
|
||||
this.songData = event.target.result.replace(/\0/g, "").split("\n")
|
||||
}))
|
||||
if(song.type === "tja"){
|
||||
reader.readAsText(songObj.chart, "sjis")
|
||||
}else{
|
||||
reader.readAsText(songObj.chart)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
promises.push(loader.ajax(this.getSongPath(song)).then(data => {
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"A": {name: "daiDon", txt: strings.note.daiDon},
|
||||
"B": {name: "daiKa", txt: strings.note.daiKa}
|
||||
}
|
||||
this.noteTypes_ex = strings.ex_note;
|
||||
this.courseTypes = {
|
||||
"0": "easy",
|
||||
"1": "normal",
|
||||
@@ -122,7 +123,7 @@
|
||||
return [string.slice(0, index), string.slice(index + delimiter.length)]
|
||||
}
|
||||
parseCircles(){
|
||||
var meta = this.metadata[this.difficulty]
|
||||
var meta = this.metadata[this.difficulty] || {}
|
||||
var ms = (meta.offset || 0) * -1000 + this.offset
|
||||
var bpm = Math.abs(meta.bpm) || 120
|
||||
var scroll = 1
|
||||
@@ -148,7 +149,32 @@
|
||||
var circles = []
|
||||
var circleID = 0
|
||||
var regexAZ = /[A-Z]/
|
||||
|
||||
var isAllDon = (note_chain, start_pos) => {
|
||||
for (var i = start_pos; i < note_chain.length; ++i) {
|
||||
var note = note_chain[i];
|
||||
if (note && note.type !== "don" && note.type !== "daiDon") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
var checkChain = (note_chain, measure_length, is_last) => {
|
||||
//console.log(note_chain, measure_length, is_last);
|
||||
/*if (measure_length >= 24) {
|
||||
for (var note of note_chain) {
|
||||
note.text = this.noteTypes_ex[note.type][0];
|
||||
}
|
||||
} else { */
|
||||
var alldon_pos = null;
|
||||
for (var i = 0; i < note_chain.length - (is_last ? 1 : 0); ++i) {
|
||||
var note = note_chain[i];
|
||||
if (alldon_pos === null && is_last && isAllDon(note_chain, i)) {
|
||||
alldon_pos = i;
|
||||
}
|
||||
note.text = this.noteTypes_ex[note.type][alldon_pos != null ? (i - alldon_pos) % 2 : 0];
|
||||
}
|
||||
//}
|
||||
}
|
||||
var pushMeasure = () => {
|
||||
var note = currentMeasure[0]
|
||||
if(note){
|
||||
@@ -183,9 +209,11 @@
|
||||
var msPerMeasure = 60000 * measure / note.bpm
|
||||
ms += msPerMeasure / currentMeasure.length
|
||||
}
|
||||
for(var i = 0; i < currentMeasure.length; i++){
|
||||
var note_chain = [];
|
||||
for (var i = 0; i < currentMeasure.length; i++){
|
||||
//console.log(note_chain.length);
|
||||
var note = currentMeasure[i]
|
||||
if(note.type){
|
||||
if (note.type) {
|
||||
circleID++
|
||||
var circleObj = new Circle({
|
||||
id: circleID,
|
||||
@@ -200,13 +228,30 @@
|
||||
branch: currentBranch,
|
||||
section: note.section
|
||||
})
|
||||
if(lastDrumroll === note){
|
||||
if (note.type === "don" || note.type === "ka" || note.type === "daiDon" || note.type === "daiKa") {
|
||||
note_chain.push(circleObj);
|
||||
} else {
|
||||
if (note_chain.length > 1 && currentMeasure.length >= 8) {
|
||||
checkChain(note_chain, currentMeasure.length, false);
|
||||
}
|
||||
note_chain = [];
|
||||
}
|
||||
if (lastDrumroll === note) {
|
||||
lastDrumroll = circleObj
|
||||
}
|
||||
|
||||
circles.push(circleObj)
|
||||
} else if (!(currentMeasure.length >= 24 && (!currentMeasure[i + 1] || currentMeasure[i + 1].type))
|
||||
&& !(currentMeasure.length >= 48 && (!currentMeasure[i + 2] || currentMeasure[i + 2].type || !currentMeasure[i + 3] || currentMeasure[i + 3].type))) {
|
||||
if (note_chain.length > 1 && currentMeasure.length >= 8) {
|
||||
checkChain(note_chain, currentMeasure.length, true);
|
||||
}
|
||||
note_chain = [];
|
||||
}
|
||||
}
|
||||
if (note_chain.length > 1 && currentMeasure.length >= 8) {
|
||||
checkChain(note_chain, currentMeasure.length, false);
|
||||
}
|
||||
}else{
|
||||
var msPerMeasure = 60000 * measure / bpm
|
||||
ms += msPerMeasure
|
||||
|
||||
@@ -10,6 +10,14 @@ class Scoresheet{
|
||||
|
||||
this.canvas = document.getElementById("canvas")
|
||||
this.ctx = this.canvas.getContext("2d")
|
||||
var resolution = settings.getItem("resolution")
|
||||
var noSmoothing = resolution === "low" || resolution === "lowest"
|
||||
if(noSmoothing){
|
||||
this.ctx.imageSmoothingEnabled = false
|
||||
}
|
||||
if(resolution === "lowest"){
|
||||
this.canvas.style.imageRendering = "pixelated"
|
||||
}
|
||||
this.game = document.getElementById("game")
|
||||
|
||||
this.fadeScreen = document.createElement("div")
|
||||
@@ -28,8 +36,8 @@ class Scoresheet{
|
||||
this.frame = 1000 / 60
|
||||
this.numbers = "001122334455667788900112233445".split("")
|
||||
|
||||
this.draw = new CanvasDraw()
|
||||
this.canvasCache = new CanvasCache()
|
||||
this.draw = new CanvasDraw(noSmoothing)
|
||||
this.canvasCache = new CanvasCache(noSmoothing)
|
||||
|
||||
this.keyboard = new Keyboard({
|
||||
confirm: ["enter", "space", "esc", "don_l", "don_r"]
|
||||
@@ -105,7 +113,7 @@ class Scoresheet{
|
||||
if(!p2.session){
|
||||
this.state.screen = "scoresShown"
|
||||
this.state.screenMS = this.getMS()
|
||||
assets.sounds["neiro_1_don"].play()
|
||||
this.controller.playSound("neiro_1_don", 0, true)
|
||||
}
|
||||
}
|
||||
toSongsel(fromP2){
|
||||
@@ -114,7 +122,7 @@ class Scoresheet{
|
||||
this.state.screen = "fadeOut"
|
||||
this.state.screenMS = this.getMS()
|
||||
if(!fromP2){
|
||||
assets.sounds["neiro_1_don"].play()
|
||||
this.controller.playSound("neiro_1_don", 0, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,15 @@ class Settings{
|
||||
constructor(){
|
||||
var ios = /iPhone|iPad/.test(navigator.userAgent)
|
||||
var phone = /Android|iPhone|iPad/.test(navigator.userAgent)
|
||||
this.allLanguages = []
|
||||
for(var i in allStrings){
|
||||
this.allLanguages.push(i)
|
||||
}
|
||||
|
||||
this.items = {
|
||||
language: {
|
||||
type: "language",
|
||||
options: ["ja", "en", "cn", "tw", "ko"],
|
||||
options: this.allLanguages,
|
||||
default: this.getLang()
|
||||
},
|
||||
resolution: {
|
||||
@@ -34,6 +38,14 @@ class Settings{
|
||||
options: ["a", "b", "c"],
|
||||
default: "a",
|
||||
gamepad: true
|
||||
},
|
||||
latency: {
|
||||
type: "latency",
|
||||
default: {
|
||||
"audio": 0,
|
||||
"video": 0,
|
||||
"drumSounds": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +73,22 @@ class Settings{
|
||||
}
|
||||
}
|
||||
this.storage[i] = obj
|
||||
}else if(current.type === "latency"){
|
||||
var obj = {}
|
||||
for(var j in current.default){
|
||||
if(storage[i] && j in storage[i]){
|
||||
if(j === "drumSounds"){
|
||||
obj[j] = !!storage[i][j]
|
||||
continue
|
||||
}else if(!isNaN(storage[i][j])){
|
||||
obj[j] = Math.round(parseFloat(storage[i][j]) || 0)
|
||||
continue
|
||||
}
|
||||
}
|
||||
obj = null
|
||||
break
|
||||
}
|
||||
this.storage[i] = obj
|
||||
}else{
|
||||
this.storage[i] = storage[i]
|
||||
}
|
||||
@@ -107,7 +135,7 @@ class Settings{
|
||||
}
|
||||
}
|
||||
}
|
||||
return "ja"
|
||||
return this.allLanguages[0]
|
||||
}
|
||||
setLang(lang, noEvent){
|
||||
strings = lang
|
||||
@@ -122,7 +150,7 @@ class Settings{
|
||||
}
|
||||
|
||||
class SettingsView{
|
||||
constructor(touchEnabled, tutorial, songId){
|
||||
constructor(touchEnabled, tutorial, songId, toSetting){
|
||||
this.touchEnabled = touchEnabled
|
||||
this.tutorial = tutorial
|
||||
this.songId = songId
|
||||
@@ -130,9 +158,15 @@ class SettingsView{
|
||||
loader.changePage("settings", tutorial)
|
||||
assets.sounds["bgm_settings"].playLoop(0.1, false, 0, 1.392, 26.992)
|
||||
this.defaultButton = document.getElementById("settings-default")
|
||||
this.viewOuter = this.getElement("view-outer")
|
||||
if(touchEnabled){
|
||||
this.getElement("view-outer").classList.add("touch-enabled")
|
||||
this.viewOuter.classList.add("touch-enabled")
|
||||
}
|
||||
this.touchEnd = []
|
||||
pageEvents.add(this.viewOuter, ["mouseup", "touchend"], event => {
|
||||
this.touchEnd.forEach(func => func(event))
|
||||
})
|
||||
|
||||
var gamepadEnabled = false
|
||||
if("getGamepads" in navigator){
|
||||
var gamepads = navigator.getGamepads()
|
||||
@@ -145,19 +179,22 @@ class SettingsView{
|
||||
}
|
||||
this.mode = "settings"
|
||||
|
||||
this.pressedKeys = {}
|
||||
this.keyboard = new Keyboard({
|
||||
"confirm": ["enter", "space", "don_l", "don_r"],
|
||||
"up": ["up"],
|
||||
"previous": ["left", "ka_l"],
|
||||
"next": ["right", "down", "ka_r"],
|
||||
"right": ["right", "ka_r"],
|
||||
"down": ["down"],
|
||||
"left": ["left", "ka_l"],
|
||||
"back": ["esc"],
|
||||
"other": ["wildcard"]
|
||||
}, this.keyPressed.bind(this))
|
||||
this.gamepad = new Gamepad({
|
||||
"confirm": ["b", "ls", "rs"],
|
||||
"up": ["u", "lsu"],
|
||||
"previous": ["l", "lb", "lt", "lsl"],
|
||||
"next": ["d", "r", "rb", "rt", "lsd", "lsr"],
|
||||
"right": ["r", "rb", "rt", "lsr"],
|
||||
"down": ["d", "lsd"],
|
||||
"left": ["l", "lb", "lt", "lsl"],
|
||||
"back": ["start", "a"]
|
||||
}, this.keyPressed.bind(this))
|
||||
|
||||
@@ -182,15 +219,15 @@ class SettingsView{
|
||||
var nameDiv = document.createElement("div")
|
||||
nameDiv.classList.add("setting-name", "stroke-sub")
|
||||
var name = strings.settings[i].name
|
||||
nameDiv.innerText = name
|
||||
nameDiv.setAttribute("alt", name)
|
||||
this.setAltText(nameDiv, name)
|
||||
settingBox.appendChild(nameDiv)
|
||||
var valueDiv = document.createElement("div")
|
||||
valueDiv.classList.add("setting-value")
|
||||
this.getValue(i, valueDiv)
|
||||
settingBox.appendChild(valueDiv)
|
||||
content.appendChild(settingBox)
|
||||
if(this.items.length === this.selected){
|
||||
if(!toSetting && this.items.length === this.selected || toSetting === i){
|
||||
this.selected = this.items.length
|
||||
settingBox.classList.add("selected")
|
||||
}
|
||||
this.addTouch(settingBox, event => this.setValue(i))
|
||||
@@ -226,8 +263,99 @@ class SettingsView{
|
||||
this.gamepadButtons = document.getElementById("gamepad-buttons")
|
||||
this.gamepadValue = document.getElementById("gamepad-value")
|
||||
|
||||
this.latencySettings = document.getElementById("settings-latency")
|
||||
this.addTouch(this.latencySettings, event => {
|
||||
if(event.target === event.currentTarget){
|
||||
this.latencyBack()
|
||||
}
|
||||
})
|
||||
this.latencyTitle = this.latencySettings.getElementsByClassName("view-title")[0]
|
||||
this.latencyItems = []
|
||||
this.latencySelected = 0
|
||||
var latencyContent = this.latencySettings.getElementsByClassName("view-content")[0]
|
||||
var latencyWindow = ["calibration", "audio", "video", "drumSounds"]
|
||||
for(let i in latencyWindow){
|
||||
let current = latencyWindow[i]
|
||||
var settingBox = document.createElement("div")
|
||||
settingBox.classList.add("setting-box")
|
||||
var nameDiv = document.createElement("div")
|
||||
nameDiv.classList.add("setting-name", "stroke-sub")
|
||||
var name = strings.settings.latency[current]
|
||||
this.setAltText(nameDiv, name)
|
||||
settingBox.appendChild(nameDiv)
|
||||
let outputObject = {
|
||||
id: current,
|
||||
settingBox: settingBox,
|
||||
nameDiv: nameDiv
|
||||
}
|
||||
if(current === "calibration"){
|
||||
nameDiv.style.width = "100%"
|
||||
}else{
|
||||
var valueDiv = document.createElement("div")
|
||||
valueDiv.classList.add("setting-value")
|
||||
settingBox.appendChild(valueDiv)
|
||||
var valueText = document.createTextNode("")
|
||||
valueDiv.appendChild(valueText)
|
||||
this.latencyGetValue(current, valueText)
|
||||
if(current !== "drumSounds"){
|
||||
var buttons = document.createElement("div")
|
||||
buttons.classList.add("latency-buttons")
|
||||
var buttonMinus = document.createElement("span")
|
||||
buttonMinus.innerText = "-"
|
||||
buttons.appendChild(buttonMinus)
|
||||
this.addTouchRepeat(buttonMinus, event => {
|
||||
this.latencySetAdjust(outputObject, -1)
|
||||
})
|
||||
var buttonPlus = document.createElement("span")
|
||||
buttonPlus.innerText = "+"
|
||||
buttons.appendChild(buttonPlus)
|
||||
this.addTouchRepeat(buttonPlus, event => {
|
||||
this.latencySetAdjust(outputObject, 1)
|
||||
})
|
||||
valueDiv.appendChild(buttons)
|
||||
}
|
||||
}
|
||||
latencyContent.appendChild(settingBox)
|
||||
if(this.latencyItems.length === this.latencySelected){
|
||||
settingBox.classList.add("selected")
|
||||
}
|
||||
this.addTouch(settingBox, event => {
|
||||
if(event.target.tagName !== "SPAN"){
|
||||
this.latencySetValue(current, event.type === "touchstart")
|
||||
}
|
||||
})
|
||||
if(current !== "calibration"){
|
||||
outputObject.valueDiv = valueDiv
|
||||
outputObject.valueText = valueText
|
||||
outputObject.buttonMinus = buttonMinus
|
||||
outputObject.buttonPlus = buttonPlus
|
||||
}
|
||||
this.latencyItems.push(outputObject)
|
||||
}
|
||||
this.latencyDefaultButton = document.getElementById("latency-default")
|
||||
this.latencyItems.push({
|
||||
id: "default",
|
||||
settingBox: this.latencyDefaultButton
|
||||
})
|
||||
this.addTouch(this.latencyDefaultButton, event => this.latencyDefault())
|
||||
this.latencyEndButton = this.latencySettings.getElementsByClassName("view-end-button")[0]
|
||||
this.latencyItems.push({
|
||||
id: "back",
|
||||
settingBox: this.latencyEndButton
|
||||
})
|
||||
this.addTouch(this.latencyEndButton, event => this.latencyBack(true))
|
||||
|
||||
this.setStrings()
|
||||
|
||||
this.drumSounds = settings.getItem("latency").drumSounds
|
||||
this.playedSounds = {}
|
||||
this.redrawRunning = true
|
||||
this.redrawBind = this.redraw.bind(this)
|
||||
this.redraw()
|
||||
if(toSetting === "latency"){
|
||||
this.mode = "latency"
|
||||
this.latencySet()
|
||||
}
|
||||
pageEvents.send("settings")
|
||||
}
|
||||
getElement(name){
|
||||
@@ -246,6 +374,23 @@ class SettingsView{
|
||||
callback(event)
|
||||
})
|
||||
}
|
||||
addTouchRepeat(element, callback){
|
||||
this.addTouch(element, event => {
|
||||
var active = true
|
||||
var func = () => {
|
||||
active = false
|
||||
this.touchEnd.splice(this.touchEnd.indexOf(func), 1)
|
||||
}
|
||||
this.touchEnd.push(func)
|
||||
var repeat = delay => {
|
||||
if(active){
|
||||
callback()
|
||||
setTimeout(() => repeat(50), delay)
|
||||
}
|
||||
}
|
||||
repeat(400)
|
||||
})
|
||||
}
|
||||
removeTouch(element){
|
||||
pageEvents.remove(element, ["mousedown", "touchstart"])
|
||||
}
|
||||
@@ -274,6 +419,17 @@ class SettingsView{
|
||||
valueDiv.appendChild(keyDiv)
|
||||
}
|
||||
return
|
||||
}else if(current.type === "latency"){
|
||||
var audioVideo = [Math.round(value.audio), Math.round(value.video)]
|
||||
var latencyValue = strings.settings[name].value.split("%s")
|
||||
var latencyIndex = 0
|
||||
value = ""
|
||||
latencyValue.forEach((string, i) => {
|
||||
if(i !== 0){
|
||||
value += this.addMs(audioVideo[latencyIndex++])
|
||||
}
|
||||
value += string
|
||||
})
|
||||
}
|
||||
valueDiv.innerText = value
|
||||
}
|
||||
@@ -285,6 +441,7 @@ class SettingsView{
|
||||
if(this.mode !== "settings"){
|
||||
if(this.selected === selectedIndex){
|
||||
this.keyboardBack(selected)
|
||||
this.playSound("se_don")
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -303,24 +460,37 @@ class SettingsView{
|
||||
selected.valueDiv.classList.add("selected")
|
||||
this.keyboardKeys = {}
|
||||
this.keyboardSet()
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
return
|
||||
}else if(current.type === "gamepad"){
|
||||
this.mode = "gamepad"
|
||||
this.gamepadSelected = current.options.indexOf(value)
|
||||
this.gamepadSet()
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
return
|
||||
}else if(current.type === "latency"){
|
||||
this.mode = "latency"
|
||||
this.latencySet()
|
||||
this.playSound("se_don")
|
||||
return
|
||||
}
|
||||
settings.setItem(name, value)
|
||||
this.getValue(name, this.items[this.selected].valueDiv)
|
||||
assets.sounds["se_ka"].play()
|
||||
this.playSound("se_ka")
|
||||
if(current.type === "language"){
|
||||
this.setLang(allStrings[value])
|
||||
}
|
||||
}
|
||||
keyPressed(pressed, name, event){
|
||||
if(!pressed){
|
||||
keyPressed(pressed, name, event, repeat){
|
||||
if(pressed){
|
||||
if(!this.pressedKeys[name]){
|
||||
this.pressedKeys[name] = this.getMS() + 300
|
||||
}
|
||||
}else{
|
||||
this.pressedKeys[name] = 0
|
||||
return
|
||||
}
|
||||
if(repeat && name !== "up" && name !== "right" && name !== "down" && name !== "left"){
|
||||
return
|
||||
}
|
||||
this.touched = false
|
||||
@@ -334,31 +504,31 @@ class SettingsView{
|
||||
}else{
|
||||
this.setValue(selected.id)
|
||||
}
|
||||
}else if(name === "up" || name === "previous" || name === "next"){
|
||||
}else if(name === "up" || name === "right" || name === "down" || name === "left"){
|
||||
selected.settingBox.classList.remove("selected")
|
||||
do{
|
||||
this.selected = this.mod(this.items.length, this.selected + (name === "next" ? 1 : -1))
|
||||
}while(this.items[this.selected].id === "default" && name !== "previous")
|
||||
this.selected = this.mod(this.items.length, this.selected + ((name === "right" || name === "down") ? 1 : -1))
|
||||
}while(this.items[this.selected].id === "default" && name !== "left")
|
||||
selected = this.items[this.selected]
|
||||
selected.settingBox.classList.add("selected")
|
||||
selected.settingBox.scrollIntoView()
|
||||
assets.sounds["se_ka"].play()
|
||||
this.playSound("se_ka")
|
||||
}else if(name === "back"){
|
||||
this.onEnd()
|
||||
}
|
||||
}else if(this.mode === "gamepad"){
|
||||
if(name === "confirm"){
|
||||
this.gamepadBack(true)
|
||||
}else if(name === "up" || name === "previous" || name === "next"){
|
||||
this.gamepadSet(name === "next" ? 1 : -1)
|
||||
}else if(name === "up" || name === "right" || name === "down" || name === "left"){
|
||||
this.gamepadSet((name === "right" || name === "down") ? 1 : -1)
|
||||
}else if(name === "back"){
|
||||
this.gamepadBack()
|
||||
}
|
||||
}else if(this.mode === "keyboard"){
|
||||
if(name === "back"){
|
||||
this.keyboardBack(selected)
|
||||
assets.sounds["se_cancel"].play()
|
||||
}else{
|
||||
this.playSound("se_cancel")
|
||||
}else if(event){
|
||||
event.preventDefault()
|
||||
var currentKey = event.key.toLowerCase()
|
||||
for(var i in this.keyboardKeys){
|
||||
@@ -367,10 +537,40 @@ class SettingsView{
|
||||
}
|
||||
}
|
||||
var current = this.keyboardCurrent
|
||||
assets.sounds[current === "ka_l" || current === "ka_r" ? "se_ka" : "se_don"].play()
|
||||
this.playSound(current === "ka_l" || current === "ka_r" ? "se_ka" : "se_don")
|
||||
this.keyboardKeys[current] = [currentKey]
|
||||
this.keyboardSet()
|
||||
}
|
||||
}else if(this.mode === "latency"){
|
||||
var latencySelected = this.latencyItems[this.latencySelected]
|
||||
if(name === "confirm"){
|
||||
if(latencySelected.id === "back"){
|
||||
this.latencyBack(true)
|
||||
}else if(latencySelected.id === "default"){
|
||||
this.latencyDefault()
|
||||
}else{
|
||||
this.latencySetValue(latencySelected.id)
|
||||
}
|
||||
}else if(name === "up" || name === "right" || name === "down" || name === "left"){
|
||||
latencySelected.settingBox.classList.remove("selected")
|
||||
do{
|
||||
this.latencySelected = this.mod(this.latencyItems.length, this.latencySelected + ((name === "right" || name === "down") ? 1 : -1))
|
||||
}while(this.latencyItems[this.latencySelected].id === "default" && name !== "left")
|
||||
latencySelected = this.latencyItems[this.latencySelected]
|
||||
latencySelected.settingBox.classList.add("selected")
|
||||
latencySelected.settingBox.scrollIntoView()
|
||||
this.playSound("se_ka")
|
||||
}else if(name === "back"){
|
||||
this.latencyBack()
|
||||
}
|
||||
}else if(this.mode === "latencySet"){
|
||||
var latencySelected = this.latencyItems[this.latencySelected]
|
||||
if(name === "confirm" || name === "back"){
|
||||
this.latencySetBack(latencySelected)
|
||||
this.playSound(name === "confirm" ? "se_don" : "se_cancel")
|
||||
}else if(name === "up" || name === "right" || name === "down" || name === "left"){
|
||||
this.latencySetAdjust(latencySelected, (name === "up" || name === "right") ? 1 : -1)
|
||||
}
|
||||
}
|
||||
}
|
||||
keyboardSet(){
|
||||
@@ -416,14 +616,13 @@ class SettingsView{
|
||||
var current = settings.items[selected.id]
|
||||
if(diff){
|
||||
this.gamepadSelected = this.mod(current.options.length, this.gamepadSelected + diff)
|
||||
assets.sounds["se_ka"].play()
|
||||
this.playSound("se_ka")
|
||||
}
|
||||
var opt = current.options[this.gamepadSelected]
|
||||
var value = strings.settings[selected.id][opt]
|
||||
this.gamepadValue.innerText = value
|
||||
this.gamepadValue.setAttribute("alt", value)
|
||||
this.gamepadButtons.style.backgroundPosition = "0 " + (-318 - 132 * this.gamepadSelected) + "px"
|
||||
this.gamepadSettings.style.display = "block"
|
||||
this.setAltText(this.gamepadValue, value)
|
||||
this.gamepadButtons.style.backgroundPosition = "0 " + (-11.87 - 4.93 * this.gamepadSelected) + "em"
|
||||
this.gamepadSettings.style.display = "flex"
|
||||
}
|
||||
gamepadBack(confirm){
|
||||
if(this.mode !== "gamepad"){
|
||||
@@ -433,10 +632,142 @@ class SettingsView{
|
||||
var current = settings.items[selected.id]
|
||||
settings.setItem(selected.id, current.options[this.gamepadSelected])
|
||||
this.getValue(selected.id, selected.valueDiv)
|
||||
assets.sounds[confirm ? "se_don" : "se_cancel"].play()
|
||||
this.playSound(confirm ? "se_don" : "se_cancel")
|
||||
this.gamepadSettings.style.display = ""
|
||||
this.mode = "settings"
|
||||
}
|
||||
latencySet(){
|
||||
if(this.mode !== "latency"){
|
||||
return
|
||||
}
|
||||
var selected = this.items[this.selected]
|
||||
var current = settings.items[selected.id]
|
||||
this.latencySettings.style.display = "flex"
|
||||
}
|
||||
latencyGetValue(name, valueText){
|
||||
var currentLatency = settings.getItem("latency")
|
||||
if(name === "drumSounds"){
|
||||
valueText.data = currentLatency[name] ? strings.settings.on : strings.settings.off
|
||||
}else{
|
||||
valueText.data = this.addMs(currentLatency[name] || 0)
|
||||
}
|
||||
}
|
||||
latencySetValue(name, touched){
|
||||
var selectedIndex = this.latencyItems.findIndex(item => item.id === name)
|
||||
var selected = this.latencyItems[selectedIndex]
|
||||
if(this.mode === "latencySet"){
|
||||
this.latencySetBack(this.latencyItems[this.latencySelected])
|
||||
if(this.latencySelected === selectedIndex){
|
||||
this.playSound("se_don")
|
||||
return
|
||||
}
|
||||
}else if(this.mode !== "latency"){
|
||||
return
|
||||
}
|
||||
if(name === "calibration"){
|
||||
this.playSound("se_don")
|
||||
this.clean()
|
||||
new LoadSong({
|
||||
"title": strings.calibration.title,
|
||||
"folder": "calibration",
|
||||
"type": "tja",
|
||||
"songSkin": {}
|
||||
}, false, false, touched)
|
||||
}else if(name === "drumSounds"){
|
||||
this.drumSounds = !settings.getItem("latency")[name]
|
||||
this.latencySave(name, this.drumSounds)
|
||||
this.latencyGetValue(name, selected.valueText)
|
||||
this.playSound("se_don")
|
||||
}else{
|
||||
var value = Math.round(settings.getItem("latency")[name] || 0)
|
||||
if(this.latencySelected !== selectedIndex){
|
||||
this.latencyItems[this.latencySelected].settingBox.classList.remove("selected")
|
||||
this.latencySelected = selectedIndex
|
||||
selected.settingBox.classList.add("selected")
|
||||
}
|
||||
this.mode = "latencySet"
|
||||
selected.settingBox.style.animation = "none"
|
||||
selected.valueDiv.classList.add("selected")
|
||||
selected.value = value
|
||||
this.playSound("se_don")
|
||||
}
|
||||
}
|
||||
latencySetAdjust(selected, add){
|
||||
selected.value += add
|
||||
if(selected.value > 500){
|
||||
selected.value = 500
|
||||
}else if(selected.value < -200){
|
||||
selected.value = -200
|
||||
}else{
|
||||
this.playSound("se_ka")
|
||||
}
|
||||
selected.valueText.data = this.addMs(selected.value)
|
||||
}
|
||||
latencySetBack(selected){
|
||||
this.mode = "latency"
|
||||
selected.settingBox.style.animation = ""
|
||||
selected.valueDiv.classList.remove("selected")
|
||||
this.latencySave(selected.id, selected.value)
|
||||
this.latencyGetValue(selected.id, selected.valueText)
|
||||
}
|
||||
latencySave(id, value){
|
||||
var input = settings.getItem("latency")
|
||||
var output = {}
|
||||
for(var i in input){
|
||||
if(i === id){
|
||||
output[i] = value
|
||||
}else{
|
||||
output[i] = input[i]
|
||||
}
|
||||
}
|
||||
settings.setItem("latency", output)
|
||||
}
|
||||
latencyDefault(){
|
||||
if(this.mode === "latencySet"){
|
||||
this.latencySetBack(this.latencyItems[this.latencySelected])
|
||||
}else if(this.mode !== "latency"){
|
||||
return
|
||||
}
|
||||
settings.setItem("latency", null)
|
||||
this.latencyItems.forEach(item => {
|
||||
if(item.id === "audio" || item.id === "video" || item.id === "drumSounds"){
|
||||
this.latencyGetValue(item.id, item.valueText)
|
||||
}
|
||||
})
|
||||
this.drumSounds = settings.getItem("latency").drumSounds
|
||||
this.playSound("se_don")
|
||||
}
|
||||
latencyBack(confirm){
|
||||
if(this.mode === "latencySet"){
|
||||
this.latencySetBack(this.latencyItems[this.latencySelected])
|
||||
if(!confirm){
|
||||
this.playSound("se_don")
|
||||
return
|
||||
}
|
||||
}
|
||||
if(this.mode !== "latency"){
|
||||
return
|
||||
}
|
||||
var selected = this.items[this.selected]
|
||||
var current = settings.items[selected.id]
|
||||
this.getValue(selected.id, selected.valueDiv)
|
||||
this.playSound(confirm ? "se_don" : "se_cancel")
|
||||
this.latencySettings.style.display = ""
|
||||
this.mode = "settings"
|
||||
}
|
||||
addMs(input){
|
||||
var split = strings.calibration.ms.split("%s")
|
||||
var index = 0
|
||||
var output = ""
|
||||
var inputStrings = [(input > 0 ? "+" : "") + input.toString()]
|
||||
split.forEach((string, i) => {
|
||||
if(i !== 0){
|
||||
output += inputStrings[index++]
|
||||
}
|
||||
output += string
|
||||
})
|
||||
return output
|
||||
}
|
||||
defaultSettings(){
|
||||
if(this.mode === "keyboard"){
|
||||
this.keyboardBack(this.items[this.selected])
|
||||
@@ -447,11 +778,17 @@ class SettingsView{
|
||||
this.setLang(allStrings[settings.getItem("language")])
|
||||
this.keyboard.update()
|
||||
pageEvents.setKbd()
|
||||
assets.sounds["se_don"].play()
|
||||
this.latencyItems.forEach(item => {
|
||||
if(item.id === "audio" || item.id === "video" || item.id === "drumSounds"){
|
||||
this.latencyGetValue(item.id, item.valueText)
|
||||
}
|
||||
})
|
||||
this.drumSounds = settings.getItem("latency").drumSounds
|
||||
this.playSound("se_don")
|
||||
}
|
||||
onEnd(){
|
||||
this.clean()
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
setTimeout(() => {
|
||||
if(this.tutorial && !this.touched){
|
||||
new Tutorial(false, this.songId)
|
||||
@@ -472,41 +809,94 @@ class SettingsView{
|
||||
var item = this.items[i]
|
||||
if(item.valueDiv){
|
||||
var name = strings.settings[item.id].name
|
||||
item.nameDiv.innerText = name
|
||||
item.nameDiv.setAttribute("alt", name)
|
||||
this.setAltText(item.nameDiv, name)
|
||||
this.getValue(item.id, item.valueDiv)
|
||||
}
|
||||
}
|
||||
for(var i in this.latencyItems){
|
||||
var current = this.latencyItems[i]
|
||||
if(current.nameDiv){
|
||||
this.setAltText(current.nameDiv, strings.settings.latency[current.id])
|
||||
}
|
||||
if(current.valueText){
|
||||
this.latencyGetValue(current.id, current.valueText)
|
||||
}
|
||||
}
|
||||
this.setStrings()
|
||||
}
|
||||
setStrings(){
|
||||
this.viewTitle.innerText = strings.gameSettings
|
||||
this.viewTitle.setAttribute("alt", strings.gameSettings)
|
||||
this.endButton.innerText = strings.settings.ok
|
||||
this.endButton.setAttribute("alt", strings.settings.ok)
|
||||
this.gamepadTitle.innerText = strings.settings.gamepadLayout.name
|
||||
this.gamepadTitle.setAttribute("alt", strings.settings.gamepadLayout.name)
|
||||
this.gamepadEndButton.innerText = strings.settings.ok
|
||||
this.gamepadEndButton.setAttribute("alt", strings.settings.ok)
|
||||
this.defaultButton.innerText = strings.settings.default
|
||||
this.defaultButton.setAttribute("alt", strings.settings.default)
|
||||
this.setAltText(this.viewTitle, strings.gameSettings)
|
||||
this.setAltText(this.endButton, strings.settings.ok)
|
||||
this.setAltText(this.gamepadTitle, strings.settings.gamepadLayout.name)
|
||||
this.setAltText(this.gamepadEndButton, strings.settings.ok)
|
||||
this.setAltText(this.latencyTitle, strings.settings.latency.name)
|
||||
this.setAltText(this.latencyDefaultButton, strings.settings.default)
|
||||
this.setAltText(this.latencyEndButton, strings.settings.ok)
|
||||
this.setAltText(this.defaultButton, strings.settings.default)
|
||||
}
|
||||
setAltText(element, text){
|
||||
element.innerText = text
|
||||
element.setAttribute("alt", text)
|
||||
}
|
||||
mod(length, index){
|
||||
return ((index % length) + length) % length
|
||||
}
|
||||
playSound(id, time){
|
||||
if(!this.drumSounds && (id === "se_don" || id === "se_ka" || id === "se_cancel")){
|
||||
return
|
||||
}
|
||||
var ms = Date.now() + (time || 0) * 1000
|
||||
if(!(id in this.playedSounds) || ms > this.playedSounds[id] + 30){
|
||||
assets.sounds[id].play(time)
|
||||
this.playedSounds[id] = ms
|
||||
}
|
||||
}
|
||||
redraw(){
|
||||
if(!this.redrawRunning){
|
||||
return
|
||||
}
|
||||
requestAnimationFrame(this.redrawBind)
|
||||
var ms = this.getMS()
|
||||
|
||||
for(var key in this.pressedKeys){
|
||||
if(this.pressedKeys[key]){
|
||||
if(ms >= this.pressedKeys[key] + 50){
|
||||
this.keyPressed(true, key, null, true)
|
||||
this.pressedKeys[key] = ms
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getMS(){
|
||||
return Date.now()
|
||||
}
|
||||
clean(){
|
||||
this.redrawRunning = false
|
||||
this.keyboard.clean()
|
||||
this.gamepad.clean()
|
||||
assets.sounds["bgm_settings"].stop()
|
||||
pageEvents.remove(this.viewOuter, ["mouseup", "touchend"])
|
||||
for(var i in this.items){
|
||||
this.removeTouch(this.items[i].settingBox)
|
||||
}
|
||||
for(var i in this.latencyItems){
|
||||
this.removeTouch(this.latencyItems[i].settingBox)
|
||||
if(this.latencyItems[i].buttonMinus){
|
||||
this.removeTouch(this.latencyItems[i].buttonMinus)
|
||||
this.removeTouch(this.latencyItems[i].buttonPlus)
|
||||
}
|
||||
}
|
||||
if(this.defaultButton){
|
||||
delete this.defaultButton
|
||||
}
|
||||
this.removeTouch(this.gamepadSettings)
|
||||
this.removeTouch(this.gamepadEndButton)
|
||||
this.removeTouch(this.gamepadBox)
|
||||
this.removeTouch(this.latencySettings)
|
||||
this.removeTouch(this.latencyDefaultButton)
|
||||
this.removeTouch(this.latencyEndButton)
|
||||
delete this.viewOuter
|
||||
delete this.touchEnd
|
||||
delete this.tutorialTitle
|
||||
delete this.endButton
|
||||
delete this.items
|
||||
@@ -516,6 +906,11 @@ class SettingsView{
|
||||
delete this.gamepadBox
|
||||
delete this.gamepadButtons
|
||||
delete this.gamepadValue
|
||||
delete this.latencyItems
|
||||
delete this.latencySettings
|
||||
delete this.latencyTitle
|
||||
delete this.latencyDefaultButton
|
||||
delete this.latencyEndButton
|
||||
if(this.resolution !== settings.getItem("resolution")){
|
||||
for(var i in assets.image){
|
||||
if(i === "touch_drum" || i.startsWith("bg_song_") || i.startsWith("bg_stage_") || i.startsWith("bg_don_")){
|
||||
|
||||
@@ -5,6 +5,14 @@ class SongSelect{
|
||||
loader.changePage("songselect", false)
|
||||
this.canvas = document.getElementById("song-sel-canvas")
|
||||
this.ctx = this.canvas.getContext("2d")
|
||||
var resolution = settings.getItem("resolution")
|
||||
var noSmoothing = resolution === "low" || resolution === "lowest"
|
||||
if(noSmoothing){
|
||||
this.ctx.imageSmoothingEnabled = false
|
||||
}
|
||||
if(resolution === "lowest"){
|
||||
this.canvas.style.imageRendering = "pixelated"
|
||||
}
|
||||
|
||||
this.songSkin = {
|
||||
"selected": {
|
||||
@@ -209,13 +217,13 @@ class SongSelect{
|
||||
}]
|
||||
this.optionsList = [strings.none, strings.auto, strings.netplay]
|
||||
|
||||
this.draw = new CanvasDraw()
|
||||
this.songTitleCache = new CanvasCache()
|
||||
this.selectTextCache = new CanvasCache()
|
||||
this.categoryCache = new CanvasCache()
|
||||
this.difficultyCache = new CanvasCache()
|
||||
this.sessionCache = new CanvasCache()
|
||||
this.currentSongCache = new CanvasCache()
|
||||
this.draw = new CanvasDraw(noSmoothing)
|
||||
this.songTitleCache = new CanvasCache(noSmoothing)
|
||||
this.selectTextCache = new CanvasCache(noSmoothing)
|
||||
this.categoryCache = new CanvasCache(noSmoothing)
|
||||
this.difficultyCache = new CanvasCache(noSmoothing)
|
||||
this.sessionCache = new CanvasCache(noSmoothing)
|
||||
this.currentSongCache = new CanvasCache(noSmoothing)
|
||||
|
||||
this.difficulty = [strings.easy, strings.normal, strings.hard, strings.oni]
|
||||
this.difficultyId = ["easy", "normal", "hard", "oni", "ura"]
|
||||
@@ -236,6 +244,9 @@ class SongSelect{
|
||||
fromTutorial = false
|
||||
}
|
||||
|
||||
this.drumSounds = settings.getItem("latency").drumSounds
|
||||
this.playedSounds = {}
|
||||
|
||||
var songIdIndex = -1
|
||||
if(fromTutorial){
|
||||
this.selectedSong = this.songs.findIndex(song => song.action === fromTutorial)
|
||||
@@ -254,7 +265,7 @@ class SongSelect{
|
||||
}else if((!p2.session || fadeIn) && "selectedSong" in localStorage){
|
||||
this.selectedSong = Math.min(Math.max(0, localStorage["selectedSong"] |0), this.songs.length - 1)
|
||||
}
|
||||
assets.sounds[songIdIndex !== -1 ? "v_diffsel" : "v_songsel"].play()
|
||||
this.playSound(songIdIndex !== -1 ? "v_diffsel" : "v_songsel")
|
||||
snd.musicGain.fadeOut()
|
||||
this.playBgm(false)
|
||||
}
|
||||
@@ -453,7 +464,7 @@ class SongSelect{
|
||||
window.open(this.songs[this.selectedSong].maker.url)
|
||||
}else if(moveBy === this.diffOptions.length + 4){
|
||||
this.state.ura = !this.state.ura
|
||||
assets.sounds["se_ka"].play()
|
||||
this.playSound("se_ka")
|
||||
if(this.selectedDiff === this.diffOptions.length + 4 && !this.state.ura){
|
||||
this.state.move = -1
|
||||
}
|
||||
@@ -581,7 +592,7 @@ class SongSelect{
|
||||
var soundsDelay = Math.abs((scroll + resize) / moveBy)
|
||||
|
||||
for(var i = 0; i < Math.abs(moveBy) - 1; i++){
|
||||
assets.sounds["se_ka"].play((resize + i * soundsDelay) / 1000)
|
||||
this.playSound("se_ka", (resize + i * soundsDelay) / 1000)
|
||||
}
|
||||
this.pointer(false)
|
||||
}
|
||||
@@ -605,7 +616,7 @@ class SongSelect{
|
||||
this.state.move = moveBy
|
||||
this.state.moveMS = this.getMS() - 500
|
||||
this.state.locked = 1
|
||||
assets.sounds["se_ka"].play()
|
||||
this.playSound("se_ka")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,15 +647,15 @@ class SongSelect{
|
||||
this.selectedDiff = this.diffOptions.length + 3
|
||||
}
|
||||
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
assets.sounds["v_songsel"].stop()
|
||||
assets.sounds["v_diffsel"].play(0.3)
|
||||
this.playSound("v_diffsel", 0.3)
|
||||
pageEvents.send("song-select-difficulty", currentSong)
|
||||
}else if(currentSong.action === "back"){
|
||||
this.clean()
|
||||
this.toTitleScreen()
|
||||
}else if(currentSong.action === "random"){
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
this.state.locked = true
|
||||
do{
|
||||
var i = Math.floor(Math.random() * this.songs.length)
|
||||
@@ -681,7 +692,7 @@ class SongSelect{
|
||||
this.state.moveHover = null
|
||||
|
||||
assets.sounds["v_diffsel"].stop()
|
||||
assets.sounds["se_cancel"].play()
|
||||
this.playSound("se_cancel")
|
||||
}
|
||||
this.clearHash()
|
||||
pageEvents.send("song-select-back")
|
||||
@@ -690,7 +701,7 @@ class SongSelect{
|
||||
this.clean()
|
||||
var selectedSong = this.songs[this.selectedSong]
|
||||
assets.sounds["v_diffsel"].stop()
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
|
||||
try{
|
||||
if(assets.customSongs){
|
||||
@@ -729,7 +740,7 @@ class SongSelect{
|
||||
}
|
||||
toOptions(moveBy){
|
||||
if(!p2.session){
|
||||
assets.sounds["se_ka"].play()
|
||||
this.playSound("se_ka")
|
||||
this.selectedDiff = 1
|
||||
do{
|
||||
this.state.options = this.mod(this.optionsList.length, this.state.options + moveBy)
|
||||
@@ -738,7 +749,7 @@ class SongSelect{
|
||||
}
|
||||
toTitleScreen(){
|
||||
if(!p2.session){
|
||||
assets.sounds["se_cancel"].play()
|
||||
this.playSound("se_cancel")
|
||||
this.clean()
|
||||
setTimeout(() => {
|
||||
new Titlescreen()
|
||||
@@ -746,21 +757,21 @@ class SongSelect{
|
||||
}
|
||||
}
|
||||
toTutorial(){
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
this.clean()
|
||||
setTimeout(() => {
|
||||
new Tutorial(true)
|
||||
}, 500)
|
||||
}
|
||||
toAbout(){
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
this.clean()
|
||||
setTimeout(() => {
|
||||
new About(this.touchEnabled)
|
||||
}, 500)
|
||||
}
|
||||
toSettings(){
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
this.clean()
|
||||
setTimeout(() => {
|
||||
new SettingsView(this.touchEnabled)
|
||||
@@ -775,7 +786,7 @@ class SongSelect{
|
||||
}else{
|
||||
localStorage["selectedSong"] = this.selectedSong
|
||||
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
this.clean()
|
||||
setTimeout(() => {
|
||||
new Session(this.touchEnabled)
|
||||
@@ -786,7 +797,7 @@ class SongSelect{
|
||||
if(assets.customSongs){
|
||||
assets.customSongs = false
|
||||
assets.songs = assets.songsDefault
|
||||
assets.sounds["se_don"].play()
|
||||
this.playSound("se_don")
|
||||
this.clean()
|
||||
setTimeout(() => {
|
||||
new SongSelect("browse", false, this.touchEnabled)
|
||||
@@ -1014,6 +1025,7 @@ class SongSelect{
|
||||
var resize2 = changeSpeed - resize
|
||||
var scroll = resize2 - resize - scrollDelay * 2
|
||||
var elapsed = ms - this.state.moveMS
|
||||
|
||||
if(this.state.catJump || (this.state.move && ms > this.state.moveMS + resize2 - scrollDelay)){
|
||||
var isJump = this.state.catJump
|
||||
var previousSelectedSong = this.selectedSong
|
||||
@@ -2116,6 +2128,17 @@ class SongSelect{
|
||||
}
|
||||
}
|
||||
|
||||
playSound(id, time){
|
||||
if(!this.drumSounds && (id === "se_don" || id === "se_ka" || id === "se_cancel")){
|
||||
return
|
||||
}
|
||||
var ms = Date.now() + (time || 0) * 1000
|
||||
if(!(id in this.playedSounds) || ms > this.playedSounds[id] + 30){
|
||||
assets.sounds[id].play(time)
|
||||
this.playedSounds[id] = ms
|
||||
}
|
||||
}
|
||||
|
||||
getMS(){
|
||||
return Date.now()
|
||||
}
|
||||
|
||||
@@ -50,6 +50,22 @@
|
||||
daiDrumroll: "連打(大)ーっ!!",
|
||||
balloon: "ふうせん"
|
||||
}
|
||||
this.ex_note = {
|
||||
don: [
|
||||
"ド",
|
||||
"コ"
|
||||
],
|
||||
ka: [
|
||||
"カ"
|
||||
],
|
||||
daiDon: [
|
||||
"ドン(大)",
|
||||
"ドン(大)"
|
||||
],
|
||||
daiKa: [
|
||||
"カッ(大)"
|
||||
]
|
||||
}
|
||||
this.combo = "コンボ"
|
||||
this.clear = "クリア"
|
||||
this.good = "良"
|
||||
@@ -127,11 +143,42 @@
|
||||
b: "タイプB",
|
||||
c: "タイプC"
|
||||
},
|
||||
latency: {
|
||||
name: "Latency",
|
||||
value: "Audio: %s, Video: %s",
|
||||
calibration: "Latency Calibration",
|
||||
audio: "Audio",
|
||||
video: "Video",
|
||||
drumSounds: "Drum Sounds"
|
||||
},
|
||||
on: "オン",
|
||||
off: "オフ",
|
||||
default: "既定値にリセット",
|
||||
ok: "OK"
|
||||
}
|
||||
this.calibration = {
|
||||
title: "Latency Calibration",
|
||||
ms: "%sms",
|
||||
back: "Back to Settings",
|
||||
retryPrevious: "Retry Previous",
|
||||
start: "Start",
|
||||
finish: "Finish",
|
||||
audioHelp: {
|
||||
title: "Audio Latency Calibration",
|
||||
content: "Listen to a sound playing in the background.\n\nHit the surface of the drum (%s or %s) as you hear it!",
|
||||
contentAlt: "Listen to a sound playing in the background.\n\nHit the surface of the drum as you hear it!"
|
||||
},
|
||||
audioComplete: "Audio Latency Calibration completed!",
|
||||
videoHelp: {
|
||||
title: "Video Latency Calibration",
|
||||
content: "This time there will be no sounds.\n\nInstead, watch for notes blinking on the circle-shaped frame, hit the drum as they appear!"
|
||||
},
|
||||
videoComplete: "Video Latency Calibration completed!",
|
||||
results: {
|
||||
title: "Latency Calibration Results",
|
||||
content: "Audio latency: %s\nVideo latency: %s\n\nYou can configure these latency values in the settings."
|
||||
}
|
||||
}
|
||||
this.browserSupport = {
|
||||
browserWarning: "サポートされていないブラウザを実行しています (%s)",
|
||||
details: "詳しく",
|
||||
@@ -195,6 +242,22 @@ function StringsEn(){
|
||||
daiDrumroll: "DRUM ROLLー!!",
|
||||
balloon: "Balloon"
|
||||
}
|
||||
this.ex_note = {
|
||||
don: [
|
||||
"Do",
|
||||
"Do"
|
||||
],
|
||||
ka: [
|
||||
"Ka"
|
||||
],
|
||||
daiDon: [
|
||||
"DON",
|
||||
"DON"
|
||||
],
|
||||
daiKa: [
|
||||
"KA"
|
||||
]
|
||||
}
|
||||
this.combo = "Combo"
|
||||
this.clear = "Clear"
|
||||
this.good = "GOOD"
|
||||
@@ -272,11 +335,42 @@ function StringsEn(){
|
||||
b: "Type B",
|
||||
c: "Type C"
|
||||
},
|
||||
latency: {
|
||||
name: "Latency",
|
||||
value: "Audio: %s, Video: %s",
|
||||
calibration: "Latency Calibration",
|
||||
audio: "Audio",
|
||||
video: "Video",
|
||||
drumSounds: "Drum Sounds"
|
||||
},
|
||||
on: "On",
|
||||
off: "Off",
|
||||
default: "Reset to Defaults",
|
||||
ok: "OK"
|
||||
}
|
||||
this.calibration = {
|
||||
title: "Latency Calibration",
|
||||
ms: "%sms",
|
||||
back: "Back to Settings",
|
||||
retryPrevious: "Retry Previous",
|
||||
start: "Start",
|
||||
finish: "Finish",
|
||||
audioHelp: {
|
||||
title: "Audio Latency Calibration",
|
||||
content: "Listen to a sound playing in the background.\n\nHit the surface of the drum (%s or %s) as you hear it!",
|
||||
contentAlt: "Listen to a sound playing in the background.\n\nHit the surface of the drum as you hear it!"
|
||||
},
|
||||
audioComplete: "Audio Latency Calibration completed!",
|
||||
videoHelp: {
|
||||
title: "Video Latency Calibration",
|
||||
content: "This time there will be no sounds.\n\nInstead, watch for notes blinking on the circle-shaped frame, hit the drum as they appear!"
|
||||
},
|
||||
videoComplete: "Video Latency Calibration completed!",
|
||||
results: {
|
||||
title: "Latency Calibration Results",
|
||||
content: "Audio latency: %s\nVideo latency: %s\n\nYou can configure these latency values in the settings."
|
||||
}
|
||||
}
|
||||
this.browserSupport = {
|
||||
browserWarning: "You are running an unsupported browser (%s)",
|
||||
details: "Details...",
|
||||
@@ -340,6 +434,22 @@ function StringsCn(){
|
||||
daiDrumroll: "连打(大)ー!!",
|
||||
balloon: "气球"
|
||||
}
|
||||
this.ex_note = {
|
||||
don: [
|
||||
"咚",
|
||||
"咚"
|
||||
],
|
||||
ka: [
|
||||
"咔"
|
||||
],
|
||||
daiDon: [
|
||||
"咚(大)",
|
||||
"咚(大)"
|
||||
],
|
||||
daiKa: [
|
||||
"咔(大)"
|
||||
]
|
||||
}
|
||||
this.combo = "连段"
|
||||
this.clear = "通关"
|
||||
this.good = "良"
|
||||
@@ -417,11 +527,42 @@ function StringsCn(){
|
||||
b: "类型B",
|
||||
c: "类型C"
|
||||
},
|
||||
latency: {
|
||||
name: "Latency",
|
||||
value: "Audio: %s, Video: %s",
|
||||
calibration: "Latency Calibration",
|
||||
audio: "Audio",
|
||||
video: "Video",
|
||||
drumSounds: "Drum Sounds"
|
||||
},
|
||||
on: "开",
|
||||
off: "关",
|
||||
default: "重置为默认值",
|
||||
ok: "确定"
|
||||
}
|
||||
this.calibration = {
|
||||
title: "Latency Calibration",
|
||||
ms: "%sms",
|
||||
back: "Back to Settings",
|
||||
retryPrevious: "Retry Previous",
|
||||
start: "Start",
|
||||
finish: "Finish",
|
||||
audioHelp: {
|
||||
title: "Audio Latency Calibration",
|
||||
content: "Listen to a sound playing in the background.\n\nHit the surface of the drum (%s or %s) as you hear it!",
|
||||
contentAlt: "Listen to a sound playing in the background.\n\nHit the surface of the drum as you hear it!"
|
||||
},
|
||||
audioComplete: "Audio Latency Calibration completed!",
|
||||
videoHelp: {
|
||||
title: "Video Latency Calibration",
|
||||
content: "This time there will be no sounds.\n\nInstead, watch for notes blinking on the circle-shaped frame, hit the drum as they appear!"
|
||||
},
|
||||
videoComplete: "Video Latency Calibration completed!",
|
||||
results: {
|
||||
title: "Latency Calibration Results",
|
||||
content: "Audio latency: %s\nVideo latency: %s\n\nYou can configure these latency values in the settings."
|
||||
}
|
||||
}
|
||||
this.browserSupport = {
|
||||
browserWarning: "You are running an unsupported browser (%s)",
|
||||
details: "Details...",
|
||||
@@ -485,6 +626,22 @@ function StringsTw(){
|
||||
daiDrumroll: "連打(大)ー!!",
|
||||
balloon: "氣球"
|
||||
}
|
||||
this.ex_note = {
|
||||
don: [
|
||||
"咚",
|
||||
"咚"
|
||||
],
|
||||
ka: [
|
||||
"咔"
|
||||
],
|
||||
daiDon: [
|
||||
"咚(大)",
|
||||
"咚(大)"
|
||||
],
|
||||
daiKa: [
|
||||
"咔(大)"
|
||||
]
|
||||
}
|
||||
this.combo = "連段"
|
||||
this.clear = "通關"
|
||||
this.good = "良"
|
||||
@@ -562,11 +719,42 @@ function StringsTw(){
|
||||
b: "類型B",
|
||||
c: "類型C"
|
||||
},
|
||||
latency: {
|
||||
name: "Latency",
|
||||
value: "Audio: %s, Video: %s",
|
||||
calibration: "Latency Calibration",
|
||||
audio: "Audio",
|
||||
video: "Video",
|
||||
drumSounds: "Drum Sounds"
|
||||
},
|
||||
on: "開",
|
||||
off: "關",
|
||||
default: "重置為默認值",
|
||||
ok: "確定"
|
||||
}
|
||||
this.calibration = {
|
||||
title: "Latency Calibration",
|
||||
ms: "%sms",
|
||||
back: "Back to Settings",
|
||||
retryPrevious: "Retry Previous",
|
||||
start: "Start",
|
||||
finish: "Finish",
|
||||
audioHelp: {
|
||||
title: "Audio Latency Calibration",
|
||||
content: "Listen to a sound playing in the background.\n\nHit the surface of the drum (%s or %s) as you hear it!",
|
||||
contentAlt: "Listen to a sound playing in the background.\n\nHit the surface of the drum as you hear it!"
|
||||
},
|
||||
audioComplete: "Audio Latency Calibration completed!",
|
||||
videoHelp: {
|
||||
title: "Video Latency Calibration",
|
||||
content: "This time there will be no sounds.\n\nInstead, watch for notes blinking on the circle-shaped frame, hit the drum as they appear!"
|
||||
},
|
||||
videoComplete: "Video Latency Calibration completed!",
|
||||
results: {
|
||||
title: "Latency Calibration Results",
|
||||
content: "Audio latency: %s\nVideo latency: %s\n\nYou can configure these latency values in the settings."
|
||||
}
|
||||
}
|
||||
this.browserSupport = {
|
||||
browserWarning: "You are running an unsupported browser (%s)",
|
||||
details: "Details...",
|
||||
@@ -630,6 +818,22 @@ function StringsKo(){
|
||||
daiDrumroll: "연타(대)ー!!",
|
||||
balloon: "풍선"
|
||||
}
|
||||
this.ex_note = {
|
||||
don: [
|
||||
"쿠",
|
||||
"쿠"
|
||||
],
|
||||
ka: [
|
||||
"딱"
|
||||
],
|
||||
daiDon: [
|
||||
"쿵(대)",
|
||||
"쿵(대)"
|
||||
],
|
||||
daiKa: [
|
||||
"딱(대)"
|
||||
]
|
||||
}
|
||||
this.combo = "콤보"
|
||||
this.clear = "클리어"
|
||||
this.good = "얼쑤"
|
||||
@@ -707,11 +911,42 @@ function StringsKo(){
|
||||
b: "타입 B",
|
||||
c: "타입 C"
|
||||
},
|
||||
latency: {
|
||||
name: "Latency",
|
||||
value: "Audio: %s, Video: %s",
|
||||
calibration: "Latency Calibration",
|
||||
audio: "Audio",
|
||||
video: "Video",
|
||||
drumSounds: "Drum Sounds"
|
||||
},
|
||||
on: "온",
|
||||
off: "오프",
|
||||
default: "기본값으로 재설정",
|
||||
ok: "확인"
|
||||
}
|
||||
this.calibration = {
|
||||
title: "Latency Calibration",
|
||||
ms: "%sms",
|
||||
back: "Back to Settings",
|
||||
retryPrevious: "Retry Previous",
|
||||
start: "Start",
|
||||
finish: "Finish",
|
||||
audioHelp: {
|
||||
title: "Audio Latency Calibration",
|
||||
content: "Listen to a sound playing in the background.\n\nHit the surface of the drum (%s or %s) as you hear it!",
|
||||
contentAlt: "Listen to a sound playing in the background.\n\nHit the surface of the drum as you hear it!"
|
||||
},
|
||||
audioComplete: "Audio Latency Calibration completed!",
|
||||
videoHelp: {
|
||||
title: "Video Latency Calibration",
|
||||
content: "This time there will be no sounds.\n\nInstead, watch for notes blinking on the circle-shaped frame, hit the drum as they appear!"
|
||||
},
|
||||
videoComplete: "Video Latency Calibration completed!",
|
||||
results: {
|
||||
title: "Latency Calibration Results",
|
||||
content: "Audio latency: %s\nVideo latency: %s\n\nYou can configure these latency values in the settings."
|
||||
}
|
||||
}
|
||||
this.browserSupport = {
|
||||
browserWarning: "You are running an unsupported browser (%s)",
|
||||
details: "Details...",
|
||||
|
||||
@@ -4,8 +4,15 @@
|
||||
|
||||
this.canvas = document.getElementById("canvas")
|
||||
this.ctx = this.canvas.getContext("2d")
|
||||
var resolution = settings.getItem("resolution")
|
||||
var noSmoothing = resolution === "low" || resolution === "lowest"
|
||||
if(noSmoothing){
|
||||
this.ctx.imageSmoothingEnabled = false
|
||||
}
|
||||
if(resolution === "lowest"){
|
||||
this.canvas.style.imageRendering = "pixelated"
|
||||
}
|
||||
|
||||
this.cursor = document.getElementById("cursor")
|
||||
this.gameDiv = document.getElementById("game")
|
||||
this.songBg = document.getElementById("songbg")
|
||||
this.songStage = document.getElementById("song-stage")
|
||||
@@ -73,6 +80,7 @@
|
||||
}
|
||||
this.nextBeat = 0
|
||||
this.gogoTime = 0
|
||||
this.gogoTimeStarted = -Infinity
|
||||
this.drumroll = []
|
||||
this.touchEvents = 0
|
||||
if(this.controller.parsedSongData.branches){
|
||||
@@ -103,16 +111,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
this.beatInterval = this.controller.parsedSongData.beatInfo.beatInterval
|
||||
if(this.controller.calibrationMode){
|
||||
this.beatInterval = 512
|
||||
}else{
|
||||
this.beatInterval = this.controller.parsedSongData.beatInfo.beatInterval
|
||||
}
|
||||
this.font = strings.font
|
||||
|
||||
this.draw = new CanvasDraw()
|
||||
this.draw = new CanvasDraw(noSmoothing)
|
||||
this.assets = new ViewAssets(this)
|
||||
|
||||
this.titleCache = new CanvasCache()
|
||||
this.comboCache = new CanvasCache()
|
||||
this.pauseCache = new CanvasCache()
|
||||
this.branchCache = new CanvasCache()
|
||||
this.titleCache = new CanvasCache(noSmoothing)
|
||||
this.comboCache = new CanvasCache(noSmoothing)
|
||||
this.pauseCache = new CanvasCache(noSmoothing)
|
||||
this.branchCache = new CanvasCache(noSmoothing)
|
||||
|
||||
this.multiplayer = this.controller.multiplayer
|
||||
|
||||
@@ -120,6 +132,9 @@
|
||||
this.touch = -Infinity
|
||||
this.touchAnimation = settings.getItem("touchAnimation")
|
||||
|
||||
versionDiv.classList.add("version-hide")
|
||||
loader.screen.parentNode.insertBefore(versionDiv, loader.screen)
|
||||
|
||||
if(this.multiplayer !== 2){
|
||||
|
||||
if(this.controller.touchEnabled){
|
||||
@@ -134,7 +149,6 @@
|
||||
pageEvents.add(this.canvas, "touchstart", this.ontouch.bind(this))
|
||||
|
||||
this.gameDiv.classList.add("touch-visible")
|
||||
document.getElementById("version").classList.add("version-hide")
|
||||
|
||||
this.touchFullBtn = document.getElementById("touch-full-btn")
|
||||
pageEvents.add(this.touchFullBtn, "touchend", toggleFullscreen)
|
||||
@@ -444,12 +458,14 @@
|
||||
ctx.fill()
|
||||
|
||||
// Difficulty
|
||||
ctx.drawImage(assets.image["difficulty"],
|
||||
0, 144 * this.difficulty[this.controller.selectedSong.difficulty],
|
||||
168, 143,
|
||||
126, this.multiplayer === 2 ? 497 : 228,
|
||||
62, 53
|
||||
)
|
||||
if(this.controller.selectedSong.difficulty){
|
||||
ctx.drawImage(assets.image["difficulty"],
|
||||
0, 144 * this.difficulty[this.controller.selectedSong.difficulty],
|
||||
168, 143,
|
||||
126, this.multiplayer === 2 ? 497 : 228,
|
||||
62, 53
|
||||
)
|
||||
}
|
||||
|
||||
// Badges
|
||||
if(this.controller.autoPlayEnabled && !this.controller.multiplayer){
|
||||
@@ -593,24 +609,26 @@
|
||||
ctx.globalAlpha = 1
|
||||
|
||||
// Difficulty
|
||||
ctx.drawImage(assets.image["difficulty"],
|
||||
0, 144 * this.difficulty[this.controller.selectedSong.difficulty],
|
||||
168, 143,
|
||||
16, this.multiplayer === 2 ? 194 : 232,
|
||||
141, 120
|
||||
)
|
||||
var diff = this.controller.selectedSong.difficulty
|
||||
var text = strings[diff === "ura" ? "oni" : diff]
|
||||
ctx.font = this.draw.bold(this.font) + "20px " + this.font
|
||||
ctx.textAlign = "center"
|
||||
ctx.textBaseline = "bottom"
|
||||
ctx.strokeStyle = "#000"
|
||||
ctx.fillStyle = "#fff"
|
||||
ctx.lineWidth = 7
|
||||
ctx.miterLimit = 1
|
||||
ctx.strokeText(text, 87, this.multiplayer === 2 ? 310 : 348)
|
||||
ctx.fillText(text, 87, this.multiplayer === 2 ? 310 : 348)
|
||||
ctx.miterLimit = 10
|
||||
if(this.controller.selectedSong.difficulty){
|
||||
ctx.drawImage(assets.image["difficulty"],
|
||||
0, 144 * this.difficulty[this.controller.selectedSong.difficulty],
|
||||
168, 143,
|
||||
16, this.multiplayer === 2 ? 194 : 232,
|
||||
141, 120
|
||||
)
|
||||
var diff = this.controller.selectedSong.difficulty
|
||||
var text = strings[diff === "ura" ? "oni" : diff]
|
||||
ctx.font = this.draw.bold(this.font) + "20px " + this.font
|
||||
ctx.textAlign = "center"
|
||||
ctx.textBaseline = "bottom"
|
||||
ctx.strokeStyle = "#000"
|
||||
ctx.fillStyle = "#fff"
|
||||
ctx.lineWidth = 7
|
||||
ctx.miterLimit = 1
|
||||
ctx.strokeText(text, 87, this.multiplayer === 2 ? 310 : 348)
|
||||
ctx.fillText(text, 87, this.multiplayer === 2 ? 310 : 348)
|
||||
ctx.miterLimit = 10
|
||||
}
|
||||
|
||||
// Badges
|
||||
if(this.controller.autoPlayEnabled && !this.controller.multiplayer){
|
||||
@@ -947,6 +965,20 @@
|
||||
ctx.clip()
|
||||
|
||||
this.drawCircles(this.controller.getCircles())
|
||||
if(this.controller.game.calibrationState === "video"){
|
||||
if(ms % this.beatInterval < 1000 / 60 * 5){
|
||||
this.drawCircle({
|
||||
ms: ms,
|
||||
type: "don",
|
||||
endTime: ms + 100,
|
||||
speed: 0
|
||||
}, {
|
||||
x: this.slotPos.x,
|
||||
y: this.slotPos.y
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
ctx.restore()
|
||||
|
||||
// Hit notes explosion
|
||||
@@ -1001,6 +1033,22 @@
|
||||
ctx.translate(frameLeft, frameTop)
|
||||
}
|
||||
|
||||
var state = this.controller.game.calibrationState
|
||||
if(state && state in strings.calibration){
|
||||
var boldTitle = strings.calibration[state].title
|
||||
}
|
||||
if(boldTitle){
|
||||
this.draw.layeredText({
|
||||
ctx: ctx,
|
||||
text: boldTitle,
|
||||
fontSize: 35,
|
||||
fontFamily: this.font,
|
||||
x: 300,
|
||||
y: 70
|
||||
}, [
|
||||
{outline: "#fff", letterBorder: 22}
|
||||
])
|
||||
}
|
||||
var pauseRect = (ctx, mul) => {
|
||||
this.draw.roundedRect({
|
||||
ctx: ctx,
|
||||
@@ -1025,86 +1073,284 @@
|
||||
dx: 68,
|
||||
dy: 11
|
||||
})
|
||||
|
||||
ctx.drawImage(assets.image["mimizu"],
|
||||
313, 247, 136, 315
|
||||
)
|
||||
|
||||
var _y = 108
|
||||
var _w = 80
|
||||
var _h = 464
|
||||
for(var i = 0; i < this.pauseOptions.length; i++){
|
||||
var _x = 520 + 110 * i
|
||||
if(this.state.moveHover !== null){
|
||||
var selected = i === this.state.moveHover
|
||||
}else{
|
||||
var selected = i === this.state.pausePos
|
||||
}
|
||||
if(selected){
|
||||
ctx.fillStyle = "#ffb447"
|
||||
this.draw.roundedRect({
|
||||
ctx: ctx,
|
||||
x: _x - _w / 2,
|
||||
y: _y,
|
||||
w: _w,
|
||||
h: _h,
|
||||
radius: 30
|
||||
})
|
||||
ctx.fill()
|
||||
}
|
||||
this.pauseCache.get({
|
||||
if(boldTitle){
|
||||
this.draw.layeredText({
|
||||
ctx: ctx,
|
||||
x: _x - _w / 2,
|
||||
y: _y,
|
||||
w: _w,
|
||||
h: _h,
|
||||
id: this.pauseOptions[i] + (selected ? "1" : "0")
|
||||
}, ctx => {
|
||||
var textConfig = {
|
||||
text: boldTitle,
|
||||
fontSize: 35,
|
||||
fontFamily: this.font,
|
||||
x: 300,
|
||||
y: 70
|
||||
}, [
|
||||
{outline: "#000", letterBorder: 10},
|
||||
{fill: "#fff"}
|
||||
])
|
||||
}
|
||||
|
||||
switch(state){
|
||||
case "audioHelp":
|
||||
case "videoHelp":
|
||||
case "results":
|
||||
var content = state === "audioHelp" && this.touchEnabled ? "contentAlt" : "content"
|
||||
if(state === "audioHelp"){
|
||||
var kbdSettings = settings.getItem("keyboardSettings")
|
||||
var keys = [
|
||||
kbdSettings.don_l[0].toUpperCase(),
|
||||
kbdSettings.don_r[0].toUpperCase()
|
||||
]
|
||||
var substitute = (config, index, width) => {
|
||||
var ctx = config.ctx
|
||||
var bold = this.draw.bold(config.fontFamily)
|
||||
ctx.font = bold + (config.fontSize * 0.66) + "px " + config.fontFamily
|
||||
var w = config.fontSize * 0.6 + ctx.measureText(keys[index]).width
|
||||
if(width){
|
||||
return w
|
||||
}else{
|
||||
var h = 30
|
||||
ctx.lineWidth = 3
|
||||
ctx.strokeStyle = "rgba(0, 0, 0, 0.2)"
|
||||
this.draw.roundedRect({
|
||||
ctx: ctx,
|
||||
x: 0, y: 1, w: w, h: h,
|
||||
radius: 3
|
||||
})
|
||||
ctx.stroke()
|
||||
ctx.strokeStyle = "#ccc"
|
||||
ctx.fillStyle = "#fff"
|
||||
this.draw.roundedRect({
|
||||
ctx: ctx,
|
||||
x: 0, y: 0, w: w, h: h,
|
||||
radius: 3
|
||||
})
|
||||
ctx.stroke()
|
||||
ctx.fill()
|
||||
ctx.fillStyle = "#f7f7f7"
|
||||
ctx.fillRect(2, 2, w - 4, h - 4)
|
||||
|
||||
ctx.fillStyle = "#333"
|
||||
ctx.textBaseline = "middle"
|
||||
ctx.textAlign = "center"
|
||||
ctx.fillText(keys[index], w / 2, h / 2)
|
||||
}
|
||||
}
|
||||
}else if(state === "results"){
|
||||
var progress = this.controller.game.calibrationProgress
|
||||
var latency = [
|
||||
progress.audio,
|
||||
progress.video
|
||||
]
|
||||
var substitute = (config, index, width) => {
|
||||
var ctx = config.ctx
|
||||
var bold = this.draw.bold(config.fontFamily)
|
||||
ctx.font = bold + (config.fontSize * 1.1) + "px " + config.fontFamily
|
||||
var text = this.addMs(latency[index])
|
||||
if(width){
|
||||
return ctx.measureText(text).width
|
||||
}else{
|
||||
ctx.fillText(text, 0, 0)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
var substitute = null
|
||||
}
|
||||
this.draw.wrappingText({
|
||||
ctx: ctx,
|
||||
text: this.pauseOptions[i],
|
||||
x: _w / 2,
|
||||
y: 18,
|
||||
width: _w,
|
||||
height: _h - 54,
|
||||
text: strings.calibration[state][content],
|
||||
fontSize: 30,
|
||||
fontFamily: this.font,
|
||||
x: 300,
|
||||
y: 130,
|
||||
width: 680,
|
||||
height: 240,
|
||||
lineHeight: 35,
|
||||
fill: "#000",
|
||||
verticalAlign: "middle",
|
||||
substitute: substitute
|
||||
})
|
||||
|
||||
var _x = 640
|
||||
var _w = 464
|
||||
var _h = 80
|
||||
for(var i = 0; i < this.pauseOptions.length; i++){
|
||||
var text = this.pauseOptions[i]
|
||||
var _y = 470 - 90 * (this.pauseOptions.length - i - 1)
|
||||
if(this.state.moveHover !== null){
|
||||
var selected = i === this.state.moveHover
|
||||
}else{
|
||||
var selected = i === this.state.pausePos
|
||||
}
|
||||
if(selected){
|
||||
ctx.fillStyle = "#ffb447"
|
||||
this.draw.roundedRect({
|
||||
ctx: ctx,
|
||||
x: _x - _w / 2,
|
||||
y: _y,
|
||||
w: _w,
|
||||
h: _h,
|
||||
radius: 30
|
||||
})
|
||||
ctx.fill()
|
||||
}
|
||||
if(selected){
|
||||
var layers = [
|
||||
{outline: "#000", letterBorder: 10},
|
||||
{fill: "#fff"}
|
||||
]
|
||||
}else{
|
||||
var layers = [
|
||||
{fill: "#000"}
|
||||
]
|
||||
}
|
||||
this.draw.layeredText({
|
||||
ctx: ctx,
|
||||
text: text,
|
||||
x: _x,
|
||||
y: _y + 18,
|
||||
width: _w,
|
||||
height: _h - 54,
|
||||
fontSize: 40,
|
||||
fontFamily: this.font,
|
||||
letterSpacing: -1,
|
||||
align: "center"
|
||||
}, layers)
|
||||
|
||||
var highlight = 0
|
||||
if(this.state.moveHover === i){
|
||||
highlight = 2
|
||||
}else if(selected){
|
||||
highlight = 1
|
||||
}
|
||||
if(highlight){
|
||||
this.draw.highlight({
|
||||
ctx: ctx,
|
||||
x: _x - _w / 2 - 3.5,
|
||||
y: _y - 3.5,
|
||||
w: _w + 7,
|
||||
h: _h + 7,
|
||||
animate: highlight === 1,
|
||||
animateMS: this.state.moveMS,
|
||||
opacity: highlight === 2 ? 0.8 : 1,
|
||||
radius: 30
|
||||
})
|
||||
}
|
||||
}
|
||||
break
|
||||
case "audioComplete":
|
||||
case "videoComplete":
|
||||
this.draw.wrappingText({
|
||||
ctx: ctx,
|
||||
text: strings.calibration[state],
|
||||
fontSize: 40,
|
||||
fontFamily: this.font,
|
||||
letterSpacing: -1
|
||||
}
|
||||
if(selected){
|
||||
textConfig.fill = "#fff"
|
||||
textConfig.outline = "#000"
|
||||
textConfig.outlineSize = 10
|
||||
}else{
|
||||
textConfig.fill = "#000"
|
||||
}
|
||||
this.draw.verticalText(textConfig)
|
||||
})
|
||||
|
||||
var highlight = 0
|
||||
if(this.state.moveHover === i){
|
||||
highlight = 2
|
||||
}else if(selected){
|
||||
highlight = 1
|
||||
}
|
||||
if(highlight){
|
||||
this.draw.highlight({
|
||||
ctx: ctx,
|
||||
x: _x - _w / 2 - 3.5,
|
||||
y: _y - 3.5,
|
||||
w: _w + 7,
|
||||
h: _h + 7,
|
||||
animate: highlight === 1,
|
||||
animateMS: this.state.moveMS,
|
||||
opacity: highlight === 2 ? 0.8 : 1,
|
||||
radius: 30
|
||||
x: 300,
|
||||
y: 130,
|
||||
width: 680,
|
||||
height: 420,
|
||||
lineHeight: 47,
|
||||
fill: "#000",
|
||||
verticalAlign: "middle",
|
||||
textAlign: "center",
|
||||
})
|
||||
}
|
||||
break
|
||||
default:
|
||||
ctx.drawImage(assets.image["mimizu"],
|
||||
313, 247, 136, 315
|
||||
)
|
||||
|
||||
var _y = 108
|
||||
var _w = 80
|
||||
var _h = 464
|
||||
for(var i = 0; i < this.pauseOptions.length; i++){
|
||||
var text = this.pauseOptions[i]
|
||||
if(this.controller.calibrationMode && i === this.pauseOptions.length - 1){
|
||||
text = strings.calibration.back
|
||||
}
|
||||
var _x = 520 + 110 * i
|
||||
if(this.state.moveHover !== null){
|
||||
var selected = i === this.state.moveHover
|
||||
}else{
|
||||
var selected = i === this.state.pausePos
|
||||
}
|
||||
if(selected){
|
||||
ctx.fillStyle = "#ffb447"
|
||||
this.draw.roundedRect({
|
||||
ctx: ctx,
|
||||
x: _x - _w / 2,
|
||||
y: _y,
|
||||
w: _w,
|
||||
h: _h,
|
||||
radius: 30
|
||||
})
|
||||
ctx.fill()
|
||||
}
|
||||
this.pauseCache.get({
|
||||
ctx: ctx,
|
||||
x: _x - _w / 2,
|
||||
y: _y,
|
||||
w: _w,
|
||||
h: _h,
|
||||
id: text + (selected ? "1" : "0")
|
||||
}, ctx => {
|
||||
var textConfig = {
|
||||
ctx: ctx,
|
||||
text: text,
|
||||
x: _w / 2,
|
||||
y: 18,
|
||||
width: _w,
|
||||
height: _h - 54,
|
||||
fontSize: 40,
|
||||
fontFamily: this.font,
|
||||
letterSpacing: -1
|
||||
}
|
||||
if(selected){
|
||||
textConfig.fill = "#fff"
|
||||
textConfig.outline = "#000"
|
||||
textConfig.outlineSize = 10
|
||||
}else{
|
||||
textConfig.fill = "#000"
|
||||
}
|
||||
this.draw.verticalText(textConfig)
|
||||
})
|
||||
|
||||
var highlight = 0
|
||||
if(this.state.moveHover === i){
|
||||
highlight = 2
|
||||
}else if(selected){
|
||||
highlight = 1
|
||||
}
|
||||
if(highlight){
|
||||
this.draw.highlight({
|
||||
ctx: ctx,
|
||||
x: _x - _w / 2 - 3.5,
|
||||
y: _y - 3.5,
|
||||
w: _w + 7,
|
||||
h: _h + 7,
|
||||
animate: highlight === 1,
|
||||
animateMS: this.state.moveMS,
|
||||
opacity: highlight === 2 ? 0.8 : 1,
|
||||
radius: 30
|
||||
})
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
ctx.restore()
|
||||
}
|
||||
}
|
||||
addMs(input){
|
||||
var split = strings.calibration.ms.split("%s")
|
||||
var index = 0
|
||||
var output = ""
|
||||
var inputStrings = [(input > 0 ? "+" : "") + input.toString()]
|
||||
split.forEach((string, i) => {
|
||||
if(i !== 0){
|
||||
output += inputStrings[index++]
|
||||
}
|
||||
output += string
|
||||
})
|
||||
return output
|
||||
}
|
||||
setBackground(){
|
||||
var selectedSong = this.controller.selectedSong
|
||||
var songSkinName = selectedSong.songSkin.name
|
||||
@@ -1219,10 +1465,10 @@
|
||||
|
||||
measures.forEach(measure => {
|
||||
var timeForDistance = this.posToMs(distanceForCircle, measure.speed)
|
||||
var startingTime = measure.ms - timeForDistance
|
||||
var finishTime = measure.ms + this.posToMs(this.slotPos.x - this.slotPos.paddingLeft + 3, measure.speed)
|
||||
var startingTime = measure.ms - timeForDistance + this.controller.videoLatency
|
||||
var finishTime = measure.ms + this.posToMs(this.slotPos.x - this.slotPos.paddingLeft + 3, measure.speed) + this.controller.videoLatency
|
||||
if(measure.visible && (!measure.branch || measure.branch.active) && ms >= startingTime && ms <= finishTime){
|
||||
var measureX = this.slotPos.x + this.msToPos(measure.ms - ms, measure.speed)
|
||||
var measureX = this.slotPos.x + this.msToPos(measure.ms - ms + this.controller.videoLatency, measure.speed)
|
||||
this.ctx.strokeStyle = measure.branchFirst ? "#ff0" : "#bdbdbd"
|
||||
this.ctx.lineWidth = 3
|
||||
this.ctx.beginPath()
|
||||
@@ -1267,8 +1513,8 @@
|
||||
var speed = circle.speed
|
||||
|
||||
var timeForDistance = this.posToMs(distanceForCircle + this.slotPos.size / 2, speed)
|
||||
var startingTime = circle.ms - timeForDistance
|
||||
var finishTime = circle.endTime + this.posToMs(this.slotPos.x - this.slotPos.paddingLeft + this.slotPos.size * 2, speed)
|
||||
var startingTime = circle.ms - timeForDistance + this.controller.videoLatency
|
||||
var finishTime = circle.endTime + this.posToMs(this.slotPos.x - this.slotPos.paddingLeft + this.slotPos.size * 2, speed) + this.controller.videoLatency
|
||||
|
||||
if(circle.isPlayed <= 0 || circle.score === 0){
|
||||
if((!circle.branch || circle.branch.active) && ms >= startingTime && ms <= finishTime && circle.isPlayed !== -1){
|
||||
@@ -1350,7 +1596,7 @@
|
||||
|
||||
if(!circlePos){
|
||||
circlePos = {
|
||||
x: this.slotPos.x + this.msToPos(circleMs - ms, speed),
|
||||
x: this.slotPos.x + this.msToPos(circleMs - ms + this.controller.videoLatency, speed),
|
||||
y: this.slotPos.y
|
||||
}
|
||||
}
|
||||
@@ -1388,10 +1634,10 @@
|
||||
size = circleSize
|
||||
faceID = noteFace.small
|
||||
var h = size * 1.8
|
||||
if(circleMs < ms && ms <= endTime){
|
||||
if(circleMs + this.controller.audioLatency < ms && ms <= endTime + this.controller.audioLatency){
|
||||
circlePos.x = this.slotPos.x
|
||||
}else if(ms > endTime){
|
||||
circlePos.x = this.slotPos.x + this.msToPos(endTime - ms, speed)
|
||||
}else if(ms > endTime + this.controller.audioLatency){
|
||||
circlePos.x = this.slotPos.x + this.msToPos(endTime - ms + this.controller.audioLatency, speed)
|
||||
}
|
||||
ctx.drawImage(assets.image["balloon"],
|
||||
circlePos.x + size - 4,
|
||||
@@ -1596,7 +1842,9 @@
|
||||
}
|
||||
toggleGogoTime(circle){
|
||||
this.gogoTime = circle.gogoTime
|
||||
this.gogoTimeStarted = circle.ms
|
||||
if(circle.gogoTime || this.gogoTimeStarted !== -Infinity){
|
||||
this.gogoTimeStarted = circle.ms
|
||||
}
|
||||
|
||||
if(this.gogoTime){
|
||||
this.assets.fireworks.forEach(fireworksAsset => {
|
||||
@@ -1789,21 +2037,62 @@
|
||||
if(typeof pos === "undefined"){
|
||||
pos = this.state.pausePos
|
||||
}
|
||||
var game = this.controller.game
|
||||
var state = game.calibrationState
|
||||
switch(state){
|
||||
case "audioHelp":
|
||||
pos = pos === 0 ? 2 : 0
|
||||
break
|
||||
case "videoHelp":
|
||||
if(pos === 0){
|
||||
assets.sounds["se_don"].play()
|
||||
game.calibrationReset("audio")
|
||||
return
|
||||
}else{
|
||||
pos = 0
|
||||
}
|
||||
break
|
||||
case "results":
|
||||
if(pos === 0){
|
||||
assets.sounds["se_don"].play()
|
||||
game.calibrationReset("video")
|
||||
return
|
||||
}else{
|
||||
var input = settings.getItem("latency")
|
||||
var output = {}
|
||||
var progress = game.calibrationProgress
|
||||
for(var i in input){
|
||||
if(i === "audio" || i === "video"){
|
||||
output[i] = progress[i]
|
||||
}else{
|
||||
output[i] = input[i]
|
||||
}
|
||||
}
|
||||
settings.setItem("latency", output)
|
||||
pos = 2
|
||||
}
|
||||
break
|
||||
}
|
||||
switch(pos){
|
||||
case 1:
|
||||
assets.sounds["se_don"].play()
|
||||
this.controller.restartSong()
|
||||
this.controller.playSound("se_don", 0, true)
|
||||
if(state === "video"){
|
||||
game.calibrationReset(state)
|
||||
}else{
|
||||
this.controller.restartSong()
|
||||
}
|
||||
pageEvents.send("pause-restart")
|
||||
break
|
||||
case 2:
|
||||
assets.sounds["se_don"].play()
|
||||
this.controller.playSound("se_don", 0, true)
|
||||
this.controller.songSelection()
|
||||
pageEvents.send("pause-song-select")
|
||||
break
|
||||
default:
|
||||
this.controller.togglePause()
|
||||
this.controller.togglePause(false)
|
||||
break
|
||||
}
|
||||
return true
|
||||
}
|
||||
onmousedown(event){
|
||||
if(this.controller.game.paused){
|
||||
@@ -1855,23 +2144,30 @@
|
||||
x = x * pauseScale + 257
|
||||
y = y * pauseScale - 328
|
||||
}
|
||||
if(104 <= y && y <= 575 && 465 <= x && x <= 465 + 110 * this.pauseOptions.length){
|
||||
return Math.floor((x - 465) / 110)
|
||||
switch(this.controller.game.calibrationState){
|
||||
case "audioHelp":
|
||||
case "videoHelp":
|
||||
case "results":
|
||||
if(554 - 90 * this.pauseOptions.length <= y && y <= 554 && 404 <= x && x <= 876){
|
||||
return Math.floor((y - 554 + 90 * this.pauseOptions.length) / 90)
|
||||
}
|
||||
break
|
||||
default:
|
||||
if(104 <= y && y <= 575 && 465 <= x && x <= 465 + 110 * this.pauseOptions.length){
|
||||
return Math.floor((x - 465) / 110)
|
||||
}
|
||||
break
|
||||
}
|
||||
return null
|
||||
}
|
||||
mouseIdle(){
|
||||
var lastMouse = pageEvents.getMouse()
|
||||
if(lastMouse && !this.cursorHidden){
|
||||
if(lastMouse && !this.cursorHidden && !this.state.hasPointer){
|
||||
if(this.getMS() >= this.lastMousemove + 2000){
|
||||
this.cursor.style.top = lastMouse.clientY + "px"
|
||||
this.cursor.style.left = lastMouse.clientX + "px"
|
||||
this.cursor.style.pointerEvents = "auto"
|
||||
this.canvas.style.cursor = "none"
|
||||
this.cursorHidden = true
|
||||
}else{
|
||||
this.cursor.style.top = ""
|
||||
this.cursor.style.left = ""
|
||||
this.cursor.style.pointerEvents = ""
|
||||
this.canvas.style.cursor = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1890,12 +2186,13 @@
|
||||
this.pauseCache.clean()
|
||||
this.branchCache.clean()
|
||||
|
||||
versionDiv.classList.remove("version-hide")
|
||||
loader.screen.parentNode.appendChild(versionDiv)
|
||||
if(this.multiplayer !== 2){
|
||||
if(this.touchEnabled){
|
||||
pageEvents.remove(this.canvas, "touchstart")
|
||||
pageEvents.remove(this.touchPauseBtn, "touchend")
|
||||
this.gameDiv.classList.add("touch-results")
|
||||
document.getElementById("version").classList.remove("version-hide")
|
||||
this.touchDrumDiv.parentNode.removeChild(this.touchDrumDiv)
|
||||
delete this.touchDrumDiv
|
||||
delete this.touchDrumImg
|
||||
@@ -1915,7 +2212,6 @@
|
||||
pageEvents.mouseRemove(this)
|
||||
|
||||
delete this.pauseMenu
|
||||
delete this.cursor
|
||||
delete this.gameDiv
|
||||
delete this.canvas
|
||||
delete this.ctx
|
||||
|
||||
Reference in New Issue
Block a user