Merge pull request #81 from LoveEevee/songbg-add-song-skins
SongBg: Add song skins
This commit is contained in:
commit
efdb2cfef1
3
.gitignore
vendored
3
.gitignore
vendored
@ -46,4 +46,5 @@ public/api
|
|||||||
taiko.db
|
taiko.db
|
||||||
version.json
|
version.json
|
||||||
public/index.html
|
public/index.html
|
||||||
config.json
|
config.json
|
||||||
|
public/assets/song_skins
|
||||||
|
12
app.py
12
app.py
@ -154,17 +154,26 @@ def route_api_preview():
|
|||||||
@app.route('/api/songs')
|
@app.route('/api/songs')
|
||||||
def route_api_songs():
|
def route_api_songs():
|
||||||
songs = query_db('select * from songs where enabled = 1')
|
songs = query_db('select * from songs where enabled = 1')
|
||||||
|
|
||||||
raw_categories = query_db('select * from categories')
|
raw_categories = query_db('select * from categories')
|
||||||
categories = {}
|
categories = {}
|
||||||
def_category = {'title': None, 'title_en': None}
|
def_category = {'title': None, 'title_en': None}
|
||||||
for cat in raw_categories:
|
for cat in raw_categories:
|
||||||
categories[cat[0]] = {'title': cat[1], 'title_en': cat[2]}
|
categories[cat[0]] = {'title': cat[1], 'title_en': cat[2]}
|
||||||
|
|
||||||
|
raw_song_skins = query_db('select * from song_skins')
|
||||||
|
song_skins = {}
|
||||||
|
for skin in raw_song_skins:
|
||||||
|
song_skins[skin[0]] = {'name': skin[1], 'song': skin[2], 'stage': skin[3]}
|
||||||
|
|
||||||
songs_out = []
|
songs_out = []
|
||||||
for song in songs:
|
for song in songs:
|
||||||
song_id = song[0]
|
song_id = song[0]
|
||||||
song_type = song[12]
|
song_type = song[12]
|
||||||
preview = get_preview(song_id, song_type)
|
preview = get_preview(song_id, song_type)
|
||||||
|
|
||||||
category_out = categories[song[11]] if song[11] in categories else def_category
|
category_out = categories[song[11]] if song[11] in categories else def_category
|
||||||
|
song_skin_out = song_skins[song[14]] if song[14] in categories else None
|
||||||
|
|
||||||
songs_out.append({
|
songs_out.append({
|
||||||
'id': song_id,
|
'id': song_id,
|
||||||
@ -179,7 +188,8 @@ def route_api_songs():
|
|||||||
'category': category_out['title'],
|
'category': category_out['title'],
|
||||||
'category_en': category_out['title_en'],
|
'category_en': category_out['title_en'],
|
||||||
'type': song_type,
|
'type': song_type,
|
||||||
'offset': song[13]
|
'offset': song[13],
|
||||||
|
'song_skin': song_skin_out
|
||||||
})
|
})
|
||||||
|
|
||||||
return jsonify(songs_out)
|
return jsonify(songs_out)
|
||||||
|
@ -67,6 +67,15 @@
|
|||||||
animation: 1s linear songbg-pulse infinite;
|
animation: 1s linear songbg-pulse infinite;
|
||||||
mix-blend-mode: color-dodge;
|
mix-blend-mode: color-dodge;
|
||||||
}
|
}
|
||||||
|
.songbg-strobe #layer2{
|
||||||
|
animation: 0.4s linear songbg-strobe infinite;
|
||||||
|
}
|
||||||
|
.songbg-pulse #layer2{
|
||||||
|
animation: 0.4s linear songbg-pulse infinite;
|
||||||
|
}
|
||||||
|
.songbg-slowfade #layer2{
|
||||||
|
animation: 2s cubic-bezier(0.68, -0.55, 0.27, 1.55) songbg-pulse infinite;
|
||||||
|
}
|
||||||
.touch-visible #layer2{
|
.touch-visible #layer2{
|
||||||
display: none;
|
display: none;
|
||||||
background-image: none;
|
background-image: none;
|
||||||
|
@ -4,26 +4,60 @@ class loadSong{
|
|||||||
this.autoPlayEnabled = autoPlayEnabled
|
this.autoPlayEnabled = autoPlayEnabled
|
||||||
this.multiplayer = multiplayer
|
this.multiplayer = multiplayer
|
||||||
this.touchEnabled = touchEnabled
|
this.touchEnabled = touchEnabled
|
||||||
|
|
||||||
loader.changePage("loadsong")
|
loader.changePage("loadsong")
|
||||||
this.run()
|
this.run()
|
||||||
}
|
}
|
||||||
run(){
|
run(){
|
||||||
var id = this.selectedSong.folder
|
var song = this.selectedSong
|
||||||
|
var id = song.folder
|
||||||
var promises = []
|
var promises = []
|
||||||
assets.sounds["start"].play()
|
assets.sounds["start"].play()
|
||||||
|
|
||||||
this.selectedSong.songBg = this.randInt(1, 5)
|
song.songBg = this.randInt(1, 5)
|
||||||
this.selectedSong.songStage = this.randInt(1, 3)
|
song.songStage = this.randInt(1, 3)
|
||||||
|
if(song.songSkin && song.songSkin.name){
|
||||||
promises.push(new Promise(resolve => {
|
var imgLoad = []
|
||||||
var img = document.createElement("img")
|
for(var type in song.songSkin){
|
||||||
pageEvents.load(img).then(() => {
|
var value = song.songSkin[type]
|
||||||
this.selectedSong.customBg = true
|
if(type !== "name" && value && value !== "none"){
|
||||||
}, () => this.songBg(id)).then(resolve)
|
var filename = "bg_" + type + "_" + song.songSkin.name
|
||||||
img.id = "music-bg"
|
if(value === "static"){
|
||||||
img.src = gameConfig.songs_baseurl + id + "/bg.png"
|
imgLoad.push({
|
||||||
document.getElementById("assets").appendChild(img)
|
filename: filename,
|
||||||
}))
|
type: type
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
imgLoad.push({
|
||||||
|
filename: filename + "_a",
|
||||||
|
type: type
|
||||||
|
})
|
||||||
|
imgLoad.push({
|
||||||
|
filename: filename + "_b",
|
||||||
|
type: type
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var skinBase = gameConfig.assets_baseurl + "song_skins/"
|
||||||
|
for(var i = 0; i < imgLoad.length; i++){
|
||||||
|
let img = document.createElement("img")
|
||||||
|
let filename = imgLoad[i].filename
|
||||||
|
let promise = pageEvents.load(img)
|
||||||
|
if(imgLoad[i].type === "song"){
|
||||||
|
promises.push(promise.then(() => {
|
||||||
|
return this.scaleImg(img, filename)
|
||||||
|
}))
|
||||||
|
}else{
|
||||||
|
promises.push(promise.then(() => {
|
||||||
|
assets.image[filename] = img
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
img.src = skinBase + filename + ".png"
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
promises.push(this.songBg(id))
|
||||||
|
}
|
||||||
|
|
||||||
promises.push(new Promise((resolve, reject) => {
|
promises.push(new Promise((resolve, reject) => {
|
||||||
var songObj
|
var songObj
|
||||||
@ -42,7 +76,7 @@ class loadSong{
|
|||||||
}, reject)
|
}, reject)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
promises.push(loader.ajax(this.getSongPath(this.selectedSong)).then(data => {
|
promises.push(loader.ajax(this.getSongPath(song)).then(data => {
|
||||||
this.songData = data.replace(/\0/g, "").split("\n")
|
this.songData = data.replace(/\0/g, "").split("\n")
|
||||||
}))
|
}))
|
||||||
Promise.all(promises).then(() => {
|
Promise.all(promises).then(() => {
|
||||||
@ -63,27 +97,7 @@ class loadSong{
|
|||||||
let filenameAb = filename + (i === 0 ? "a" : "b")
|
let filenameAb = filename + (i === 0 ? "a" : "b")
|
||||||
let img = document.createElement("img")
|
let img = document.createElement("img")
|
||||||
promises.push(pageEvents.load(img).then(() => {
|
promises.push(pageEvents.load(img).then(() => {
|
||||||
if(this.touchEnabled){
|
return this.scaleImg(img, filenameAb)
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
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)
|
|
||||||
canvas.toBlob(blob => {
|
|
||||||
let img2 = document.createElement("img")
|
|
||||||
pageEvents.load(img2).then(() => {
|
|
||||||
assets.image[filenameAb] = img2
|
|
||||||
resolve()
|
|
||||||
}, reject)
|
|
||||||
img2.src = URL.createObjectURL(blob)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
assets.image[filenameAb] = img
|
|
||||||
}
|
|
||||||
}))
|
}))
|
||||||
img.src = gameConfig.assets_baseurl + "img/" + filenameAb + ".png"
|
img.src = gameConfig.assets_baseurl + "img/" + filenameAb + ".png"
|
||||||
}
|
}
|
||||||
@ -91,6 +105,30 @@ class loadSong{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
scaleImg(img, filename){
|
||||||
|
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)
|
||||||
|
canvas.toBlob(blob => {
|
||||||
|
let img2 = document.createElement("img")
|
||||||
|
pageEvents.load(img2).then(() => {
|
||||||
|
assets.image[filename] = img2
|
||||||
|
resolve()
|
||||||
|
}, reject)
|
||||||
|
img2.src = URL.createObjectURL(blob)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
assets.image[filename] = img
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
randInt(min, max){
|
randInt(min, max){
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min
|
return Math.floor(Math.random() * (max - min + 1)) + min
|
||||||
}
|
}
|
||||||
@ -103,6 +141,8 @@ class loadSong{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setupMultiplayer(){
|
setupMultiplayer(){
|
||||||
|
var song = this.selectedSong
|
||||||
|
|
||||||
if(this.multiplayer){
|
if(this.multiplayer){
|
||||||
var loadingText = document.getElementsByClassName("loading-text")[0]
|
var loadingText = document.getElementsByClassName("loading-text")[0]
|
||||||
var waitingText = "Waiting for Another Player..."
|
var waitingText = "Waiting for Another Player..."
|
||||||
@ -114,22 +154,22 @@ class loadSong{
|
|||||||
pageEvents.add(this.cancelButton, ["mousedown", "touchstart"], this.cancelLoad.bind(this))
|
pageEvents.add(this.cancelButton, ["mousedown", "touchstart"], this.cancelLoad.bind(this))
|
||||||
|
|
||||||
this.song2Data = this.songData
|
this.song2Data = this.songData
|
||||||
this.selectedSong2 = this.selectedSong
|
this.selectedSong2 = song
|
||||||
pageEvents.add(p2, "message", event => {
|
pageEvents.add(p2, "message", event => {
|
||||||
if(event.type === "gameload"){
|
if(event.type === "gameload"){
|
||||||
this.cancelButton.style.display = ""
|
this.cancelButton.style.display = ""
|
||||||
|
|
||||||
if(event.value === this.selectedSong.difficulty){
|
if(event.value === song.difficulty){
|
||||||
this.startMultiplayer()
|
this.startMultiplayer()
|
||||||
}else{
|
}else{
|
||||||
this.selectedSong2 = {
|
this.selectedSong2 = {
|
||||||
title: this.selectedSong.title,
|
title: song.title,
|
||||||
folder: this.selectedSong.folder,
|
folder: song.folder,
|
||||||
difficulty: event.value,
|
difficulty: event.value,
|
||||||
type: this.selectedSong.type,
|
type: song.type,
|
||||||
offset: this.selectedSong.offset
|
offset: song.offset
|
||||||
}
|
}
|
||||||
if(this.selectedSong.type === "tja"){
|
if(song.type === "tja"){
|
||||||
this.startMultiplayer()
|
this.startMultiplayer()
|
||||||
}else{
|
}else{
|
||||||
loader.ajax(this.getSongPath(this.selectedSong2)).then(data => {
|
loader.ajax(this.getSongPath(this.selectedSong2)).then(data => {
|
||||||
@ -144,7 +184,7 @@ class loadSong{
|
|||||||
this.clean()
|
this.clean()
|
||||||
p2.clearMessage("songsel")
|
p2.clearMessage("songsel")
|
||||||
loader.changePage("game")
|
loader.changePage("game")
|
||||||
var taikoGame1 = new Controller(this.selectedSong, this.songData, false, 1, this.touchEnabled)
|
var taikoGame1 = new Controller(song, this.songData, false, 1, this.touchEnabled)
|
||||||
var taikoGame2 = new Controller(this.selectedSong2, this.song2Data, true, 2, this.touchEnabled)
|
var taikoGame2 = new Controller(this.selectedSong2, this.song2Data, true, 2, this.touchEnabled)
|
||||||
taikoGame1.run(taikoGame2)
|
taikoGame1.run(taikoGame2)
|
||||||
}else if(event.type === "left" || event.type === "gameend"){
|
}else if(event.type === "left" || event.type === "gameend"){
|
||||||
@ -153,13 +193,13 @@ class loadSong{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
p2.send("join", {
|
p2.send("join", {
|
||||||
id: this.selectedSong.folder,
|
id: song.folder,
|
||||||
diff: this.selectedSong.difficulty
|
diff: song.difficulty
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
this.clean()
|
this.clean()
|
||||||
loader.changePage("game")
|
loader.changePage("game")
|
||||||
var taikoGame = new Controller(this.selectedSong, this.songData, this.autoPlayEnabled, false, this.touchEnabled)
|
var taikoGame = new Controller(song, this.songData, this.autoPlayEnabled, false, this.touchEnabled)
|
||||||
taikoGame.run()
|
taikoGame.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,8 @@ class SongSelect{
|
|||||||
category: song.category,
|
category: song.category,
|
||||||
preview: song.preview || 0,
|
preview: song.preview || 0,
|
||||||
type: song.type,
|
type: song.type,
|
||||||
offset: song.offset
|
offset: song.offset,
|
||||||
|
songSkin: song.song_skin
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.songs.sort((a, b) => {
|
this.songs.sort((a, b) => {
|
||||||
@ -614,7 +615,8 @@ class SongSelect{
|
|||||||
"difficulty": this.difficultyId[difficulty],
|
"difficulty": this.difficultyId[difficulty],
|
||||||
"category": selectedSong.category,
|
"category": selectedSong.category,
|
||||||
"type": selectedSong.type,
|
"type": selectedSong.type,
|
||||||
"offset": selectedSong.offset
|
"offset": selectedSong.offset,
|
||||||
|
"songSkin": selectedSong.songSkin
|
||||||
}, autoplay, multiplayer, touch)
|
}, autoplay, multiplayer, touch)
|
||||||
}
|
}
|
||||||
toOptions(moveBy){
|
toOptions(moveBy){
|
||||||
|
@ -960,6 +960,8 @@
|
|||||||
var songStage = document.getElementById("song-stage")
|
var songStage = document.getElementById("song-stage")
|
||||||
|
|
||||||
var selectedSong = this.controller.selectedSong
|
var selectedSong = this.controller.selectedSong
|
||||||
|
var songSkinName = selectedSong.songSkin.name
|
||||||
|
|
||||||
if(selectedSong.category in this.categories){
|
if(selectedSong.category in this.categories){
|
||||||
var catId = this.categories[selectedSong.category].sort
|
var catId = this.categories[selectedSong.category].sort
|
||||||
}else{
|
}else{
|
||||||
@ -967,17 +969,31 @@
|
|||||||
}
|
}
|
||||||
this.setBgImage(this.gameDiv, assets.image["bg_genre_" + catId].src)
|
this.setBgImage(this.gameDiv, assets.image["bg_genre_" + catId].src)
|
||||||
|
|
||||||
if(selectedSong.customBg){
|
if(!selectedSong.songSkin.song){
|
||||||
var bg = gameConfig.songs_baseurl + selectedSong.folder + "/bg.png"
|
|
||||||
this.setBgImage(songBg, bg)
|
|
||||||
}else{
|
|
||||||
var id = selectedSong.songBg
|
var id = selectedSong.songBg
|
||||||
songBg.classList.add("songbg-" + id)
|
songBg.classList.add("songbg-" + id)
|
||||||
this.setBgImage(document.getElementById("layer1"), assets.image["bg_song_" + id + "a"].src)
|
this.setLayers("bg_song_" + id, true)
|
||||||
this.setBgImage(document.getElementById("layer2"), assets.image["bg_song_" + id + "b"].src)
|
}else if(selectedSong.songSkin.song !== "none"){
|
||||||
|
var notStatic = selectedSong.songSkin.song !== "static"
|
||||||
|
if(notStatic){
|
||||||
|
songBg.classList.add("songbg-" + selectedSong.songSkin.song)
|
||||||
|
}
|
||||||
|
this.setLayers("bg_song_" + songSkinName + (notStatic ? "_" : ""), notStatic)
|
||||||
}
|
}
|
||||||
|
|
||||||
songStage.classList.add("song-stage-" + selectedSong.songStage)
|
if(!selectedSong.songSkin.stage){
|
||||||
|
songStage.classList.add("song-stage-" + selectedSong.songStage)
|
||||||
|
}else if(selectedSong.songSkin.stage !== "none"){
|
||||||
|
this.setBgImage(songStage, assets.image["bg_stage_" + songSkinName].src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setLayers(file, ab){
|
||||||
|
if(ab){
|
||||||
|
this.setBgImage(document.getElementById("layer1"), assets.image[file + "a"].src)
|
||||||
|
this.setBgImage(document.getElementById("layer2"), assets.image[file + "b"].src)
|
||||||
|
}else{
|
||||||
|
this.setBgImage(document.getElementById("layer1"), assets.image[file].src)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setBgImage(element, url){
|
setBgImage(element, url){
|
||||||
element.style.backgroundImage = "url('" + url + "')"
|
element.style.backgroundImage = "url('" + url + "')"
|
||||||
|
Loading…
Reference in New Issue
Block a user