Impl. enough for basic gameplay and has some particle effects.
const SPEED = 300.0
const JUMP_VELOCITY = -800.0
-const DEFAULT_COLOR = Color(0.7, 0.7, 0.7)
+const DEFAULT_COLOR = Color(0.7, 0.7, 0.85)
const HURT_COLOR = Color(1.0, 0.2, 0.2)
+const HURT_TIME = 0.5
+
+const MAX_PARTICLE_VELOCITY = 1500
+const MIN_PARTICLE_VELOCITY = 550
+
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
+var health = 5
+var hurt_timer = 0.0
+
+@onready var text_label = $RichTextLabel
+var text_timer = 0.0
+var text_format = "%.1f"
+
+@onready var health_label = $RichTextLabel2
+var health_text_format = "%d"
+
+@onready var self_sprite = $Sprite2D
+
+var particle = preload("res://circleParticle.tscn")
+
func _ready():
- modulate = DEFAULT_COLOR
+ self_sprite.self_modulate = DEFAULT_COLOR
+ health_label.add_text(health_text_format % health)
func _physics_process(delta):
+ if health <= 0:
+ return
+
+ text_timer += delta
+ text_label.clear()
+ text_label.add_text(text_format % text_timer)
+
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta
# Handle Jump.
- if Input.is_action_just_pressed("ui_accept") and is_on_floor():
+ if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
- var direction = Input.get_axis("ui_left", "ui_right")
+ var direction = Input.get_axis("left", "right")
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
+
+ hurt_timer -= delta
+ if hurt_timer < 0.0:
+ hurt_timer = 0.0
+ self_sprite.self_modulate = DEFAULT_COLOR
+
+func spawn_particle(color):
+ var particle_instance = particle.instantiate()
+ particle_instance.find_child("Sprite2D").self_modulate = color
+ var random_angle = randf_range(0.0, PI * 2.0)
+ particle_instance.position = self.position
+ var vel = randf_range(MIN_PARTICLE_VELOCITY, MAX_PARTICLE_VELOCITY)
+ particle_instance.linear_velocity = Vector2(cos(random_angle) * vel, sin(random_angle) * vel)
+ get_parent().add_child(particle_instance)
+
+func damaged(projectile):
+ var projectile_color = projectile.find_child("Sprite2D").self_modulate
+ for i in range(50):
+ spawn_particle(projectile_color)
+ if hurt_timer == 0.0:
+ health -= 1
+ health_label.clear()
+ health_label.add_text(health_text_format % health)
+ self_sprite.self_modulate = HURT_COLOR
+ hurt_timer = HURT_TIME
+ if health <= 0:
+ velocity = Vector2(0, 0)
+ collision_layer = 0
+ collision_mask = 0
+ self_sprite.self_modulate = Color(0, 0, 0, 0)
+ for i in range(100):
+ spawn_particle(Color(1, 1, 1))
+ get_parent().on_player_death()
--- /dev/null
+extends StaticBody2D
+
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ modulate = Color(0.7, 0.5, 0.2)
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ pass
extends Node2D
@onready var arenaBody = $StaticBody2D
+@onready var player = $CharacterBody2D
+var projectile = preload("res://circleProjectiles.tscn")
+
+const WAVE_TIME = 5.0
+const PROJECTILE_DISTANCE = 1500
+const PROJECTILE_VELOCITY = 500
+
+var wave_timer = 3.0
# Called when the node enters the scene tree for the first time.
func _ready():
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
+ if player.health <= 0:
+ return
if arenaBody.scale.x > 0.1:
arenaBody.scale -= arenaBody.scale * 0.01 * delta
+ wave_timer += delta
+ if wave_timer >= WAVE_TIME:
+ wave_timer = 0
+ for i in range(10):
+ var projectile_instance = projectile.instantiate()
+ var random_angle = randf_range(0.0, PI * 2.0)
+ var projectile_sprite = projectile_instance.find_child("Sprite2D")
+ projectile_instance.position = Vector2(cos(random_angle) * PROJECTILE_DISTANCE + player.position.x, sin(random_angle) * PROJECTILE_DISTANCE + player.position.y)
+ projectile_instance.linear_velocity = Vector2(-cos(random_angle) * PROJECTILE_VELOCITY, -sin(random_angle) * PROJECTILE_VELOCITY)
+ projectile_sprite.self_modulate = Color(randf_range(0.5, 1.0), randf_range(0.5, 1.0), randf_range(0.5, 1.0))
+ add_child(projectile_instance)
+
+func do_restart():
+ get_tree().reload_current_scene()
+
+func on_player_death():
+ var button = Button.new()
+ button.position = Vector2(0, -50)
+ button.add_theme_font_size_override("font_size", 40)
+ button.text = "Restart?"
+ button.pressed.connect(do_restart)
+ player.add_child(button)
-[gd_scene load_steps=9 format=3 uid="uid://dsb4cupghg5of"]
+[gd_scene load_steps=8 format=3 uid="uid://dsb4cupghg5of"]
[ext_resource type="Script" path="res://boxedSpace.gd" id="1_kaapg"]
-[ext_resource type="Script" path="res://PlayerCharacterBody2D.gd" id="1_l6wl1"]
+[ext_resource type="Script" path="res://boundary.gd" id="2_ifihl"]
+[ext_resource type="PackedScene" uid="uid://dv8hwks0xe3c0" path="res://player.tscn" id="3_b55g5"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_usx0l"]
size = Vector2(1353, 99)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_oer7k"]
size = Vector2(101, 850)
-[sub_resource type="RectangleShape2D" id="RectangleShape2D_yripi"]
-size = Vector2(40, 40)
-
-[sub_resource type="CanvasTexture" id="CanvasTexture_ruce8"]
-
[node name="Node2D" type="Node2D"]
script = ExtResource("1_kaapg")
[node name="StaticBody2D" type="StaticBody2D" parent="."]
+script = ExtResource("2_ifihl")
[node name="Polygon2D" type="Polygon2D" parent="StaticBody2D"]
position = Vector2(1, 0)
position = Vector2(1203.5, 322)
shape = SubResource("RectangleShape2D_oer7k")
-[node name="CharacterBody2D" type="CharacterBody2D" parent="."]
-position = Vector2(590, 561)
-script = ExtResource("1_l6wl1")
-
-[node name="CollisionShape2D" type="CollisionShape2D" parent="CharacterBody2D"]
-shape = SubResource("RectangleShape2D_yripi")
-debug_color = Color(0, 0.6, 0.701961, 0.419608)
-
-[node name="Sprite2D" type="Sprite2D" parent="CharacterBody2D"]
-scale = Vector2(40, 40)
-texture = SubResource("CanvasTexture_ruce8")
-
-[node name="Camera2D" type="Camera2D" parent="CharacterBody2D"]
+[node name="CharacterBody2D" parent="." instance=ExtResource("3_b55g5")]
--- /dev/null
+extends RigidBody2D
+
+const LIFETIME = 5
+
+var timer = 0.0
+
+@onready var sprite = $Sprite2D
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ pass # Replace with function body.
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ timer += delta
+ if timer >= LIFETIME:
+ get_parent().remove_child(self)
+ else:
+ sprite.self_modulate.a = 1.0 - timer / LIFETIME
--- /dev/null
+[gd_scene load_steps=3 format=3 uid="uid://b11lnbcljlqsm"]
+
+[ext_resource type="Texture2D" uid="uid://cx5ihekx61v8u" path="res://res/circle_64x64.png" id="1_h1v2k"]
+[ext_resource type="Script" path="res://circleParticle.gd" id="1_wpfda"]
+
+[node name="Particle" type="RigidBody2D"]
+collision_layer = 0
+collision_mask = 0
+gravity_scale = 0.0
+script = ExtResource("1_wpfda")
+
+[node name="Sprite2D" type="Sprite2D" parent="."]
+scale = Vector2(0.28, 0.28)
+texture = ExtResource("1_h1v2k")
--- /dev/null
+extends RigidBody2D
+
+const Player = preload("res://PlayerCharacterBody2D.gd")
+
+const LIFETIME = 18.0
+var timer = 0.0
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ set_contact_monitor(true)
+ set_max_contacts_reported(4)
+
+func on_collide():
+ pass
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ timer += delta
+ if timer >= LIFETIME:
+ get_parent().remove_child(self)
+ for collider in get_colliding_bodies():
+ if collider is Player:
+ collider.damaged(self)
+ get_parent().remove_child(self)
+ break
--- /dev/null
+[gd_scene load_steps=4 format=3 uid="uid://5sm3fvmwot2v"]
+
+[ext_resource type="Script" path="res://circleProjectile.gd" id="1_3n2hf"]
+[ext_resource type="Texture2D" uid="uid://cx5ihekx61v8u" path="res://res/circle_64x64.png" id="2_omdp0"]
+
+[sub_resource type="CircleShape2D" id="CircleShape2D_t1ey8"]
+
+[node name="RigidBody2D" type="RigidBody2D"]
+collision_layer = 4
+collision_mask = 2
+gravity_scale = 0.0
+script = ExtResource("1_3n2hf")
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
+scale = Vector2(2, 2)
+shape = SubResource("CircleShape2D_t1ey8")
+
+[node name="Sprite2D" type="Sprite2D" parent="CollisionShape2D"]
+position = Vector2(5.96046e-07, -5.36442e-07)
+scale = Vector2(0.3125, 0.3125)
+texture = ExtResource("2_omdp0")
--- /dev/null
+[gd_scene load_steps=4 format=3 uid="uid://dv8hwks0xe3c0"]
+
+[ext_resource type="Script" path="res://PlayerCharacterBody2D.gd" id="1_8l13s"]
+
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_yripi"]
+size = Vector2(40, 40)
+
+[sub_resource type="CanvasTexture" id="CanvasTexture_ruce8"]
+
+[node name="CharacterBody2D" type="CharacterBody2D"]
+position = Vector2(590, 561)
+collision_layer = 3
+script = ExtResource("1_8l13s")
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
+shape = SubResource("RectangleShape2D_yripi")
+debug_color = Color(0, 0.6, 0.701961, 0.419608)
+
+[node name="Sprite2D" type="Sprite2D" parent="."]
+scale = Vector2(40, 40)
+texture = SubResource("CanvasTexture_ruce8")
+
+[node name="Camera2D" type="Camera2D" parent="."]
+
+[node name="RichTextLabel" type="RichTextLabel" parent="."]
+offset_left = 35.0
+offset_top = 36.0
+offset_right = 151.0
+offset_bottom = 76.0
+
+[node name="RichTextLabel2" type="RichTextLabel" parent="."]
+offset_left = -61.0
+offset_top = -62.0
+offset_right = -21.0
+offset_bottom = -22.0
config/features=PackedStringArray("4.1", "GL Compatibility")
config/icon="res://icon.svg"
+[input]
+
+jump={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"echo":false,"script":null)
+]
+}
+left={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":0,"echo":false,"script":null)
+]
+}
+right={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":0,"echo":false,"script":null)
+]
+}
+
[rendering]
renderer/rendering_method="gl_compatibility"
--- /dev/null
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cx5ihekx61v8u"
+path="res://.godot/imported/circle_64x64.png-1390c1a53a03d404235162c57adf057c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://res/circle_64x64.png"
+dest_files=["res://.godot/imported/circle_64x64.png-1390c1a53a03d404235162c57adf057c.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1