Added event bus + a few events, for cheese!

This commit is contained in:
AllfatherHatt 2024-10-23 14:57:06 +02:00
parent c4c7aed6ed
commit a791d80626
11 changed files with 214 additions and 108 deletions

View File

@ -1,43 +1,41 @@
extends StaticBody2D
@export var max_health: float = 100.0 # Maximum health for the asteroid
@export var max_health: float = 100.0
var current_health: float
var is_destroyed: bool = false # Track if the asteroid has already been destroyed
var is_destroyed: bool = false
var event_bus: EventBus
func _ready():
current_health = max_health
update_health_label() # Update the health display when the game starts
event_bus = get_node("/root/Main/MainEventBus")
event_bus.subscribe_to(get_node("/root/Main/DamageEventScope"), "DamageEvent", Callable(self, "on_damage_event"))
add_to_group("asteroids")
update_health_label()
# Function to handle taking damage
func take_damage(damage: float):
if is_destroyed: # Prevent taking damage if already destroyed
return
func on_damage_event(event: DamageEvent) -> EventResult.ResultType:
if event.target != self or is_destroyed:
return EventResult.ResultType.KEEP_SUBSCRIPTION
apply_damage(event.damage_value)
current_health -= damage # Subtract the damage from current health
current_health = max(current_health, 0) # Ensure health doesn't drop below 0
update_health_label() # Update the label to reflect new health value
if current_health <= 0.0:
break_apart()
# Function to handle when the asteroid is destroyed
func break_apart():
is_destroyed = true # Mark the asteroid as destroyed
queue_free() # Remove the asteroid from the scene
print("Asteroid mined!")
emit_asteroid_destroyed()
return EventResult.ResultType.DISPOSE_SUBSCRIPTION
# Load the Cheese scene
var cheese_scene = load("res://Cheese.tscn")
# Instance the cheese
var cheese_instance = cheese_scene.instantiate()
# Set the position where the cheese should spawn (at the asteroid's position)
cheese_instance.global_position = global_position + Vector2(randf() * 50 - 25, randf() * 50 - 25)
return EventResult.ResultType.KEEP_SUBSCRIPTION
# Add the cheese instance to the scene
get_parent().add_child(cheese_instance)
func apply_damage(damage: float) -> void:
current_health = max(current_health - damage, 0)
update_health_label()
# Function to update the health label display
func update_health_label():
func emit_asteroid_destroyed() -> void:
is_destroyed = true
queue_free()
publish_destroyed_event()
func publish_destroyed_event() -> void:
var destroyed_event = DestroyedEvent.new(self, "asteroid", global_position, "laser")
event_bus.publish(get_node("/root/Main/DestroyedEventScope"), destroyed_event)
func update_health_label() -> void:
$AsteroidHealthLabel.text = str(round(current_health)) + " / " + str(max_health)

31
asteroid.tscn Normal file
View File

@ -0,0 +1,31 @@
[gd_scene load_steps=4 format=3 uid="uid://dcq5a8tewppk1"]
[ext_resource type="Script" path="res://asteroid.gd" id="1_spmxj"]
[ext_resource type="Texture2D" uid="uid://buirp1h6onqai" path="res://images/AsteroidBrown.png" id="2_hb7w5"]
[sub_resource type="CircleShape2D" id="CircleShape2D_w58nc"]
radius = 86.093
[node name="asteroid" type="StaticBody2D"]
position = Vector2(564, 144)
collision_mask = 2
script = ExtResource("1_spmxj")
[node name="Sprite2D" type="Sprite2D" parent="."]
position = Vector2(1.00006, -3.99998)
scale = Vector2(1.2, 1.181)
texture = ExtResource("2_hb7w5")
[node name="AsteroidCollisionPolygon2D" type="CollisionPolygon2D" parent="."]
position = Vector2(-519, -164)
polygon = PackedVector2Array(548, 101, 613, 169, 597, 210, 548, 240, 462, 221, 431, 184, 434, 133, 497, 90)
[node name="AsteroidHealthLabel" type="Label" parent="."]
offset_left = 105.0
offset_top = 38.0
offset_right = 181.0
offset_bottom = 80.0
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(0, 2)
shape = SubResource("CircleShape2D_w58nc")

