Added more per-song characters, fixed tankmans alt animation

This commit is contained in:
Entarno54 2025-05-30 03:34:40 +07:00
parent d9b589feea
commit 8e0b5e6044
19 changed files with 9061 additions and 27 deletions

202
characters/bf-car.json Normal file
View File

@ -0,0 +1,202 @@
{
"animations": [
{
"offsets": [
0,
0
],
"loop": false,
"fps": 24,
"anim": "idle",
"indices": [],
"name": "BF idle dance"
},
{
"offsets": [
12,
-6
],
"loop": false,
"fps": 24,
"anim": "singLEFT",
"indices": [],
"name": "BF NOTE LEFT"
},
{
"offsets": [
-10,
-50
],
"loop": false,
"fps": 24,
"anim": "singDOWN",
"indices": [],
"name": "BF NOTE DOWN"
},
{
"offsets": [
-29,
27
],
"loop": false,
"fps": 24,
"anim": "singUP",
"indices": [],
"name": "BF NOTE UP"
},
{
"offsets": [
-38,
-7
],
"loop": false,
"fps": 24,
"anim": "singRIGHT",
"indices": [],
"name": "BF NOTE RIGHT"
},
{
"offsets": [
12,
24
],
"loop": false,
"fps": 24,
"anim": "singLEFTmiss",
"indices": [],
"name": "BF NOTE LEFT MISS"
},
{
"offsets": [
-11,
-19
],
"loop": false,
"fps": 24,
"anim": "singDOWNmiss",
"indices": [],
"name": "BF NOTE DOWN MISS"
},
{
"offsets": [
-29,
27
],
"loop": false,
"fps": 24,
"anim": "singUPmiss",
"indices": [],
"name": "BF NOTE UP MISS"
},
{
"offsets": [
-30,
21
],
"loop": false,
"fps": 24,
"anim": "singRIGHTmiss",
"indices": [],
"name": "BF NOTE RIGHT MISS"
},
{
"offsets": [
0,
0
],
"loop": true,
"fps": 24,
"anim": "idle-loop",
"indices": [
10,
11,
12,
13
],
"name": "BF idle dance"
},
{
"offsets": [
12,
-6
],
"loop": true,
"fps": 24,
"anim": "singLEFT-loop",
"indices": [
12,
13,
14,
15
],
"name": "BF NOTE LEFT"
},
{
"offsets": [
-38,
-7
],
"loop": true,
"fps": 24,
"anim": "singRIGHT-loop",
"indices": [
58,
59,
60,
61
],
"name": "BF NOTE RIGHT"
},
{
"offsets": [
-29,
27
],
"loop": true,
"fps": 24,
"anim": "singUP-loop",
"indices": [
11,
12,
13,
14
],
"name": "BF NOTE UP"
},
{
"offsets": [
-10,
-50
],
"loop": true,
"fps": 24,
"anim": "singDOWN-loop",
"indices": [
26,
27,
28,
29
],
"name": "BF NOTE DOWN"
}
],
"no_antialiasing": false,
"image": "sprites/bfCar",
"position": [
0,
350
],
"healthicon": "bf",
"flip_x": false,
"healthbar_colors": [
49,
176,
209
],
"camera_position": [
-100,
40
],
"sing_duration": 4,
"scale": 1
}

View File

@ -0,0 +1,144 @@
{
"animations": [
{
"offsets": [
-5,
0
],
"loop": false,
"fps": 24,
"anim": "idle",
"indices": [],
"name": "BF idle dance w gf"
},
{
"offsets": [
12,
7
],
"loop": false,
"fps": 24,
"anim": "singLEFT",
"indices": [],
"name": "BF NOTE LEFT"
},
{
"offsets": [
-10,
-10
],
"loop": false,
"fps": 24,
"anim": "singDOWN",
"indices": [],
"name": "BF NOTE DOWN"
},
{
"offsets": [
-29,
10
],
"loop": false,
"fps": 24,
"anim": "singUP",
"indices": [],
"name": "BF NOTE UP"
},
{
"offsets": [
-41,
23
],
"loop": false,
"fps": 24,
"anim": "singRIGHT",
"indices": [],
"name": "BF NOTE RIGHT"
},
{
"offsets": [
12,
7
],
"loop": false,
"fps": 24,
"anim": "singLEFTmiss",
"indices": [],
"name": "BF NOTE LEFT MISS"
},
{
"offsets": [
-10,
-10
],
"loop": false,
"fps": 24,
"anim": "singDOWNmiss",
"indices": [],
"name": "BF NOTE DOWN MISS"
},
{
"offsets": [
-29,
10
],
"loop": false,
"fps": 24,
"anim": "singUPmiss",
"indices": [],
"name": "BF NOTE UP MISS"
},
{
"offsets": [
-41,
33
],
"loop": false,
"fps": 24,
"anim": "singRIGHTmiss",
"indices": [],
"name": "BF NOTE RIGHT MISS"
},
{
"loop": false,
"offsets": [
0,
96
],
"anim": "bfCatch",
"fps": 24,
"name": "BF catches GF",
"indices": []
},
{
"loop": false,
"offsets": [
0,
91
],
"anim": "hey",
"fps": 24,
"name": "BF catches GF",
"indices": []
}
],
"no_antialiasing": false,
"image": "sprites/bfAndGF",
"position": [
0,
350
],
"healthicon": "bfgf",
"flip_x": false,
"healthbar_colors": [
49,
176,
209
],
"camera_position": [
-100,
40
],
"sing_duration": 4,
"scale": 1
}

