Compare commits
10 commits
9ff2eb1867
...
c6439e9660
Author | SHA1 | Date | |
---|---|---|---|
c6439e9660 | |||
6874bb28a8 | |||
d919f42cbd | |||
e9bc30fd13 | |||
d4809bd78d | |||
174bd2575c | |||
1fdd0d7ae6 | |||
dc54aa3209 | |||
5a51da1968 | |||
c180b0312c |
43 changed files with 1477 additions and 27 deletions
|
@ -1,30 +1,78 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://b55f770t7xs6a"]
|
||||
[gd_scene load_steps=9 format=3 uid="uid://b55f770t7xs6a"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://npjqgc3tdgs1" path="res://gimp/DungeonEntrance.png" id="1_vo6aq"]
|
||||
[ext_resource type="Texture2D" uid="uid://nocjsuuft8qx" path="res://gimp/DungeonGuard.png" id="2_nujkm"]
|
||||
[ext_resource type="Script" path="res://DungeonGuard.gd" id="3_hisk5"]
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_18p8i"]
|
||||
radius = 15.0
|
||||
height = 32.0
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_fey6x"]
|
||||
size = Vector2(30.4094, 31.5789)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_0v5y2"]
|
||||
size = Vector2(30.4094, 31.5789)
|
||||
|
||||
[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_ocep5"]
|
||||
normal = Vector2(1, 0)
|
||||
|
||||
[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_gq7j0"]
|
||||
|
||||
[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_xvl4y"]
|
||||
normal = Vector2(-1, 0)
|
||||
|
||||
[node name="Node2D" type="Node2D"]
|
||||
|
||||
[node name="DungeonEntrance" type="Sprite2D" parent="."]
|
||||
texture_filter = 1
|
||||
position = Vector2(-1, -320)
|
||||
position = Vector2(0, -784)
|
||||
scale = Vector2(1.995, 1.995)
|
||||
texture = ExtResource("1_vo6aq")
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="DungeonEntrance"]
|
||||
visible = false
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="DungeonEntrance/StaticBody2D"]
|
||||
visible = false
|
||||
polygon = PackedVector2Array(-160, 127, -159, -129, 160, -126, 161, 127, 21, 127, 21, 79, -19, 79, -19, 127)
|
||||
|
||||
[node name="DungeonGuard" type="Sprite2D" parent="."]
|
||||
texture_filter = 1
|
||||
position = Vector2(0, -208)
|
||||
position = Vector2(0, -552)
|
||||
scale = Vector2(1.71, 1.71)
|
||||
texture = ExtResource("2_nujkm")
|
||||
script = ExtResource("3_hisk5")
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="DungeonGuard"]
|
||||
[node name="DungeonGuardBody" type="StaticBody2D" parent="DungeonGuard"]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="DungeonGuard/StaticBody2D"]
|
||||
shape = SubResource("CapsuleShape2D_18p8i")
|
||||
[node name="DungeonGuardCollider" type="CollisionShape2D" parent="DungeonGuard/DungeonGuardBody"]
|
||||
shape = SubResource("RectangleShape2D_fey6x")
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="DungeonGuard"]
|
||||
collision_layer = 3
|
||||
collision_mask = 0
|
||||
input_pickable = false
|
||||
monitoring = false
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="DungeonGuard/Area2D"]
|
||||
shape = SubResource("RectangleShape2D_0v5y2")
|
||||
debug_color = Color(0.643137, 0.341176, 0.988235, 0.419608)
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="."]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="StaticBody2D"]
|
||||
position = Vector2(-307, -1)
|
||||
shape = SubResource("WorldBoundaryShape2D_ocep5")
|
||||
|
||||
[node name="CollisionShape2D2" type="CollisionShape2D" parent="StaticBody2D"]
|
||||
position = Vector2(0, 243)
|
||||
shape = SubResource("WorldBoundaryShape2D_gq7j0")
|
||||
|
||||
[node name="CollisionShape2D3" type="CollisionShape2D" parent="StaticBody2D"]
|
||||
position = Vector2(314, 5)
|
||||
shape = SubResource("WorldBoundaryShape2D_xvl4y")
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
z_index = 5
|
||||
offset_left = -110.0
|
||||
offset_top = 208.0
|
||||
offset_right = 112.0
|
||||
offset_bottom = 231.0
|
||||
text = "The Dungeon is to the north!"
|
||||
|
|
23
DungeonGuard.gd
Normal file
23
DungeonGuard.gd
Normal file
|
@ -0,0 +1,23 @@
|
|||
extends Sprite2D
|
||||
|
||||
var health = 30
|
||||
var health_dirty = true
|
||||
|
||||
# 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):
|
||||
if health_dirty:
|
||||
health_dirty = false
|
||||
var hp_label = find_child("GuardHPLabel")
|
||||
if hp_label == null:
|
||||
hp_label = Label.new()
|
||||
hp_label.set_name(&"GuardHPLabel")
|
||||
add_child(hp_label, true)
|
||||
hp_label.set_owner(self)
|
||||
hp_label.position.y += 20.0
|
||||
hp_label.position.x -= 20.0
|
||||
hp_label.text = "%d HP" % health
|
22
LICENSE
Normal file
22
LICENSE
Normal file
|
@ -0,0 +1,22 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Stephen Seo
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
523
MainLogic.gd
523
MainLogic.gd
|
@ -9,6 +9,19 @@ extends Node2D
|
|||
@onready var earth_diamond = $EarthDiamond
|
||||
|
||||
@onready var music_player = $MusicPlayer
|
||||
@onready var sfx_player = $SFXPlayer
|
||||
var sfx_select
|
||||
var sfx_confirm
|
||||
var sfx_cancel
|
||||
var sfx_summon
|
||||
var sfx_enemy_hit
|
||||
var sfx_parry
|
||||
var sfx_sword_hit
|
||||
var sfx_hammer_hit
|
||||
|
||||
@onready var camera = $Camera2D
|
||||
|
||||
const camera_move_speed = 1.5
|
||||
|
||||
const text_speed = 0.08
|
||||
|
||||
|
@ -17,8 +30,8 @@ const start_text = "You seek the elementals?\nProve your worth!\nShow the elemen
|
|||
const intro_text_00 = "The name's Gander Schwartz.\nBut my friends call me the \"Wandering Gander\"."
|
||||
const intro_text_01 = "I'm what most would call a \"third-rate summoner\",\nbut there's a reason for that.\nI summon \"items\", not \"beasts\"."
|
||||
const intro_text_02 = "Most summoners summon beasts to fight for them.\nI summon items to fight with, or even tools to solve puzzles in dungeons."
|
||||
const intro_text_03 = "There is one dungeon I've been itching to conquer.\nThe elemental dungeon!"
|
||||
const intro_text_04 = "If I beat the elemental dungeon,\nI'll be able to enhance my summons with elemental properties!"
|
||||
const intro_text_03 = "There is one dungeon I've been itching to conquer.\nThe Elemental Dungeon!"
|
||||
const intro_text_04 = "If I beat the Elemental Dungeon,\nI'll be able to enhance my summons with elemental properties!"
|
||||
const intro_text_05 = "No longer would I need to light an oil lantern with flint and steel,\nor keep lugging around leather skins for water!"
|
||||
const intro_text_06 = "But the dungeon is a challenge.\nA challenge I hope to best with my wits and my item summoning!"
|
||||
|
||||
|
@ -27,6 +40,8 @@ const diamond_dist_rate = 50.0
|
|||
const diamond_start_dist = 800.0
|
||||
const diamond_min_dist = 150.0
|
||||
|
||||
const parry_penalty = 0.5
|
||||
|
||||
enum StateT {
|
||||
Start,
|
||||
Start_TextRendered,
|
||||
|
@ -46,19 +61,52 @@ enum StateT {
|
|||
Introduction_05_post,
|
||||
Introduction_06,
|
||||
Introduction_06_post,
|
||||
Dungeon_Entrance
|
||||
Dungeon_Entrance_pre,
|
||||
Dungeon_Entrance_loading,
|
||||
Dungeon_Entrance,
|
||||
Dungeon_Entrance_Battle,
|
||||
}
|
||||
|
||||
enum BattleState {
|
||||
MainMenu,
|
||||
SummonMenu,
|
||||
SummonSword,
|
||||
SummonHammer,
|
||||
SummonHealth,
|
||||
EnemyAttack,
|
||||
PlayerAttack,
|
||||
PlayerWin,
|
||||
PlayerLose,
|
||||
}
|
||||
|
||||
enum GuardPhase {
|
||||
Stomp,
|
||||
}
|
||||
|
||||
var guard_phase = GuardPhase.Stomp
|
||||
|
||||
static var state_dict = {}
|
||||
|
||||
var tween_volume
|
||||
var tween_text
|
||||
var tween_scene
|
||||
|
||||
var diamonds_gone = false
|
||||
|
||||
var music_file
|
||||
|
||||
var gander
|
||||
|
||||
var level
|
||||
var level_guard_static_body = null
|
||||
var level_guard = null
|
||||
var level_guard_cached_pos = null
|
||||
|
||||
var level_cached_pos = null
|
||||
|
||||
var viewport_size
|
||||
|
||||
var play_attack_sfx_type = null
|
||||
var play_attack_sfx_once = false
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
if not state_dict.has("state"):
|
||||
|
@ -70,6 +118,19 @@ func _ready():
|
|||
"angle" : 0.0
|
||||
}
|
||||
music_player.play()
|
||||
viewport_size = get_viewport().size
|
||||
get_viewport().size_changed.connect(func():
|
||||
viewport_size = get_viewport().size
|
||||
state_dict["battle_refresh_gui"] = true
|
||||
)
|
||||
sfx_select = load("res://audio/LD55_sfx_select.mp3")
|
||||
sfx_confirm = load("res://audio/LD55_sfx_confirm.mp3")
|
||||
sfx_cancel = load("res://audio/LD55_sfx_cancel.mp3")
|
||||
sfx_summon = load("res://audio/LD55_sfx_summon.mp3")
|
||||
sfx_enemy_hit = load("res://audio/LD55_sfx_enemy_hit.mp3")
|
||||
sfx_parry = load("res://audio/LD55_sfx_parry.mp3")
|
||||
sfx_sword_hit = load("res://audio/LD55_sfx_sword_hit.mp3")
|
||||
sfx_hammer_hit = load("res://audio/LD55_sfx_hammer_hit.mp3")
|
||||
|
||||
func update_text(text, next_state):
|
||||
if state_dict["timer"] > text_speed:
|
||||
|
@ -102,18 +163,19 @@ func _process(delta):
|
|||
main_label.text = ""
|
||||
lower_label.text = ""
|
||||
music_player.volume_db = 0.0
|
||||
music_player.stream = AudioStreamMP3.new()
|
||||
music_file = FileAccess.open("res://audio/LD55_1.mp3", FileAccess.READ)
|
||||
music_player.stream.data = music_file.get_buffer(music_file.get_length())
|
||||
music_player.stream = load("res://audio/LD55_1.mp3")
|
||||
music_player.stream.loop = true
|
||||
music_player.play()
|
||||
var gander_scene = preload("res://gander_schwartz.tscn")
|
||||
gander = gander_scene.instantiate()
|
||||
add_child(gander)
|
||||
gander.set_owner(self)
|
||||
gander.position.x = 800
|
||||
gander.position.y = 50
|
||||
gander.velocity.x = -gander.SPEED
|
||||
gander.auto_control_action = "walking_left"
|
||||
tween_scene = get_tree().create_tween()
|
||||
tween_scene.tween_method(func(c): RenderingServer.set_default_clear_color(c), Color(0.13, 0.13, 0.13, 1.0), Color(0.3, 0.4, 0.1, 1.0), 4)
|
||||
StateT.Introduction_00:
|
||||
update_stop_diamonds(delta)
|
||||
update_text(intro_text_00, StateT.Introduction_00_post)
|
||||
|
@ -149,6 +211,86 @@ func _process(delta):
|
|||
update_text(intro_text_06, StateT.Introduction_06_post)
|
||||
StateT.Introduction_06_post:
|
||||
pass
|
||||
StateT.Dungeon_Entrance_loading:
|
||||
gander.player_controlled = true
|
||||
gander.current_scene_type = gander.GanderSceneT.Gameplay
|
||||
var dungeon_scene = load("res://DungeonEntrance.tscn")
|
||||
level = dungeon_scene.instantiate()
|
||||
add_child(level)
|
||||
state_dict["state"] = StateT.Dungeon_Entrance
|
||||
lower_label.text = "Arrow keys/WASD/Left-Stick to move."
|
||||
tween_text = get_tree().create_tween()
|
||||
tween_text.tween_property(lower_label, "self_modulate", Color(1, 1, 1, 0), 5)
|
||||
tween_text.tween_callback(func():
|
||||
lower_label.text = ""
|
||||
lower_label.self_modulate = Color(1, 1, 1, 1)
|
||||
)
|
||||
music_player.volume_db = 0.0
|
||||
music_player.stream = load("res://audio/LD55_2.mp3")
|
||||
music_player.stream.loop = true
|
||||
music_player.play()
|
||||
StateT.Dungeon_Entrance:
|
||||
camera_to_gander(delta)
|
||||
if level_guard == null:
|
||||
level_guard = level.find_child("DungeonGuard")
|
||||
if level_guard_static_body == null:
|
||||
level_guard_static_body = level.find_child("DungeonGuardBody")
|
||||
if level_guard_static_body != null and gander.last_collided_id == level_guard_static_body.get_instance_id():
|
||||
print("collided with guard.")
|
||||
gander.last_collided_id = null
|
||||
music_player.stop()
|
||||
music_player.stream = preload("res://audio/LD55_3.mp3")
|
||||
music_player.stream.loop = true
|
||||
music_player.volume_db = -8.0
|
||||
music_player.play()
|
||||
level.find_child("DungeonGuardCollider").set_deferred("disabled", true)
|
||||
gander.find_child("CollisionShape2D").set_deferred("disabled", true)
|
||||
gander.player_controlled = false
|
||||
gander.current_scene_type = gander.GanderSceneT.Battle
|
||||
tween_scene = get_tree().create_tween()
|
||||
level_cached_pos = level.find_child("DungeonEntrance").position
|
||||
var battle_pos = level_cached_pos + Vector2(0.0, 500.0)
|
||||
tween_scene.set_parallel()
|
||||
tween_scene.tween_property(level.find_child("DungeonGuard"), "position", battle_pos - Vector2(200.0, 30.0), 2.0)
|
||||
tween_scene.tween_property(gander, "position", battle_pos + Vector2(200.0, 0.0), 2.0)
|
||||
gander.auto_control_action = "walking_right"
|
||||
tween_scene.set_parallel(false)
|
||||
tween_scene.tween_callback(func():
|
||||
gander.auto_control_action = "facing_left"
|
||||
state_dict["state"] = StateT.Dungeon_Entrance_Battle
|
||||
state_dict["parry_timer"] = 0.0
|
||||
state_dict["parry_failed_played"] = false
|
||||
state_dict["battle_state"] = BattleState.MainMenu
|
||||
state_dict["battle_menu_setup"] = false
|
||||
state_dict["battle_refresh_gui"] = false
|
||||
state_dict["battle_item"] = null
|
||||
var indicator_arrow = Sprite2D.new()
|
||||
indicator_arrow.texture = load("res://gimp/arrow.png")
|
||||
indicator_arrow.position.x = (indicator_arrow.get_rect().size.x - viewport_size.x) / 2.0
|
||||
indicator_arrow.position.y = (viewport_size.y - indicator_arrow.get_rect().size.y) / 2.0
|
||||
camera.add_child(indicator_arrow)
|
||||
indicator_arrow.set_owner(camera)
|
||||
tween_text = get_tree().create_tween()
|
||||
tween_text.set_parallel()
|
||||
tween_text.tween_property(indicator_arrow, "scale", Vector2(20.0, 20.0), 1.5)
|
||||
tween_text.tween_property(indicator_arrow, "self_modulate", Color(1, 1, 1, 0), 1.5)
|
||||
tween_text.set_parallel(false)
|
||||
tween_text.tween_callback(func():
|
||||
camera.remove_child(indicator_arrow)
|
||||
)
|
||||
gander.battle_started = true
|
||||
)
|
||||
StateT.Dungeon_Entrance_Battle:
|
||||
if state_dict["battle_state"] == BattleState.EnemyAttack:
|
||||
if level_guard_cached_pos == null:
|
||||
level_guard_cached_pos = level_guard.position
|
||||
camera_to_target(delta, level_cached_pos + Vector2(0.0, 500.0))
|
||||
setup_battle_menu()
|
||||
state_dict["parry_timer"] -= delta
|
||||
if not gander.parry_success and gander.hit_active and not state_dict["parry_failed_played"]:
|
||||
sfx_player.stream = sfx_enemy_hit
|
||||
sfx_player.play()
|
||||
state_dict["parry_failed_played"] = true
|
||||
_:
|
||||
pass
|
||||
if gander is MainCharacter and not gander.player_controlled and gander.current_scene_type == gander.GanderSceneT.Introduction:
|
||||
|
@ -159,7 +301,9 @@ func _process(delta):
|
|||
|
||||
|
||||
func _unhandled_input(event):
|
||||
if event.is_pressed() and event.is_action("Confirm"):
|
||||
if state_dict["state"] == StateT.Dungeon_Entrance_Battle:
|
||||
handle_battle_input(event)
|
||||
elif event.is_pressed() and event.is_action("Confirm"):
|
||||
match state_dict["state"]:
|
||||
StateT.Start:
|
||||
main_label.text = start_text
|
||||
|
@ -170,7 +314,10 @@ func _unhandled_input(event):
|
|||
state_dict["state"] = StateT.Start_Stopping
|
||||
tween_volume = get_tree().create_tween()
|
||||
tween_volume.tween_property(music_player, "volume_db", -80.0, 4.0)
|
||||
tween_volume.tween_callback(start_volume_tween_callback)
|
||||
tween_volume.tween_callback(func():
|
||||
music_player.stop()
|
||||
state_dict["state"] = StateT.MainMenu
|
||||
)
|
||||
main_label.text = ""
|
||||
lower_label.text = ""
|
||||
StateT.Introduction_00:
|
||||
|
@ -239,17 +386,20 @@ func _unhandled_input(event):
|
|||
state_dict["text_idx"] = 0
|
||||
main_label.text = intro_text_06
|
||||
StateT.Introduction_06_post:
|
||||
state_dict["state"] = StateT.Dungeon_Entrance
|
||||
state_dict["state"] = StateT.Dungeon_Entrance_pre
|
||||
state_dict["timer"] = 0.0
|
||||
state_dict["text_idx"] = 0
|
||||
main_label.text = ""
|
||||
tween_volume = get_tree().create_tween()
|
||||
tween_volume.tween_property(music_player, "volume_db", -80.0, 4.0)
|
||||
tween_volume.tween_callback(func():
|
||||
music_player.stop()
|
||||
state_dict["state"] = StateT.Dungeon_Entrance_loading
|
||||
music_player.volume_db = 0.0
|
||||
)
|
||||
_:
|
||||
pass
|
||||
|
||||
func start_volume_tween_callback():
|
||||
music_player.stop()
|
||||
state_dict["state"] = StateT.MainMenu
|
||||
|
||||
func diamond_position_update():
|
||||
fire_diamond.position.x = cos(state_dict["start_diamonds"]["angle"]) * state_dict["start_diamonds"]["dist"]
|
||||
fire_diamond.position.y = sin(state_dict["start_diamonds"]["angle"]) * state_dict["start_diamonds"]["dist"]
|
||||
|
@ -288,3 +438,346 @@ func update_stop_diamonds(delta):
|
|||
state_dict["start_diamonds"]["angle"] -= TAU
|
||||
|
||||
diamond_position_update()
|
||||
|
||||
func camera_to_gander(delta):
|
||||
camera_to_target(delta, gander.position)
|
||||
|
||||
func camera_to_target(delta, vec2):
|
||||
var diff = vec2 - camera.position
|
||||
camera.position += diff * delta * camera_move_speed
|
||||
|
||||
func setup_battle_menu():
|
||||
if state_dict["battle_state"] != BattleState.PlayerWin and state_dict["battle_state"] != BattleState.PlayerLose:
|
||||
if gander.health <= 0:
|
||||
state_dict["battle_state"] = BattleState.PlayerLose
|
||||
music_player.stop()
|
||||
music_player.stream = load("res://audio/LD55_5.mp3")
|
||||
music_player.play()
|
||||
remove_child(gander)
|
||||
main_label.text = "Thanks for playing! I ran out of time for this overly ambitious game..."
|
||||
lower_label.text = "Ohhhh, it ended with a game over... Better luck next time?"
|
||||
elif level_guard.health <= 0:
|
||||
state_dict["battle_state"] = BattleState.PlayerWin
|
||||
music_player.stop()
|
||||
music_player.stream = load("res://audio/LD55_4.mp3")
|
||||
music_player.play()
|
||||
level_guard.get_parent().remove_child(level_guard)
|
||||
main_label.text = "Thanks for playing! I ran out of time for this overly ambitious game..."
|
||||
lower_label.text = "Good show, good show!"
|
||||
elif state_dict["battle_state"] == BattleState.PlayerWin or state_dict["battle_state"] == BattleState.PlayerLose:
|
||||
return
|
||||
match state_dict["battle_state"]:
|
||||
BattleState.MainMenu:
|
||||
if not state_dict["battle_menu_setup"] or state_dict["battle_refresh_gui"]:
|
||||
state_dict["battle_menu_setup"] = true
|
||||
state_dict["battle_refresh_gui"] = false
|
||||
var battle_arrow = camera.find_child("BattleArrow")
|
||||
if battle_arrow == null:
|
||||
battle_arrow = Sprite2D.new()
|
||||
battle_arrow.set_name(&"BattleArrow")
|
||||
battle_arrow.texture = load("res://gimp/arrow.png")
|
||||
camera.add_child(battle_arrow, true)
|
||||
battle_arrow.set_owner(camera)
|
||||
battle_arrow.self_modulate = Color(1, 1, 1, 1)
|
||||
var battle_menu_item_0 = camera.find_child("BattleMenuItem0")
|
||||
if battle_menu_item_0 == null:
|
||||
battle_menu_item_0 = Label.new()
|
||||
battle_menu_item_0.set_name(&"BattleMenuItem0")
|
||||
camera.add_child(battle_menu_item_0, true)
|
||||
battle_menu_item_0.set_owner(camera)
|
||||
var battle_menu_item_1 = camera.find_child("BattleMenuItem1")
|
||||
if battle_menu_item_1 == null:
|
||||
battle_menu_item_1 = Label.new()
|
||||
battle_menu_item_1.set_name(&"BattleMenuItem1")
|
||||
camera.add_child(battle_menu_item_1, true)
|
||||
battle_menu_item_1.set_owner(camera)
|
||||
var battle_menu_item_2 = camera.find_child("BattleMenuItem2")
|
||||
if battle_menu_item_2 == null:
|
||||
battle_menu_item_2 = Label.new()
|
||||
battle_menu_item_2.set_name(&"BattleMenuItem2")
|
||||
camera.add_child(battle_menu_item_2, true)
|
||||
battle_menu_item_2.set_owner(camera)
|
||||
if state_dict["battle_item"] == null:
|
||||
battle_menu_item_0.text = "Summon Item"
|
||||
battle_menu_item_1.text = ""
|
||||
var arrow_rect = battle_arrow.get_rect()
|
||||
battle_arrow.position.x = (arrow_rect.size.x - viewport_size.x) / 2.0
|
||||
battle_arrow.position.y = (viewport_size.y - arrow_rect.size.y) / 2.0
|
||||
battle_menu_item_0.position.x = arrow_rect.size.x - viewport_size.x / 2.0
|
||||
battle_menu_item_0.position.y = battle_arrow.position.y
|
||||
state_dict["battle_selection"] = 0
|
||||
state_dict["battle_options"] = ["summon"]
|
||||
else:
|
||||
battle_menu_item_0.text = "Attack with Item"
|
||||
battle_menu_item_1.text = "Summon new Item"
|
||||
var arrow_rect = battle_arrow.get_rect()
|
||||
battle_arrow.position.x = (arrow_rect.size.x - viewport_size.x) / 2.0
|
||||
battle_arrow.position.y = (viewport_size.y - arrow_rect.size.y * 3.0) / 2.0
|
||||
battle_menu_item_0.position.x = arrow_rect.size.x - viewport_size.x / 2.0
|
||||
battle_menu_item_0.position.y = battle_arrow.position.y
|
||||
battle_menu_item_1.position.x = arrow_rect.size.x - viewport_size.x / 2.0
|
||||
battle_menu_item_1.position.y = battle_arrow.position.y + arrow_rect.size.y
|
||||
state_dict["battle_selection"] = 0
|
||||
state_dict["battle_options"] = ["attack", "summon"]
|
||||
BattleState.SummonMenu:
|
||||
if not state_dict["battle_menu_setup"] or state_dict["battle_refresh_gui"]:
|
||||
state_dict["battle_menu_setup"] = true
|
||||
state_dict["battle_refresh_gui"] = false
|
||||
var battle_arrow = camera.find_child("BattleArrow")
|
||||
var battle_menu_item_0 = camera.find_child("BattleMenuItem0")
|
||||
var battle_menu_item_1 = camera.find_child("BattleMenuItem1")
|
||||
var battle_menu_item_2 = camera.find_child("BattleMenuItem2")
|
||||
battle_arrow.self_modulate = Color(1, 1, 1, 1)
|
||||
battle_menu_item_0.text = "Summon Sword"
|
||||
battle_menu_item_1.text = "Summon Hammer"
|
||||
battle_menu_item_2.text = "Summon Health Potion (+5 HP)"
|
||||
var arrow_rect = battle_arrow.get_rect()
|
||||
battle_arrow.position.x = (arrow_rect.size.x - viewport_size.x) / 2.0
|
||||
battle_arrow.position.y = (viewport_size.y - arrow_rect.size.y * 5.0) / 2.0
|
||||
battle_menu_item_0.position.x = arrow_rect.size.x - viewport_size.x / 2.0
|
||||
battle_menu_item_0.position.y = battle_arrow.position.y
|
||||
battle_menu_item_1.position.x = arrow_rect.size.x - viewport_size.x / 2.0
|
||||
battle_menu_item_1.position.y = battle_arrow.position.y + arrow_rect.size.y
|
||||
battle_menu_item_2.position.x = arrow_rect.size.x - viewport_size.x / 2.0
|
||||
battle_menu_item_2.position.y = battle_arrow.position.y + arrow_rect.size.y * 2.0
|
||||
state_dict["battle_selection"] = 0
|
||||
state_dict["battle_options"] = ["summon_sword", "summon_hammer", "summon_health"]
|
||||
BattleState.SummonSword:
|
||||
var summon_node = find_child("SummonAttempt")
|
||||
if summon_node.success_count >= summon_node.MAX_SUCCESS:
|
||||
camera.remove_child(summon_node)
|
||||
var summon_item = gander.find_child("SummonItem")
|
||||
if summon_item == null:
|
||||
summon_item = Sprite2D.new()
|
||||
summon_item.texture = load("res://gimp/sword.png")
|
||||
summon_item.set_name(&"SummonItem")
|
||||
gander.add_child(summon_item, true)
|
||||
summon_item.set_owner(gander)
|
||||
else:
|
||||
summon_item.texture = load("res://gimp/sword.png")
|
||||
gander.summon_item = summon_item
|
||||
state_dict["battle_item"] = summon_item
|
||||
gander.attack_type = gander.AttackType.SWORD
|
||||
gander.summon_item_summoned = true
|
||||
sfx_player.stream = sfx_summon
|
||||
sfx_player.play()
|
||||
state_dict["battle_state"] = BattleState.EnemyAttack
|
||||
level_guard_cached_pos = null
|
||||
pick_guard_phase()
|
||||
elif summon_node.error_count >= summon_node.MAX_ERRORS:
|
||||
tween_scene = get_tree().create_tween()
|
||||
tween_scene.tween_method(func(c): for i in range(8): summon_node.summon_arrows_arr[i].self_modulate = c, Color(1.0, 0.0, 0.0), Color(1.0, 0.0, 0.0, 0.0), 1.0)
|
||||
tween_scene.tween_callback(func(): camera.remove_child(summon_node))
|
||||
state_dict["battle_state"] = BattleState.EnemyAttack
|
||||
level_guard_cached_pos = null
|
||||
pick_guard_phase()
|
||||
BattleState.SummonHammer:
|
||||
var summon_node = find_child("SummonAttempt")
|
||||
if summon_node.success_count >= summon_node.MAX_SUCCESS:
|
||||
camera.remove_child(summon_node)
|
||||
var summon_item = gander.find_child("SummonItem")
|
||||
if summon_item == null:
|
||||
summon_item = Sprite2D.new()
|
||||
summon_item.texture = load("res://gimp/hammer.png")
|
||||
summon_item.set_name(&"SummonItem")
|
||||
gander.add_child(summon_item, true)
|
||||
summon_item.set_owner(gander)
|
||||
else:
|
||||
summon_item.texture = load("res://gimp/hammer.png")
|
||||
gander.summon_item = summon_item
|
||||
state_dict["battle_item"] = summon_item
|
||||
gander.attack_type = gander.AttackType.HAMMER
|
||||
gander.summon_item_summoned = true
|
||||
sfx_player.stream = sfx_summon
|
||||
sfx_player.play()
|
||||
state_dict["battle_state"] = BattleState.EnemyAttack
|
||||
level_guard_cached_pos = null
|
||||
pick_guard_phase()
|
||||
elif summon_node.error_count >= summon_node.MAX_ERRORS:
|
||||
tween_scene = get_tree().create_tween()
|
||||
tween_scene.tween_method(func(c): for i in range(8): summon_node.summon_arrows_arr[i].self_modulate = c, Color(1.0, 0.0, 0.0), Color(1.0, 0.0, 0.0, 0.0), 1.0)
|
||||
tween_scene.tween_callback(func(): camera.remove_child(summon_node))
|
||||
state_dict["battle_state"] = BattleState.EnemyAttack
|
||||
level_guard_cached_pos = null
|
||||
pick_guard_phase()
|
||||
BattleState.SummonHealth:
|
||||
var summon_node = find_child("SummonAttempt")
|
||||
if summon_node.success_count >= summon_node.MAX_SUCCESS:
|
||||
camera.remove_child(summon_node)
|
||||
var summon_item = gander.find_child("SummonItem")
|
||||
if summon_item == null:
|
||||
pass
|
||||
else:
|
||||
gander.remove_child(summon_item)
|
||||
gander.summon_item = null
|
||||
gander.summon_item_summoned = false
|
||||
gander.health += 5
|
||||
if gander.health > gander.max_health:
|
||||
gander.health = gander.max_health
|
||||
gander.health_dirty = true
|
||||
sfx_player.stream = sfx_summon
|
||||
sfx_player.play()
|
||||
state_dict["battle_state"] = BattleState.EnemyAttack
|
||||
state_dict["battle_item"] = null
|
||||
level_guard_cached_pos = null
|
||||
pick_guard_phase()
|
||||
elif summon_node.error_count >= summon_node.MAX_ERRORS:
|
||||
tween_scene = get_tree().create_tween()
|
||||
tween_scene.tween_method(func(c): for i in range(8): summon_node.summon_arrows_arr[i].self_modulate = c, Color(1.0, 0.0, 0.0), Color(1.0, 0.0, 0.0, 0.0), 1.0)
|
||||
tween_scene.tween_callback(func(): camera.remove_child(summon_node))
|
||||
state_dict["battle_state"] = BattleState.EnemyAttack
|
||||
level_guard_cached_pos = null
|
||||
pick_guard_phase()
|
||||
BattleState.EnemyAttack:
|
||||
if not state_dict["battle_menu_setup"] or state_dict["battle_refresh_gui"]:
|
||||
state_dict["battle_menu_setup"] = true
|
||||
state_dict["battle_refresh_gui"] = false
|
||||
state_dict["parry_failed_played"] = false
|
||||
var battle_arrow = camera.find_child("BattleArrow")
|
||||
var battle_menu_item_0 = camera.find_child("BattleMenuItem0")
|
||||
var battle_menu_item_1 = camera.find_child("BattleMenuItem1")
|
||||
var battle_menu_item_2 = camera.find_child("BattleMenuItem2")
|
||||
battle_arrow.self_modulate = Color(1, 1, 1, 0)
|
||||
battle_menu_item_0.text = ""
|
||||
battle_menu_item_1.text = ""
|
||||
battle_menu_item_2.text = ""
|
||||
if gander.summon_item != null:
|
||||
lower_label.text = "Press key-Z, button-A, or Spacebar at the right time to parry!"
|
||||
match guard_phase:
|
||||
GuardPhase.Stomp:
|
||||
tween_scene = get_tree().create_tween()
|
||||
var diff = gander.position.x - level_guard_cached_pos.x
|
||||
tween_scene.tween_property(level_guard, "position", level_guard_cached_pos + Vector2(diff / 2.0, -200.0), 1.0)
|
||||
tween_scene.tween_property(level_guard, "position", level_guard_cached_pos + Vector2(diff / 2.0, 0.0), 0.7)
|
||||
tween_scene.tween_property(level_guard, "position", level_guard_cached_pos + Vector2(diff, -200.0), 1.0)
|
||||
tween_scene.tween_property(level_guard, "position", level_guard_cached_pos + Vector2(diff, 0.0), 0.7)
|
||||
tween_scene.tween_callback(func():
|
||||
state_dict["battle_state"] = BattleState.MainMenu
|
||||
state_dict["battle_menu_setup"] = false
|
||||
lower_label.text = ""
|
||||
)
|
||||
tween_scene.tween_property(level_guard, "position", level_guard_cached_pos, 1.0)
|
||||
_:
|
||||
state_dict["battle_state"] = BattleState.MainMenu
|
||||
state_dict["battle_menu_setup"] = false
|
||||
BattleState.PlayerAttack:
|
||||
if gander.attack_target == null:
|
||||
state_dict["battle_state"] = BattleState.EnemyAttack
|
||||
state_dict["battle_menu_setup"] = false
|
||||
play_attack_sfx_type = null
|
||||
play_attack_sfx_once = false
|
||||
elif not play_attack_sfx_once and play_attack_sfx_type != null:
|
||||
var rng = RandomNumberGenerator.new()
|
||||
if play_attack_sfx_type == "sword":
|
||||
sfx_player.stream = sfx_sword_hit
|
||||
sfx_player.play()
|
||||
level_guard.health -= rng.randi_range(3, 4)
|
||||
level_guard.health_dirty = true
|
||||
elif play_attack_sfx_type == "hammer":
|
||||
sfx_player.stream = sfx_hammer_hit
|
||||
sfx_player.play()
|
||||
level_guard.health -= rng.randi_range(2, 5)
|
||||
level_guard.health_dirty = true
|
||||
play_attack_sfx_type = null
|
||||
play_attack_sfx_once = true
|
||||
|
||||
func handle_battle_input(event: InputEvent):
|
||||
if state_dict["battle_state"] == BattleState.SummonSword or state_dict["battle_state"] == BattleState.SummonHammer \
|
||||
or state_dict["battle_state"] == BattleState.SummonHealth \
|
||||
or state_dict["battle_state"] == BattleState.PlayerWin or state_dict["battle_state"] == BattleState.PlayerLose:
|
||||
return
|
||||
elif state_dict["battle_state"] == BattleState.EnemyAttack:
|
||||
if event.is_pressed() and event.is_action("Confirm"):
|
||||
if state_dict["parry_timer"] < 0.0 and gander.parry_active and not gander.hit_active and gander.summon_item != null:
|
||||
lower_label.text = "Nice parry!"
|
||||
gander.parry_success = true
|
||||
sfx_player.stream = sfx_parry
|
||||
sfx_player.play()
|
||||
tween_scene.kill()
|
||||
tween_scene = get_tree().create_tween()
|
||||
tween_scene.tween_property(level_guard, "position", level_guard_cached_pos, 0.8)
|
||||
tween_scene.tween_callback(func():
|
||||
state_dict["battle_state"] = BattleState.MainMenu
|
||||
state_dict["battle_menu_setup"] = false
|
||||
lower_label.text = ""
|
||||
)
|
||||
state_dict["parry_timer"] = parry_penalty
|
||||
return
|
||||
if event.is_pressed():
|
||||
if event.is_action("Down"):
|
||||
state_dict["battle_selection"] += 1
|
||||
if state_dict["battle_selection"] >= state_dict["battle_options"].size():
|
||||
state_dict["battle_selection"] = 0
|
||||
battle_arrow_positioning()
|
||||
elif event.is_action("Up"):
|
||||
state_dict["battle_selection"] -= 1
|
||||
if state_dict["battle_selection"] < 0:
|
||||
state_dict["battle_selection"] = state_dict["battle_options"].size() - 1
|
||||
battle_arrow_positioning()
|
||||
elif event.is_action("Confirm"):
|
||||
handle_battle_action(state_dict["battle_options"][state_dict["battle_selection"]])
|
||||
elif event.is_action("Cancel"):
|
||||
handle_battle_action("cancel")
|
||||
|
||||
func handle_battle_action(action):
|
||||
match action:
|
||||
"attack":
|
||||
state_dict["battle_state"] = BattleState.PlayerAttack
|
||||
state_dict["battle_menu_setup"] = false
|
||||
sfx_player.stream = sfx_confirm
|
||||
sfx_player.play()
|
||||
if gander.summon_item != null:
|
||||
gander.attack_target = level_guard
|
||||
"summon":
|
||||
state_dict["battle_state"] = BattleState.SummonMenu
|
||||
state_dict["battle_menu_setup"] = false
|
||||
sfx_player.stream = sfx_confirm
|
||||
sfx_player.play()
|
||||
"summon_sword":
|
||||
state_dict["battle_state"] = BattleState.SummonSword
|
||||
state_dict["battle_menu_setup"] = false
|
||||
var summon_scene = load("res://summoning.tscn")
|
||||
var summon_node = summon_scene.instantiate()
|
||||
summon_node.set_name(&"SummonAttempt")
|
||||
camera.add_child(summon_node, true)
|
||||
summon_node.set_owner(camera)
|
||||
sfx_player.stream = sfx_confirm
|
||||
sfx_player.play()
|
||||
"summon_hammer":
|
||||
state_dict["battle_state"] = BattleState.SummonHammer
|
||||
state_dict["battle_menu_setup"] = false
|
||||
var summon_scene = load("res://summoning.tscn")
|
||||
var summon_node = summon_scene.instantiate()
|
||||
summon_node.set_name(&"SummonAttempt")
|
||||
camera.add_child(summon_node, true)
|
||||
summon_node.set_owner(camera)
|
||||
sfx_player.stream = sfx_confirm
|
||||
sfx_player.play()
|
||||
"summon_health":
|
||||
state_dict["battle_state"] = BattleState.SummonHealth
|
||||
state_dict["battle_menu_setup"] = false
|
||||
var summon_scene = load("res://summoning.tscn")
|
||||
var summon_node = summon_scene.instantiate()
|
||||
summon_node.set_name(&"SummonAttempt")
|
||||
camera.add_child(summon_node, true)
|
||||
summon_node.set_owner(camera)
|
||||
sfx_player.stream = sfx_confirm
|
||||
sfx_player.play()
|
||||
"cancel":
|
||||
state_dict["battle_state"] = BattleState.MainMenu
|
||||
state_dict["battle_menu_setup"] = false
|
||||
sfx_player.stream = sfx_cancel
|
||||
sfx_player.play()
|
||||
_:
|
||||
pass
|
||||
|
||||
func battle_arrow_positioning():
|
||||
var battle_arrow: Sprite2D = camera.find_child("BattleArrow")
|
||||
if battle_arrow != null:
|
||||
var arrow_rect = battle_arrow.get_rect()
|
||||
battle_arrow.position.y = (viewport_size.y + arrow_rect.size.y) / 2.0 - (arrow_rect.size.y * (state_dict["battle_options"].size() - state_dict["battle_selection"]))
|
||||
sfx_player.stream = sfx_select
|
||||
sfx_player.play()
|
||||
|
||||
func pick_guard_phase():
|
||||
guard_phase = GuardPhase.Stomp
|
||||
|
|
BIN
audio/LD55_2.mp3
Normal file
BIN
audio/LD55_2.mp3
Normal file
Binary file not shown.
19
audio/LD55_2.mp3.import
Normal file
19
audio/LD55_2.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://18u0r46uho0f"
|
||||
path="res://.godot/imported/LD55_2.mp3-34aece3f1076ff4ee4a342f09742ae03.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_2.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_2.mp3-34aece3f1076ff4ee4a342f09742ae03.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=true
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_3.mp3
Normal file
BIN
audio/LD55_3.mp3
Normal file
Binary file not shown.
19
audio/LD55_3.mp3.import
Normal file
19
audio/LD55_3.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://dymc7p8pyr5y4"
|
||||
path="res://.godot/imported/LD55_3.mp3-20ea91918fd2eaba4ffbeab07a2323ed.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_3.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_3.mp3-20ea91918fd2eaba4ffbeab07a2323ed.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=true
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_4.mp3
Normal file
BIN
audio/LD55_4.mp3
Normal file
Binary file not shown.
19
audio/LD55_4.mp3.import
Normal file
19
audio/LD55_4.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://bg8bmtdt0c7kb"
|
||||
path="res://.godot/imported/LD55_4.mp3-e210e6cf7c5b774440f99e24ae975dbc.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_4.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_4.mp3-e210e6cf7c5b774440f99e24ae975dbc.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_5.mp3
Normal file
BIN
audio/LD55_5.mp3
Normal file
Binary file not shown.
19
audio/LD55_5.mp3.import
Normal file
19
audio/LD55_5.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://eygtgx2p30nt"
|
||||
path="res://.godot/imported/LD55_5.mp3-b747345ea626a35323705fe51d8f7236.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_5.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_5.mp3-b747345ea626a35323705fe51d8f7236.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_sfx_cancel.mp3
Normal file
BIN
audio/LD55_sfx_cancel.mp3
Normal file
Binary file not shown.
19
audio/LD55_sfx_cancel.mp3.import
Normal file
19
audio/LD55_sfx_cancel.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://bwu8jqdfa78j"
|
||||
path="res://.godot/imported/LD55_sfx_cancel.mp3-cadc5a46716d397037e2593cd887cdee.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_sfx_cancel.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_sfx_cancel.mp3-cadc5a46716d397037e2593cd887cdee.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_sfx_confirm.mp3
Normal file
BIN
audio/LD55_sfx_confirm.mp3
Normal file
Binary file not shown.
19
audio/LD55_sfx_confirm.mp3.import
Normal file
19
audio/LD55_sfx_confirm.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://d0ekb3bk74p26"
|
||||
path="res://.godot/imported/LD55_sfx_confirm.mp3-f5943f8e9f465983820ed67c99df309e.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_sfx_confirm.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_sfx_confirm.mp3-f5943f8e9f465983820ed67c99df309e.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_sfx_enemy_hit.mp3
Normal file
BIN
audio/LD55_sfx_enemy_hit.mp3
Normal file
Binary file not shown.
19
audio/LD55_sfx_enemy_hit.mp3.import
Normal file
19
audio/LD55_sfx_enemy_hit.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://bu34dnb7q3arr"
|
||||
path="res://.godot/imported/LD55_sfx_enemy_hit.mp3-33970ec45349dad7d9a01186fd03e09a.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_sfx_enemy_hit.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_sfx_enemy_hit.mp3-33970ec45349dad7d9a01186fd03e09a.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_sfx_hammer_hit.mp3
Normal file
BIN
audio/LD55_sfx_hammer_hit.mp3
Normal file
Binary file not shown.
19
audio/LD55_sfx_hammer_hit.mp3.import
Normal file
19
audio/LD55_sfx_hammer_hit.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://clxh0pmhvavne"
|
||||
path="res://.godot/imported/LD55_sfx_hammer_hit.mp3-3164a70ab500317d475c03a94852df6f.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_sfx_hammer_hit.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_sfx_hammer_hit.mp3-3164a70ab500317d475c03a94852df6f.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_sfx_parry.mp3
Normal file
BIN
audio/LD55_sfx_parry.mp3
Normal file
Binary file not shown.
19
audio/LD55_sfx_parry.mp3.import
Normal file
19
audio/LD55_sfx_parry.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://cnumagq6o3qxj"
|
||||
path="res://.godot/imported/LD55_sfx_parry.mp3-7a46deb538aa1e0147d4915f42b03709.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_sfx_parry.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_sfx_parry.mp3-7a46deb538aa1e0147d4915f42b03709.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_sfx_select.mp3
Normal file
BIN
audio/LD55_sfx_select.mp3
Normal file
Binary file not shown.
19
audio/LD55_sfx_select.mp3.import
Normal file
19
audio/LD55_sfx_select.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://d1q1gfvi1i8po"
|
||||
path="res://.godot/imported/LD55_sfx_select.mp3-fd7a087b2218aec4761b872fc6130921.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_sfx_select.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_sfx_select.mp3-fd7a087b2218aec4761b872fc6130921.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_sfx_summon.mp3
Normal file
BIN
audio/LD55_sfx_summon.mp3
Normal file
Binary file not shown.
19
audio/LD55_sfx_summon.mp3.import
Normal file
19
audio/LD55_sfx_summon.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://3iqdxpvo7xkp"
|
||||
path="res://.godot/imported/LD55_sfx_summon.mp3-7fc4acd7d569064aef60ead4e1e4c32a.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_sfx_summon.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_sfx_summon.mp3-7fc4acd7d569064aef60ead4e1e4c32a.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
audio/LD55_sfx_sword_hit.mp3
Normal file
BIN
audio/LD55_sfx_sword_hit.mp3
Normal file
Binary file not shown.
19
audio/LD55_sfx_sword_hit.mp3.import
Normal file
19
audio/LD55_sfx_sword_hit.mp3.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="mp3"
|
||||
type="AudioStreamMP3"
|
||||
uid="uid://c2tvj7l0latop"
|
||||
path="res://.godot/imported/LD55_sfx_sword_hit.mp3-d10764d82f6cd1f6e91970f219d44ea5.mp3str"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/LD55_sfx_sword_hit.mp3"
|
||||
dest_files=["res://.godot/imported/LD55_sfx_sword_hit.mp3-d10764d82f6cd1f6e91970f219d44ea5.mp3str"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
140
export_presets.cfg
Normal file
140
export_presets.cfg
Normal file
|
@ -0,0 +1,140 @@
|
|||
[preset.0]
|
||||
|
||||
name="Linux/X11"
|
||||
platform="Linux/X11"
|
||||
runnable=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="../../GodotExported/LD55_Linux64_GanderAndTheElementalDungeon_by_BurnedKirby/LD55_Linux64_GanderAndTheElementalDungeon_by_BurnedKirby.x86_64"
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
|
||||
[preset.0.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
debug/export_console_wrapper=1
|
||||
binary_format/embed_pck=false
|
||||
texture_format/bptc=true
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
binary_format/architecture="x86_64"
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
ssh_remote_deploy/port="22"
|
||||
ssh_remote_deploy/extra_args_ssh=""
|
||||
ssh_remote_deploy/extra_args_scp=""
|
||||
ssh_remote_deploy/run_script="#!/usr/bin/env bash
|
||||
export DISPLAY=:0
|
||||
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
|
||||
\"{temp_dir}/{exe_name}\" {cmd_args}"
|
||||
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
|
||||
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
|
||||
rm -rf \"{temp_dir}\""
|
||||
|
||||
[preset.1]
|
||||
|
||||
name="Windows Desktop"
|
||||
platform="Windows Desktop"
|
||||
runnable=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="../../GodotExported/LD55_Windows_GanderAndTheElementalDungeon_by_BurnedKirby/LD55_Windows_GanderAndTheElementalDungeon_by_BurnedKirby.exe"
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
|
||||
[preset.1.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
debug/export_console_wrapper=1
|
||||
binary_format/embed_pck=false
|
||||
texture_format/bptc=true
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
binary_format/architecture="x86_64"
|
||||
codesign/enable=false
|
||||
codesign/timestamp=true
|
||||
codesign/timestamp_server_url=""
|
||||
codesign/digest_algorithm=1
|
||||
codesign/description=""
|
||||
codesign/custom_options=PackedStringArray()
|
||||
application/modify_resources=false
|
||||
application/icon=""
|
||||
application/console_wrapper_icon=""
|
||||
application/icon_interpolation=4
|
||||
application/file_version=""
|
||||
application/product_version=""
|
||||
application/company_name=""
|
||||
application/product_name=""
|
||||
application/file_description=""
|
||||
application/copyright=""
|
||||
application/trademarks=""
|
||||
application/export_angle=0
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
ssh_remote_deploy/port="22"
|
||||
ssh_remote_deploy/extra_args_ssh=""
|
||||
ssh_remote_deploy/extra_args_scp=""
|
||||
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
|
||||
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
|
||||
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
|
||||
$settings = New-ScheduledTaskSettingsSet
|
||||
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
|
||||
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
|
||||
Start-ScheduledTask -TaskName godot_remote_debug
|
||||
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
|
||||
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
||||
Remove-Item -Recurse -Force '{temp_dir}'"
|
||||
|
||||
[preset.2]
|
||||
|
||||
name="Web"
|
||||
platform="Web"
|
||||
runnable=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="../../GodotExported/Web/LD55.html"
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
|
||||
[preset.2.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
variant/extensions_support=false
|
||||
vram_texture_compression/for_desktop=true
|
||||
vram_texture_compression/for_mobile=false
|
||||
html/export_icon=true
|
||||
html/custom_html_shell=""
|
||||
html/head_include=""
|
||||
html/canvas_resize_policy=2
|
||||
html/focus_canvas_on_start=true
|
||||
html/experimental_virtual_keyboard=false
|
||||
progressive_web_app/enabled=false
|
||||
progressive_web_app/offline_page=""
|
||||
progressive_web_app/display=1
|
||||
progressive_web_app/orientation=0
|
||||
progressive_web_app/icon_144x144=""
|
||||
progressive_web_app/icon_180x180=""
|
||||
progressive_web_app/icon_512x512=""
|
||||
progressive_web_app/background_color=Color(0, 0, 0, 1)
|
|
@ -6,14 +6,157 @@ var player_controlled = false
|
|||
enum GanderSceneT {
|
||||
Introduction,
|
||||
Gameplay,
|
||||
Battle,
|
||||
}
|
||||
var current_scene_type = GanderSceneT.Introduction
|
||||
var auto_control_action = "facing_front"
|
||||
|
||||
var last_collided_id = null
|
||||
|
||||
@onready var parry_area = $ParryArea2D
|
||||
@onready var hit_area = $HitArea2D
|
||||
|
||||
@onready var animated = $AnimatedSprite2D
|
||||
|
||||
var battle_started = false
|
||||
|
||||
var max_health = 30
|
||||
var health = 30
|
||||
var health_dirty = true
|
||||
|
||||
var summon_item = null
|
||||
var summon_item_angle = 0.0
|
||||
var summon_item_summoned = false
|
||||
var summon_tween
|
||||
|
||||
var parry_tween = null
|
||||
|
||||
var parry_active = false
|
||||
var parry_body = null
|
||||
var hit_active = false
|
||||
var parry_success = false
|
||||
var parry_success_checked = false
|
||||
|
||||
enum AttackType {
|
||||
SWORD,
|
||||
HAMMER,
|
||||
}
|
||||
|
||||
var attack_target = null
|
||||
var attack_tween = null
|
||||
var attack_type = AttackType.SWORD
|
||||
|
||||
const SPEED = 150.0
|
||||
const ANIM_DEADZONE = 0.3
|
||||
const SUMMON_ITEM_DIST = 100.0
|
||||
const SUMMON_ITEM_Y_OFFSET = -30.0
|
||||
|
||||
func parry_entered(node):
|
||||
parry_active = true
|
||||
parry_success_checked = false
|
||||
parry_body = node
|
||||
func parry_exited(node):
|
||||
parry_active = false
|
||||
parry_body = null
|
||||
if battle_started:
|
||||
if parry_success:
|
||||
print("Successful parry")
|
||||
parry_success = false
|
||||
else:
|
||||
print("Failed to parry")
|
||||
var rng = RandomNumberGenerator.new()
|
||||
health -= rng.randi_range(1, 5)
|
||||
health_dirty = true
|
||||
|
||||
func hit_entered(node):
|
||||
hit_active = true
|
||||
func hit_exited(node):
|
||||
hit_active = false
|
||||
|
||||
func _ready():
|
||||
parry_area.area_entered.connect(parry_entered)
|
||||
parry_area.area_exited.connect(parry_exited)
|
||||
hit_area.area_entered.connect(hit_entered)
|
||||
hit_area.area_exited.connect(hit_exited)
|
||||
|
||||
func _process(delta):
|
||||
if parry_tween == null and attack_target == null:
|
||||
summon_item_angle += delta
|
||||
if summon_item_angle > TAU:
|
||||
summon_item_angle -= TAU
|
||||
if summon_item != null and not parry_success:
|
||||
summon_item.position.x = cos(-summon_item_angle) * SUMMON_ITEM_DIST
|
||||
summon_item.position.y = sin(-summon_item_angle) * SUMMON_ITEM_DIST + SUMMON_ITEM_Y_OFFSET
|
||||
elif parry_success and not parry_success_checked and parry_body != null:
|
||||
parry_success_checked = true
|
||||
parry_tween = get_tree().create_tween()
|
||||
parry_tween.set_parallel()
|
||||
parry_tween.set_trans(Tween.TRANS_SPRING)
|
||||
var between = parry_body.get_parent().position - self.position
|
||||
parry_tween.tween_property(summon_item, "position", between, 0.2)
|
||||
parry_tween.set_trans(Tween.TRANS_EXPO)
|
||||
parry_tween.tween_property(summon_item, "rotation", TAU * 10, 0.3)
|
||||
parry_tween.set_parallel(false)
|
||||
var old_x = cos(-summon_item_angle) * SUMMON_ITEM_DIST
|
||||
var old_y = sin(-summon_item_angle) * SUMMON_ITEM_DIST + SUMMON_ITEM_Y_OFFSET
|
||||
parry_tween.set_trans(Tween.TRANS_EXPO)
|
||||
parry_tween.tween_property(summon_item, "position", Vector2(old_x, old_y), 0.4)
|
||||
parry_tween.tween_callback(func():
|
||||
parry_tween = null
|
||||
summon_item.rotation = 0.0
|
||||
)
|
||||
elif attack_target != null and summon_item != null:
|
||||
attack_tween = get_tree().create_tween()
|
||||
var prev_x = cos(-summon_item_angle) * SUMMON_ITEM_DIST
|
||||
var prev_y = sin(-summon_item_angle) * SUMMON_ITEM_DIST + SUMMON_ITEM_Y_OFFSET
|
||||
attack_tween.set_parallel()
|
||||
attack_tween.tween_property(summon_item, "position", attack_target.position - self.position, 0.2)
|
||||
attack_tween.tween_property(summon_item, "rotation", -PI / 2.0, 0.2)
|
||||
attack_tween.set_parallel(false)
|
||||
var parent = get_parent()
|
||||
attack_tween.tween_callback(func():
|
||||
match attack_type:
|
||||
AttackType.SWORD:
|
||||
parent.play_attack_sfx_type = "sword"
|
||||
AttackType.HAMMER:
|
||||
parent.play_attack_sfx_type = "hammer"
|
||||
)
|
||||
attack_tween.set_parallel()
|
||||
attack_tween.tween_property(summon_item, "position", Vector2(prev_x, prev_y), 0.4)
|
||||
attack_tween.tween_property(summon_item, "rotation", 0.0, 0.4)
|
||||
attack_tween.set_parallel(false)
|
||||
attack_tween.tween_callback(func():
|
||||
attack_target = null
|
||||
)
|
||||
|
||||
if summon_item_summoned:
|
||||
summon_item_summoned = false
|
||||
var summon_overlay = Sprite2D.new()
|
||||
summon_overlay.set_name(&"SummonOverlay")
|
||||
summon_overlay.set_texture(summon_item.get_texture())
|
||||
add_child(summon_overlay, true)
|
||||
summon_overlay.set_owner(self)
|
||||
summon_overlay.set_scale(Vector2(5.0, 5.0))
|
||||
summon_overlay.self_modulate = Color(1.0, 1.0, 1.0, 0.4)
|
||||
summon_tween = get_tree().create_tween()
|
||||
summon_tween.set_parallel()
|
||||
summon_tween.set_trans(Tween.TRANS_EXPO)
|
||||
summon_tween.tween_property(summon_overlay, "rotation", -TAU * 50.0, 2.0)
|
||||
summon_tween.set_trans(Tween.TRANS_QUAD)
|
||||
summon_tween.tween_property(summon_overlay, "self_modulate", Color(1.0, 1.0, 1.0, 0.0), 2.0)
|
||||
summon_tween.set_parallel(false)
|
||||
summon_tween.tween_callback(func(): self.remove_child(summon_overlay))
|
||||
if health_dirty:
|
||||
health_dirty = false
|
||||
var hp_label = find_child("PlayerHPLabel")
|
||||
if hp_label == null:
|
||||
hp_label = Label.new()
|
||||
hp_label.set_name(&"PlayerHPLabel")
|
||||
add_child(hp_label, true)
|
||||
hp_label.set_owner(self)
|
||||
hp_label.position.y += 10.0
|
||||
hp_label.position.x -= 18.0
|
||||
hp_label.text = "%d HP" % health
|
||||
|
||||
func _physics_process(delta):
|
||||
var vec2 = Vector2()
|
||||
|
@ -57,4 +200,10 @@ func _physics_process(delta):
|
|||
elif animated.animation != auto_control_action:
|
||||
animated.play(auto_control_action)
|
||||
|
||||
if current_scene_type != GanderSceneT.Battle:
|
||||
move_and_slide()
|
||||
var last_collision = get_last_slide_collision()
|
||||
if last_collision != null:
|
||||
last_collided_id = last_collision.get_collider_id()
|
||||
else:
|
||||
last_collided_id = null
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=21 format=3 uid="uid://ktxqc7xtqkex"]
|
||||
[gd_scene load_steps=23 format=3 uid="uid://ktxqc7xtqkex"]
|
||||
|
||||
[ext_resource type="Script" path="res://gander_schwartz.gd" id="1_6ob4s"]
|
||||
[ext_resource type="Texture2D" uid="uid://cv0qw4j1q78r8" path="res://gimp/GanderSchwartz_spritesheet.png" id="1_n7bds"]
|
||||
|
@ -162,6 +162,14 @@ animations = [{
|
|||
radius = 15.0
|
||||
height = 80.0
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_sy0be"]
|
||||
radius = 32.0
|
||||
height = 126.0
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_58op3"]
|
||||
radius = 13.0
|
||||
height = 76.0
|
||||
|
||||
[node name="GanderSchwartz" type="CharacterBody2D"]
|
||||
motion_mode = 1
|
||||
script = ExtResource("1_6ob4s")
|
||||
|
@ -178,3 +186,25 @@ frame_progress = 0.126405
|
|||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
position = Vector2(0, -40)
|
||||
shape = SubResource("CapsuleShape2D_u3k2h")
|
||||
|
||||
[node name="ParryArea2D" type="Area2D" parent="."]
|
||||
collision_layer = 4
|
||||
collision_mask = 2
|
||||
input_pickable = false
|
||||
monitorable = false
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="ParryArea2D"]
|
||||
position = Vector2(0, -40)
|
||||
shape = SubResource("CapsuleShape2D_sy0be")
|
||||
debug_color = Color(0.631373, 0.352941, 0.984314, 0.419608)
|
||||
|
||||
[node name="HitArea2D" type="Area2D" parent="."]
|
||||
collision_layer = 4
|
||||
collision_mask = 2
|
||||
input_pickable = false
|
||||
monitorable = false
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="HitArea2D"]
|
||||
position = Vector2(0, -40)
|
||||
shape = SubResource("CapsuleShape2D_58op3")
|
||||
debug_color = Color(0.988235, 0, 0.290196, 0.419608)
|
||||
|
|
BIN
gimp/arrow.png
Normal file
BIN
gimp/arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 793 B |
34
gimp/arrow.png.import
Normal file
34
gimp/arrow.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c7ey8ay7etot7"
|
||||
path="res://.godot/imported/arrow.png-1ff2c1793b6898e6750b81c11b16be86.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://gimp/arrow.png"
|
||||
dest_files=["res://.godot/imported/arrow.png-1ff2c1793b6898e6750b81c11b16be86.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
|
BIN
gimp/hammer.png
Normal file
BIN
gimp/hammer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 684 B |
34
gimp/hammer.png.import
Normal file
34
gimp/hammer.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b6ci7lm15okhr"
|
||||
path="res://.godot/imported/hammer.png-430b8e98de82f10ad08a61167ab515de.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://gimp/hammer.png"
|
||||
dest_files=["res://.godot/imported/hammer.png-430b8e98de82f10ad08a61167ab515de.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
|
BIN
gimp/summon_arrow.png
Normal file
BIN
gimp/summon_arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 910 B |
34
gimp/summon_arrow.png.import
Normal file
34
gimp/summon_arrow.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dvyxj067n812g"
|
||||
path="res://.godot/imported/summon_arrow.png-8be3d4d199ac77e639f7001be6b20b00.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://gimp/summon_arrow.png"
|
||||
dest_files=["res://.godot/imported/summon_arrow.png-8be3d4d199ac77e639f7001be6b20b00.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
|
BIN
gimp/sword.png
Normal file
BIN
gimp/sword.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 644 B |
34
gimp/sword.png.import
Normal file
34
gimp/sword.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bemf77dxebgw1"
|
||||
path="res://.godot/imported/sword.png-10267e2e65de70563df10750bee7e827.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://gimp/sword.png"
|
||||
dest_files=["res://.godot/imported/sword.png-10267e2e65de70563df10750bee7e827.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
|
|
@ -44,3 +44,5 @@ texture = ExtResource("5_3irym")
|
|||
|
||||
[node name="MusicPlayer" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource("6_3kpot")
|
||||
|
||||
[node name="SFXPlayer" type="AudioStreamPlayer" parent="."]
|
||||
|
|
|
@ -10,10 +10,12 @@ config_version=5
|
|||
|
||||
[application]
|
||||
|
||||
config/name="LD55"
|
||||
config/name="LD55 - Gander and the Elemental Dungeon - by BurnedKirby"
|
||||
run/main_scene="res://main_scene.tscn"
|
||||
config/features=PackedStringArray("4.2", "GL Compatibility")
|
||||
boot_splash/bg_color=Color(0.141176, 0.141176, 0.141176, 1)
|
||||
config/icon="res://icon.svg"
|
||||
boot_splash/minimum_display_time=1000
|
||||
|
||||
[input]
|
||||
|
||||
|
|
123
summoning.gd
Normal file
123
summoning.gd
Normal file
|
@ -0,0 +1,123 @@
|
|||
extends Node2D
|
||||
|
||||
enum Direction {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
UP,
|
||||
DOWN,
|
||||
}
|
||||
|
||||
@onready var ar_one = $SummonArrow
|
||||
@onready var ar_two = $SummonArrow2
|
||||
@onready var ar_three = $SummonArrow3
|
||||
@onready var ar_four = $SummonArrow4
|
||||
@onready var ar_five = $SummonArrow5
|
||||
@onready var ar_six = $SummonArrow6
|
||||
@onready var ar_seven = $SummonArrow7
|
||||
@onready var ar_eight = $SummonArrow8
|
||||
|
||||
@onready var timer_box = $TimerBox
|
||||
const TIMER_BOX_WIDTH = 380.0
|
||||
|
||||
var summon_arrows_arr = []
|
||||
|
||||
var arrow_directions = []
|
||||
|
||||
const MAX_ERRORS = 3
|
||||
const MAX_SUCCESS = 8
|
||||
var error_count = 0
|
||||
var success_count = 0
|
||||
|
||||
const TIMER_AMOUNT = 5.0
|
||||
var timer = 0.0
|
||||
|
||||
func int_to_dir(i):
|
||||
match i:
|
||||
0:
|
||||
return Direction.LEFT
|
||||
1:
|
||||
return Direction.RIGHT
|
||||
2:
|
||||
return Direction.UP
|
||||
3:
|
||||
return Direction.DOWN
|
||||
_:
|
||||
return Direction.DOWN
|
||||
|
||||
func dir_to_angle(d: Direction):
|
||||
match d:
|
||||
Direction.LEFT:
|
||||
return 0.0
|
||||
Direction.RIGHT:
|
||||
return PI
|
||||
Direction.UP:
|
||||
return PI / 2.0
|
||||
Direction.DOWN:
|
||||
return PI * 3.0 / 2.0
|
||||
|
||||
func _ready():
|
||||
summon_arrows_arr.append(ar_one)
|
||||
summon_arrows_arr.append(ar_two)
|
||||
summon_arrows_arr.append(ar_three)
|
||||
summon_arrows_arr.append(ar_four)
|
||||
summon_arrows_arr.append(ar_five)
|
||||
summon_arrows_arr.append(ar_six)
|
||||
summon_arrows_arr.append(ar_seven)
|
||||
summon_arrows_arr.append(ar_eight)
|
||||
var rng = RandomNumberGenerator.new()
|
||||
for i in range(8):
|
||||
arrow_directions.append(int_to_dir(rng.randi_range(0, 3)))
|
||||
summon_arrows_arr[i].rotation = dir_to_angle(arrow_directions[i])
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
timer += delta
|
||||
if timer >= TIMER_AMOUNT:
|
||||
timer = 0.0
|
||||
if success_count < MAX_SUCCESS and error_count < MAX_ERRORS:
|
||||
on_summon_error()
|
||||
if success_count < MAX_SUCCESS and error_count < MAX_ERRORS:
|
||||
var interp_amount = (TIMER_AMOUNT - timer) / TIMER_AMOUNT
|
||||
timer_box.scale.x = interp_amount * TIMER_BOX_WIDTH
|
||||
timer_box.self_modulate = Color((1.0 - interp_amount), interp_amount, 0.0)
|
||||
|
||||
func _unhandled_input(event):
|
||||
if error_count >= MAX_ERRORS or success_count >= MAX_SUCCESS:
|
||||
return
|
||||
if event.is_pressed():
|
||||
if event.is_action("Left"):
|
||||
if arrow_directions[success_count] == Direction.LEFT:
|
||||
on_summon_success(success_count)
|
||||
else:
|
||||
on_summon_error()
|
||||
elif event.is_action("Right"):
|
||||
if arrow_directions[success_count] == Direction.RIGHT:
|
||||
on_summon_success(success_count)
|
||||
else:
|
||||
on_summon_error()
|
||||
elif event.is_action("Up"):
|
||||
if arrow_directions[success_count] == Direction.UP:
|
||||
on_summon_success(success_count)
|
||||
else:
|
||||
on_summon_error()
|
||||
elif event.is_action("Down"):
|
||||
if arrow_directions[success_count] == Direction.DOWN:
|
||||
on_summon_success(success_count)
|
||||
else:
|
||||
on_summon_error()
|
||||
|
||||
func on_summon_success(idx):
|
||||
summon_arrows_arr[idx].self_modulate = Color(0.0, 1.0, 0.0)
|
||||
success_count += 1
|
||||
|
||||
func on_summon_error():
|
||||
timer = 0.0
|
||||
success_count = 0
|
||||
error_count += 1
|
||||
if error_count >= MAX_ERRORS:
|
||||
for i in range(8):
|
||||
summon_arrows_arr[i].self_modulate = Color(1.0, 0.0, 0.0)
|
||||
else:
|
||||
for i in range(8):
|
||||
summon_arrows_arr[i].self_modulate = Color(1.0, 1.0, 1.0)
|
54
summoning.tscn
Normal file
54
summoning.tscn
Normal file
|
@ -0,0 +1,54 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://b7tummdg08cfc"]
|
||||
|
||||
[ext_resource type="Script" path="res://summoning.gd" id="1_qh1sn"]
|
||||
[ext_resource type="Texture2D" uid="uid://dvyxj067n812g" path="res://gimp/summon_arrow.png" id="2_io4qw"]
|
||||
|
||||
[sub_resource type="CanvasTexture" id="CanvasTexture_oraey"]
|
||||
|
||||
[node name="Node2D" type="Node2D"]
|
||||
script = ExtResource("1_qh1sn")
|
||||
|
||||
[node name="SummonArrow" type="Sprite2D" parent="."]
|
||||
position = Vector2(-136, -56)
|
||||
texture = ExtResource("2_io4qw")
|
||||
|
||||
[node name="SummonArrow2" type="Sprite2D" parent="."]
|
||||
position = Vector2(-46, -56)
|
||||
texture = ExtResource("2_io4qw")
|
||||
|
||||
[node name="SummonArrow3" type="Sprite2D" parent="."]
|
||||
position = Vector2(47, -55)
|
||||
texture = ExtResource("2_io4qw")
|
||||
|
||||
[node name="SummonArrow4" type="Sprite2D" parent="."]
|
||||
position = Vector2(143, -56)
|
||||
texture = ExtResource("2_io4qw")
|
||||
|
||||
[node name="SummonArrow5" type="Sprite2D" parent="."]
|
||||
position = Vector2(-144, 57)
|
||||
texture = ExtResource("2_io4qw")
|
||||
|
||||
[node name="SummonArrow6" type="Sprite2D" parent="."]
|
||||
position = Vector2(-49, 56)
|
||||
texture = ExtResource("2_io4qw")
|
||||
|
||||
[node name="SummonArrow7" type="Sprite2D" parent="."]
|
||||
position = Vector2(47, 57)
|
||||
texture = ExtResource("2_io4qw")
|
||||
|
||||
[node name="SummonArrow8" type="Sprite2D" parent="."]
|
||||
position = Vector2(136, 58)
|
||||
texture = ExtResource("2_io4qw")
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
offset_left = -187.0
|
||||
offset_top = -140.0
|
||||
offset_right = 188.0
|
||||
offset_bottom = -100.0
|
||||
theme_override_font_sizes/font_size = 24
|
||||
text = "Press the directions to summon!"
|
||||
|
||||
[node name="TimerBox" type="Sprite2D" parent="."]
|
||||
position = Vector2(0, 135)
|
||||
scale = Vector2(380, 50)
|
||||
texture = SubResource("CanvasTexture_oraey")
|
Loading…
Reference in a new issue