View File

@ -1,18 +1,12 @@
extends Area2D
func _ready():
pass # Replace with function body.
pass
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
func _on_body_entered(body):
if body.name == "spaceship":
queue_free() # This removes the cheese from the scene
print("Cheese collected!") # Replace this with actual game logic
queue_free()
print("Cheese collected!")

10
damage_event.gd Normal file
View File

@ -0,0 +1,10 @@
class_name DamageEvent
extends Event
var damage_value: float
var target: Node
func _init(_damage_value: float, _target: Node):
damage_value = _damage_value
target = _target
type = "DamageEvent"

22
destroyed_event.gd Normal file
View File

@ -0,0 +1,22 @@
class_name DestroyedEvent
extends Event
var destroyed_object: Node
var object_type: String
var position: Vector2
var destruction_cause: String
func _init(_destroyed_object: Node, _object_type: String, _position: Vector2, _destruction_cause: String = ""):
destroyed_object = _destroyed_object
object_type = _object_type
position = _position
destruction_cause = _destruction_cause
type = "DestroyedEvent"
func get_event_details() -> Dictionary:
return {
"object": destroyed_object,
"type": object_type,
"position": position,
"cause": destruction_cause
}

View File

@ -7,12 +7,14 @@ extends Node2D
var hardpoint = null # Reference to the attached hardpoint
var is_firing = false # Track the laser's firing state
var current_damage_output: float = 0.0 # Track the current damage output
var event_bus: EventBus
func _ready():
# Register the laser to the "weapons" group
add_to_group("weapons")
# Connect to the correct hardpoint when ready
call_deferred("_connect_to_hardpoint")
event_bus = get_node("/root/Main/MainEventBus")
# Initialize LaserLine2D with two points (origin and target)
$LaserLine2D.clear_points()
@ -32,16 +34,16 @@ func _connect_to_hardpoint():
func fire():
is_firing = true
current_damage_output = laser_damage
$DamageOutputLabel.text = str(current_damage_output)
_process_laser(true)
current_damage_output = laser_damage
$DamageOutputLabel.text = str(current_damage_output)
func cease_fire():
is_firing = false
current_damage_output = 0.0
$DamageOutputLabel.text = str(current_damage_output)
_process_laser(false)
current_damage_output = 0.0
$DamageOutputLabel.text = str(current_damage_output)
func _process(delta: float) -> void:
if is_firing:
@ -52,27 +54,21 @@ func _process_laser(active: bool):
var raycast = $LaserBeam2D
raycast.enabled = active
if active:
raycast.force_raycast_update()
if raycast.is_colliding():
var collision_point = raycast.get_collision_point()
$LaserLine2D.set_point_position(0, Vector2.ZERO)
$LaserLine2D.set_point_position(1, to_local(collision_point))
$LaserLine2D.set_point_position(0, Vector2.ZERO)
$LaserLine2D.set_point_position(1, to_local(collision_point))
var collider = raycast.get_collider()
if collider.has_method("take_damage"):
collider.take_damage(laser_damage)
if collider:
var damage_event = DamageEvent.new(laser_damage, collider)
event_bus.publish(get_node("/root/Main/DamageEventScope"), damage_event)
else:
$LaserLine2D.set_point_position(0, Vector2.ZERO)
$LaserLine2D.set_point_position(1, Vector2(0, -laser_range))
$LaserLine2D.set_point_position(1, Vector2(0, -laser_range))
else:
$LaserLine2D.clear_points()
$LaserLine2D.add_point(Vector2.ZERO) # Re-add the origin point
$LaserLine2D.add_point(Vector2.ZERO) # Reset target point to origin
$LaserLine2D.add_point(Vector2.ZERO)
$LaserLine2D.add_point(Vector2.ZERO)

