japanese-drum-game/public/src/js/loadsong.js

305 lines
8.5 KiB
JavaScript
Raw Normal View History

2018-12-13 17:18:52 +08:00
class LoadSong{
2018-10-06 01:03:59 +08:00
constructor(selectedSong, autoPlayEnabled, multiplayer, touchEnabled){
2018-09-11 06:17:13 +08:00
this.selectedSong = selectedSong
this.autoPlayEnabled = autoPlayEnabled
2018-10-06 01:03:59 +08:00
this.multiplayer = multiplayer
this.touchEnabled = touchEnabled
2018-11-26 06:42:24 +08:00
loader.changePage("loadsong", true)
2019-01-05 15:44:28 +08:00
var loadingText = document.getElementById("loading-text")
loadingText.appendChild(document.createTextNode(strings.loading))
loadingText.setAttribute("alt", strings.loading)
if(multiplayer){
var cancel = document.getElementById("p2-cancel-button")
cancel.appendChild(document.createTextNode(strings.cancel))
cancel.setAttribute("alt", strings.cancel)
}
2018-09-18 06:37:59 +08:00
this.run()
pageEvents.send("load-song", {
selectedSong: selectedSong,
autoPlayEnabled: autoPlayEnabled,
multiplayer: multiplayer,
touchEnabled: touchEnabled
})
2018-09-11 06:17:13 +08:00
}
run(){
2018-11-26 06:42:24 +08:00
var song = this.selectedSong
var id = song.folder
2018-09-11 06:17:13 +08:00
var promises = []
2019-02-04 17:14:42 +08:00
assets.sounds["v_start"].play()
2015-07-18 10:57:56 +08:00
2018-11-26 06:42:24 +08:00
song.songBg = this.randInt(1, 5)
song.songStage = this.randInt(1, 3)
2018-12-02 23:25:42 +08:00
song.donBg = this.randInt(1, 6)
2019-02-03 20:04:25 +08:00
var songObj = assets.songs.find(song => song.id === id)
2018-11-26 06:42:24 +08:00
if(song.songSkin && song.songSkin.name){
var imgLoad = []
for(var type in song.songSkin){
var value = song.songSkin[type]
2019-02-03 20:04:25 +08:00
if(["song", "stage", "don"].indexOf(type) !== -1 && value && value !== "none"){
2018-11-26 06:42:24 +08:00
var filename = "bg_" + type + "_" + song.songSkin.name
if(value === "static"){
imgLoad.push({
filename: filename,
type: type
})
}else{
imgLoad.push({
filename: filename + "_a",
type: type
})
imgLoad.push({
filename: filename + "_b",
type: type
})
}
2019-01-01 09:16:55 +08:00
if(type === "don"){
song.donBg = null
}
2018-12-02 23:25:42 +08:00
if(type === "song"){
song.songBg = null
}
2018-11-26 06:42:24 +08:00
}
}
var skinBase = gameConfig.assets_baseurl + "song_skins/"
for(var i = 0; i < imgLoad.length; i++){
2019-02-03 20:04:25 +08:00
let filename = imgLoad[i].filename
let prefix = song.songSkin.prefix || ""
if((prefix + filename) in assets.image){
continue
}
2018-11-26 06:42:24 +08:00
let img = document.createElement("img")
2019-02-03 20:04:25 +08:00
if(!songObj.music && this.touchEnabled && imgLoad[i].type === "song"){
2018-11-30 22:47:53 +08:00
img.crossOrigin = "Anonymous"
}
2018-11-26 06:42:24 +08:00
let promise = pageEvents.load(img)
if(imgLoad[i].type === "song"){
promises.push(promise.then(() => {
2019-02-03 20:04:25 +08:00
return this.scaleImg(img, filename, prefix)
2018-11-26 06:42:24 +08:00
}))
}else{
promises.push(promise.then(() => {
2019-02-03 20:04:25 +08:00
assets.image[prefix + filename] = img
2018-11-26 06:42:24 +08:00
}))
}
2019-02-03 20:04:25 +08:00
if(songObj.music){
img.src = URL.createObjectURL(song.songSkin[filename + ".png"])
}else{
img.src = skinBase + filename + ".png"
}
2018-11-26 06:42:24 +08:00
}
}
2018-12-02 23:25:42 +08:00
promises.push(this.loadSongBg(id))
2015-07-17 16:22:46 +08:00
2018-09-11 06:17:13 +08:00
promises.push(new Promise((resolve, reject) => {
if(songObj.sound){
songObj.sound.gain = snd.musicGain
resolve()
}else if(!songObj.music){
snd.musicGain.load(gameConfig.songs_baseurl + id + "/main.mp3").then(sound => {
songObj.sound = sound
resolve()
}, reject)
}else if(songObj.music !== "muted"){
snd.musicGain.load(songObj.music, true).then(sound => {
2018-09-11 06:17:13 +08:00
songObj.sound = sound
resolve()
}, reject)
}else{
resolve()
}
2018-09-11 06:17:13 +08:00
}))
if(songObj.chart){
this.songData = songObj.chart
}else{
promises.push(loader.ajax(this.getSongPath(song)).then(data => {
this.songData = data.replace(/\0/g, "").split("\n")
}))
}
2018-09-11 06:17:13 +08:00
Promise.all(promises).then(() => {
2018-09-18 06:37:59 +08:00
this.setupMultiplayer()
2018-09-13 01:10:00 +08:00
}, error => {
2018-12-04 06:23:11 +08:00
if(Array.isArray(error) && error[1] instanceof HTMLElement){
error = error[0] + ": " + error[1].outerHTML
}
console.error(error)
pageEvents.send("load-song-error", error)
2018-12-04 06:23:11 +08:00
errorMessage(new Error(error).stack)
2018-09-11 06:17:13 +08:00
alert("An error occurred, please refresh")
})
2015-07-17 16:22:46 +08:00
}
2018-12-02 23:25:42 +08:00
loadSongBg(){
2018-11-24 02:52:24 +08:00
return new Promise((resolve, reject) => {
2018-12-02 23:25:42 +08:00
var promises = []
var filenames = []
if(this.selectedSong.songBg !== null){
filenames.push("bg_song_" + this.selectedSong.songBg)
}
if(this.selectedSong.donBg !== null){
filenames.push("bg_don_" + this.selectedSong.donBg)
if(this.multiplayer){
filenames.push("bg_don2_" + this.selectedSong.donBg)
}
2018-12-02 23:25:42 +08:00
}
for(var i = 0; i < filenames.length; i++){
for(var letter = 0; letter < 2; letter++){
let filenameAb = filenames[i] + (letter === 0 ? "a" : "b")
if(!(filenameAb in assets.image)){
let img = document.createElement("img")
if(filenameAb.startsWith("bg_song_")){
if(this.touchEnabled){
img.crossOrigin = "Anonymous"
}
promises.push(pageEvents.load(img).then(() => {
2019-02-03 20:04:25 +08:00
return this.scaleImg(img, filenameAb, "")
2018-12-02 23:25:42 +08:00
}))
}else{
promises.push(pageEvents.load(img).then(() => {
assets.image[filenameAb] = img
}))
}
img.src = gameConfig.assets_baseurl + "img/" + filenameAb + ".png"
2018-11-30 22:47:53 +08:00
}
2018-11-24 02:52:24 +08:00
}
}
2018-12-02 23:25:42 +08:00
Promise.all(promises).then(resolve, reject)
2018-11-24 02:52:24 +08:00
})
}
2019-02-03 20:04:25 +08:00
scaleImg(img, filename, prefix){
2018-11-26 06:42:24 +08:00
return new Promise((resolve, reject) => {
if(this.touchEnabled){
var canvas = document.createElement("canvas")
var w = Math.floor(img.width / 2)
var h = Math.floor(img.height / 2)
canvas.width = w
canvas.height = h
var ctx = canvas.getContext("2d")
ctx.drawImage(img, 0, 0, w, h)
2018-11-27 07:05:02 +08:00
var saveScaled = url => {
2018-11-26 06:42:24 +08:00
let img2 = document.createElement("img")
pageEvents.load(img2).then(() => {
2019-02-03 20:04:25 +08:00
assets.image[prefix + filename] = img2
2018-11-26 06:42:24 +08:00
resolve()
}, reject)
2018-11-27 07:05:02 +08:00
img2.src = url
}
if("toBlob" in canvas){
canvas.toBlob(blob => {
saveScaled(URL.createObjectURL(blob))
})
}else{
saveScaled(canvas.toDataURL())
}
2018-11-26 06:42:24 +08:00
}else{
2019-02-03 20:04:25 +08:00
assets.image[prefix + filename] = img
2018-11-26 06:42:24 +08:00
resolve()
}
})
}
2018-11-24 02:52:24 +08:00
randInt(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min
}
2018-10-11 06:13:24 +08:00
getSongPath(selectedSong){
2018-10-28 05:42:28 +08:00
var directory = gameConfig.songs_baseurl + selectedSong.folder + "/"
2018-10-11 06:13:24 +08:00
if(selectedSong.type === "tja"){
return directory + "main.tja"
}else{
return directory + selectedSong.difficulty + ".osu"
}
}
2018-09-13 01:10:00 +08:00
setupMultiplayer(){
2018-11-26 06:42:24 +08:00
var song = this.selectedSong
2018-09-13 01:10:00 +08:00
if(this.multiplayer){
2018-09-18 06:37:59 +08:00
var loadingText = document.getElementsByClassName("loading-text")[0]
2019-01-30 00:10:56 +08:00
loadingText.firstChild.data = strings.waitingForP2
loadingText.setAttribute("alt", strings.waitingForP2)
2018-09-18 06:37:59 +08:00
2018-11-13 12:36:15 +08:00
this.cancelButton = document.getElementById("p2-cancel-button")
this.cancelButton.style.display = "inline-block"
pageEvents.add(this.cancelButton, ["mousedown", "touchstart"], this.cancelLoad.bind(this))
2018-09-13 01:10:00 +08:00
this.song2Data = this.songData
2018-11-26 06:42:24 +08:00
this.selectedSong2 = song
2018-09-18 06:37:59 +08:00
pageEvents.add(p2, "message", event => {
if(event.type === "gameload"){
2018-11-13 12:36:15 +08:00
this.cancelButton.style.display = ""
2018-11-26 06:42:24 +08:00
if(event.value === song.difficulty){
2018-11-13 12:36:15 +08:00
this.startMultiplayer()
2018-09-18 06:37:59 +08:00
}else{
2018-12-04 06:23:11 +08:00
this.selectedSong2 = {}
for(var i in this.selectedSong){
this.selectedSong2[i] = this.selectedSong[i]
2018-09-18 06:37:59 +08:00
}
2018-12-04 06:23:11 +08:00
this.selectedSong2.difficulty = event.value
2018-11-26 06:42:24 +08:00
if(song.type === "tja"){
2018-11-13 12:36:15 +08:00
this.startMultiplayer()
}else{
loader.ajax(this.getSongPath(this.selectedSong2)).then(data => {
this.song2Data = data.replace(/\0/g, "").split("\n")
2018-11-13 12:36:15 +08:00
this.startMultiplayer()
}, () => {
2018-11-13 12:36:15 +08:00
this.startMultiplayer()
})
}
2018-09-18 06:37:59 +08:00
}
}else if(event.type === "gamestart"){
this.clean()
2018-11-02 06:05:18 +08:00
p2.clearMessage("songsel")
2018-11-26 06:42:24 +08:00
var taikoGame1 = new Controller(song, this.songData, false, 1, this.touchEnabled)
2018-10-25 22:18:41 +08:00
var taikoGame2 = new Controller(this.selectedSong2, this.song2Data, true, 2, this.touchEnabled)
2018-09-18 06:37:59 +08:00
taikoGame1.run(taikoGame2)
pageEvents.send("load-song-player2", this.selectedSong2)
2018-11-13 12:36:15 +08:00
}else if(event.type === "left" || event.type === "gameend"){
this.clean()
new SongSelect(false, false, this.touchEnabled)
2018-09-13 01:10:00 +08:00
}
2018-09-18 06:37:59 +08:00
})
2018-09-13 01:10:00 +08:00
p2.send("join", {
2018-11-26 06:42:24 +08:00
id: song.folder,
diff: song.difficulty
2018-09-13 01:10:00 +08:00
})
}else{
2018-09-18 06:37:59 +08:00
this.clean()
2018-11-26 06:42:24 +08:00
var taikoGame = new Controller(song, this.songData, this.autoPlayEnabled, false, this.touchEnabled)
2018-09-13 01:10:00 +08:00
taikoGame.run()
}
}
2018-11-13 12:36:15 +08:00
startMultiplayer(repeat){
if(document.hasFocus()){
p2.send("gamestart")
}else{
if(!repeat){
2019-02-04 17:14:42 +08:00
assets.sounds["v_sanka"].play()
pageEvents.send("load-song-unfocused")
2018-11-13 12:36:15 +08:00
}
setTimeout(() => {
this.startMultiplayer(true)
}, 100)
}
}
cancelLoad(event){
if(event.type === "mousedown"){
if(event.which !== 1){
return
}
}else{
event.preventDefault()
}
p2.send("leave")
2019-02-04 17:14:42 +08:00
assets.sounds["se_don"].play()
2018-11-13 12:36:15 +08:00
this.cancelButton.style.pointerEvents = "none"
pageEvents.send("load-song-cancel")
2018-11-13 12:36:15 +08:00
}
2018-09-18 06:37:59 +08:00
clean(){
pageEvents.remove(p2, "message")
2018-11-13 12:36:15 +08:00
if(this.cancelButton){
pageEvents.remove(this.cancelButton, ["mousedown", "touchstart"])
delete this.cancelButton
}
2018-09-18 06:37:59 +08:00
}
2018-09-13 01:10:00 +08:00
}