Browse Source

Add explosion stage 1 PNG assets for all directions

- Added BMP_1_EXPLOSION_DOWN.png to original and preview directories.
- Added BMP_1_EXPLOSION_LEFT.png to original and preview directories.
- Added BMP_1_EXPLOSION_RIGHT.png to original and preview directories.
- Added BMP_1_EXPLOSION_UP.png to original and preview directories.

These assets are part of the explosion animation for the game, enhancing visual effects during gameplay.
master
Matteo Benedetto 3 weeks ago
parent
commit
b243cf04d3
  1. BIN
      assets/Rat/BMP_1_EXPLOSION_DOWN.png
  2. BIN
      assets/Rat/BMP_1_EXPLOSION_LEFT.png
  3. BIN
      assets/Rat/BMP_1_EXPLOSION_RIGHT.png
  4. BIN
      assets/Rat/BMP_1_EXPLOSION_UP.png
  5. 4
      rats.py
  6. 74
      tools/vernon/enhance_stage1_explosions.py
  7. 24712
      tools/vernon/output/explosion_stage1_json/BMP_1_EXPLOSION_DOWN.json
  8. 24712
      tools/vernon/output/explosion_stage1_json/BMP_1_EXPLOSION_LEFT.json
  9. 24712
      tools/vernon/output/explosion_stage1_json/BMP_1_EXPLOSION_RIGHT.json
  10. 24712
      tools/vernon/output/explosion_stage1_json/BMP_1_EXPLOSION_UP.json
  11. BIN
      tools/vernon/output/explosion_stage1_original/BMP_1_EXPLOSION_DOWN.png
  12. BIN
      tools/vernon/output/explosion_stage1_original/BMP_1_EXPLOSION_LEFT.png
  13. BIN
      tools/vernon/output/explosion_stage1_original/BMP_1_EXPLOSION_RIGHT.png
  14. BIN
      tools/vernon/output/explosion_stage1_original/BMP_1_EXPLOSION_UP.png
  15. BIN
      tools/vernon/output/explosion_stage1_preview/BMP_1_EXPLOSION_DOWN.png
  16. BIN
      tools/vernon/output/explosion_stage1_preview/BMP_1_EXPLOSION_LEFT.png
  17. BIN
      tools/vernon/output/explosion_stage1_preview/BMP_1_EXPLOSION_RIGHT.png
  18. BIN
      tools/vernon/output/explosion_stage1_preview/BMP_1_EXPLOSION_UP.png
  19. 9
      units/bomb.py
  20. 6
      units/gas.py
  21. 3
      units/mine.py
  22. 16
      units/unit.py

BIN
assets/Rat/BMP_1_EXPLOSION_DOWN.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
assets/Rat/BMP_1_EXPLOSION_LEFT.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 B

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
assets/Rat/BMP_1_EXPLOSION_RIGHT.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 B

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
assets/Rat/BMP_1_EXPLOSION_UP.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

After

Width:  |  Height:  |  Size: 1.8 KiB

4
rats.py

