Files

145 lines
4.5 KiB
GDScript3
Raw Permalink Normal View History

2024-12-02 13:45:17 +01:00
extends RigidBody2D
@export var speed = 400
2024-12-04 08:48:48 +01:00
@export var explosion_damage = 600
2024-12-02 13:45:17 +01:00
var velocity = Vector2.ZERO
var is_in_flight = false
var has_exploded = false # Flag to track if the bomb has exploded
@onready var sprite = $Sprite2D
@onready var collision = $CollisionShape2D
@onready var particles = $Explosion
@onready var explosion_sound = $AudioStreamPlayer2D
@onready var explosion_area = $ExplosionArea
@onready var timer = $Timer
@onready var camera = get_parent().get_parent().get_node("MultiTargetCamera")
@onready var tile_map_layer = get_parent().get_parent().get_node("TileMapLayer")
@export var off_screen_margin = 2000
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
camera.add_target(self)
global_position = position
z_index = -1
# Disable the particles and audio on start
particles.emitting = false
explosion_sound.playing = false
# Connect the timer's timeout signal to the cleanup function
timer.connect("timeout", _on_timeout)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if is_in_flight:
# Explode if the bomb goes off-screen
if is_off_screen() and not has_exploded:
trigger_explosion()
# This function is used to set the velocity of the bomb when its thrown
func set_velocity(new_velocity: Vector2) -> void:
# Apply an impulse based on the new velocity
apply_central_impulse(new_velocity)
is_in_flight = true
# Function to trigger the explosion
func trigger_explosion():
if has_exploded:
return # Prevent multiple explosions
# Set the flag to true, indicating that the bomb has exploded
has_exploded = true
camera.remove_target(self)
# Play the explosion sound
explosion_sound.play()
# Enable and emit the particles
particles.emitting = true
# Push away players within the explosion radius
push_away_players()
# Destroy tiles in the explosion radius
destroy_tiles_in_explosion_area()
2024-12-04 16:17:31 +01:00
tile_map_layer.detect_and_make_tiles_fall()
2024-12-02 13:45:17 +01:00
# Start the timer to cleanup the explosion
timer.start()
sprite.hide()
func push_away_players():
if not explosion_area:
print("ExplosionArea2D is missing!")
return
var overlapping_bodies = explosion_area.get_overlapping_bodies()
print("Overlapping bodies:", overlapping_bodies)
for body in overlapping_bodies:
if body is RigidBody2D:
print("Pushing body:", body.name)
var direction = (body.global_position - global_position).normalized()
var impulse = direction * explosion_damage
body.apply_central_impulse(impulse)
func destroy_tiles_in_explosion_area():
2024-12-03 20:16:17 +01:00
var center = global_position # Explosion center in global coordinates
var radius = 150 # Explosion radius in pixels
# Convert center to map coordinates
2024-12-02 13:45:17 +01:00
var map_center = tile_map_layer.local_to_map(center)
2024-12-03 20:16:17 +01:00
print("Explosion center in map coordinates:", center, map_center)
# Tile dimensions
2024-12-02 13:45:17 +01:00
var tile_width = 16
var tile_height = 16
2024-12-03 20:16:17 +01:00
# Calculate bounds of explosion in tile coordinates
var min_x = int((center.x - radius) / tile_width)
var max_x = int((center.x + radius) / tile_width)
var min_y = int((center.y - radius) / tile_height)
var max_y = int((center.y + radius) / tile_height)
print("Explosion bounds in tile coordinates: ", Vector2i(min_x, min_y), Vector2i(max_x, max_y))
# Loop through the affected tiles
2024-12-02 13:45:17 +01:00
for x in range(min_x, max_x + 1):
for y in range(min_y, max_y + 1):
2024-12-03 20:16:17 +01:00
# Calculate the distance from the explosion center to the tile center
var tile_pos = tile_map_layer.map_to_local(Vector2i(x, y))
var dist = center.distance_to(tile_pos)
# Check if the tile is within the explosion radius
2024-12-02 13:45:17 +01:00
if dist <= radius:
2024-12-03 20:16:17 +01:00
print("Checking tile at:", Vector2i(x, y), "Distance:", dist)
print(tile_map_layer.get_cell_source_id(Vector2i(x, y)))
# Erase the tile if it exists
2024-12-02 13:45:17 +01:00
if tile_map_layer.get_cell_source_id(Vector2i(x, y)) != -1:
tile_map_layer.erase_cell(Vector2i(x, y))
2024-12-03 20:16:17 +01:00
print("Erased tile at:", Vector2i(x, y))
2024-12-02 13:45:17 +01:00
# Function to check if the bomb is off-screen
func is_off_screen() -> bool:
var screen_rect = Rect2(camera.position - camera.zoom * camera.get_viewport_rect().size / 2,
camera.zoom * camera.get_viewport_rect().size)
screen_rect = screen_rect.grow(off_screen_margin) # Expand the screen rectangle by the margin
return not screen_rect.has_point(global_position)
# Cleanup function called when the timer times out
func _on_timeout():
# Once the timer finishes, queue the particles for cleanup (optional)
particles.emitting = false
explosion_sound.stop() # Stop the sound if it's still playing
queue_free()