47
main.gd
View File

@ -12,12 +12,24 @@ func _init() -> void:
node = EventScope.new()
node.set_name("InputEventScope")
add_child(node)
node = EventScope.new()
node.set_name("DamageEventScope")
add_child(node)
node = EventScope.new()
node.set_name("DestroyedEventScope")
add_child(node)
# Instantiate and add the RewardSpawner
node = RewardSpawner.new()
node.set_name("RewardSpawner")
add_child(node)
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
var actions = [
@ -33,3 +45,36 @@ func _process(delta: float) -> void:
elif Input.is_action_just_released(action):
get_node("/root/Main/MainEventBus").publish(get_node("/root/Main/InputEventScope"), KeyboardInputEvent.new(action, false))
pass
# Spawn function and random position logic are placed here
func spawn_asteroid():
var asteroid_scene = preload("res://asteroid.tscn")
var asteroid_instance = asteroid_scene.instantiate()
# Generate random positions within a defined area
var spawn_position = get_random_position()
# Check that it's not too close to the player or other asteroids
while !is_valid_position(spawn_position):
spawn_position = get_random_position()
asteroid_instance.global_position = spawn_position
add_child(asteroid_instance)
func get_random_position() -> Vector2:
var screen_size = get_viewport().size
return Vector2(randf_range(0, screen_size.x), randf_range(0, screen_size.y))
func is_valid_position(spawn_position: Vector2) -> bool:
var player = get_node("spaceship") # Adjust the path to your player node
var player_distance = player.global_position.distance_to(spawn_position)
if player_distance < 200:
return false
var asteroids = get_tree().get_nodes_in_group("asteroids")
for asteroid in asteroids:
if asteroid.global_position.distance_to(spawn_position) < 150:
return false
return true

View File

@ -1,14 +1,13 @@
[gd_scene load_steps=13 format=3 uid="uid://8ocp10j32f62"]
[gd_scene load_steps=11 format=3 uid="uid://8ocp10j32f62"]
[ext_resource type="Script" path="res://main.gd" id="1_eedai"]
[ext_resource type="Texture2D" uid="uid://y6phkg4twpdm" path="res://images/bg_space_seamless.png" id="1_rpyi5"]
[ext_resource type="Texture2D" uid="uid://cran7fr1i2qou" path="res://images/spaceship-placeholder.png" id="2_f2x66"]
[ext_resource type="Script" path="res://spaceship.gd" id="3_ttkgl"]
[ext_resource type="Script" path="res://laser.gd" id="4_uhf7q"]
[ext_resource type="Script" path="res://asteroid.gd" id="6_n4dsl"]
[ext_resource type="Texture2D" uid="uid://bxgw2u7j4b634" path="res://images/laser_turret.png" id="6_qxhyw"]
[ext_resource type="Texture2D" uid="uid://buirp1h6onqai" path="res://images/AsteroidBrown.png" id="7_0tjls"]
[ext_resource type="Script" path="res://hardpoint.gd" id="7_6cr6a"]
[ext_resource type="Script" path="res://spawn_asteroid_button.gd" id="9_21dg0"]
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_3vtwu"]
radius = 48.0
@ -18,9 +17,6 @@ height = 102.0
offsets = PackedFloat32Array(0.961735, 1)
colors = PackedColorArray(1, 1, 0, 1, 1, 1, 1, 0.137255)
[sub_resource type="CircleShape2D" id="CircleShape2D_w58nc"]
radius = 88.0057
[node name="Main" type="Node2D"]
script = ExtResource("1_eedai")
@ -30,7 +26,7 @@ scale = Vector2(2, 2)
texture = ExtResource("1_rpyi5")
[node name="spaceship" type="CharacterBody2D" parent="."]
position = Vector2(908, 835)
position = Vector2(956, 623)
collision_layer = 2
motion_mode = 1
script = ExtResource("3_ttkgl")
@ -75,45 +71,10 @@ offset_bottom = -20.0
position = Vector2(0, -46)
script = ExtResource("7_6cr6a")
[node name="asteroid" type="StaticBody2D" parent="."]
position = Vector2(564, 144)
collision_mask = 2
script = ExtResource("6_n4dsl")
[node name="Sprite2D" type="Sprite2D" parent="asteroid"]
position = Vector2(1.00006, -3.99998)
scale = Vector2(1.2, 1.181)
texture = ExtResource("7_0tjls")
[node name="AsteroidCollisionPolygon2D" type="CollisionPolygon2D" parent="asteroid"]
position = Vector2(-519, -164)
polygon = PackedVector2Array(548, 101, 613, 169, 597, 210, 548, 240, 462, 221, 431, 184, 434, 133, 497, 90)
[node name="AsteroidHealthLabel" type="Label" parent="asteroid"]
offset_left = 105.0
offset_top = 38.0
offset_right = 181.0
offset_bottom = 80.0
[node name="CollisionShape2D" type="CollisionShape2D" parent="asteroid"]
position = Vector2(-2, 1)
shape = SubResource("CircleShape2D_w58nc")
[node name="asteroid2" type="StaticBody2D" parent="."]
position = Vector2(1405, 413)
script = ExtResource("6_n4dsl")
[node name="Sprite2D" type="Sprite2D" parent="asteroid2"]
position = Vector2(1.00006, -3.99998)
scale = Vector2(1.2, 1.181)
texture = ExtResource("7_0tjls")
[node name="AsteroidCollisionPolygon2D" type="CollisionPolygon2D" parent="asteroid2"]
position = Vector2(-519, -164)
polygon = PackedVector2Array(548, 101, 613, 169, 597, 210, 548, 240, 462, 221, 431, 184, 434, 133, 497, 90)
[node name="AsteroidHealthLabel" type="Label" parent="asteroid2"]
offset_left = 105.0
offset_top = 38.0
offset_right = 181.0
offset_bottom = 80.0
[node name="SpawnAsteroidButton" type="Button" parent="."]
offset_left = 72.0
offset_top = 993.0
offset_right = 249.0
offset_bottom = 1049.0
text = "SPAWN ASTEROID"
script = ExtResource("9_21dg0")

View File

@ -24,7 +24,7 @@ window/size/viewport_height=1080
ui_fire={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}

20
reward_spawner.gd Normal file
View File

@ -0,0 +1,20 @@
class_name RewardSpawner
extends Node
var event_bus: EventBus
func _ready():
event_bus = get_node("/root/Main/MainEventBus")
event_bus.subscribe_to(get_node("/root/Main/DestroyedEventScope"), "DestroyedEvent", Callable(self, "on_destroyed"))
func on_destroyed(event: DestroyedEvent):
if event.object_type == "asteroid":
spawn_cheese(event.position)
func spawn_cheese(position: Vector2):
var cheese_scene = load("res://cheese.tscn")
var cheese_instance = cheese_scene.instantiate()
cheese_instance.global_position = position + Vector2(randf() * 50 - 25, randf() * 50 - 25)
get_parent().add_child(cheese_instance)

29
spawn_asteroid_button.gd Normal file
View File

@ -0,0 +1,29 @@
extends Button
@onready var main_script = get_node("/root/Main")
func _ready():
# Connect the "pressed" signal to a custom function in this script
self.pressed.connect(self.on_button_pressed)
# Handle what happens when the button is pressed
func on_button_pressed():
# Call the main script's spawn_asteroid function
main_script.spawn_asteroid()
# Disable the button temporarily to prevent immediate re-trigger
self.disabled = true
self.release_focus()
# Start a timer to re-enable the button after 0.2 seconds
var timer = Timer.new()
timer.wait_time = 0.2
timer.one_shot = true
timer.timeout.connect(self.on_timeout)
add_child(timer)
timer.start()
# Re-enable the button when the timer times out
func on_timeout():
self.disabled = false