89
characters/gf-car.json Normal file
View File

@ -0,0 +1,89 @@
{
"animations": [
{
"loop": false,
"offsets": [
2,
0
],
"anim": "singUP",
"fps": 24,
"name": "GF Dancing Beat Hair blowing CAR",
"indices": []
},
{
"loop": false,
"offsets": [
0,
0
],
"fps": 24,
"anim": "danceRight",
"indices": [
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29
],
"name": "GF Dancing Beat Hair blowing CAR"
},
{
"loop": false,
"offsets": [
0,
0
],
"fps": 24,
"anim": "danceLeft",
"indices": [
30,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14
],
"name": "GF Dancing Beat Hair blowing CAR"
}
],
"no_antialiasing": false,
"image": "sprites/gfCar",
"position": [
0,
160
],
"healthicon": "gf",
"flip_x": false,
"healthbar_colors": [
165,
0,
77
],
"camera_position": [
0,
0
],
"sing_duration": 4,
"scale": 1
}

View File

@ -139,8 +139,8 @@
"no_antialiasing": false,
"image": "sprites/momCar",
"position": [
0,
0
-200,
160
],
"healthicon": "mom",
"flip_x": false,
@ -150,9 +150,9 @@
142
],
"camera_position": [
0,
-800,
0
],
"sing_duration": 4,
"scale": 1
}
}

View File

@ -0,0 +1,129 @@
{
"animations": [
{
"offsets": [
0,
0
],
"loop": false,
"fps": 24,
"anim": "danceLeft",
"indices": [],
"name": "Pico shoot ",
"random": [1, 4]
},
{
"offsets": [
-1,
-128
],
"loop": false,
"fps": 24,
"anim": "danceRight",
"indices": [],
"name": "Pico shoot 2 "
},
{
"offsets": [
412,
-64
],
"loop": false,
"fps": 24,
"anim": "shoot3",
"indices": [],
"name": "Pico shoot 3 "
},
{
"offsets": [
439,
-19
],
"loop": false,
"fps": 24,
"anim": "shoot4",
"indices": [],
"name": "Pico shoot 4 "
},
{
"offsets": [
412,
-64
],
"loop": true,
"fps": 24,
"anim": "shoot3-loop",
"indices": [
50,
51,
52
],
"name": "Pico shoot 3 "
},
{
"offsets": [
0,
0
],
"loop": true,
"fps": 24,
"anim": "shoot1-loop",
"indices": [
23,
24,
25
],
"name": "Pico shoot 1 "
},
{
"offsets": [
1,
-128
],
"loop": true,
"fps": 24,
"anim": "shoot2-loop",
"indices": [
57,
58,
59
],
"name": "Pico shoot 2 "
},
{
"offsets": [
439,
-19
],
"loop": true,
"fps": 24,
"anim": "shoot4-loop",
"indices": [
50,
51,
52
],
"name": "Pico shoot 4 "
}
],
"no_antialiasing": false,
"image": "sprites/picoSpeaker",
"position": [
0,
170
],
"healthicon": "pico",
"flip_x": false,
"healthbar_colors": [
183,
216,
85
],
"camera_position": [
-310,
100
],
"sing_duration": 4,
"scale": 1,
"beats": 1
}

View File

@ -61,7 +61,7 @@
-8
],
"loop": false,
"fps": 24,
"fps": 50,
"anim": "singUP-alt",
"indices": [],
"name": "TANKMAN UGH "
@ -72,7 +72,7 @@
16
],
"loop": false,
"fps": 24,
"fps": 50,
"anim": "singDOWN-alt",
"indices": [],
"name": "PRETTY GOOD tankman "

View File