@ -281,7 +281,6 @@ class MiceMaze(
self.render_engine.delete_tag("unit") self.render_engine.delete_tag("unit")
self.render_engine.delete_tag("effect") self.render_engine.delete_tag("effect")
self.render_engine.delete_tag("cave") self.render_engine.delete_tag("cave")
self.render_engine.draw_pointer(self.pointer[0] * self.cell_size, self.pointer[1] * self.cell_size)
# Clear collision system for new frame # Clear collision system for new frame
self.collision_system.clear() self.collision_system.clear()
@ -333,13 +332,14 @@ class MiceMaze(
self.unit_positions.setdefault(unit.position, []).append(unit) self.unit_positions.setdefault(unit.position, []).append(unit)
self.unit_positions_before.setdefault(unit.position_before, []).append(unit) self.unit_positions_before.setdefault(unit.position_before, []).append(unit)
self.draw_cave_foreground()
self.render_engine.draw_pointer(self.pointer[0] * self.cell_size, self.pointer[1] * self.cell_size)
# Fourth pass: check collisions and draw # Fourth pass: check collisions and draw
for unit in self.units.copy().values(): for unit in self.units.copy().values():
unit.collisions() unit.collisions()
unit.draw() unit.draw()
self.draw_cave_foreground()
self.render_engine.update_status(f"Mice: {self.count_rats()} - Points: {self.points}") self.render_engine.update_status(f"Mice: {self.count_rats()} - Points: {self.points}")
self.refill_ammo() self.refill_ammo()

74
tools/vernon/enhance_stage1_explosions.py

@ -0,0 +1,74 @@
#!/usr/bin/env python3
import json
import sys
from pathlib import Path
from PIL import Image
CHROMAKEY = [128, 128, 128, 255]
GREEN_LIGHT = [0, 255, 0, 255]
GREEN_DARK = [0, 128, 0, 255]
def is_green(pixel):
return pixel == GREEN_LIGHT or pixel == GREEN_DARK
def is_background(pixel):
return pixel == CHROMAKEY or is_green(pixel)
def cave_reference_path(sprite_name):
direction = sprite_name.rsplit("_", 1)[-1]
return Path("assets/Rat") / f"BMP_1_CAVE_{direction}.png"
def load_cave_grid(sprite_name):
cave_path = cave_reference_path(sprite_name)
cave_image = Image.open(cave_path).convert("RGBA")
width, height = cave_image.size
pixel_access = cave_image.load()
return [
[list(pixel_access[x, y]) for x in range(width)]
for y in range(height)
]
def enhance_pixels(name, pixels):
cave_pixels = load_cave_grid(name)
enhanced = []
for y, row in enumerate(pixels):
enhanced_row = []
for x, pixel in enumerate(row):
if is_background(pixel):
enhanced_row.append(cave_pixels[y][x][:])
else:
enhanced_row.append(pixel[:])
enhanced.append(enhanced_row)
return enhanced
def process_file(src_path, dst_path):
data = json.loads(src_path.read_text())
pixels = data["pixels"]
data["pixels"] = enhance_pixels(src_path.stem, pixels)
dst_path.write_text(json.dumps(data, indent=2))
def main():
if len(sys.argv) != 3:
raise SystemExit("usage: enhance_stage1_explosions.py <src_dir> <dst_dir>")
src_dir = Path(sys.argv[1])
dst_dir = Path(sys.argv[2])
dst_dir.mkdir(parents=True, exist_ok=True)
for src_path in sorted(src_dir.glob("BMP_1_EXPLOSION_*.json")):
dst_path = dst_dir / src_path.name
process_file(src_path, dst_path)
print(f"Wrote {dst_path}")
if __name__ == "__main__":
main()

24712
tools/vernon/output/explosion_stage1_json/BMP_1_EXPLOSION_DOWN.json

File diff suppressed because it is too large Load Diff

24712
tools/vernon/output/explosion_stage1_json/BMP_1_EXPLOSION_LEFT.json

File diff suppressed because it is too large Load Diff

24712
tools/vernon/output/explosion_stage1_json/BMP_1_EXPLOSION_RIGHT.json

File diff suppressed because it is too large Load Diff

24712
tools/vernon/output/explosion_stage1_json/BMP_1_EXPLOSION_UP.json

File diff suppressed because it is too large Load Diff

BIN
tools/vernon/output/explosion_stage1_original/BMP_1_EXPLOSION_DOWN.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

BIN
tools/vernon/output/explosion_stage1_original/BMP_1_EXPLOSION_LEFT.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

BIN
tools/vernon/output/explosion_stage1_original/BMP_1_EXPLOSION_RIGHT.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

BIN
tools/vernon/output/explosion_stage1_original/BMP_1_EXPLOSION_UP.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

BIN
tools/vernon/output/explosion_stage1_preview/BMP_1_EXPLOSION_DOWN.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
tools/vernon/output/explosion_stage1_preview/BMP_1_EXPLOSION_LEFT.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
tools/vernon/output/explosion_stage1_preview/BMP_1_EXPLOSION_RIGHT.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
tools/vernon/output/explosion_stage1_preview/BMP_1_EXPLOSION_UP.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

9
units/bomb.py

@ -44,6 +44,9 @@ class Bomb(Unit):
x_pos = self.position_before[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x x_pos = self.position_before[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x
y_pos = self.position_before[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y y_pos = self.position_before[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y
if self.is_hidden_in_tunnel(image_size):
return
self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit") self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit")
class Timer(Bomb): class Timer(Bomb):
@ -132,6 +135,9 @@ class Explosion(Bomb):
x_pos = self.position_before[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x x_pos = self.position_before[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x
y_pos = self.position_before[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y y_pos = self.position_before[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y
if self.is_hidden_in_tunnel(image_size):
return
self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit") self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit")
@ -186,4 +192,7 @@ class NuclearBomb(Unit):
x_pos = self.position[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 x_pos = self.position[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2
y_pos = self.position[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 y_pos = self.position[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2
if self.is_hidden_in_tunnel(image_size, position=self.position):
return
self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit") self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit")

6
units/gas.py

@ -79,8 +79,10 @@ class Gas(Unit):
x_pos = self.position_before[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x x_pos = self.position_before[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x
y_pos = self.position_before[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y y_pos = self.position_before[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y
self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit") if not self.is_hidden_in_tunnel(image_size):
self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit")
for cell in self.spreading_cells: for cell in self.spreading_cells:
x_pos = cell[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x x_pos = cell[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x
y_pos = cell[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y y_pos = cell[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y
self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit") if not self.is_hidden_in_tunnel(image_size, position=cell):
self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit")

3
units/mine.py

@ -56,6 +56,9 @@ class Mine(Unit):
x_pos = self.position[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 x_pos = self.position[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2
y_pos = self.position[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 y_pos = self.position[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2
if self.is_hidden_in_tunnel(image_size, position=self.position):
return
self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit") self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit")
def die(self, score=None): def die(self, score=None):

16
units/unit.py

@ -67,6 +67,22 @@ class Unit(ABC):
"""Handle collisions with other units. Default implementation does nothing.""" """Handle collisions with other units. Default implementation does nothing."""
pass pass
def is_hidden_in_tunnel(self, image_size, position=None):
"""Return True when the sprite center falls inside a tunnel cell."""
if position is None:
position = self.position_before
x_pos = position[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2
y_pos = position[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2
center_x = int(x_pos + image_size[0] / 2)
center_y = int(y_pos + image_size[1] / 2)
cell_x = center_x // self.game.cell_size
cell_y = center_y // self.game.cell_size
if not self.game.map.in_bounds(cell_x, cell_y):
return False
return self.game.map.is_tunnel(cell_x, cell_y)
def die(self, score=None): def die(self, score=None):
"""Remove unit from game and handle basic cleanup.""" """Remove unit from game and handle basic cleanup."""
if self.id in self.game.units: if self.id in self.game.units:

Loading…
Cancel
Save