@@ -58,39 +58,35 @@ enum EnemyType {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the current animation state for a given sprite index.
|
|
||||||
/// Returns null if the sprite index does not belong to this enemy.
|
|
||||||
EnemyAnimation? getAnimationFromSprite(int spriteIndex) {
|
EnemyAnimation? getAnimationFromSprite(int spriteIndex) {
|
||||||
if (!claimsSpriteIndex(spriteIndex)) return null;
|
if (!claimsSpriteIndex(spriteIndex)) return null;
|
||||||
|
|
||||||
// By working with offsets, we don't have to hardcode the 100+ sprite indices!
|
|
||||||
int offset = spriteIndex - spriteBaseIdx;
|
int offset = spriteIndex - spriteBaseIdx;
|
||||||
|
|
||||||
// All standard enemies use offsets 0-7 for their 8 directional Idle frames
|
|
||||||
if (offset >= 0 && offset <= 7) return EnemyAnimation.idle;
|
if (offset >= 0 && offset <= 7) return EnemyAnimation.idle;
|
||||||
|
|
||||||
// The action frames vary slightly depending on the enemy type
|
|
||||||
return switch (this) {
|
return switch (this) {
|
||||||
EnemyType.guard || EnemyType.ss => switch (offset) {
|
EnemyType.guard || EnemyType.ss => switch (offset) {
|
||||||
>= 8 && <= 39 => EnemyAnimation.walking, // 4 frames * 8 directions
|
>= 8 && <= 39 => EnemyAnimation.walking,
|
||||||
>= 40 && <= 42 => EnemyAnimation.attacking, // Aim, Fire, Recoil
|
>= 40 && <= 42 => EnemyAnimation.dying,
|
||||||
43 => EnemyAnimation.pain,
|
43 => EnemyAnimation.pain,
|
||||||
>= 44 && <= 46 => EnemyAnimation.dying,
|
>= 44 && <= 46 => EnemyAnimation.attacking,
|
||||||
_ => EnemyAnimation.dead, // Catch-all for final frames
|
_ => EnemyAnimation.dead,
|
||||||
},
|
},
|
||||||
|
|
||||||
EnemyType.officer || EnemyType.mutant => switch (offset) {
|
EnemyType.officer || EnemyType.mutant => switch (offset) {
|
||||||
>= 8 && <= 39 => EnemyAnimation.walking,
|
>= 8 && <= 39 => EnemyAnimation.walking,
|
||||||
>= 40 && <= 41 => EnemyAnimation.attacking, // Only 2 attack frames!
|
// All humanoids share 3 dying frames
|
||||||
42 => EnemyAnimation.pain,
|
>= 40 && <= 42 => EnemyAnimation.dying,
|
||||||
>= 43 && <= 45 => EnemyAnimation.dying,
|
43 => EnemyAnimation.pain,
|
||||||
|
// Officers/Mutants only have 2 attack frames
|
||||||
|
>= 44 && <= 45 => EnemyAnimation.attacking,
|
||||||
_ => EnemyAnimation.dead,
|
_ => EnemyAnimation.dead,
|
||||||
},
|
},
|
||||||
|
|
||||||
EnemyType.dog => switch (offset) {
|
EnemyType.dog => switch (offset) {
|
||||||
// Dogs are special: 3 walk frames (24 total) and NO pain frame!
|
|
||||||
>= 8 && <= 31 => EnemyAnimation.walking,
|
>= 8 && <= 31 => EnemyAnimation.walking,
|
||||||
>= 32 && <= 34 => EnemyAnimation.attacking, // Leap and bite
|
>= 32 && <= 34 => EnemyAnimation.attacking,
|
||||||
>= 35 && <= 37 => EnemyAnimation.dying,
|
>= 35 && <= 37 => EnemyAnimation.dying,
|
||||||
_ => EnemyAnimation.dead,
|
_ => EnemyAnimation.dead,
|
||||||
},
|
},
|
||||||
@@ -104,7 +100,6 @@ enum EnemyType {
|
|||||||
double angleDiff = 0,
|
double angleDiff = 0,
|
||||||
int? walkFrameOverride,
|
int? walkFrameOverride,
|
||||||
}) {
|
}) {
|
||||||
// 1. Calculate Octant for directional sprites (Idle/Walk)
|
|
||||||
int octant = ((angleDiff + (math.pi / 8)) / (math.pi / 4)).floor() % 8;
|
int octant = ((angleDiff + (math.pi / 8)) / (math.pi / 4)).floor() % 8;
|
||||||
if (octant < 0) octant += 8;
|
if (octant < 0) octant += 8;
|
||||||
|
|
||||||
@@ -120,18 +115,16 @@ enum EnemyType {
|
|||||||
EnemyAnimation.attacking => () {
|
EnemyAnimation.attacking => () {
|
||||||
int time = elapsedMs - lastActionTime;
|
int time = elapsedMs - lastActionTime;
|
||||||
return switch (this) {
|
return switch (this) {
|
||||||
// Offset 40-42 is the Shooting sequence (Aim, Fire, Recoil)
|
|
||||||
EnemyType.guard || EnemyType.ss =>
|
EnemyType.guard || EnemyType.ss =>
|
||||||
spriteBaseIdx +
|
spriteBaseIdx +
|
||||||
(time < 150
|
(time < 150
|
||||||
? 40
|
? 44
|
||||||
: time < 300
|
: time < 300
|
||||||
? 41
|
? 45
|
||||||
: 42),
|
: 46),
|
||||||
EnemyType.officer ||
|
EnemyType.officer ||
|
||||||
EnemyType.mutant => spriteBaseIdx + (time < 200 ? 40 : 41),
|
EnemyType.mutant => spriteBaseIdx + (time < 200 ? 44 : 45),
|
||||||
EnemyType.dog =>
|
EnemyType.dog => spriteBaseIdx + (time < 150 ? 32 : 33),
|
||||||
spriteBaseIdx + (time < 150 ? 32 : 33), // Dog Leap/Bite
|
|
||||||
};
|
};
|
||||||
}(),
|
}(),
|
||||||
|
|
||||||
@@ -139,16 +132,14 @@ enum EnemyType {
|
|||||||
spriteBaseIdx +
|
spriteBaseIdx +
|
||||||
switch (this) {
|
switch (this) {
|
||||||
EnemyType.dog => 32,
|
EnemyType.dog => 32,
|
||||||
EnemyType.officer || EnemyType.mutant => 42,
|
_ => 43,
|
||||||
_ => 43, // guard, ss
|
|
||||||
},
|
},
|
||||||
|
|
||||||
EnemyAnimation.dying => () {
|
EnemyAnimation.dying => () {
|
||||||
int frame = (elapsedMs - lastActionTime) ~/ 150;
|
int frame = (elapsedMs - lastActionTime) ~/ 150;
|
||||||
int dyingStart = switch (this) {
|
int dyingStart = switch (this) {
|
||||||
EnemyType.dog => 35,
|
EnemyType.dog => 35,
|
||||||
EnemyType.officer || EnemyType.mutant => 43,
|
_ => 40,
|
||||||
_ => 44, // guard, ss
|
|
||||||
};
|
};
|
||||||
return spriteBaseIdx + dyingStart + (frame.clamp(0, 2));
|
return spriteBaseIdx + dyingStart + (frame.clamp(0, 2));
|
||||||
}(),
|
}(),
|
||||||
@@ -158,7 +149,7 @@ enum EnemyType {
|
|||||||
switch (this) {
|
switch (this) {
|
||||||
EnemyType.dog => 38,
|
EnemyType.dog => 38,
|
||||||
EnemyType.officer || EnemyType.mutant => 46,
|
EnemyType.officer || EnemyType.mutant => 46,
|
||||||
_ => 48, // guard, ss
|
_ => 48,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user