From 7cb180c2458dc720972721865712a3120025fff7 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Sat, 30 Sep 2023 15:38:24 +0900 Subject: [PATCH] Work Impl. enough for basic gameplay and has some particle effects. --- PlayerCharacterBody2D.gd | 68 +++++++++++++++++++++++++++++++++--- boundary.gd | 11 ++++++ boxedSpace.gd | 32 +++++++++++++++++ boxedSpace.tscn | 25 +++---------- circleParticle.gd | 20 +++++++++++ circleParticle.tscn | 14 ++++++++ circleProjectile.gd | 25 +++++++++++++ circleProjectiles.tscn | 21 +++++++++++ player.tscn | 35 +++++++++++++++++++ project.godot | 22 ++++++++++++ res/circle_64x64.png | Bin 0 -> 1191 bytes res/circle_64x64.png.import | 34 ++++++++++++++++++ 12 files changed, 283 insertions(+), 24 deletions(-) create mode 100644 boundary.gd create mode 100644 circleParticle.gd create mode 100644 circleParticle.tscn create mode 100644 circleProjectile.gd create mode 100644 circleProjectiles.tscn create mode 100644 player.tscn create mode 100644 res/circle_64x64.png create mode 100644 res/circle_64x64.png.import diff --git a/PlayerCharacterBody2D.gd b/PlayerCharacterBody2D.gd index 16ca89f..f99d0be 100644 --- a/PlayerCharacterBody2D.gd +++ b/PlayerCharacterBody2D.gd @@ -4,30 +4,90 @@ extends CharacterBody2D 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() diff --git a/boundary.gd b/boundary.gd new file mode 100644 index 0000000..6cd77a1 --- /dev/null +++ b/boundary.gd @@ -0,0 +1,11 @@ +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 diff --git a/boxedSpace.gd b/boxedSpace.gd index 911828e..f743529 100644 --- a/boxedSpace.gd +++ b/boxedSpace.gd @@ -1,6 +1,14 @@ 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(): @@ -9,5 +17,29 @@ 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) diff --git a/boxedSpace.tscn b/boxedSpace.tscn index 598e14c..16cee41 100644 --- a/boxedSpace.tscn +++ b/boxedSpace.tscn @@ -1,7 +1,8 @@ -[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) @@ -15,15 +16,11 @@ size = Vector2(1355, 100) [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) @@ -46,16 +43,4 @@ shape = SubResource("RectangleShape2D_o01kj") 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")] diff --git a/circleParticle.gd b/circleParticle.gd new file mode 100644 index 0000000..ca45814 --- /dev/null +++ b/circleParticle.gd @@ -0,0 +1,20 @@ +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 diff --git a/circleParticle.tscn b/circleParticle.tscn new file mode 100644 index 0000000..0202828 --- /dev/null +++ b/circleParticle.tscn @@ -0,0 +1,14 @@ +[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") diff --git a/circleProjectile.gd b/circleProjectile.gd new file mode 100644 index 0000000..d96dfa2 --- /dev/null +++ b/circleProjectile.gd @@ -0,0 +1,25 @@ +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 diff --git a/circleProjectiles.tscn b/circleProjectiles.tscn new file mode 100644 index 0000000..6246598 --- /dev/null +++ b/circleProjectiles.tscn @@ -0,0 +1,21 @@ +[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") diff --git a/player.tscn b/player.tscn new file mode 100644 index 0000000..f9292ef --- /dev/null +++ b/player.tscn @@ -0,0 +1,35 @@ +[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 diff --git a/project.godot b/project.godot index 700cc84..c2e33e8 100644 --- a/project.godot +++ b/project.godot @@ -15,6 +15,28 @@ run/main_scene="res://boxedSpace.tscn" 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" diff --git a/res/circle_64x64.png b/res/circle_64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..38bc38cd6a1c9105b8c7a58f2eea290688633875 GIT binary patch literal 1191 zcmV;Y1X%ltP)EX>4Tx04R}tkv&MmKpe$i(~4Cp4t5X`$eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00MtWL_t(|+U=X6PaHuM#(!^I1qr6fHGzaWObJyeL6cX83LPT_Uow#*v(ixN!#wk2uN$}bKos`^BY(*vr#z$b{vQ&Y22AK1h(`kM_6$TMiA_0kbHEO7%+z&U|foZyw)K&;I0%1t1arFdl&i2Gz-83tlO zl2C9svMf z9Xwi+>aWW07z|e(AEVnSCxFd}>GN zkXTrh3s*@K|71X_rs`y5Kxa~g*t57UluQQrE|pCt_$`($nc%ZrzBC+sHcXU^@Yym` zGQn@tRLKaRZFA)Xl-tJ1k`aw;ops+lZ8M0B6>8i*{}&)-@kO~yry&3U002ovPDHLk FV1j{j95?^~ literal 0 HcmV?d00001 diff --git a/res/circle_64x64.png.import b/res/circle_64x64.png.import new file mode 100644 index 0000000..39e2799 --- /dev/null +++ b/res/circle_64x64.png.import @@ -0,0 +1,34 @@ +[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