@ -1,7 +1,7 @@
{
"song": {
"player1": "bf",
"player2": "dad",
"player1": "bf-car",
"player2": "mom-car",
"events": [],
"notes": [
{

View File

@ -1,8 +1,8 @@
{
"song": {
"player1": "bf",
"player1": "bf-holding-gf",
"events": [],
"gfVersion": "gf",
"gfVersion": "none",
"notes": [
{
"sectionNotes": [
@ -2402,7 +2402,7 @@
62022.4727,
1,
0,
"No Animation"
"Alt"
],
[
62696.63,

View File

@ -94,7 +94,7 @@ return function(songName, songDifficulty)
local currentTime = socket.gettime()
elapsed = elapsed + dt * 1000
elapsed = (currentTime - startTime) * 1000
conductor.songPosition = elapsed
@ -110,7 +110,7 @@ return function(songName, songDifficulty)
for name, character in next, characters do
if not character.singing then
if name == "gf" then
if beat % 4 == 0 then
if beat % character.beats == 0 then
character:PlayAnimation("danceLeft")
end
else
@ -159,6 +159,7 @@ return function(songName, songDifficulty)
for index, note in next, notes do
if note.position - conductor.songPosition < 0 then
if note.mustPress then
note:destroy()
miss:stop()
miss:play()
characters.bf:PlayAnimation("sing"..directions[note.direction].."miss")
@ -194,7 +195,7 @@ return function(songName, songDifficulty)
else
if note.position - elapsed < 50 then
table.remove(notes, index)
if section.altAnim then
if section.altAnim or note.altAnim then
characters.dad:PlayAnimation("sing"..directions[note.direction].."-alt")
else
characters.dad:PlayAnimation("sing"..directions[note.direction])
@ -237,8 +238,10 @@ return function(songName, songDifficulty)
function state.load()
-- GF first so she is below other chars
characters.gf = myTypes.character(chart.gfVersion)
characters.gf.stagePosition = myTypes.Vector2(stage.girlfriend[1], stage.girlfriend[2])
if chart.gfVersion ~= "none" then
characters.gf = myTypes.character(chart.gfVersion)
characters.gf.stagePosition = myTypes.Vector2(stage.girlfriend[1], stage.girlfriend[2])
end
characters.bf = myTypes.character(chart.player1)
characters.bf.stagePosition = myTypes.Vector2(stage.boyfriend[1], stage.boyfriend[2])
@ -277,6 +280,8 @@ return function(songName, songDifficulty)
elapsed = 0
playing = true
startTime = socket.gettime()
end
return state

View File

@ -120,7 +120,7 @@ end
function module.updateSprites(dt)
for index, sprite in next, Sprites do
if not sprite.animation then goto continue end
if not sprite.animation or not sprite.quads[sprite.animation] then goto continue end
sprite.elapsed = sprite.elapsed + dt

View File

@ -9,8 +9,13 @@ CharacterClass.__index = CharacterClass
function CharacterClass:PlayAnimation(name)
local animName = self.animations[name]
self.sprite:PlayAnimation(animName, self.animInfo[name].fps)
self.sprite.extraOffset = module.myTypes.Vector2(self.animInfo[name].offsets[1] - self.stagePosition.x, self.animInfo[name].offsets[2] - self.stagePosition.y)
if self.animInfo[name].random then
self.sprite:PlayAnimation(animName..string.format("%s ", math.random(self.animInfo[name].random[1], self.animInfo[name].random[2])), self.animInfo[name].fps)
self.sprite.extraOffset = module.myTypes.Vector2(self.animInfo[name].offsets[1] - self.stagePosition.x, self.animInfo[name].offsets[2] - self.stagePosition.y)
else
self.sprite:PlayAnimation(animName, self.animInfo[name].fps)
self.sprite.extraOffset = module.myTypes.Vector2(self.animInfo[name].offsets[1] - self.stagePosition.x, self.animInfo[name].offsets[2] - self.stagePosition.y)
end
self.singing = name ~= "idle" and name ~= "danceLeft" and name ~= "danceRight"
end
@ -38,7 +43,8 @@ function module.character(name)
singing = false,
stagePosition = module.myTypes.Vector2(0,0), -- Changeable
stageCamera = module.myTypes.Vector2(parsed.camera_position[1], parsed.camera_position[2]),
flipX = parsed.flip_x
flipX = parsed.flip_x,
beats = parsed.beats or 4
}, CharacterClass)
for index, alias in next, parsed.animations do

View File

@ -18,7 +18,8 @@ function module.note(raw, mustHitSection)
mustPress = mustHitSection and raw[2] <= 3 or not mustHitSection and raw[2] > 3,
direction = raw[2] <= 3 and raw[2] + 1 or raw[2] - 3,
spawned = false,
sprite = nil -- For unspawned notes
sprite = nil, -- For unspawned notes
altAnim = raw[4] == "Alt"
}, NoteClass)
return newNote
@ -44,4 +45,4 @@ function NoteClass:destroy()
end
return module
return module

3362
sprites/bfAndGF.json Normal file

File diff suppressed because it is too large Load Diff

BIN
sprites/bfAndGF.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 MiB

2977
sprites/bfCar.json Normal file

File diff suppressed because it is too large Load Diff

BIN
sprites/bfCar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -1,6 +1,5 @@
{
{
"TextureAtlas": {
"imagePath": "momCar.png",
"SubTexture": [
{
"_name": "MOM DOWN POSE0000",
@ -684,7 +683,7 @@
"_frameHeight": "861"
},
{
"__name": "Mom Up Pose0014",
"_name": "Mom Up Pose0014",
"_x": "5466",
"_y": "1648",
"_width": "455",
@ -694,6 +693,7 @@
"_frameWidth": "473",
"_frameHeight": "861"
}
]
],
"_imagePath": "momCar.png"
}
}
}

2119
sprites/picoSpeaker.json Normal file

File diff suppressed because it is too large Load Diff

BIN
sprites/picoSpeaker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 MiB