Merge pull request #411 from bui/bug-fixes

Bug fixes
This commit is contained in:
Bui 2022-02-17 22:54:09 +00:00 committed by GitHub
commit ebc3c79c75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 291 additions and 124 deletions

11
app.py
View File

@ -371,12 +371,15 @@ def route_admin_users_post():
max_level = admin['user_level'] - 1
username = request.form.get('username')
level = int(request.form.get('level')) or 0
try:
level = int(request.form.get('level')) or 0
except ValueError:
level = 0
user = db.users.find_one({'username': username})
user = db.users.find_one({'username_lower': username.lower()})
if not user:
flash('Error: User was not found.')
elif admin_name == username:
elif admin['username'] == user['username']:
flash('Error: You cannot modify your own level.')
else:
user_level = user['user_level']
@ -386,7 +389,7 @@ def route_admin_users_post():
flash('Error: This user has higher level than you.')
else:
output = {'user_level': level}
db.users.update_one({'username': username}, {'$set': output})
db.users.update_one({'username': user['username']}, {'$set': output})
flash('User updated.')
return render_template('admin_users.html', config=get_config(), max_level=max_level, username=username, level=level)

View File

@ -201,6 +201,20 @@ kbd{
.setting-name::before{
padding-left: 0.3em;
}
.setting-name::after{
content: "";
display: block;
position: absolute;
top: 0;
right: 0;
width: 40px;
height: 100%;
background-image: linear-gradient(90deg, transparent, #f6ead4 90%);
}
.view-content:not(:hover) .setting-box.selected .setting-name::after,
.setting-box:hover .setting-name::after{
background-image: linear-gradient(90deg, transparent, #ffb547 90%);
}
.setting-value{
display: flex;
background: #fff;
@ -403,6 +417,7 @@ kbd{
}
.customdon-canvas{
width: 13em;
cursor: pointer;
}
.customdon-div label{
display: block;

View File

@ -13,7 +13,7 @@ function filePermission(file){
if(response === "granted"){
return file
}else{
return Promise.reject(file)
return Promise.reject(strings.accessNotGrantedError)
}
})
}

View File

@ -46,6 +46,8 @@ class Account{
this.inputForms.push(this.displayname)
this.redrawRunning = true
this.redrawPaused = matchMedia("(prefers-reduced-motion: reduce)").matches
this.redrawForce = true
this.customdonRedrawBind = this.customdonRedraw.bind(this)
this.start = new Date().getTime()
this.frames = [
@ -57,6 +59,7 @@ class Account{
this.customdonCache = new CanvasCache()
this.customdonCache.resize(723 * 2, 1858, 1)
this.customdonCanvas = this.getElement("customdon-canvas")
pageEvents.add(this.customdonCanvas, "click", this.customdonPause.bind(this))
this.customdonCtx = this.customdonCanvas.getContext("2d")
this.customdonBodyFill = this.getElement("customdon-bodyfill")
this.customdonBodyFill.value = account.don.body_fill
@ -120,6 +123,11 @@ class Account{
pageEvents.add(this.inputForms[i], ["keydown", "keyup", "keypress"], this.onFormPress.bind(this))
}
}
customdonPause(){
this.redrawPaused = !this.redrawPaused
this.redrawForce = true
this.start = new Date().getTime()
}
customdonChange(){
var ctx = this.customdonCtx
this.customdonCache.clear()
@ -148,6 +156,7 @@ class Account{
id: "bodyFill"
})
})
this.redrawForce = true
}
customdonReset(event){
if(event.type === "touchstart"){
@ -162,12 +171,16 @@ class Account{
return
}
requestAnimationFrame(this.customdonRedrawBind)
if(!document.hasFocus()){
if(!document.hasFocus() || this.redrawPaused && !this.redrawForce){
return
}
var ms = new Date().getTime()
var ctx = this.customdonCtx
var frame = this.frames[Math.floor((ms - this.start) / 30) % this.frames.length]
if(this.redrawPaused){
var frame = 0
}else{
var frame = this.frames[Math.floor((ms - this.start) / 30) % this.frames.length]
}
var w = 360
var h = 184
var sx = Math.floor(frame / 10) * (w + 2)
@ -183,6 +196,7 @@ class Account{
sx, sy, w, h,
-26, 0, w, h
)
this.redrawForce = false
}
showDiv(event, div){
if(event){
@ -318,6 +332,7 @@ class Account{
onFormPress(event){
event.stopPropagation()
if(event.type === "keypress" && event.keyCode === 13){
event.preventDefault()
if(this.mode === "account"){
this.onSave()
}else{
@ -611,6 +626,7 @@ class Account{
}
this.redrawRunning = false
this.customdonCache.clean()
pageEvents.remove(this.customdonCanvas, "click")
pageEvents.remove(this.customdonBodyFill, ["change", "input"])
pageEvents.remove(this.customdonFaceFill, ["change", "input"])
pageEvents.remove(this.customdonResetBtn, ["click", "touchstart"])

View File

@ -27,8 +27,8 @@ class CanvasCache{
this.h = h
this.lastW = 0
this.lastH = 0
this.canvas.width = this.w * this.scale
this.canvas.height = this.h * this.scale
this.canvas.width = Math.max(1, this.w * this.scale)
this.canvas.height = Math.max(1, this.h * this.scale)
this.ctx.scale(this.scale, this.scale)
}
get(config, callback, setOnly){

View File

@ -157,7 +157,7 @@
ctx.fillRect(0, 0, w, h)
}
if(config.cached){
if(this.songFrameCache.w !== config.frameCache.w){
if(this.songFrameCache.w !== config.frameCache.w || this.songFrameCache.scale !== config.frameCache.ratio){
this.songFrameCache.resize(config.frameCache.w, config.frameCache.h, config.frameCache.ratio)
}
this.songFrameCache.get({
@ -1680,8 +1680,8 @@
if(amount >= 1){
return callback(ctx)
}else if(amount >= 0){
this.tmpCanvas.width = winW || ctx.canvas.width
this.tmpCanvas.height = winH || ctx.canvas.height
this.tmpCanvas.width = Math.max(1, winW || ctx.canvas.width)
this.tmpCanvas.height = Math.max(1, winH || ctx.canvas.height)
callback(this.tmpCtx)
ctx.save()
ctx.globalAlpha = amount

View File

@ -7,8 +7,8 @@ class CanvasTest{
var pixelRatio = window.devicePixelRatio || 1
var width = innerWidth * pixelRatio
var height = innerHeight * pixelRatio
this.canvas.width = width
this.canvas.height = height
this.canvas.width = Math.max(1, width)
this.canvas.height = Math.max(1, height)
this.ctx = this.canvas.getContext("2d")
this.ctx.scale(pixelRatio, pixelRatio)
this.ratio = pixelRatio

View File

@ -231,6 +231,9 @@ class Controller{
this.view.displayScore(score, notPlayed, bigNote)
}
songSelection(fadeIn, showWarning){
if(this.cleaned){
return
}
if(!fadeIn){
this.clean()
}
@ -241,6 +244,9 @@ class Controller{
}
}
restartSong(){
if(this.cleaned){
return
}
this.clean()
if(this.multiplayer){
new LoadSong(this.selectedSong, false, true, this.touchEnabled)
@ -363,6 +369,7 @@ class Controller{
return true
}
clean(){
this.cleaned = true
if(this.multiplayer === 1){
this.syncWith.clean()
}

View File

@ -506,10 +506,10 @@ class Game{
p2.send("gameend")
}
this.musicFadeOut++
}else if(this.musicFadeOut === 2 && (ms >= started + 8600 && ms >= musicDuration + 250)){
}else if(this.musicFadeOut === 2 && (ms >= Math.max(started + 8600, Math.min(started + 8600 + 5000, musicDuration + 250)))){
this.controller.displayResults()
this.musicFadeOut++
}else if(this.musicFadeOut === 3 && (ms >= started + 9600 && ms >= musicDuration + 1250)){
}else if(this.musicFadeOut === 3 && (ms >= Math.max(started + 9600, Math.min(started + 9600 + 5000, musicDuration + 1250)))){
this.controller.clean()
if(this.controller.scoresheet){
this.controller.scoresheet.startRedraw()

View File

@ -111,10 +111,7 @@
var plugin = plugins.add(obj.data, obj.name)
if(plugin){
pluginAmount++
plugins.imported.push({
name: plugin.name,
plugin: plugin
})
plugin.imported = true
startPromises.push(plugin.start())
}
})

View File

@ -239,8 +239,8 @@ class LoadSong{
var canvas = document.createElement("canvas")
var w = Math.floor(img.width * scale)
var h = Math.floor(img.height * scale)
canvas.width = w
canvas.height = h
canvas.width = Math.max(1, w)
canvas.height = Math.max(1, h)
var ctx = canvas.getContext("2d")
ctx.drawImage(img, 0, 0, w, h)
var saveScaled = url => {

View File

@ -64,8 +64,8 @@
var pixelRatio = window.devicePixelRatio || 1
var winW = this.canvas.offsetWidth * pixelRatio
var winH = this.canvas.offsetHeight * pixelRatio
this.canvas.width = winW
this.canvas.height = winH
this.canvas.width = Math.max(1, winW)
this.canvas.height = Math.max(1, winH)
ctx.scale(winW / this.width, winH / this.height)
ctx.lineJoin = "round"

View File

@ -28,16 +28,18 @@ class P2Connection{
}
}
open(){
this.closed = false
var wsProtocol = location.protocol == "https:" ? "wss:" : "ws:"
this.socket = new WebSocket(wsProtocol + "//" + location.host + "/p2")
pageEvents.race(this.socket, "open", "close").then(response => {
if(response.type === "open"){
return this.openEvent()
}
return this.closeEvent()
})
pageEvents.add(this.socket, "message", this.messageEvent.bind(this))
if(this.closed && !this.disabled){
this.closed = false
var wsProtocol = location.protocol == "https:" ? "wss:" : "ws:"
this.socket = new WebSocket(wsProtocol + "//" + location.host + "/p2")
pageEvents.race(this.socket, "open", "close").then(response => {
if(response.type === "open"){
return this.openEvent()
}
return this.closeEvent()
})
pageEvents.add(this.socket, "message", this.messageEvent.bind(this))
}
}
openEvent(){
var addedType = this.allEvents.get("open")
@ -46,8 +48,12 @@ class P2Connection{
}
}
close(){
this.closed = true
this.socket.close()
if(!this.closed){
this.closed = true
if(this.socket){
this.socket.close()
}
}
}
closeEvent(){
this.removeEventListener(onmessage)
@ -250,4 +256,12 @@ class P2Connection{
this.notes.shift()
}
}
enable(){
this.disabled = false
this.open()
}
disable(){
this.disabled = true
this.close()
}
}

View File

@ -3,10 +3,10 @@ class Plugins{
this.init(...args)
}
init(){
this.imported = []
this.allPlugins = []
this.pluginMap = {}
this.hashes = []
this.startOrder = []
}
add(script, name){
var hash = md5.base64(script.toString())
@ -16,7 +16,7 @@ class Plugins{
}
name = name || "plugin"
var baseName = name
for(var i = 2; name in this.allPlugins; i++){
for(var i = 2; name in this.pluginMap; i++){
name = baseName + i.toString()
}
var plugin = new PluginLoader(script, name, hash)
@ -37,10 +37,6 @@ class Plugins{
}
}
this.unload(name)
var index = this.imported.findIndex(obj => obj.name === name)
if(index !== -1){
this.imported.splice(index, 1)
}
var index = this.allPlugins.findIndex(obj => obj.name === name)
if(index !== -1){
this.allPlugins.splice(index, 1)
@ -67,21 +63,33 @@ class Plugins{
this.pluginMap[name].stop()
}
stopAll(){
for(var i = this.allPlugins.length; i--;){
this.allPlugins[i].plugin.stop()
for(var i = this.startOrder.length; i--;){
this.pluginMap[this.startOrder[i]].stop()
}
}
unload(name){
this.pluginMap[name].unload()
}
unloadAll(){
for(var i = this.startOrder.length; i--;){
this.pluginMap[this.startOrder[i]].unload()
}
for(var i = this.allPlugins.length; i--;){
this.allPlugins[i].plugin.unload()
}
}
unloadImported(){
for(var i = this.imported.length; i--;){
this.imported[i].plugin.unload()
for(var i = this.startOrder.length; i--;){
var plugin = this.pluginMap[this.startOrder[i]]
if(plugin.imported){
plugin.unload()
}
}
for(var i = this.allPlugins.length; i--;){
var obj = this.allPlugins[i]
if(obj.plugin.imported){
obj.plugin.unload()
}
}
}
@ -130,9 +138,9 @@ class Plugins{
getItem: () => plugin.started,
setItem: value => {
if(plugin.started && !value){
plugin.stop()
this.stop(plugin.name)
}else if(!plugin.started && value){
plugin.start()
this.start(plugin.name)
}
}
}
@ -188,10 +196,17 @@ class PluginLoader{
console.error(e)
this.error()
}
}, e => {
console.error(e)
this.error()
return Promise.resolve()
})
}
}
start(){
start(orderChange){
if(!orderChange){
plugins.startOrder.push(this.name)
}
return this.load().then(() => {
if(!this.started && this.module){
this.started = true
@ -209,8 +224,18 @@ class PluginLoader{
}
})
}
stop(error){
stop(orderChange, error){
if(this.loaded && this.started){
if(!orderChange){
var stopIndex = plugins.startOrder.indexOf(this.name)
if(stopIndex !== -1){
plugins.startOrder.splice(stopIndex, 1)
for(var i = plugins.startOrder.length; i-- > stopIndex;){
plugins.pluginMap[plugins.startOrder[i]].stop(true)
}
}
}
this.started = false
try{
if(this.module.beforeStop){
@ -225,12 +250,18 @@ class PluginLoader{
this.error()
}
}
if(!orderChange && stopIndex !== -1){
for(var i = stopIndex; i < plugins.startOrder.length; i++){
plugins.pluginMap[plugins.startOrder[i]].start(true)
}
}
}
}
unload(error){
if(this.loaded){
if(this.started){
this.stop(error)
this.stop(false, error)
}
this.loaded = false
plugins.remove(this.name)
@ -267,7 +298,6 @@ class EditValue{
}
init(parent, name){
if(name){
this.original = parent[name]
this.name = [parent, name]
this.delete = !(name in parent)
}else{
@ -275,18 +305,21 @@ class EditValue{
}
}
load(callback){
var output = callback(this.original)
if(typeof output === "undefined"){
throw new Error("A value is expected to be returned")
}
this.edited = output
this.loadCallback = callback
return this
}
start(){
if(this.name){
this.name[0][this.name[1]] = this.edited
this.original = this.name[0][this.name[1]]
}
return this.edited
var output = this.loadCallback(this.original)
if(typeof output === "undefined"){
throw new Error("A value is expected to be returned")
}
if(this.name){
this.name[0][this.name[1]] = output
}
return output
}
stop(){
if(this.name){
@ -300,20 +333,26 @@ class EditValue{
}
unload(){
delete this.name
delete this.edited
delete this.original
delete this.loadCallback
}
}
class EditFunction extends EditValue{
load(callback){
var output = callback(plugins.strFromFunc(this.original))
start(){
if(this.name){
this.original = this.name[0][this.name[1]]
}
var args = plugins.argsFromFunc(this.original)
var output = this.loadCallback(plugins.strFromFunc(this.original), args)
if(typeof output === "undefined"){
throw new Error("A value is expected to be returned")
}
var args = plugins.argsFromFunc(this.original)
this.edited = Function(...args, output)
return this
var output = Function(...args, output)
if(this.name){
this.name[0][this.name[1]] = output
}
return output
}
}

View File

@ -215,8 +215,8 @@ class Scoresheet{
if(this.redrawing){
if(this.winW !== winW || this.winH !== winH){
this.canvas.width = winW
this.canvas.height = winH
this.canvas.width = Math.max(1, winW)
this.canvas.height = Math.max(1, winH)
ctx.scale(ratio, ratio)
this.canvas.style.width = (winW / this.pixelRatio) + "px"
this.canvas.style.height = (winH / this.pixelRatio) + "px"

View File

@ -104,18 +104,20 @@ class SongSelect{
return a.id > b.id ? 1 : -1
}
})
this.songs.push({
title: strings.back,
skin: this.songSkin.back,
action: "back"
})
this.songs.push({
title: strings.randomSong,
skin: this.songSkin.random,
action: "random",
category: strings.random,
canJump: true
})
if(assets.songs.length){
this.songs.push({
title: strings.back,
skin: this.songSkin.back,
action: "back"
})
this.songs.push({
title: strings.randomSong,
skin: this.songSkin.random,
action: "random",
category: strings.random,
canJump: true
})
}
if(touchEnabled){
if(fromTutorial === "tutorial"){
fromTutorial = false
@ -287,7 +289,8 @@ class SongSelect{
options: 0,
selLock: false,
catJump: false,
focused: true
focused: true,
waitPreview: 0
}
this.songSelecting = {
speed: 400,
@ -472,7 +475,7 @@ class SongSelect{
this.toAccount()
}else if(p2.session && 438 < mouse.x && mouse.x < 834 && mouse.y > 603){
this.toSession()
}else if(!p2.session && mouse.x > 641 && mouse.y > 603 && p2.socket.readyState === 1 && !assets.customSongs){
}else if(!p2.session && mouse.x > 641 && mouse.y > 603 && p2.socket && p2.socket.readyState === 1 && !assets.customSongs){
this.toSession()
}else{
var moveBy = this.songSelMouse(mouse.x, mouse.y)
@ -508,7 +511,7 @@ class SongSelect{
event.preventDefault()
}
mouseWheel(event){
if(this.state.screen === "song"){
if(this.state.screen === "song" && this.state.focused){
this.wheelTimer = this.getMS()
if(event.deltaY < 0) {
@ -809,7 +812,7 @@ class SongSelect{
this.selectedDiff = 1
do{
this.state.options = this.mod(this.optionsList.length, this.state.options + moveBy)
}while((p2.socket.readyState !== 1 || assets.customSongs) && this.state.options === 2)
}while((p2.socket && p2.socket.readyState !== 1 || assets.customSongs) && this.state.options === 2)
}
}
toTitleScreen(){
@ -913,12 +916,7 @@ class SongSelect{
}
}
}
if(this.wheelScrolls !== 0 && !this.state.locked && ms >= this.wheelTimer + 20) {
this.moveToSong(this.wheelScrolls)
this.wheelScrolls -= this.wheelScrolls
}
if(!this.redrawRunning){
return
}
@ -944,8 +942,8 @@ class SongSelect{
var ratioY = winH / 720
var ratio = (ratioX < ratioY ? ratioX : ratioY)
if(this.winW !== winW || this.winH !== winH){
this.canvas.width = winW
this.canvas.height = winH
this.canvas.width = Math.max(1, winW)
this.canvas.height = Math.max(1, winH)
ctx.scale(ratio, ratio)
this.canvas.style.width = (winW / this.pixelRatio) + "px"
this.canvas.style.height = (winH / this.pixelRatio) + "px"
@ -1034,6 +1032,17 @@ class SongSelect{
var screen = this.state.screen
var selectedWidth = this.songAsset.width
if(this.wheelScrolls !== 0 && !this.state.locked && ms >= this.wheelTimer + 20) {
if(p2.session){
this.moveToSong(this.wheelScrolls)
}else{
this.state.move = this.wheelScrolls
this.state.waitPreview = ms + 400
this.endPreview()
}
this.wheelScrolls = 0
}
if(screen === "title" || screen === "titleFadeIn"){
if(ms > this.state.screenMS + 1000){
this.state.screen = "song"
@ -2439,7 +2448,7 @@ class SongSelect{
}
startPreview(loadOnly){
if(!loadOnly && this.state && this.state.showWarning){
if(!loadOnly && this.state && this.state.showWarning || this.state.waitPreview > this.getMS()){
return
}
var currentSong = this.songs[this.selectedSong]

View File

@ -73,7 +73,10 @@
}
}
class SoundGain{
constructor(soundBuffer, channel){
constructor(...args){
this.init(...args)
}
init(soundBuffer, channel){
this.soundBuffer = soundBuffer
this.gainNode = soundBuffer.context.createGain()
if(channel){
@ -121,7 +124,10 @@ class SoundGain{
}
}
class Sound{
constructor(gain, buffer){
constructor(...args){
this.init(...args)
}
init(gain, buffer){
this.gain = gain
this.buffer = buffer
this.soundBuffer = gain.soundBuffer

View File

@ -216,6 +216,10 @@ var translations = {
ja: "曲「%s」を読み込むことができませんでした。ID%s\n\n%s",
en: "Could not load song %s with ID %s.\n\n%s"
},
accessNotGrantedError: {
ja: null,
en: "Permission to access the file was not granted"
},
loading: {
ja: "ロード中...",
en: "Loading...",

View File

@ -12,29 +12,86 @@ class Tutorial{
this.tutorialTitle = this.getElement("view-title")
this.tutorialDiv = document.createElement("div")
this.getElement("view-content").appendChild(this.tutorialDiv)
this.items = []
this.items.push(this.endButton)
this.selected = this.items.length - 1
this.setStrings()
pageEvents.add(this.endButton, ["mousedown", "touchstart"], event => {
if(event.type === "touchstart"){
event.preventDefault()
this.touched = true
}else if(event.type === "mousedown" && event.which !== 1){
return
}
this.onEnd(true)
})
pageEvents.add(this.endButton, ["mousedown", "touchstart"], this.onEnd.bind(this))
this.keyboard = new Keyboard({
confirm: ["enter", "space", "esc", "don_l", "don_r"]
}, this.onEnd.bind(this))
confirm: ["enter", "space", "don_l", "don_r"],
previous: ["left", "up", "ka_l"],
next: ["right", "down", "ka_r"],
back: ["escape"]
}, this.keyPressed.bind(this))
this.gamepad = new Gamepad({
confirm: ["start", "b", "ls", "rs"]
}, this.onEnd.bind(this))
"confirm": ["b", "ls", "rs"],
"previous": ["u", "l", "lb", "lt", "lsu", "lsl"],
"next": ["d", "r", "rb", "rt", "lsd", "lsr"],
"back": ["start", "a"]
}, this.keyPressed.bind(this))
pageEvents.send("tutorial")
}
getElement(name){
return loader.screen.getElementsByClassName(name)[0]
}
keyPressed(pressed, name){
if(!pressed){
return
}
var selected = this.items[this.selected]
if(name === "confirm"){
if(selected === this.endButton){
this.onEnd()
}else{
this.getLink(selected).click()
assets.sounds["se_don"].play()
}
}else if(name === "previous" || name === "next"){
if(this.items.length >= 2){
selected.classList.remove("selected")
this.selected = this.mod(this.items.length, this.selected + (name === "next" ? 1 : -1))
this.items[this.selected].classList.add("selected")
assets.sounds["se_ka"].play()
}
}else if(name === "back"){
this.onEnd()
}
}
mod(length, index){
return ((index % length) + length) % length
}
onEnd(event){
var touched = false
if(event){
if(event.type === "touchstart"){
event.preventDefault()
touched = true
}else if(event.which !== 1){
return
}
}
this.clean()
assets.sounds["se_don"].play()
try{
localStorage.setItem("tutorial", "true")
}catch(e){}
setTimeout(() => {
new SongSelect(this.fromSongSel ? "tutorial" : false, false, touched, this.songId)
}, 500)
}
getLink(target){
return target.getElementsByTagName("a")[0]
}
linkButton(event){
if(event.target === event.currentTarget && (event.type === "touchstart" || event.which === 1)){
this.getLink(event.currentTarget).click()
assets.sounds["se_don"].play()
}
}
insertText(text, parent){
parent.appendChild(document.createTextNode(text))
}
@ -63,18 +120,6 @@ class Tutorial{
parent.appendChild(kbd)
}
}
onEnd(pressed, name){
if(pressed){
this.clean()
assets.sounds["se_don"].play()
try{
localStorage.setItem("tutorial", "true")
}catch(e){}
setTimeout(() => {
new SongSelect(this.fromSongSel ? "tutorial" : false, false, this.touched, this.songId)
}, 500)
}
}
setStrings(){
this.tutorialTitle.innerText = strings.howToPlay
this.tutorialTitle.setAttribute("alt", strings.howToPlay)

View File

@ -199,8 +199,8 @@
this.ratio = ratio
if(this.player !== 2){
this.canvas.width = winW
this.canvas.height = winH
this.canvas.width = Math.max(1, winW)
this.canvas.height = Math.max(1, winH)
ctx.scale(ratio, ratio)
this.canvas.style.width = (winW / this.pixelRatio) + "px"
this.canvas.style.height = (winH / this.pixelRatio) + "px"
@ -1515,6 +1515,7 @@
}
updateNoteFaces(){
var ms = this.getMS()
var lastNextBeat = this.nextBeat
while(ms >= this.nextBeat){
this.nextBeat += this.beatInterval
if(this.controller.getCombo() >= 50){
@ -1529,6 +1530,9 @@
big: 3
}
}
if(this.nextBeat <= lastNextBeat){
break
}
}
}
drawCircles(circles){

View File

@ -6,6 +6,8 @@
<link rel="icon" href="{{config.assets_baseurl}}img/favicon.png" type="image/png">
<meta name="viewport" content="width=device-width, user-scalable=no">
<meta name="description" content="パソコンとスマホのブラウザ向けの太鼓の達人シミュレータ 🥁 Taiko no Tatsujin rhythm game simulator for desktop and mobile browsers">
<meta name="keywords" content="taiko no tatsujin, taiko, don chan, online, rhythm, browser, html5, game, for browsers, pc, arcade, emulator, free, download, website, 太鼓の達人, 太鼓ウェブ, 太鼓之達人, 太鼓達人, 太鼓网页, 网页版, 太鼓網頁, 網頁版, 태고의 달인, 태고 웹">
<meta name="color-scheme" content="only light">
<link rel="stylesheet" href="/src/css/loader.css?{{version.commit_short}}">
@ -18,14 +20,20 @@
<body>
<div id="assets"></div>
<div id="screen" class="pattern-bg"></div>
<div id="version">
<div data-nosnippet id="version">
{% if version.version and version.commit_short and version.commit %}
<a href="{{version.url}}commit/{{version.commit}}" target="_blank" id="version-link" class="stroke-sub" alt="taiko-web ver.{{version.version}} ({{version.commit_short}})">taiko-web ver.{{version.version}} ({{version.commit_short}})</a>
{% else %}
<a href="{{version.url}}" target="_blank" id="version-link" class="stroke-sub" alt="taiko-web (unknown version)">taiko-web (unknown version)</a>
<a href="{{version.url}}" target="_blank" rel="noopener" id="version-link" class="stroke-sub" alt="taiko-web (unknown version)">taiko-web (unknown version)</a>
{% endif %}
</div>
<script src="/src/js/browsersupport.js?{{version.commit_short}}"></script>
<script src="/src/js/main.js?{{version.commit_short}}"></script>
<noscript>
<div data-nosnippet id="unsupportedBrowser">
<div id="unsupportedWarn">!</div>
<span>Taiko Web requires JavaScript to be enabled in the browser</span>
</div>
</noscript>
</body>
</html>
</html>