extends RigidBody2D @export var speed = 400 @export var explosion_damage = 600 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 it’s 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() # 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(): var center = global_position # Explosion center in global coordinates var radius = 150 # Explosion radius in pixels # Convert center to map coordinates var map_center = tile_map_layer.local_to_map(center) print("Explosion center in map coordinates:", center, map_center) # Tile dimensions var tile_width = 16 var tile_height = 16 # 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 for x in range(min_x, max_x + 1): for y in range(min_y, max_y + 1): # 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 if dist <= radius: 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 if tile_map_layer.get_cell_source_id(Vector2i(x, y)) != -1: tile_map_layer.erase_cell(Vector2i(x, y)) print("Erased tile at:", Vector2i(x, y)) # 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()