diff options
60 files changed, 1660 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..b84b01d --- /dev/null +++ b/Readme.md @@ -0,0 +1,5 @@ +## TODO + +- Type change items +- Melon +- Berries diff --git a/SoundManager.tscn b/SoundManager.tscn new file mode 100644 index 0000000..8ccfe6f --- /dev/null +++ b/SoundManager.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=5 format=3 uid="uid://bn8cjxpontcbf"] + +[ext_resource type="AudioStream" uid="uid://c3pvnjmmcmyor" path="res://item/assets/item_pickup.ogg" id="1_kgewx"] +[ext_resource type="AudioStream" uid="uid://b7ijltkkhtl0" path="res://item/assets/sfx_-_success.ogg" id="2_silpf"] +[ext_resource type="AudioStream" uid="uid://dt7j663brwu3k" path="res://item/assets/hurt.ogg" id="3_ihrpf"] +[ext_resource type="AudioStream" uid="uid://1tatxmb1yho1" path="res://character/assets/boss_ko_2_speed_up.wav" id="4_fu3vr"] + +[node name="SoundManager" type="Node"] + +[node name="ItemPickUpShoe" type="AudioStreamPlayer" parent="."] +stream = ExtResource("1_kgewx") + +[node name="ItemPickUpCrown" type="AudioStreamPlayer" parent="."] +stream = ExtResource("2_silpf") + +[node name="OpponentHit" type="AudioStreamPlayer" parent="."] +stream = ExtResource("3_ihrpf") + +[node name="PlayerKO" type="AudioStreamPlayer" parent="."] +stream = ExtResource("4_fu3vr") diff --git a/character/assets/boss_ko_2.wav b/character/assets/boss_ko_2.wav Binary files differnew file mode 100644 index 0000000..0eed22b --- /dev/null +++ b/character/assets/boss_ko_2.wav diff --git a/character/assets/boss_ko_2.wav.import b/character/assets/boss_ko_2.wav.import new file mode 100644 index 0000000..d462c6a --- /dev/null +++ b/character/assets/boss_ko_2.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://c5fphxg1torik" +path="res://.godot/imported/boss_ko_2.wav-82c65adb3b984cb2964503f8b8f2e1a5.sample" + +[deps] + +source_file="res://character/assets/boss_ko_2.wav" +dest_files=["res://.godot/imported/boss_ko_2.wav-82c65adb3b984cb2964503f8b8f2e1a5.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=0 diff --git a/character/assets/boss_ko_2_speed_up.wav b/character/assets/boss_ko_2_speed_up.wav Binary files differnew file mode 100644 index 0000000..b1d9139 --- /dev/null +++ b/character/assets/boss_ko_2_speed_up.wav diff --git a/character/assets/boss_ko_2_speed_up.wav.import b/character/assets/boss_ko_2_speed_up.wav.import new file mode 100644 index 0000000..cc5b88a --- /dev/null +++ b/character/assets/boss_ko_2_speed_up.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://1tatxmb1yho1" +path="res://.godot/imported/boss_ko_2_speed_up.wav-755e37e7a7926935cf77cd90f2568d2d.sample" + +[deps] + +source_file="res://character/assets/boss_ko_2_speed_up.wav" +dest_files=["res://.godot/imported/boss_ko_2_speed_up.wav-755e37e7a7926935cf77cd90f2568d2d.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=0 diff --git a/character/assets/character_spritesheet.png b/character/assets/character_spritesheet.png Binary files differnew file mode 100644 index 0000000..9c1b844 --- /dev/null +++ b/character/assets/character_spritesheet.png diff --git a/character/assets/character_spritesheet.png.import b/character/assets/character_spritesheet.png.import new file mode 100644 index 0000000..3009953 --- /dev/null +++ b/character/assets/character_spritesheet.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d3cp58o1j55au" +path="res://.godot/imported/character_spritesheet.png-2d80c8875136c51fbbec17d53bbcb841.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://character/assets/character_spritesheet.png" +dest_files=["res://.godot/imported/character_spritesheet.png-2d80c8875136c51fbbec17d53bbcb841.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 diff --git a/character/assets/character_spritesheet.png~ b/character/assets/character_spritesheet.png~ Binary files differnew file mode 100644 index 0000000..2136c69 --- /dev/null +++ b/character/assets/character_spritesheet.png~ diff --git a/character/character.gd b/character/character.gd new file mode 100644 index 0000000..ef18bbc --- /dev/null +++ b/character/character.gd @@ -0,0 +1,223 @@ +class_name Character +extends Node2D + + +const BASE_SPEED := 50.0 +const VERTICAL_DISTANCE := 24 + +signal speed_changed +var speed_modifier := 1.0: + set(value): + speed_modifier = value + speed_changed.emit() + +enum Type { + Rock, + Paper, + Scissors, +} + +signal type_change_finished +signal type_changed +@export var current_type: Type = Type.Rock: + set(value): + current_type = value + type_changed.emit() + +enum Direction { + None, + Left, + Right, +} + +enum State { + Idle, + Walk, + Jump, + Fall, + Transform, +} + +var current_state: State = State.Idle + +var vertical_tween: Tween + +@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D + + +func _ready() -> void: + speed_changed.connect(func(): + $AnimatedSprite2D.speed_scale = speed_modifier + ) + + type_changed.connect(func(): + if current_state == State.Jump: + $AnimatedSprite2D.play("%s_jump" % get_type_name()) + elif current_state == State.Fall: + $AnimatedSprite2D.play("%s_fall" % get_type_name()) + ) + + +func get_type_name(type: Type = current_type): + match type: + Type.Rock: + return "rock" + Type.Paper: + return "paper" + Type.Scissors: + return "scissors" + + +func idle(): + current_state = State.Idle + + $AnimatedSprite2D.play("%s_idle" % get_type_name()) + + +func walk(direction: Direction): + current_state = State.Walk + + $AnimatedSprite2D.flip_h = direction == Direction.Left + $AnimatedSprite2D.play("%s_walk" % get_type_name()) + + if is_on_wall(direction): + return + + var direction_vector: Vector2 + match direction: + Direction.Left: + direction_vector = Vector2.LEFT + + Direction.Right: + direction_vector = Vector2.RIGHT + + position.x = lerp( + position.x, + position.x + (BASE_SPEED * speed_modifier * direction_vector.x), + get_process_delta_time() + ) + + +func jump(): + if is_below_ceiling(): + return + + current_state = State.Jump + + $AnimatedSprite2D.play("%s_jump" % get_type_name()) + + vertical_tween = get_tree().create_tween() + vertical_tween.tween_property( + self, + "position", + position - Vector2(0, VERTICAL_DISTANCE), + min(1.0 / speed_modifier, 1.0) + ) + + await vertical_tween.finished + + if not is_on_floor(): + fall() + else: + current_state = State.Idle + + +func fall(): + current_state = State.Fall + + $AnimatedSprite2D.play("%s_fall" % get_type_name()) + + vertical_tween = get_tree().create_tween() + vertical_tween.tween_property( + self, + "position", + position + Vector2(0, VERTICAL_DISTANCE), + min(1.0 / speed_modifier, 1.0) + ) + + await vertical_tween.finished + + if not is_on_floor(): + fall() + else: + current_state = State.Idle + + +func is_on_floor() -> bool: + $RayDownLeft.force_raycast_update() + $RayDownRight.force_raycast_update() + + return $RayDownLeft.is_colliding() or $RayDownRight.is_colliding() + + +func is_on_ledge() -> bool: + return true + pass + # TODO: add two more down Rays + # and up rays for is_below wall and is_below_ledge + # to fix falling through wall + # funktion im base-game aber auch gar nicht vorhanden:) + + +func is_on_bottom_floor() -> bool: + var stage: Stage = get_tree().current_scene + var map: TileMapLayer = get_tree().get_first_node_in_group("tilemap") + var bottom = position.y + (get_sprite_size().y / 2) + map.tile_set.tile_size.y + + return bottom >= stage.get_world_boundaries()[Vector2.DOWN] + + +func is_below_ceiling() -> bool: + return $RayUpLeft.is_colliding() or $RayUpRight.is_colliding() + + +func is_on_wall(direction: Direction) -> bool: + var stage: Stage = get_tree().current_scene + + match direction: + Direction.None: + return $RayLeft.is_colliding() or $RayRight.is_colliding() + + Direction.Left: + var left = position.x - (get_sprite_size().x / 2) + return $RayLeft.is_colliding() or left <= stage.get_world_boundaries()[Vector2.LEFT] + + Direction.Right: + var right = position.x + (get_sprite_size().x / 2) + return $RayRight.is_colliding() or right >= stage.get_world_boundaries()[Vector2.RIGHT] + + return false + + +func change_type_random(): + var types = Type.values() + types.erase(current_type) + + current_type = types.pick_random() + + +func animate_type_change(): + var previous_state := current_state + current_state = State.Transform + + var tween_was_running := false + if vertical_tween and vertical_tween.is_running(): + vertical_tween.pause() + tween_was_running = true + + $AnimatedSprite2D.play("transform") + await $AnimatedSprite2D.animation_finished + + current_state = previous_state + + type_change_finished.emit() + + if tween_was_running: + vertical_tween.play() + + +func get_sprite_size() -> Vector2: + var sprite_frames: SpriteFrames = $AnimatedSprite2D.sprite_frames + var texture := sprite_frames.get_frame_texture($AnimatedSprite2D.animation, $AnimatedSprite2D.frame) + + return texture.get_size() - Vector2(4, 0) diff --git a/character/character.tscn b/character/character.tscn new file mode 100644 index 0000000..3a1b0e8 --- /dev/null +++ b/character/character.tscn @@ -0,0 +1,52 @@ +[gd_scene load_steps=4 format=3 uid="uid://d21spw8y5yiuu"] + +[ext_resource type="Script" path="res://character/character.gd" id="1_wqxem"] +[ext_resource type="SpriteFrames" uid="uid://cvbw222po7psr" path="res://character/character_sprite_frames.tres" id="2_xbkcg"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_wfm33"] +size = Vector2(12, 12) + +[node name="Character" type="Node2D"] +script = ExtResource("1_wqxem") + +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] +texture_filter = 1 +position = Vector2(-10, -10) +sprite_frames = ExtResource("2_xbkcg") +animation = &"scissors_idle" +centered = false + +[node name="Collision" type="Area2D" parent="."] +collision_layer = 0 +collision_mask = 256 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Collision"] +shape = SubResource("RectangleShape2D_wfm33") + +[node name="RayLeft" type="RayCast2D" parent="."] +target_position = Vector2(-8, 0) +collision_mask = 256 + +[node name="RayRight" type="RayCast2D" parent="."] +target_position = Vector2(8, 0) +collision_mask = 256 + +[node name="RayUpLeft" type="RayCast2D" parent="."] +position = Vector2(-6, 0) +target_position = Vector2(0, -10) +collision_mask = 256 + +[node name="RayUpRight" type="RayCast2D" parent="."] +position = Vector2(6, 0) +target_position = Vector2(0, -10) +collision_mask = 256 + +[node name="RayDownLeft" type="RayCast2D" parent="."] +position = Vector2(-6, 0) +target_position = Vector2(0, 9) +collision_mask = 768 + +[node name="RayDownRight" type="RayCast2D" parent="."] +position = Vector2(6, 0) +target_position = Vector2(0, 9) +collision_mask = 768 diff --git a/character/character_sprite_frames.tres b/character/character_sprite_frames.tres new file mode 100644 index 0000000..6aa4352 --- /dev/null +++ b/character/character_sprite_frames.tres @@ -0,0 +1,265 @@ +[gd_resource type="SpriteFrames" load_steps=29 format=3 uid="uid://cvbw222po7psr"] + +[ext_resource type="Texture2D" uid="uid://d3cp58o1j55au" path="res://character/assets/character_spritesheet.png" id="1_0ukqc"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_q8pdk"] +atlas = ExtResource("1_0ukqc") +region = Rect2(0, 60, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_k21bg"] +atlas = ExtResource("1_0ukqc") +region = Rect2(20, 60, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_a33vs"] +atlas = ExtResource("1_0ukqc") +region = Rect2(40, 60, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ad1cw"] +atlas = ExtResource("1_0ukqc") +region = Rect2(100, 40, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_khl7x"] +atlas = ExtResource("1_0ukqc") +region = Rect2(0, 40, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_yqka7"] +atlas = ExtResource("1_0ukqc") +region = Rect2(20, 40, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_6o2jd"] +atlas = ExtResource("1_0ukqc") +region = Rect2(80, 40, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_fi3xw"] +atlas = ExtResource("1_0ukqc") +region = Rect2(40, 40, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8aswo"] +atlas = ExtResource("1_0ukqc") +region = Rect2(60, 40, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_0x2b7"] +atlas = ExtResource("1_0ukqc") +region = Rect2(100, 20, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_luqcw"] +atlas = ExtResource("1_0ukqc") +region = Rect2(0, 20, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_er4mc"] +atlas = ExtResource("1_0ukqc") +region = Rect2(20, 20, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_h68fd"] +atlas = ExtResource("1_0ukqc") +region = Rect2(80, 20, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_2uumw"] +atlas = ExtResource("1_0ukqc") +region = Rect2(40, 20, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_isrrp"] +atlas = ExtResource("1_0ukqc") +region = Rect2(60, 20, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_1xa27"] +atlas = ExtResource("1_0ukqc") +region = Rect2(100, 60, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qhn6i"] +atlas = ExtResource("1_0ukqc") +region = Rect2(0, 0, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_wsjy3"] +atlas = ExtResource("1_0ukqc") +region = Rect2(20, 0, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_g2iar"] +atlas = ExtResource("1_0ukqc") +region = Rect2(80, 0, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_btwgo"] +atlas = ExtResource("1_0ukqc") +region = Rect2(40, 0, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_g5iao"] +atlas = ExtResource("1_0ukqc") +region = Rect2(60, 0, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_i0gr8"] +atlas = ExtResource("1_0ukqc") +region = Rect2(120, 0, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_uf1gj"] +atlas = ExtResource("1_0ukqc") +region = Rect2(140, 0, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_06q0h"] +atlas = ExtResource("1_0ukqc") +region = Rect2(120, 20, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_k4wtj"] +atlas = ExtResource("1_0ukqc") +region = Rect2(140, 20, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_064a1"] +atlas = ExtResource("1_0ukqc") +region = Rect2(120, 40, 20, 20) + +[sub_resource type="AtlasTexture" id="AtlasTexture_komno"] +atlas = ExtResource("1_0ukqc") +region = Rect2(140, 40, 20, 20) + +[resource] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_q8pdk") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_k21bg") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_a33vs") +}], +"loop": false, +"name": &"ko", +"speed": 6.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_ad1cw") +}], +"loop": true, +"name": &"paper_fall", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_khl7x") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_yqka7") +}], +"loop": true, +"name": &"paper_idle", +"speed": 4.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_6o2jd") +}], +"loop": true, +"name": &"paper_jump", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_fi3xw") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8aswo") +}], +"loop": true, +"name": &"paper_walk", +"speed": 4.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_0x2b7") +}], +"loop": false, +"name": &"rock_fall", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_luqcw") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_er4mc") +}], +"loop": true, +"name": &"rock_idle", +"speed": 4.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_h68fd") +}], +"loop": false, +"name": &"rock_jump", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_2uumw") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_isrrp") +}], +"loop": true, +"name": &"rock_walk", +"speed": 4.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_1xa27") +}], +"loop": false, +"name": &"scissors_fall", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_qhn6i") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_wsjy3") +}], +"loop": true, +"name": &"scissors_idle", +"speed": 4.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_g2iar") +}], +"loop": false, +"name": &"scissors_jump", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_btwgo") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_g5iao") +}], +"loop": true, +"name": &"scissors_walk", +"speed": 4.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_i0gr8") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_uf1gj") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_06q0h") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_k4wtj") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_064a1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_komno") +}], +"loop": false, +"name": &"transform", +"speed": 4.0 +}] diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..9d8b7fa --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>
\ No newline at end of file diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..287fee7 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dwt6h37ll70f" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/item/assets/hurt.ogg b/item/assets/hurt.ogg Binary files differnew file mode 100644 index 0000000..f824056 --- /dev/null +++ b/item/assets/hurt.ogg diff --git a/item/assets/hurt.ogg.import b/item/assets/hurt.ogg.import new file mode 100644 index 0000000..e9875fc --- /dev/null +++ b/item/assets/hurt.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://dt7j663brwu3k" +path="res://.godot/imported/hurt.ogg-70ee6cc8b521e110664ed33e18f38ac7.oggvorbisstr" + +[deps] + +source_file="res://item/assets/hurt.ogg" +dest_files=["res://.godot/imported/hurt.ogg-70ee6cc8b521e110664ed33e18f38ac7.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/item/assets/item-crown.png b/item/assets/item-crown.png Binary files differnew file mode 100644 index 0000000..56efa7a --- /dev/null +++ b/item/assets/item-crown.png diff --git a/item/assets/item-crown.png.import b/item/assets/item-crown.png.import new file mode 100644 index 0000000..6f3c73c --- /dev/null +++ b/item/assets/item-crown.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://wp7r2fnlaty5" +path="res://.godot/imported/item-crown.png-ec868573b1dc0cd10108d94b8a454b1b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://item/assets/item-crown.png" +dest_files=["res://.godot/imported/item-crown.png-ec868573b1dc0cd10108d94b8a454b1b.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 diff --git a/item/assets/item-shoe.png b/item/assets/item-shoe.png Binary files differnew file mode 100644 index 0000000..fa2a6ae --- /dev/null +++ b/item/assets/item-shoe.png diff --git a/item/assets/item-shoe.png.import b/item/assets/item-shoe.png.import new file mode 100644 index 0000000..8f43447 --- /dev/null +++ b/item/assets/item-shoe.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d12cln2og1pon" +path="res://.godot/imported/item-shoe.png-e12e4c5ea27054908dc8103fd004bc0e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://item/assets/item-shoe.png" +dest_files=["res://.godot/imported/item-shoe.png-e12e4c5ea27054908dc8103fd004bc0e.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 diff --git a/item/assets/item_pickup.flac b/item/assets/item_pickup.flac Binary files differnew file mode 100644 index 0000000..7af81d8 --- /dev/null +++ b/item/assets/item_pickup.flac diff --git a/item/assets/item_pickup.ogg b/item/assets/item_pickup.ogg Binary files differnew file mode 100644 index 0000000..a3b7efa --- /dev/null +++ b/item/assets/item_pickup.ogg diff --git a/item/assets/item_pickup.ogg.import b/item/assets/item_pickup.ogg.import new file mode 100644 index 0000000..248be74 --- /dev/null +++ b/item/assets/item_pickup.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://c3pvnjmmcmyor" +path="res://.godot/imported/item_pickup.ogg-bbbc329c8dfb09e723abd2fbea1c1417.oggvorbisstr" + +[deps] + +source_file="res://item/assets/item_pickup.ogg" +dest_files=["res://.godot/imported/item_pickup.ogg-bbbc329c8dfb09e723abd2fbea1c1417.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/item/assets/sfx_-_success.ogg b/item/assets/sfx_-_success.ogg Binary files differnew file mode 100644 index 0000000..761468a --- /dev/null +++ b/item/assets/sfx_-_success.ogg diff --git a/item/assets/sfx_-_success.ogg.import b/item/assets/sfx_-_success.ogg.import new file mode 100644 index 0000000..aade728 --- /dev/null +++ b/item/assets/sfx_-_success.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://b7ijltkkhtl0" +path="res://.godot/imported/sfx_-_success.ogg-83f02af82e030026e9833067c3de9acd.oggvorbisstr" + +[deps] + +source_file="res://item/assets/sfx_-_success.ogg" +dest_files=["res://.godot/imported/sfx_-_success.ogg-83f02af82e030026e9833067c3de9acd.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/item/crown.gd b/item/crown.gd new file mode 100644 index 0000000..3ff1c84 --- /dev/null +++ b/item/crown.gd @@ -0,0 +1,7 @@ +extends Item + + +func apply(player: Player): + SoundManager.get_node("ItemPickUpCrown").play() + player.change_type_random() + queue_free() diff --git a/item/crown.tscn b/item/crown.tscn new file mode 100644 index 0000000..0d38cb9 --- /dev/null +++ b/item/crown.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=4 format=3 uid="uid://05jcjn7fw7iu"] + +[ext_resource type="PackedScene" uid="uid://36cam5oaj8p5" path="res://item/item.tscn" id="1_4htir"] +[ext_resource type="Script" path="res://item/crown.gd" id="2_74yne"] +[ext_resource type="Texture2D" uid="uid://wp7r2fnlaty5" path="res://item/assets/item-crown.png" id="3_ejtdy"] + +[node name="Crown" instance=ExtResource("1_4htir")] +script = ExtResource("2_74yne") + +[node name="Sprite2D" parent="." index="0"] +texture = ExtResource("3_ejtdy") diff --git a/item/item-crown.kra b/item/item-crown.kra Binary files differnew file mode 100644 index 0000000..d558a50 --- /dev/null +++ b/item/item-crown.kra diff --git a/item/item-shoe.kra b/item/item-shoe.kra Binary files differnew file mode 100644 index 0000000..ad5d1a5 --- /dev/null +++ b/item/item-shoe.kra diff --git a/item/item.gd b/item/item.gd new file mode 100644 index 0000000..4f99999 --- /dev/null +++ b/item/item.gd @@ -0,0 +1,6 @@ +class_name Item +extends Node2D + + +func apply(_player: Player): + pass diff --git a/item/item.tscn b/item/item.tscn new file mode 100644 index 0000000..ee13cda --- /dev/null +++ b/item/item.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=3 format=3 uid="uid://36cam5oaj8p5"] + +[ext_resource type="Script" path="res://item/item.gd" id="1_xhv56"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_23apt"] +size = Vector2(16, 16) + +[node name="Item" type="Node2D"] +script = ExtResource("1_xhv56") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture_filter = 1 +position = Vector2(-8, -8) +centered = false + +[node name="Area2D" type="Area2D" parent="." groups=["item"]] +visible = false +collision_layer = 16 +collision_mask = 0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +shape = SubResource("RectangleShape2D_23apt") diff --git a/item/item_pickup.flac b/item/item_pickup.flac Binary files differnew file mode 100644 index 0000000..7af81d8 --- /dev/null +++ b/item/item_pickup.flac diff --git a/item/shoe.gd b/item/shoe.gd new file mode 100644 index 0000000..821af95 --- /dev/null +++ b/item/shoe.gd @@ -0,0 +1,7 @@ +extends Item + + +func apply(player: Player): + SoundManager.get_node("ItemPickUpShoe").play() + player.speed_modifier = min(player.speed_modifier + 0.5, 2.0) + queue_free() diff --git a/item/shoe.tscn b/item/shoe.tscn new file mode 100644 index 0000000..c35facd --- /dev/null +++ b/item/shoe.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=4 format=3 uid="uid://bpl6aiic6muas"] + +[ext_resource type="PackedScene" uid="uid://36cam5oaj8p5" path="res://item/item.tscn" id="1_1i4gm"] +[ext_resource type="Script" path="res://item/shoe.gd" id="2_byls7"] +[ext_resource type="Texture2D" uid="uid://d12cln2og1pon" path="res://item/assets/item-shoe.png" id="3_n8grx"] + +[node name="Shoe" instance=ExtResource("1_1i4gm")] +script = ExtResource("2_byls7") + +[node name="Sprite2D" parent="." index="0"] +texture = ExtResource("3_n8grx") diff --git a/player/opponent.gd b/player/opponent.gd new file mode 100644 index 0000000..ec20cd1 --- /dev/null +++ b/player/opponent.gd @@ -0,0 +1,57 @@ +extends Character + + +var current_direction := Direction.Left + +@export var random_start_type := false + + +func _ready() -> void: + super._ready() + + var rng = RandomNumberGenerator.new() + rng.seed = ((get_tree().current_scene as Stage).scene_file_path as String).md5_buffer().decode_u64(0) + Time.get_ticks_msec() + + $AnimatedSprite2D.modulate = Color(max(0.1, rng.randf()), max(0.1, rng.randf()), max(0.1, rng.randf())) + + speed_modifier = 0.5 + + if random_start_type: + current_type = Type.values().pick_random() + + idle() + + +func _process(_delta: float) -> void: + if current_state == State.Idle or current_state == State.Walk: + walk(current_direction) + + if is_on_wall(current_direction): + change_direction() + + if not is_on_floor(): + fall() + + +func is_below_ledge() -> bool: + return $RayUpLeft2.is_colliding() or $RayUpRight2.is_colliding() + + +func change_direction(): + if current_direction == Direction.Left: + current_direction = Direction.Right + else: + current_direction = Direction.Left + + +func _on_vertical_timer_timeout() -> void: + if current_state == State.Idle or current_state == State.Walk: + if randi_range(0, 100) > 75: + change_direction() + + if randi_range(0, 100) > 75 and is_below_ledge(): + await jump() + elif randi_range(0, 100) > 75 and not is_on_bottom_floor(): + await fall() + + $VerticalTimer.start() diff --git a/player/opponent.tscn b/player/opponent.tscn new file mode 100644 index 0000000..92d0af6 --- /dev/null +++ b/player/opponent.tscn @@ -0,0 +1,27 @@ +[gd_scene load_steps=3 format=3 uid="uid://d1h8psjxqge0a"] + +[ext_resource type="PackedScene" uid="uid://d21spw8y5yiuu" path="res://character/character.tscn" id="1_ykya6"] +[ext_resource type="Script" path="res://player/opponent.gd" id="2_pkqiw"] + +[node name="Opponent" instance=ExtResource("1_ykya6")] +script = ExtResource("2_pkqiw") +random_start_type = false + +[node name="Collision" parent="." index="1" groups=["opponent"]] +collision_layer = 2 + +[node name="RayUpLeft2" type="RayCast2D" parent="." index="6"] +position = Vector2(-6, 0) +target_position = Vector2(0, -10) +collision_mask = 512 + +[node name="RayUpRight2" type="RayCast2D" parent="." index="7"] +position = Vector2(6, 0) +target_position = Vector2(0, -10) +collision_mask = 512 + +[node name="VerticalTimer" type="Timer" parent="." index="10"] +one_shot = true +autostart = true + +[connection signal="timeout" from="VerticalTimer" to="." method="_on_vertical_timer_timeout"] diff --git a/player/player.gd b/player/player.gd new file mode 100644 index 0000000..4257f2a --- /dev/null +++ b/player/player.gd @@ -0,0 +1,148 @@ +class_name Player +extends Character + + +var is_invincible := false + +@onready var camera := $Camera2D + + +func _ready() -> void: + super._ready() + + $AnimatedSprite2D.modulate = Color(max(0.1, randf()), max(0.1, randf()), max(0.1, randf())) + + +func _process(_delta: float) -> void: + if current_state == State.Idle: + if Input.is_action_pressed("ui_left"): + walk(Direction.Left) + elif Input.is_action_pressed("ui_right"): + walk(Direction.Right) + else: + idle() + + if Input.is_action_pressed("ui_up"): + jump() + if Input.is_action_pressed("ui_down"): + if not is_on_bottom_floor(): + fall() + + if not is_on_floor(): + fall() + + + elif current_state == State.Walk: + if Input.is_action_pressed("ui_left"): + walk(Direction.Left) + elif Input.is_action_pressed("ui_right"): + walk(Direction.Right) + else: + idle() + + if Input.is_action_pressed("ui_up"): + jump() + if Input.is_action_pressed("ui_down"): + if not is_on_bottom_floor(): + fall() + + if not is_on_floor(): + fall() + + + if Input.is_action_just_pressed("ui_accept"): + change_type_random() + + +func invincible(duration: float): + is_invincible = true + + var tween := get_tree().create_tween().set_loops(int(duration / 0.5)) + tween.tween_property($AnimatedSprite2D, "self_modulate", Color(1.0, 1.0, 1.0, 0.25), 0.25) + tween.tween_property($AnimatedSprite2D, "self_modulate", Color(1.0, 1.0, 1.0, 1.0), 0.25) + + await tween.finished + is_invincible = false + + +enum Result { + Draw, + Win, + Lose, +} + +static func is_rock_paper_scissors_win(player: Character, opponent: Character) -> Result: + if player.current_type == Type.Rock and opponent.current_type == Type.Scissors: + return Result.Win + elif player.current_type == Type.Paper and opponent.current_type == Type.Rock: + return Result.Win + elif player.current_type == Type.Scissors and opponent.current_type == Type.Paper: + return Result.Win + elif player.current_type == Type.Rock and opponent.current_type == Type.Paper: + return Result.Lose + elif player.current_type == Type.Paper and opponent.current_type == Type.Scissors: + return Result.Lose + elif player.current_type == Type.Rock and opponent.current_type == Type.Paper: + return Result.Lose + elif player.current_type == Type.Scissors and opponent.current_type == Type.Rock: + return Result.Lose + else: + return Result.Draw + + +func _on_collision_area_entered(area: Area2D) -> void: + if area.is_in_group("item"): + var item: Item = area.get_parent() + item.apply(self) + + elif area.is_in_group("opponent"): + if is_invincible or current_state == State.Transform: + return + + var opponent: Character = area.get_parent() + var result := Player.is_rock_paper_scissors_win(self, opponent) + if result == Result.Draw: + type_change_finished.connect(func(): + change_type_random() + ) + animate_type_change() + + elif result == Result.Win: + (get_tree().get_first_node_in_group("hud") as HUD).score += 1 + + SoundManager.get_node("OpponentHit").play() + + type_change_finished.connect(func(): + change_type_random() + invincible(1.0) + ) + animate_type_change() + + opponent.process_mode = Node.PROCESS_MODE_DISABLED + var tween = get_tree().create_tween() + tween.tween_property( + opponent, + "position", + position + (opponent.position - position) * 10, + 0.5 + ) + await tween.finished + + opponent.queue_free() + + await get_tree().process_frame + if (get_tree().current_scene as Stage).has_win_condition(): + await get_tree().create_timer(2.0).timeout + get_tree().change_scene_to_file("res://stage/stage_01.tscn") + + elif result == Result.Lose: + (func(): $Collision.process_mode = Node.PROCESS_MODE_DISABLED).call_deferred() + set_process(false) + if vertical_tween: vertical_tween.stop() + + SoundManager.get_node("PlayerKO").play() + $AnimatedSprite2D.play("ko") + await $AnimatedSprite2D.animation_finished + SoundManager.get_node("PlayerKO").stop() + visible = false + get_tree().change_scene_to_file("res://stage/stage_01.tscn") diff --git a/player/player.tscn b/player/player.tscn new file mode 100644 index 0000000..b213030 --- /dev/null +++ b/player/player.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=5 format=4 uid="uid://b4t3ipnq8vq2p"] + +[ext_resource type="PackedScene" uid="uid://d21spw8y5yiuu" path="res://character/character.tscn" id="1_eixx6"] +[ext_resource type="Script" path="res://player/player.gd" id="1_wqxem"] +[ext_resource type="AudioStream" uid="uid://c3pvnjmmcmyor" path="res://item/assets/item_pickup.ogg" id="3_o0r1j"] + +[sub_resource type="AudioStreamMP3" id="AudioStreamMP3_sy3f5"] +data = PackedByteArray("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") + +[node name="Player" instance=ExtResource("1_eixx6")] +script = ExtResource("1_wqxem") + +[node name="Collision" parent="." index="1"] +collision_layer = 1 +collision_mask = 18 + +[node name="Camera2D" type="Camera2D" parent="." index="2"] + +[node name="ShoeItemPickUp" type="AudioStreamPlayer" parent="." index="9"] +stream = ExtResource("3_o0r1j") + +[node name="CrownItemPickUp" type="AudioStreamPlayer" parent="." index="10"] +stream = SubResource("AudioStreamMP3_sy3f5") + +[connection signal="area_entered" from="Collision" to="." method="_on_collision_area_entered"] diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..3001e57 --- /dev/null +++ b/project.godot @@ -0,0 +1,50 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Magical Tower" +run/main_scene="res://ui/start_screen.tscn" +config/features=PackedStringArray("4.3", "GL Compatibility") +config/icon="res://icon.svg" + +[autoload] + +SoundManager="*res://SoundManager.tscn" + +[debug] + +gdscript/warnings/integer_division=0 + +[display] + +window/size/viewport_width=160 +window/size/viewport_height=144 +window/stretch/mode="viewport" + +[global_group] + +item="" +tilemap="" +opponent="" +hud="" + +[layer_names] + +2d_physics/layer_1="Player" +2d_physics/layer_2="Opponent" +2d_physics/layer_5="Item" +2d_physics/layer_9="Wall" +2d_physics/layer_10="Ledge" + +[rendering] + +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility" diff --git a/stage/assets/tileset-01.png b/stage/assets/tileset-01.png Binary files differnew file mode 100644 index 0000000..f2006f8 --- /dev/null +++ b/stage/assets/tileset-01.png diff --git a/stage/assets/tileset-01.png.import b/stage/assets/tileset-01.png.import new file mode 100644 index 0000000..8429b38 --- /dev/null +++ b/stage/assets/tileset-01.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://4sbg8fnguw48" +path="res://.godot/imported/tileset-01.png-85eb1066afb12100d0b0c110ba758473.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://stage/assets/tileset-01.png" +dest_files=["res://.godot/imported/tileset-01.png-85eb1066afb12100d0b0c110ba758473.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 diff --git a/stage/stage.gd b/stage/stage.gd new file mode 100644 index 0000000..8d72ee1 --- /dev/null +++ b/stage/stage.gd @@ -0,0 +1,15 @@ +class_name Stage +extends Node2D + + +func get_world_boundaries() -> Dictionary: #Dictionary[Vector2, float] + return { + Vector2.LEFT: 0.0, + Vector2.RIGHT: 0.0, + Vector2.UP: 0.0, + Vector2.DOWN: 0.0, + } + + +func has_win_condition() -> bool: + return false diff --git a/stage/stage.tscn b/stage/stage.tscn new file mode 100644 index 0000000..9c8e256 --- /dev/null +++ b/stage/stage.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=3 format=3 uid="uid://ivf0v2snsls5"] + +[ext_resource type="Script" path="res://stage/stage.gd" id="1_8ax4l"] +[ext_resource type="PackedScene" uid="uid://ciyxysx3rwjhf" path="res://ui/hud.tscn" id="5_gnx55"] + +[node name="Stage" type="Node2D"] +script = ExtResource("1_8ax4l") + +[node name="ColorRect" type="ColorRect" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_right = 256.0 +offset_bottom = 144.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.419608, 0.65098, 0.290196, 1) + +[node name="Opponents" type="Node2D" parent="."] +unique_name_in_owner = true + +[node name="HUD" parent="." instance=ExtResource("5_gnx55")] + +[node name="TickTimer" type="Timer" parent="."] +wait_time = 2.0 +autostart = true + +[connection signal="timeout" from="TickTimer" to="." method="_on_tick_timer_timeout"] diff --git a/stage/stage_01.gd b/stage/stage_01.gd new file mode 100644 index 0000000..01cc558 --- /dev/null +++ b/stage/stage_01.gd @@ -0,0 +1,103 @@ +extends Stage + + +var item_pool: Array = [] +var reserved_item_positions: Array = [] + + +func _ready() -> void: + $Player.camera.limit_left = get_world_boundaries()[Vector2.LEFT] + $Player.camera.limit_right = get_world_boundaries()[Vector2.RIGHT] + $Player.camera.limit_top = get_world_boundaries()[Vector2.UP] + $Player.camera.limit_bottom = get_world_boundaries()[Vector2.DOWN] + + $TileMapLayer.modulate = Color(max(0.1, randf()), max(0.1, randf()), max(0.1, randf())) + + +func get_world_boundaries() -> Dictionary: + return { + Vector2.LEFT: $TileMapLayer.get_used_rect().position.x * $TileMapLayer.tile_set.tile_size.x, + Vector2.RIGHT: $TileMapLayer.get_used_rect().end.x * $TileMapLayer.tile_set.tile_size.x, + Vector2.UP: $TileMapLayer.get_used_rect().position.y * $TileMapLayer.tile_set.tile_size.y - $HUD.size.y, + Vector2.DOWN: $TileMapLayer.get_used_rect().end.y * $TileMapLayer.tile_set.tile_size.y, + } + + +func has_win_condition() -> bool: + return %Opponents.get_child_count() == 0 + + +func _on_tick_timer_timeout() -> void: + if randf() > 0.8 and item_pool.size() < 3: + var item_scene: PackedScene = [ + preload("res://item/shoe.tscn"), + preload("res://item/crown.tscn"), + ].pick_random() + + var item: Item = item_scene.instantiate() + var map: TileMapLayer = get_tree().get_first_node_in_group("tilemap") + + var size_x := map.get_used_rect().position.x + map.get_used_rect().size.x + var size_y := map.get_used_rect().position.y + map.get_used_rect().size.y + + var start_x: int = max(map.get_used_rect().position.x, range(size_x / 2).pick_random()) + var start_y: int = max(map.get_used_rect().position.y, range(size_y / 2).pick_random()) + + var get_map_position = func() -> Vector2i: + for x in range(start_x, size_x): + for y in range(start_y, size_y): + var data = map.get_cell_tile_data(Vector2(x, y)) + if not data: + return Vector2i(x, y) + return Vector2i.ZERO + + var map_position = get_map_position.call() + + #print(map_position) + if reserved_item_positions.has(map_position): + return + + var local_position = map.map_to_local(map_position) + + var _was_shifted := false + var collide_top = map.get_cell_tile_data(map.get_neighbor_cell(map_position, TileSet.CELL_NEIGHBOR_TOP_SIDE)) + var collide_bottom = map.get_cell_tile_data(map.get_neighbor_cell(map_position, TileSet.CELL_NEIGHBOR_BOTTOM_SIDE)) + var collide_right = map.get_cell_tile_data(map.get_neighbor_cell(map_position, TileSet.CELL_NEIGHBOR_RIGHT_SIDE)) + if collide_top: + local_position += Vector2(0, map.tile_set.tile_size.y / 2) + _was_shifted = true + if collide_bottom: + local_position += Vector2(0, -map.tile_set.tile_size.y / 2) + _was_shifted = true + if collide_right: + local_position += Vector2(-map.tile_set.tile_size.x, 0) + _was_shifted = true + if not collide_top and not collide_right: + if map.get_cell_tile_data(map.get_neighbor_cell(map_position, TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER)): + local_position += Vector2(-map.tile_set.tile_size.x, map.tile_set.tile_size.y / 2) + _was_shifted = true + + #if not was_shifted: + local_position += Vector2(map.tile_set.tile_size.x / 2, 0) + + item.position = local_position + add_child(item) + + var get_reserved_positions = func() -> Array[Vector2i]: + var rp := [] as Array[Vector2i] + for x in range(0, 3): + for y in range(0, 3): + rp.append(Vector2i(x, y)) + rp.append(Vector2i(-x, y)) + rp.append(Vector2i(x, -y)) + rp.append(Vector2i(-x, -y)) + return rp + + item.tree_exiting.connect(func(): + item_pool.erase(item) + for v in get_reserved_positions.call(): + reserved_item_positions.erase(map_position + v) + ) + item_pool.append(item) + for v in get_reserved_positions.call(): + reserved_item_positions.append(map_position + v) diff --git a/stage/stage_01.tscn b/stage/stage_01.tscn new file mode 100644 index 0000000..6b0d67c --- /dev/null +++ b/stage/stage_01.tscn @@ -0,0 +1,29 @@ +[gd_scene load_steps=6 format=4 uid="uid://yb0no7vyekil"] + +[ext_resource type="Script" path="res://stage/stage_01.gd" id="1_2ycoy"] +[ext_resource type="PackedScene" uid="uid://dfioemvleakyt" path="res://stage/tile_map_layer.tscn" id="1_4iotk"] +[ext_resource type="PackedScene" uid="uid://ivf0v2snsls5" path="res://stage/stage.tscn" id="1_uanw1"] +[ext_resource type="PackedScene" uid="uid://b4t3ipnq8vq2p" path="res://player/player.tscn" id="2_34lp1"] +[ext_resource type="PackedScene" uid="uid://d1h8psjxqge0a" path="res://player/opponent.tscn" id="4_h35rr"] + +[node name="Stage01" instance=ExtResource("1_uanw1")] +script = ExtResource("1_2ycoy") + +[node name="TileMapLayer" parent="." index="1" groups=["tilemap"] instance=ExtResource("1_4iotk")] +tile_map_data = PackedByteArray("AAAIAAIAAAADAAAAAAAIAAMAAAAAAAAAAAAJAAIAAAAEAAAAAAAJAAMAAAACAAAAAAAKAAsAAAAAAAAAAAAKAAwAAAAAAAEAAAALAAsAAAACAAAAAAALAAwAAAACAAEAAAASAAgAAAAAAAAAAAASAAkAAAAAAAEAAAASAAoAAAAAAAEAAAASAAsAAAAAAAEAAAASAAwAAAAAAAEAAAATAAgAAAACAAAAAAATAAkAAAACAAEAAAATAAoAAAACAAEAAAATAAsAAAACAAEAAAATAAwAAAACAAEAAAAAAAIAAAADAAAAAAAAAAUAAAADAAEAAAAAAAgAAAADAAEAAAAAAAsAAAADAAEAAAAAAA4AAAADAAEAAAAAABEAAAADAAAAAAABAAIAAAAEAAAAAAABAAUAAAADAAEAAAABAAgAAAADAAEAAAABAAsAAAADAAEAAAABAA4AAAADAAEAAAABABEAAAAEAAAAAAACAAIAAAADAAAAAAACAAUAAAADAAEAAAACAAgAAAADAAEAAAACAAsAAAADAAEAAAACAA4AAAADAAEAAAACABEAAAADAAAAAAADAAIAAAAEAAAAAAADAAUAAAADAAEAAAADAAgAAAADAAEAAAADAAsAAAADAAEAAAADAA4AAAADAAEAAAADABEAAAAEAAAAAAAEAAIAAAADAAAAAAAEAAUAAAADAAEAAAAEAAgAAAADAAEAAAAEAAsAAAADAAEAAAAEABEAAAADAAAAAAAFAAIAAAAEAAAAAAAFAAUAAAADAAEAAAAFAAgAAAADAAEAAAAFAAsAAAADAAEAAAAFABEAAAAEAAAAAAAGAAIAAAADAAAAAAAGAAgAAAADAAEAAAAGAAsAAAADAAEAAAAGAA4AAAADAAEAAAAGABEAAAADAAAAAAAHAAIAAAAEAAAAAAAHAAgAAAADAAEAAAAHAAsAAAADAAEAAAAHAA4AAAADAAEAAAAHABEAAAAEAAAAAAAIAAQAAAAAAAEAAAAIAAUAAAAAAAIAAAAIAAsAAAADAAEAAAAIAA4AAAADAAEAAAAIABEAAAADAAAAAAAJAAQAAAACAAEAAAAJAAUAAAACAAIAAAAJAAsAAAADAAEAAAAJAA4AAAADAAEAAAAJABEAAAAEAAAAAAAKAAIAAAADAAAAAAAKAAgAAAADAAEAAAAKAA0AAAAAAAEAAAAKAA4AAAAAAAIAAAAKABEAAAADAAAAAAALAAIAAAAEAAAAAAALAAgAAAADAAEAAAALAA0AAAACAAEAAAALAA4AAAACAAIAAAALABEAAAAEAAAAAAAMAAIAAAADAAAAAAAMAAUAAAADAAEAAAAMAAgAAAADAAEAAAAMAA4AAAADAAEAAAAMABEAAAADAAAAAAANAAIAAAAEAAAAAAANAAUAAAADAAEAAAANAAgAAAADAAEAAAANAA4AAAADAAEAAAANABEAAAAEAAAAAAAOAAIAAAADAAAAAAAOAAUAAAADAAEAAAAOAAgAAAADAAEAAAAOAAsAAAADAAEAAAAOAA4AAAADAAEAAAAOABEAAAADAAAAAAAPAAIAAAAEAAAAAAAPAAUAAAADAAEAAAAPAAgAAAADAAEAAAAPAAsAAAADAAEAAAAPAA4AAAADAAEAAAAPABEAAAAEAAAAAAAQAAIAAAADAAAAAAAQAAUAAAADAAEAAAAQAAgAAAADAAEAAAAQAAsAAAADAAEAAAAQABEAAAADAAAAAAARAAIAAAAEAAAAAAARAAUAAAADAAEAAAARAAgAAAADAAEAAAARAAsAAAADAAEAAAARABEAAAAEAAAAAAASAAIAAAADAAAAAAASAAUAAAADAAEAAAASAA0AAAAAAAEAAAASAA4AAAAAAAIAAAASABEAAAADAAAAAAATAAIAAAAEAAAAAAATAAUAAAADAAEAAAATAA0AAAACAAEAAAATAA4AAAACAAIAAAATABEAAAAEAAAAAAAUAAIAAAADAAAAAAAUAAUAAAADAAEAAAAUAAgAAAADAAEAAAAUABEAAAADAAAAAAAVAAIAAAAEAAAAAAAVAAUAAAADAAEAAAAVAAgAAAADAAEAAAAVABEAAAAEAAAAAAAWAAIAAAADAAAAAAAWAAUAAAADAAEAAAAWAAgAAAADAAEAAAAWABEAAAADAAAAAAAXAAIAAAAEAAAAAAAXAAUAAAADAAEAAAAXAAgAAAADAAEAAAAXABEAAAAEAAAAAAAYAAIAAAADAAAAAAAYABEAAAADAAAAAAAZAAIAAAAEAAAAAAAZABEAAAAEAAAAAAAaAAIAAAADAAAAAAAaABEAAAADAAAAAAAbAAIAAAAEAAAAAAAbABEAAAAEAAAAAAAcAAIAAAADAAAAAAAcABEAAAADAAAAAAAdAAIAAAAEAAAAAAAdABEAAAAEAAAAAAAeAAIAAAADAAAAAAAeABEAAAADAAAAAAAfAAIAAAAEAAAAAAAfABEAAAAEAAAAAAAWAA4AAAADAAEAAAAXAA4AAAADAAEAAAAYAA4AAAADAAEAAAAZAA4AAAADAAEAAAAaAA4AAAADAAEAAAAUAAsAAAADAAEAAAAVAAsAAAADAAEAAAAYAAsAAAADAAEAAAAZAAsAAAADAAEAAAAaAAsAAAADAAEAAAAaAAgAAAADAAEAAAAbAAgAAAADAAEAAAAcAAgAAAADAAEAAAAdAAgAAAADAAEAAAAeAAgAAAADAAEAAAAfAAgAAAADAAEAAAAYAAUAAAADAAEAAAAZAAUAAAADAAEAAAAcAAUAAAADAAEAAAAdAAUAAAADAAEAAAAfAAUAAAADAAEAAAAeAAUAAAADAAEAAAAcAAsAAAAAAAAAAAAcAAwAAAAAAAEAAAAcAA0AAAAAAAEAAAAcAA4AAAAAAAIAAAAdAAsAAAACAAAAAAAdAAwAAAACAAEAAAAdAA0AAAACAAEAAAAdAA4AAAACAAIAAAAbAAsAAAADAAEAAAAbAA4AAAADAAEAAAAeAAsAAAADAAEAAAAfAAsAAAADAAEAAAAeAA4AAAADAAEAAAAfAA4AAAADAAEAAAA=") + +[node name="Opponent" parent="Opponents" index="0" instance=ExtResource("4_h35rr")] +position = Vector2(105, 128) +current_type = null + +[node name="Opponent2" parent="Opponents" index="1" instance=ExtResource("4_h35rr")] +position = Vector2(52, 80) +current_type = 1 + +[node name="Opponent3" parent="Opponents" index="2" instance=ExtResource("4_h35rr")] +position = Vector2(120, 80) +current_type = 2 + +[node name="Player" parent="." index="3" instance=ExtResource("2_34lp1")] +position = Vector2(16, 128) +current_type = 2 diff --git a/stage/tile_map_layer.tscn b/stage/tile_map_layer.tscn new file mode 100644 index 0000000..6fd9df1 --- /dev/null +++ b/stage/tile_map_layer.tscn @@ -0,0 +1,44 @@ +[gd_scene load_steps=4 format=3 uid="uid://dfioemvleakyt"] + +[ext_resource type="Texture2D" uid="uid://4sbg8fnguw48" path="res://stage/assets/tileset-01.png" id="1_kgkhx"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_kmxxx"] +texture = ExtResource("1_kgkhx") +separation = Vector2i(1, 1) +texture_region_size = Vector2i(8, 8) +0:0/0 = 0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, -4, 4, 4, 4, 4, -4) +1:0/0 = 0 +1:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, -4, 4, 4, 4, 4, -4) +2:0/0 = 0 +2:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, -4, 4, 4, 4, 4, -4) +0:1/0 = 0 +0:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, -4, 4, 4, 4, 4, -4) +1:1/0 = 0 +1:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, -4, 4, 4, 4, 4, -4) +2:1/0 = 0 +2:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, -4, 4, 4, 4, 4, -4) +0:2/0 = 0 +0:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, -4, 4, 4, 4, 4, -4) +1:2/0 = 0 +1:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, -4, 4, 4, 4, 4, -4) +2:2/0 = 0 +2:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, -4, 4, 4, 4, 4, -4) +3:0/0 = 0 +3:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, 4, -4, 4, 4, -4, 4) +4:0/0 = 0 +4:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-4, -4, 4, -4, 4, 4, -4, 4) +3:1/0 = 0 +3:1/0/physics_layer_1/polygon_0/points = PackedVector2Array(-4, -4, -4, 4, 4, 4, 4, -4) + +[sub_resource type="TileSet" id="TileSet_277cy"] +tile_size = Vector2i(8, 8) +physics_layer_0/collision_layer = 256 +physics_layer_0/collision_mask = 256 +physics_layer_1/collision_layer = 512 +physics_layer_1/collision_mask = 0 +sources/0 = SubResource("TileSetAtlasSource_kmxxx") + +[node name="TileMapLayer" type="TileMapLayer"] +texture_filter = 1 +tile_set = SubResource("TileSet_277cy") diff --git a/stage/tileset-01.kra b/stage/tileset-01.kra Binary files differnew file mode 100644 index 0000000..68a3bf4 --- /dev/null +++ b/stage/tileset-01.kra diff --git a/ui/assets/Minimal3x5.ttf b/ui/assets/Minimal3x5.ttf Binary files differnew file mode 100644 index 0000000..3024b74 --- /dev/null +++ b/ui/assets/Minimal3x5.ttf diff --git a/ui/assets/Minimal3x5.ttf.import b/ui/assets/Minimal3x5.ttf.import new file mode 100644 index 0000000..17c2eab --- /dev/null +++ b/ui/assets/Minimal3x5.ttf.import @@ -0,0 +1,34 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://16usq1tjtauh" +path="res://.godot/imported/Minimal3x5.ttf-68b9a4ba08b6cadb0cd3e189612c985e.fontdata" + +[deps] + +source_file="res://ui/assets/Minimal3x5.ttf" +dest_files=["res://.godot/imported/Minimal3x5.ttf-68b9a4ba08b6cadb0cd3e189612c985e.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/ui/assets/Minimal5x5Monospaced.ttf b/ui/assets/Minimal5x5Monospaced.ttf Binary files differnew file mode 100644 index 0000000..8ef9fa1 --- /dev/null +++ b/ui/assets/Minimal5x5Monospaced.ttf diff --git a/ui/assets/Minimal5x5Monospaced.ttf.import b/ui/assets/Minimal5x5Monospaced.ttf.import new file mode 100644 index 0000000..294e8fd --- /dev/null +++ b/ui/assets/Minimal5x5Monospaced.ttf.import @@ -0,0 +1,34 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://2hbnsvgx1y4u" +path="res://.godot/imported/Minimal5x5Monospaced.ttf-fd9125b575442d5a0ab82dd016487ac3.fontdata" + +[deps] + +source_file="res://ui/assets/Minimal5x5Monospaced.ttf" +dest_files=["res://.godot/imported/Minimal5x5Monospaced.ttf-fd9125b575442d5a0ab82dd016487ac3.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/ui/assets/Minimal5x7.ttf b/ui/assets/Minimal5x7.ttf Binary files differnew file mode 100644 index 0000000..7372987 --- /dev/null +++ b/ui/assets/Minimal5x7.ttf diff --git a/ui/assets/Minimal5x7.ttf.import b/ui/assets/Minimal5x7.ttf.import new file mode 100644 index 0000000..dad8bcf --- /dev/null +++ b/ui/assets/Minimal5x7.ttf.import @@ -0,0 +1,34 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://c5se3wxtkeley" +path="res://.godot/imported/Minimal5x7.ttf-a34c0ec56184d93c2e894a2cb938e1c0.fontdata" + +[deps] + +source_file="res://ui/assets/Minimal5x7.ttf" +dest_files=["res://.godot/imported/Minimal5x7.ttf-a34c0ec56184d93c2e894a2cb938e1c0.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/ui/hud.gd b/ui/hud.gd new file mode 100644 index 0000000..49c5d34 --- /dev/null +++ b/ui/hud.gd @@ -0,0 +1,13 @@ +class_name HUD +extends CanvasLayer + + +var size: Vector2: + get(): + return get_child(0).size + + +var score: int: + set(value): + score = value + %Score.text = str(score) diff --git a/ui/hud.tscn b/ui/hud.tscn new file mode 100644 index 0000000..340d7a2 --- /dev/null +++ b/ui/hud.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=3 format=3 uid="uid://ciyxysx3rwjhf"] + +[ext_resource type="Script" path="res://ui/hud.gd" id="1_c8cqk"] +[ext_resource type="Theme" uid="uid://b067xhqktnmhr" path="res://ui/theme.tres" id="1_it884"] + +[node name="HUD" type="CanvasLayer" groups=["hud"]] +script = ExtResource("1_c8cqk") + +[node name="MarginContainer" type="MarginContainer" parent="."] +custom_minimum_size = Vector2(0, 16) +offset_right = 43.0 +offset_bottom = 10.0 +theme_override_constants/margin_left = 2 +theme_override_constants/margin_top = 2 +theme_override_constants/margin_right = 2 +theme_override_constants/margin_bottom = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] +layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 0 + +[node name="Label" type="Label" parent="MarginContainer/HBoxContainer"] +texture_filter = 1 +layout_mode = 2 +theme = ExtResource("1_it884") +text = "Score:" + +[node name="Score" type="Label" parent="MarginContainer/HBoxContainer"] +unique_name_in_owner = true +texture_filter = 1 +layout_mode = 2 +theme = ExtResource("1_it884") +text = "0" diff --git a/ui/start_screen.gd b/ui/start_screen.gd new file mode 100644 index 0000000..418e407 --- /dev/null +++ b/ui/start_screen.gd @@ -0,0 +1,13 @@ +extends Control + + +func _ready() -> void: + %CountdownTimer.start() + + +func _process(delta: float) -> void: + %CountdownLabel.text = "%.1f" % %CountdownTimer.time_left + + +func _on_countdown_timer_timeout() -> void: + (func(): get_tree().change_scene_to_file("res://stage/stage_01.tscn")).call_deferred() diff --git a/ui/start_screen.tscn b/ui/start_screen.tscn new file mode 100644 index 0000000..6d40d01 --- /dev/null +++ b/ui/start_screen.tscn @@ -0,0 +1,51 @@ +[gd_scene load_steps=3 format=3 uid="uid://brfnvqsla72pn"] + +[ext_resource type="Script" path="res://ui/start_screen.gd" id="1_bpjye"] +[ext_resource type="Theme" uid="uid://b067xhqktnmhr" path="res://ui/theme.tres" id="2_qfrkp"] + +[node name="StartScreen" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_bpjye") + +[node name="ColorRect" type="ColorRect" parent="."] +layout_mode = 0 +offset_right = 160.0 +offset_bottom = 144.0 +color = Color(0.419608, 0.65098, 0.290196, 1) + +[node name="CenterContainer" type="CenterContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="CenterContainer"] +layout_mode = 2 +theme_override_constants/separation = 2 + +[node name="Label" type="Label" parent="CenterContainer/HBoxContainer"] +texture_filter = 1 +layout_mode = 2 +theme = ExtResource("2_qfrkp") +text = "Starting in" + +[node name="CountdownLabel" type="Label" parent="CenterContainer/HBoxContainer"] +unique_name_in_owner = true +texture_filter = 1 +layout_mode = 2 +theme = ExtResource("2_qfrkp") +text = "0" + +[node name="CountdownTimer" type="Timer" parent="."] +unique_name_in_owner = true +wait_time = 3.0 +one_shot = true + +[connection signal="timeout" from="CountdownTimer" to="." method="_on_countdown_timer_timeout"] diff --git a/ui/theme.tres b/ui/theme.tres new file mode 100644 index 0000000..eb181eb --- /dev/null +++ b/ui/theme.tres @@ -0,0 +1,8 @@ +[gd_resource type="Theme" load_steps=2 format=3 uid="uid://b067xhqktnmhr"] + +[ext_resource type="FontFile" uid="uid://16usq1tjtauh" path="res://ui/assets/Minimal3x5.ttf" id="1_qtw8w"] + +[resource] +Label/colors/font_color = Color(0.12549, 0.345098, 0.313726, 1) +Label/font_sizes/font_size = 8 +Label/fonts/font = ExtResource("1_qtw8w") |