Files
Bomber-Thorsten/bomb.gd

143 lines
4.5 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 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()
# 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()