Compare commits

..

1 Commits

65 changed files with 85 additions and 1408 deletions

BIN
.DS_Store vendored 100644

Binary file not shown.

3
.gitignore vendored
View File

@ -2,8 +2,5 @@
.godot/
/android/
# macOS metadata
.DS_Store
# Claude Code
.claude/worktrees/

View File

@ -1,46 +0,0 @@
# Hexwarden
> **Brew. Cast. Survive.**
A top-down survival roguelike where you play as a witch holding her ground against endless waves of slimes. Collect magical fruits, brew powerful potions, and unleash devastating spells — for as long as you can.
Built with **Godot 4.6** as part of a university game engineering course at Hochschule Mannheim.
🎮 **[Play on itch.io](https://mik141.itch.io/hexwarden)**
---
## Gameplay
Enemies swarm in from all sides. Your only weapons are the spells you brew.
- Move with **WASD**
- Slimes drop **fruits** when killed — run over them to collect
- Fill all **3 cauldron slots** to trigger a brew and unleash a spell
- The fruit combination determines the spell
- Earn XP from kills → **level up** → choose one of multiple Perks
- Survive as long as possible
---
## Team
**Jaro Winkelhausen** — Game Development
**Arthur David** — Game Development
**Meik Schürmann** — Game Design, UI & Menu System
---
## About the Project
Hexwarden was built for the *Game Engineering* course (Prof. Dr. Kai Eckert, Hochschule Mannheim, SS 2026). None of us had significant game development experience when we started — this is a learning project made with a lot of trial, error, and genuine enthusiasm for the genre.
Inspired by [Vampire Survivors](https://store.steampowered.com/app/1794680/Vampire_Survivors/).
We're still actively developing it — expect bugs, rough edges, and future updates.
---
## License
This project was created for educational purposes. Assets from third-party packs are used under their respective licenses — see individual asset folders for details.

BIN
assets/.DS_Store vendored 100644

Binary file not shown.

BIN
assets/Swordsman_lvl1/.DS_Store vendored 100644

Binary file not shown.

BIN
assets/Swordsman_lvl2/.DS_Store vendored 100644

Binary file not shown.

View File

@ -1,14 +0,0 @@
Pixel Art License
Copyright © OceansCurse 2026 — All rights reserved.
You are free to:
- Use these assets in any personal or commercial project (including games, apps, merchandise, etc.).
- Modify, adapt, and create derivative works from these assets.
You are not permitted to:
- Redistribute, resell, or re-upload these assets (or substantial portions/modified versions) as standalone files, asset packs, or listings on itch.io, other marketplaces, or elsewhere.
- Present or claim these assets (original or modified) as your own original creation in a way that removes my authorship.
Attribution is not required, but always appreciated (e.g., "Assets by OceansCurse on itch.io").
These terms do not affect your rights under fair use or other applicable law.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://blotgjvb5lg5n"
path="res://.godot/imported/books_blue_gem.png-6b9e1efe847341054172f4dc841820d4.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_blue_gem.png"
dest_files=["res://.godot/imported/books_blue_gem.png-6b9e1efe847341054172f4dc841820d4.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 537 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b1dpo1suawep6"
path="res://.godot/imported/books_crimson_gem.png-e8e082c355c0dfd58d6abd9b647c9d64.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_crimson_gem.png"
dest_files=["res://.godot/imported/books_crimson_gem.png-e8e082c355c0dfd58d6abd9b647c9d64.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 472 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b0p1bbqie3r44"
path="res://.godot/imported/books_cross.png-35551b7d8d063fdb0725cd59a672b335.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_cross.png"
dest_files=["res://.godot/imported/books_cross.png-35551b7d8d063fdb0725cd59a672b335.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 621 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://jghgdp2kyjo7"
path="res://.godot/imported/books_eye.png-0b5ed65a09665cddbdbac80092f229ee.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_eye.png"
dest_files=["res://.godot/imported/books_eye.png-0b5ed65a09665cddbdbac80092f229ee.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 542 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://colq7wi3ti117"
path="res://.godot/imported/books_green_gem.png-1a6532ce505dc88ac93cf48f05352ebe.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_green_gem.png"
dest_files=["res://.godot/imported/books_green_gem.png-1a6532ce505dc88ac93cf48f05352ebe.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cq4qf7to1wg0m"
path="res://.godot/imported/books_health_potion.png-f8c3182e75c659e8cd07cbcee2ba8296.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_health_potion.png"
dest_files=["res://.godot/imported/books_health_potion.png-f8c3182e75c659e8cd07cbcee2ba8296.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://lo5ocyv4wo3e"
path="res://.godot/imported/books_jewel.png-81cbdb01e058151fa333b7a570f883b8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_jewel.png"
dest_files=["res://.godot/imported/books_jewel.png-81cbdb01e058151fa333b7a570f883b8.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 545 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://1pr5rqdnpnw5"
path="res://.godot/imported/books_mana_potion.png-e9b0c98b6782a5538a4f682f9d61384f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_mana_potion.png"
dest_files=["res://.godot/imported/books_mana_potion.png-e9b0c98b6782a5538a4f682f9d61384f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dlygc6jakfapg"
path="res://.godot/imported/books_pentagram.png-3e29e3d9c342d860aa7f6d22635f65db.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_pentagram.png"
dest_files=["res://.godot/imported/books_pentagram.png-3e29e3d9c342d860aa7f6d22635f65db.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 566 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cogqoxfqsnvv1"
path="res://.godot/imported/books_poison.png-3e8beaf0e04a26a46016fddeb0daf0f8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_poison.png"
dest_files=["res://.godot/imported/books_poison.png-3e8beaf0e04a26a46016fddeb0daf0f8.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ryhfe1a3haxf"
path="res://.godot/imported/books_purple_gem.png-a017fe601493fdc75182a2e7b6cf68cb.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_purple_gem.png"
dest_files=["res://.godot/imported/books_purple_gem.png-a017fe601493fdc75182a2e7b6cf68cb.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bnlacakjmdnp1"
path="res://.godot/imported/books_set_2_preview.png-e47aaf46da7c1d64191f8dfb0958de3a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_set_2_preview.png"
dest_files=["res://.godot/imported/books_set_2_preview.png-e47aaf46da7c1d64191f8dfb0958de3a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 B

View File

@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dm3wtcchfipcf"
path="res://.godot/imported/books_upside_down_cross.png-f374141fa42ba8d66998f6c556ae5908.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/books_set_2/books_upside_down_cross.png"
dest_files=["res://.godot/imported/books_upside_down_cross.png-f374141fa42ba8d66998f6c556ae5908.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

View File

@ -69,53 +69,3 @@ Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorActi
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.1]
name="Web"
platform="Web"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../Hexwarden/index.html"
patches=PackedStringArray()
patch_delta_encoding=false
patch_delta_compression_level_zstd=19
patch_delta_min_reduction=0.1
patch_delta_include_filters="*"
patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.1.options]
custom_template/debug=""
custom_template/release=""
variant/extensions_support=false
variant/thread_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/ensure_cross_origin_isolation_headers=true
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)
threads/emscripten_pool_size=8
threads/godot_pool_size=4

View File

@ -589,7 +589,7 @@ animations = [{
}],
"loop": false,
"name": &"hurt_down",
"speed": 20.0
"speed": 10.0
}, {
"frames": [{
"duration": 1.0,
@ -609,7 +609,7 @@ animations = [{
}],
"loop": false,
"name": &"hurt_left",
"speed": 20.0
"speed": 10.0
}, {
"frames": [{
"duration": 1.0,
@ -629,7 +629,7 @@ animations = [{
}],
"loop": false,
"name": &"hurt_right",
"speed": 20.0
"speed": 10.0
}, {
"frames": [{
"duration": 1.0,
@ -649,7 +649,7 @@ animations = [{
}],
"loop": false,
"name": &"hurt_up",
"speed": 20.0
"speed": 10.0
}, {
"frames": [{
"duration": 1.0,

View File

@ -1,68 +0,0 @@
[gd_scene format=3 uid="uid://bhcew4ksnx081"]
[ext_resource type="Script" uid="uid://dt85lj7ts5i87" path="res://scripts/credits.gd" id="1_0ctdu"]
[ext_resource type="Texture2D" uid="uid://2ddggeetjj1t" path="res://assets/images/screenshot_game.png" id="1_2ckv8"]
[ext_resource type="FontFile" uid="uid://8v71dcws4q6o" path="res://assets/fonts/slkscre.ttf" id="2_0ctdu"]
[node name="Credits" type="CanvasLayer" unique_id=45816245]
script = ExtResource("1_0ctdu")
[node name="BackgroundSprite" type="TextureRect" parent="." unique_id=356379919]
z_index = -2
offset_left = 4.0
offset_top = 2.0
offset_right = 1277.0
offset_bottom = 718.0
texture = ExtResource("1_2ckv8")
expand_mode = 2
[node name="BackgroundRect" type="ColorRect" parent="." unique_id=2118797143]
z_index = -1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 0.47058824)
[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=391956149]
z_index = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -308.5
offset_top = -106.0
offset_right = 308.5
offset_bottom = 106.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/separation = 50
alignment = 1
[node name="TitleLabel" type="Label" parent="VBoxContainer" unique_id=155909881]
layout_mode = 2
theme_override_fonts/font = ExtResource("2_0ctdu")
theme_override_font_sizes/font_size = 64
text = "Credits"
horizontal_alignment = 1
[node name="CreditsLabel" type="Label" parent="VBoxContainer" unique_id=267626570]
layout_mode = 2
theme_override_fonts/font = ExtResource("2_0ctdu")
theme_override_font_sizes/font_size = 20
text = "Assets — Swordsman, Slimes, Tiles craftpix.net
Asset — Witch AntumDeluge
Asset — Various Effects bdragon1727
Music — Main Menu (8 Bit Dungeon) Kaden_Cook
Music — In-Game (Ashveil) Pixelmaniax"
[node name="BackButton" type="Button" parent="VBoxContainer" unique_id=561894849]
layout_mode = 2
theme_override_fonts/font = ExtResource("2_0ctdu")
theme_override_font_sizes/font_size = 32
text = "Back"
[connection signal="pressed" from="VBoxContainer/BackButton" to="." method="_on_back_button_pressed"]

View File

@ -542,9 +542,9 @@ animations = [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_rdhnu")
}],
"loop": false,
"loop": true,
"name": &"hurt_down",
"speed": 20.0
"speed": 10.0
}, {
"frames": [{
"duration": 1.0,
@ -564,7 +564,7 @@ animations = [{
}],
"loop": true,
"name": &"hurt_left",
"speed": 20.0
"speed": 10.0
}, {
"frames": [{
"duration": 1.0,
@ -587,7 +587,7 @@ animations = [{
}],
"loop": true,
"name": &"hurt_right",
"speed": 20.0
"speed": 10.0
}, {
"frames": [{
"duration": 1.0,
@ -607,7 +607,7 @@ animations = [{
}],
"loop": true,
"name": &"hurt_up",
"speed": 20.0
"speed": 10.0
}, {
"frames": [{
"duration": 1.0,
@ -739,7 +739,7 @@ metadata/_custom_type_script = "uid://c0uv02nt5ocvg"
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=1151813585]
texture_filter = 1
sprite_frames = SubResource("SpriteFrames_05veu")
animation = &"hurt_up"
animation = &"walk_down"
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=2114857632]
position = Vector2(0, 1)

View File

@ -4,20 +4,36 @@
[ext_resource type="Script" uid="uid://cphrdy0xexx30" path="res://scenes/game.gd" id="1_vtaks"]
[ext_resource type="PackedScene" uid="uid://7vohdw0xop0g" path="res://scenes/worldborder.tscn" id="2_dinhu"]
[ext_resource type="Script" uid="uid://coplu13jpw4xq" path="res://scripts/camera_2d.gd" id="3_kvpfn"]
[ext_resource type="Script" uid="uid://b4jrogrq54c8f" path="res://scripts/SpawnEntry.gd" id="6_ir15t"]
[ext_resource type="Script" uid="uid://dovkm6w8af08x" path="res://scripts/spawn_control.gd" id="6_p57ef"]
[ext_resource type="PackedScene" uid="uid://ccotbw7gepsge" path="res://scenes/slime.tscn" id="7_ca42v"]
[ext_resource type="Texture2D" uid="uid://c4i3fnr6gpjp" path="res://assets/tileset/Tiled_files/details.png" id="7_gee14"]
[ext_resource type="PackedScene" uid="uid://b4v0ntaukg2je" path="res://scenes/witch.tscn" id="7_u5sy4"]
[ext_resource type="Texture2D" uid="uid://0xu8ohipv2mj" path="res://assets/tileset/Tiled_files/Objects.png" id="8_0tnpc"]
[ext_resource type="PackedScene" uid="uid://cj83ht5o2l8c1" path="res://scenes/blue_slime.tscn" id="8_rysoc"]
[ext_resource type="PackedScene" uid="uid://cgu7w2jd42f3a" path="res://scenes/tile_map_layer(background).tscn" id="8_vtaks"]
[ext_resource type="PackedScene" uid="uid://bgpsc6dvsn7ak" path="res://scenes/tile_map_layer(objects).tscn" id="9_kvpfn"]
[ext_resource type="PackedScene" uid="uid://co8t1fr3b3kub" path="res://scenes/tile_map_layer(overlay).tscn" id="10_dinhu"]
[ext_resource type="Script" uid="uid://ckv6prbe1o7s1" path="res://scripts/drop_manager.gd" id="10_vtaks"]
[ext_resource type="Script" uid="uid://pmmc7tivuuo4" path="res://scripts/perk_effects.gd" id="16_ca42v"]
[ext_resource type="Script" uid="uid://dm1sntwjrv3vl" path="res://scripts/level_up_manager.gd" id="16_rysoc"]
[ext_resource type="Texture2D" uid="uid://dp8o40ssuh8ip" path="res://assets/Tiny RPG Mana Soul GUI v1.0/20250421barB-Sheet.png" id="16_ssvqc"]
[ext_resource type="Script" path="res://scripts/pause_menu.gd" id="18_264po"]
[ext_resource type="Script" uid="uid://duauc778wc3hd" path="res://scripts/pause_menu.gd" id="18_264po"]
[ext_resource type="FontFile" uid="uid://8v71dcws4q6o" path="res://assets/fonts/slkscre.ttf" id="19_1kice"]
[ext_resource type="Script" path="res://scripts/options_menu_ingame.gd" id="20_1kice"]
[ext_resource type="Script" uid="uid://586y330mhx8" path="res://scripts/options_menu_ingame.gd" id="20_1kice"]
[ext_resource type="Texture2D" uid="uid://dp8o40ssuh8ip" path="res://assets/Tiny RPG Mana Soul GUI v1.0/20250421barB-Sheet.png" id="16_ssvqc"]
[sub_resource type="Resource" id="Resource_ssvqc"]
script = ExtResource("6_ir15t")
weight = 1.0
enemy = ExtResource("7_ca42v")
metadata/_custom_type_script = "uid://b4jrogrq54c8f"
[sub_resource type="Resource" id="Resource_264po"]
script = ExtResource("6_ir15t")
min_time = 10.0
weight = 0.5
enemy = ExtResource("8_rysoc")
metadata/_custom_type_script = "uid://b4jrogrq54c8f"
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_vtaks"]
texture = ExtResource("7_gee14")
@ -2429,14 +2445,14 @@ offset_top = 31.0
offset_right = 60.0
offset_bottom = 55.0
grow_horizontal = 2
text = "00:00"
horizontal_alignment = 1
theme_override_fonts/font = ExtResource("19_1kice")
theme_override_font_sizes/font_size = 20
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_colors/font_shadow_color = Color(0, 0, 0, 1)
theme_override_constants/shadow_offset_x = 1
theme_override_constants/shadow_offset_y = 1
theme_override_fonts/font = ExtResource("19_1kice")
theme_override_font_sizes/font_size = 20
text = "00:00"
horizontal_alignment = 1
[node name="LevelUpManager" type="Control" parent="CanvasLayer" unique_id=292400493]
process_mode = 3

View File

@ -45,8 +45,7 @@ alignment = 1
layout_mode = 2
theme_override_fonts/font = ExtResource("4_3vvtq")
theme_override_font_sizes/font_size = 64
text = "Hexwarden"
horizontal_alignment = 1
text = "Working Title"
[node name="PlayButton" type="Button" parent="VBoxContainer" unique_id=1536378372]
custom_minimum_size = Vector2(200, 45)
@ -62,12 +61,6 @@ theme_override_fonts/font = ExtResource("4_3vvtq")
theme_override_font_sizes/font_size = 32
text = "Options"
[node name="CreditsButton" type="Button" parent="VBoxContainer" unique_id=98861855]
layout_mode = 2
theme_override_fonts/font = ExtResource("4_3vvtq")
theme_override_font_sizes/font_size = 32
text = "Credits"
[node name="QuitButton" type="Button" parent="VBoxContainer" unique_id=1704957427]
custom_minimum_size = Vector2(200, 45)
layout_mode = 2
@ -77,5 +70,4 @@ text = "Quit"
[connection signal="pressed" from="VBoxContainer/PlayButton" to="." method="_on_play_button_pressed"]
[connection signal="pressed" from="VBoxContainer/OptionsButton" to="." method="_on_options_button_pressed"]
[connection signal="pressed" from="VBoxContainer/CreditsButton" to="." method="_on_credits_button_pressed"]
[connection signal="pressed" from="VBoxContainer/QuitButton" to="." method="_on_quit_button_pressed"]

View File

@ -399,7 +399,7 @@ animations = [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_qk6i7")
}],
"loop": false,
"loop": true,
"name": &"attack_down",
"speed": 10.0
}, {
@ -422,7 +422,7 @@ animations = [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_jx8is")
}],
"loop": false,
"loop": true,
"name": &"attack_left",
"speed": 10.0
}, {
@ -445,7 +445,7 @@ animations = [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_cbf1i")
}],
"loop": false,
"loop": true,
"name": &"attack_right",
"speed": 10.0
}, {
@ -468,7 +468,7 @@ animations = [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_qmsq4")
}],
"loop": false,
"loop": true,
"name": &"attack_up",
"speed": 10.0
}, {
@ -775,9 +775,6 @@ animations = [{
"speed": 10.0
}]
[sub_resource type="CircleShape2D" id="CircleShape2D_tuyoq"]
radius = 30.0
[node name="Player" type="CharacterBody2D" unique_id=804585690]
collision_mask = 129
motion_mode = 1
@ -789,16 +786,4 @@ shape = SubResource("CapsuleShape2D_u8vuu")
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=1616479252]
texture_filter = 1
sprite_frames = SubResource("SpriteFrames_giy8y")
animation = &"attack_left"
[node name="MeleeArea" type="Area2D" parent="." unique_id=24997730]
[node name="CollisionShape2D" type="CollisionShape2D" parent="MeleeArea" unique_id=2002113716]
shape = SubResource("CircleShape2D_tuyoq")
[node name="AttackSpeed" type="Timer" parent="." unique_id=2072925004]
wait_time = 0.506
autostart = true
[connection signal="body_entered" from="MeleeArea" to="." method="_on_melee_area_body_entered"]
[connection signal="timeout" from="AttackSpeed" to="." method="_on_attack_speed_timeout"]
animation = &"attack_up"

View File

@ -7,7 +7,6 @@
[ext_resource type="Texture2D" uid="uid://cxddvfs2wfwcl" path="res://assets/Slime1/Without_shadow/Slime1_Idle_without_shadow.png" id="3_rrqju"]
[ext_resource type="Texture2D" uid="uid://b2bmw70co6noy" path="res://assets/Slime1/Without_shadow/Slime1_Walk_without_shadow.png" id="4_wyhst"]
[ext_resource type="Texture2D" uid="uid://bshpjl3w1n0y1" path="res://assets/Slime1/With_shadow/Slime1_Death_with_shadow.png" id="5_gstla"]
[ext_resource type="Texture2D" uid="uid://dwpyocmvqptui" path="res://assets/Slime1/With_shadow/Slime1_Hurt_with_shadow.png" id="7_v5wyi"]
[sub_resource type="Resource" id="Resource_gstla"]
script = ExtResource("2_2npkn")
@ -239,86 +238,6 @@ region = Rect2(256, 0, 64, 64)
atlas = ExtResource("3_rrqju")
region = Rect2(320, 0, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_p5vph"]
atlas = ExtResource("7_v5wyi")
region = Rect2(0, 0, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_4vxow"]
atlas = ExtResource("7_v5wyi")
region = Rect2(64, 0, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_ymo5x"]
atlas = ExtResource("7_v5wyi")
region = Rect2(128, 0, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_v338d"]
atlas = ExtResource("7_v5wyi")
region = Rect2(192, 0, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_vn1yr"]
atlas = ExtResource("7_v5wyi")
region = Rect2(256, 0, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_il7ig"]
atlas = ExtResource("7_v5wyi")
region = Rect2(0, 128, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_5baf8"]
atlas = ExtResource("7_v5wyi")
region = Rect2(64, 128, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_mmuop"]
atlas = ExtResource("7_v5wyi")
region = Rect2(128, 128, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_7fqim"]
atlas = ExtResource("7_v5wyi")
region = Rect2(192, 128, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_0ivba"]
atlas = ExtResource("7_v5wyi")
region = Rect2(256, 128, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_0f1a3"]
atlas = ExtResource("7_v5wyi")
region = Rect2(0, 192, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_3qxe4"]
atlas = ExtResource("7_v5wyi")
region = Rect2(64, 192, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_8tsuk"]
atlas = ExtResource("7_v5wyi")
region = Rect2(128, 192, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_uxjht"]
atlas = ExtResource("7_v5wyi")
region = Rect2(192, 192, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_72t0a"]
atlas = ExtResource("7_v5wyi")
region = Rect2(256, 192, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_e0x1h"]
atlas = ExtResource("7_v5wyi")
region = Rect2(0, 64, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_eodiq"]
atlas = ExtResource("7_v5wyi")
region = Rect2(64, 64, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_d4gio"]
atlas = ExtResource("7_v5wyi")
region = Rect2(128, 64, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_q2l3s"]
atlas = ExtResource("7_v5wyi")
region = Rect2(192, 64, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_3l0w5"]
atlas = ExtResource("7_v5wyi")
region = Rect2(256, 64, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_fur4c"]
atlas = ExtResource("4_wyhst")
region = Rect2(0, 0, 64, 64)
@ -649,86 +568,6 @@ animations = [{
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_p5vph")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_4vxow")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ymo5x")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_v338d")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_vn1yr")
}],
"loop": true,
"name": &"hurt_down",
"speed": 20.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_il7ig")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5baf8")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_mmuop")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_7fqim")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0ivba")
}],
"loop": true,
"name": &"hurt_left",
"speed": 20.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_0f1a3")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_3qxe4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_8tsuk")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_uxjht")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_72t0a")
}],
"loop": true,
"name": &"hurt_right",
"speed": 20.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_e0x1h")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_eodiq")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_d4gio")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_q2l3s")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_3l0w5")
}],
"loop": true,
"name": &"hurt_up",
"speed": 20.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_fur4c")
}, {
"duration": 1.0,
@ -857,7 +696,7 @@ drop_table = Array[ExtResource("2_2npkn")]([SubResource("Resource_gstla")])
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=752118449]
texture_filter = 1
sprite_frames = SubResource("SpriteFrames_cbi0b")
animation = &"hurt_up"
animation = &"walk_right"
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=769710804]
position = Vector2(0, 1)

View File

@ -1,35 +0,0 @@
[gd_scene format=3 uid="uid://s5m6whnjl3cv"]
[ext_resource type="Script" uid="uid://c6w6hhayguqoj" path="res://scripts/spellbook.gd" id="1_f8wgx"]
[ext_resource type="Texture2D" uid="uid://dlygc6jakfapg" path="res://assets/books_set_2/books_pentagram.png" id="2_g1ouv"]
[sub_resource type="AtlasTexture" id="AtlasTexture_md3wj"]
atlas = ExtResource("2_g1ouv")
region = Rect2(0, 0, 32, 32)
[sub_resource type="SpriteFrames" id="SpriteFrames_qgan7"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_md3wj")
}],
"loop": true,
"name": &"default",
"speed": 10.0
}]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_i8red"]
size = Vector2(22.5, 26.5)
[node name="Spellbook" type="Area2D" unique_id=1926827672]
script = ExtResource("1_f8wgx")
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=1402601698]
texture_filter = 1
scale = Vector2(0.5, 0.5)
sprite_frames = SubResource("SpriteFrames_qgan7")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=609912720]
position = Vector2(-0.625, -0.625)
scale = Vector2(0.5, 0.5)
shape = SubResource("RectangleShape2D_i8red")

View File

@ -1,152 +0,0 @@
[gd_scene format=3 uid="uid://byqfrmwg0mi3y"]
[ext_resource type="Script" uid="uid://cikwl1ib4puyt" path="res://scripts/tornado.gd" id="1_shahy"]
[ext_resource type="Texture2D" uid="uid://c50u48fy7jtd" path="res://assets/Free Effect Bullet Impact Explosion 32x32 V1/Purple Effect Bullet Impact Explosion 32x32.png" id="2_3gxx4"]
[sub_resource type="AtlasTexture" id="AtlasTexture_vctls"]
atlas = ExtResource("2_3gxx4")
region = Rect2(192, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_2nlrq"]
atlas = ExtResource("2_3gxx4")
region = Rect2(224, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_yxxy5"]
atlas = ExtResource("2_3gxx4")
region = Rect2(256, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_mdjqp"]
atlas = ExtResource("2_3gxx4")
region = Rect2(288, 0, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_shahy"]
atlas = ExtResource("2_3gxx4")
region = Rect2(608, 160, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_3gxx4"]
atlas = ExtResource("2_3gxx4")
region = Rect2(576, 160, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_2nqqh"]
atlas = ExtResource("2_3gxx4")
region = Rect2(544, 160, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_g5iue"]
atlas = ExtResource("2_3gxx4")
region = Rect2(512, 160, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_c1uv1"]
atlas = ExtResource("2_3gxx4")
region = Rect2(512, 416, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_ido5e"]
atlas = ExtResource("2_3gxx4")
region = Rect2(512, 448, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_e7sy5"]
atlas = ExtResource("2_3gxx4")
region = Rect2(512, 384, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_0xwcu"]
atlas = ExtResource("2_3gxx4")
region = Rect2(544, 352, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_jd32a"]
atlas = ExtResource("2_3gxx4")
region = Rect2(576, 352, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_p68fy"]
atlas = ExtResource("2_3gxx4")
region = Rect2(608, 352, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_1h6yc"]
atlas = ExtResource("2_3gxx4")
region = Rect2(576, 384, 32, 32)
[sub_resource type="AtlasTexture" id="AtlasTexture_3p0aw"]
atlas = ExtResource("2_3gxx4")
region = Rect2(608, 384, 32, 32)
[sub_resource type="SpriteFrames" id="SpriteFrames_2nqqh"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_vctls")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_2nlrq")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_yxxy5")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_mdjqp")
}],
"loop": true,
"name": &"default",
"speed": 10.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_shahy")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_3gxx4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_2nqqh")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_g5iue")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_c1uv1")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ido5e")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_e7sy5")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0xwcu")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_jd32a")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_p68fy")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_1h6yc")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_3p0aw")
}],
"loop": false,
"name": &"explosion",
"speed": 10.0
}]
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_g5iue"]
radius = 25.0
height = 50.0
[sub_resource type="CircleShape2D" id="CircleShape2D_07hm3"]
radius = 54.0
[node name="Tornado" type="Area2D" unique_id=892015509]
script = ExtResource("1_shahy")
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=1613801541]
texture_filter = 1
scale = Vector2(1.5, 1.5)
sprite_frames = SubResource("SpriteFrames_2nqqh")
frame_progress = 0.68617874
[node name="ExplosionCollision" type="CollisionShape2D" parent="." unique_id=1019771818]
shape = SubResource("CapsuleShape2D_g5iue")
disabled = true
[node name="TornadoArea" type="CollisionShape2D" parent="." unique_id=1356386666]
shape = SubResource("CircleShape2D_07hm3")

View File

@ -2,9 +2,8 @@ extends Area2D
class_name ProjectileBase
@export var size: float
@export var damage: int = 5
var speed = 200
@export var element: String
@export var element: String
var direction: Vector2
func _ready() -> void:
@ -21,7 +20,7 @@ func launch(target: Vector2):
func _on_body_entered(body: Node2D) -> void:
if body.is_in_group("enemies"):
body.take_damage(damage)
body.hit()
queue_free()
func _remove():

View File

@ -3,9 +3,8 @@ extends EnemyBase
func _ready() -> void:
super()
speed = 15.0
max_hp = 25
hp = max_hp
# $Area2D.body_entered.connect(_on_area_2d_body_entered)
hits_remaining = 2
$Area2D.body_entered.connect(_on_area_2d_body_entered)
func _process(delta: float) -> void:
super._process(delta)
@ -13,6 +12,6 @@ func _process(delta: float) -> void:
return
_chase_witch()
#func _on_area_2d_body_entered(body: Node2D) -> void:
#if body == player:
#take_damage(player.damage)
func _on_area_2d_body_entered(body: Node2D) -> void:
if body == player:
hit()

View File

@ -82,16 +82,16 @@ func progres_bar(fruit):
func brew(fruits):
is_brewing = true
var unique = get_unique_fruits()
await ignite_cauldrons()
var apple_count = fruits.count(2)
var grape_count = fruits.count(4)
if apple_count == 2 and grape_count == 1:
if fruits == [2, 2, 4]:
witch.shoot_fire_swirl()
elif apple_count == 3:
elif unique.has(2) and unique.size() == 1:
witch.shoot_fireballs()
elif unique.has(4) and unique.size() == 1:
witch.shoot_shuriken()
elif unique.has(2) and unique.has(4) and unique.size() == 2:
witch.shoot_fireballs()
elif grape_count == 3:
witch.shoot_tornado()
elif apple_count == 1 and grape_count == 2:
witch.shoot_shuriken()
reset_texture()
is_brewing = false

View File

@ -1,15 +0,0 @@
extends CanvasLayer
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func _on_back_button_pressed() -> void:
get_tree().change_scene_to_file("res://scenes/mainmenu.tscn")

View File

@ -1 +0,0 @@
uid://dt85lj7ts5i87

View File

@ -6,11 +6,9 @@ extends CharacterBody2D
@export var damage: int = 2
@export var max_hp: int = 10
var is_dying = false
var is_hurt = false
var hp: int
var hits_remaining = 1
var _touching_witch: bool = false
var speed
var witch
@ -26,7 +24,6 @@ func _ready() -> void:
witch = get_node("/root/Game/Witch")
player = get_node("/root/Game/Player")
animated_sprite_2d.sprite_frames = animated_sprite_2d.sprite_frames.duplicate()
hp = max_hp
$Area2D.body_entered.connect(_on_base_body_entered)
$Area2D.body_exited.connect(_on_base_body_exited)
@ -48,44 +45,34 @@ func die():
death_anim = "death_up" if last_direction.y < 0 else "death_down"
animated_sprite_2d.sprite_frames.set_animation_loop(death_anim, false)
animated_sprite_2d.play(death_anim)
_play_hit_sound()
var player = AudioStreamPlayer.new()
add_child(player)
player.stream = death_sound
player.bus = "SFX"
player.play()
died.emit(self)
await animated_sprite_2d.animation_finished
queue_free()
func _play_hit_sound() -> void:
var ap = AudioStreamPlayer.new()
add_child(ap)
ap.stream = death_sound
ap.bus = "SFX"
ap.pitch_scale = randf_range(0.7, 1.3)
ap.play()
func take_damage(amount: int) -> void:
func hit() -> void:
if is_dying or is_hurt:
return
hp -= amount
if hp <= 0:
hits_remaining -= 1
if hits_remaining <= 0:
die()
else:
_play_hurt()
func hit() -> void:
take_damage(1)
func _play_hurt() -> void:
is_hurt = true
var hurt_anim: String
if abs(last_direction.x) >= abs(last_direction.y):
hurt_anim = "hurt_left" if last_direction.x < 0 else "hurt_right"
else:
hurt_anim = "hurt_up" if last_direction.y < 0 else "hurt_down"
if not animated_sprite_2d.sprite_frames.has_animation(hurt_anim):
return
is_hurt = true
_play_hit_sound()
animated_sprite_2d.sprite_frames.set_animation_loop(hurt_anim, false)
animated_sprite_2d.play(hurt_anim)
await get_tree().create_timer(0.25, true).timeout
await animated_sprite_2d.animation_finished
is_hurt = false
func _process(delta: float) -> void:

View File

@ -1,12 +1,12 @@
extends Area2D
@export var damage: int = 15
# Called when the node enters the scene tree for the first time.
func _ready():
await get_tree().physics_frame
for body in get_overlapping_bodies():
if body.is_in_group("enemies"):
body.take_damage(damage)
body.hit()
await $AnimatedSprite2D.animation_finished
queue_free()

View File

@ -3,8 +3,7 @@ extends EnemyBase
func _ready() -> void:
super()
speed = 15.0
max_hp = 50
hp = max_hp
hits_remaining = 3
$Area2D.body_entered.connect(_on_area_2d_body_entered)
func _process(delta: float) -> void:
@ -14,6 +13,5 @@ func _process(delta: float) -> void:
_chase_witch()
func _on_area_2d_body_entered(body: Node2D) -> void:
#if body == player:
# take_damage(player.damage)
pass
if body == player:
hit()

View File

@ -15,10 +15,9 @@ const DIRS := [
func _on_body_entered(body: Node2D) -> void:
if body.is_in_group("enemies"):
body.take_damage(damage)
body.hit()
func _ready() -> void:
damage = 6
if _is_spread_child:
super()
return

View File

@ -2,16 +2,11 @@ extends ProjectileBase
var fireball_aoe = false
var explosion_scene = preload("res://scenes/explosion.tscn")
@onready var perk_effects = get_node("/root/Game/PerkEffects")
func _ready() -> void:
super()
damage = 8
@onready var perk_effects = get_node("/root/Game/PerkEffects")# Called when the node enters the scene tree for the first time.
func _on_body_entered(body: Node2D) -> void:
fireball_aoe = perk_effects.fireball_aoe_enabled
if body.is_in_group("enemies"):
body.take_damage(damage)
body.hit()
if fireball_aoe:
var boom = explosion_scene.instantiate()
boom.global_position = global_position

View File

@ -8,9 +8,6 @@ func _on_play_button_pressed() -> void:
func _on_options_button_pressed() -> void:
get_tree().change_scene_to_file("res://scenes/options.tscn")
func _on_credits_button_pressed() -> void:
get_tree().change_scene_to_file("res://scenes/credits.tscn")
func _on_quit_button_pressed() -> void:
get_tree().quit()

View File

@ -9,17 +9,8 @@ var available_perks: Array[Perk] = []
var fireball_aoe_enabled = false
var throwing_knife_enabled = false
var throwing_knife_cooldown: float = 2.0
var throwing_knife_count: int = 1
var _knife_timer: float = 0.0
var spellbook_scene = preload("res://scenes/spellbook.tscn")
var spellbook_count: int = 0
var spellbook_damage: int = 12
var spellbook_speed: float = 1.5
const SPELLBOOK_RADIUS: float = 60.0
var _spellbook_angle: float = 0.0
var _spellbooks: Array = []
func _ready() -> void:
cauldron = witch.get_node("CauldronBar")
var dsh = Perk.new()
@ -42,11 +33,6 @@ func _ready() -> void:
tk.description = "Automatically throw a knife at the nearest enemy every second"
tk.effect = enable_throwing_knife
available_perks.append(tk)
var sb = Perk.new()
sb.name = "Spellbook"
sb.description = "A spellbook orbits the witch, dealing 12 damage to enemies it touches"
sb.effect = unlock_spellbook
available_perks.append(sb)
func _process(delta: float) -> void:
if throwing_knife_enabled:
@ -54,11 +40,6 @@ func _process(delta: float) -> void:
if _knife_timer >= throwing_knife_cooldown:
_knife_timer = 0.0
_shoot_throwing_knife()
if spellbook_count > 0:
_spellbook_angle += spellbook_speed * delta
for i in range(_spellbooks.size()):
var offset = (TAU / _spellbooks.size()) * i
_spellbooks[i].global_position = witch.global_position + Vector2(cos(_spellbook_angle + offset), sin(_spellbook_angle + offset)) * SPELLBOOK_RADIUS
func double_shuriken():
witch.shuriken_count = 2
@ -76,20 +57,6 @@ func enable_throwing_knife():
upg.description = "Reduce throwing knife cooldown by 0.2s (min 1s)"
upg.effect = knife_cooldown_upgrade
available_perks.append(upg)
var ek = Perk.new()
ek.name = "Extra Knife"
ek.description = "Throw one additional knife per attack (max 3)"
ek.effect = extra_knife
available_perks.append(ek)
func extra_knife():
throwing_knife_count = min(throwing_knife_count + 1, 3)
if throwing_knife_count < 3:
var ek = Perk.new()
ek.name = "Extra Knife"
ek.description = "Throw one additional knife per attack (max 3)"
ek.effect = extra_knife
available_perks.append(ek)
func knife_cooldown_upgrade():
throwing_knife_cooldown = maxf(1.0, throwing_knife_cooldown - 0.2)
@ -101,65 +68,7 @@ func knife_cooldown_upgrade():
available_perks.append(upg)
func _shoot_throwing_knife() -> void:
for i in range(throwing_knife_count):
var knife = throwing_knife.instantiate()
knife.global_position = witch.global_position
witch.get_parent().add_child(knife)
func unlock_spellbook() -> void:
spellbook_count = 1
_rebuild_spellbooks()
var eb = Perk.new()
eb.name = "Extra Book"
eb.description = "Add another spellbook (max 5)"
eb.effect = extra_book
available_perks.append(eb)
var fo = Perk.new()
fo.name = "Faster Orbit"
fo.description = "Spellbooks orbit the witch faster"
fo.effect = faster_orbit
available_perks.append(fo)
var bd = Perk.new()
bd.name = "Book Damage"
bd.description = "Spellbooks deal 4 more damage"
bd.effect = book_damage
available_perks.append(bd)
func extra_book() -> void:
spellbook_count = min(spellbook_count + 1, 5)
_rebuild_spellbooks()
if spellbook_count < 5:
var eb = Perk.new()
eb.name = "Extra Book"
eb.description = "Add another spellbook (max 5)"
eb.effect = extra_book
available_perks.append(eb)
func faster_orbit() -> void:
spellbook_speed += 0.5
var fo = Perk.new()
fo.name = "Faster Orbit"
fo.description = "Spellbooks orbit the witch faster"
fo.effect = faster_orbit
available_perks.append(fo)
func book_damage() -> void:
spellbook_damage += 4
for book in _spellbooks:
book.damage = spellbook_damage
var bd = Perk.new()
bd.name = "Book Damage"
bd.description = "Spellbooks deal 4 more damage"
bd.effect = book_damage
available_perks.append(bd)
func _rebuild_spellbooks() -> void:
for book in _spellbooks:
book.queue_free()
_spellbooks.clear()
for i in range(spellbook_count):
var book = spellbook_scene.instantiate()
book.damage = spellbook_damage
witch.get_parent().add_child(book)
_spellbooks.append(book)
var knife = throwing_knife.instantiate()
knife.global_position = witch.global_position
witch.get_parent().add_child(knife)

View File

@ -1,19 +1,14 @@
extends CharacterBody2D
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
var current_xp = 0
var max_xp = 5
var max_xp =5
var level = 1
var speed = 200
var damage: int = 10
var strength = 3
var attacks = false
var speed = 200 # speed in pixels/sec
func _physics_process(delta):
var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
velocity = direction * speed
move_and_slide()
if attacks == true:
return
if direction == Vector2.ZERO:
animated_sprite_2d.play("idle")
elif abs(direction.x) >= abs(direction.y):
@ -28,54 +23,4 @@ func _physics_process(delta):
animated_sprite_2d.play("walk_down")
func attack():
if attacks:
return
for body in $MeleeArea.get_overlapping_bodies():
if body.is_in_group("enemies"):
attacks = true
var dir = global_position.direction_to(body.global_position)
if dir == Vector2.ZERO:
animated_sprite_2d.play("idle")
elif abs(dir.x) >= abs(dir.y):
if dir.x < 0:
animated_sprite_2d.play("attack_left")
else:
animated_sprite_2d.play("attack_right")
else:
if dir.y < 0:
animated_sprite_2d.play("attack_up")
else:
animated_sprite_2d.play("attack_down")
animated_sprite_2d.speed_scale = 0.5 / $AttackSpeed.wait_time * 1.4
var wait_time = $AttackSpeed.wait_time
await get_tree().create_timer(wait_time / 2).timeout
body.take_damage(strength)
var knockback_dir = global_position.direction_to(body.global_position)
var enemy_tween = create_tween()
enemy_tween.tween_property(body, "global_position", body.global_position + knockback_dir * 20, 0.1).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_QUAD)
var player_tween = create_tween()
player_tween.tween_property(self, "global_position", global_position - knockback_dir * 10, 0.1).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_QUAD)
await animated_sprite_2d.animation_finished
animated_sprite_2d.speed_scale = 1
attacks = false
break
func _on_attack_speed_timeout() -> void:
if $MeleeArea.get_overlapping_bodies().any(func(b): return b.is_in_group("enemies")):
attack()
else:
$AttackSpeed.call_deferred("stop")
pass # Replace with function body.
func _on_melee_area_body_entered(body: Node2D) -> void:
if body.is_in_group("enemies"):
if $AttackSpeed.is_stopped():
attack()
$AttackSpeed.start()
move_and_slide()

View File

@ -6,7 +6,6 @@ var enemies_hit = 0
func _ready() -> void:
speed = 500
super()
damage = 5
var first = get_nearest_enemy(global_position)
if first == null:
queue_free()
@ -16,7 +15,7 @@ func _ready() -> void:
func _on_body_entered(body: Node2D) -> void:
if body.is_in_group("enemies") and not body.is_hurt and not body.is_dying:
enemies_hit += 1
body.take_damage(damage)
body.hit()
if enemies_hit == 20:
queue_free()
else:

View File

@ -3,17 +3,15 @@ extends EnemyBase
func _ready() -> void:
super()
speed = 15.0
max_hp = 10
hp = max_hp
func _process(delta: float) -> void:
super._process(delta)
if is_dying or is_hurt:
if is_dying:
return
_chase_witch()
func _on_area_2d_body_entered(body: Node2D) -> void:
if is_dying:
return
# if body == player:
# take_damage(player.damage)
if body == player:
die()

View File

@ -1,18 +0,0 @@
extends Area2D
var damage: int = 12
var _hit_cooldowns: Dictionary = {}
func _ready() -> void:
body_entered.connect(_on_body_entered)
func _process(delta: float) -> void:
for enemy in _hit_cooldowns.keys():
_hit_cooldowns[enemy] -= delta
if _hit_cooldowns[enemy] <= 0.0:
_hit_cooldowns.erase(enemy)
func _on_body_entered(body: Node2D) -> void:
if body.is_in_group("enemies") and not _hit_cooldowns.has(body):
body.take_damage(damage)
_hit_cooldowns[body] = 0.8

View File

@ -1 +0,0 @@
uid://c6w6hhayguqoj

View File

@ -5,7 +5,6 @@ var _target_enemy: Node = null
func _ready() -> void:
super()
speed = 400.0
damage = 12
var witch = get_node("/root/Game/Witch")
_target_enemy = witch.get_nearest_enemy(witch.global_position, _knife_filter)
if _target_enemy == null:

View File

@ -1,47 +0,0 @@
extends Area2D
@export var pull_duration: float = 1.2
@export var pull_strength: float = 140.0
@export var explosion_damage: int = 50
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
@onready var tornado_area: CollisionShape2D = $TornadoArea
@onready var explosion_collision: CollisionShape2D = $ExplosionCollision
var _is_pulling := true
var _damaged_enemies: Array[Node] = []
func _ready() -> void:
tornado_area.disabled = false
explosion_collision.disabled = true
if animated_sprite_2d.sprite_frames.has_animation("default"):
animated_sprite_2d.play("default")
await get_tree().create_timer(pull_duration).timeout
_explode()
func _physics_process(delta: float) -> void:
if not _is_pulling:
return
for enemy in get_overlapping_bodies():
if not enemy.is_in_group("enemies"):
continue
if enemy.is_dying:
continue
enemy.global_position = enemy.global_position.move_toward(global_position, pull_strength * delta)
func _explode() -> void:
_is_pulling = false
tornado_area.disabled = true
explosion_collision.disabled = false
if animated_sprite_2d.sprite_frames.has_animation("explosion"):
animated_sprite_2d.play("explosion")
await get_tree().physics_frame
for body in get_overlapping_bodies():
if body.is_in_group("enemies") and not _damaged_enemies.has(body):
body.take_damage(explosion_damage)
_damaged_enemies.append(body)
if animated_sprite_2d.sprite_frames.has_animation("explosion"):
await animated_sprite_2d.animation_finished
else:
await get_tree().create_timer(0.35).timeout
queue_free()

View File

@ -1 +0,0 @@
uid://cikwl1ib4puyt

View File

@ -7,7 +7,6 @@ var is_casting = false
var fireball = preload("res://scenes/fireball.tscn")
var shuriken = preload("res://scenes/shuriken.tscn")
var fire_swirl = preload("res://scenes/fire_swirl.tscn")
var tornado = preload("res://scenes/tornado.tscn")
var shuriken_count = 1
var max_hp: int = 100
@ -69,13 +68,6 @@ func shoot_shuriken():
sh.global_position = global_position
get_parent().add_child(sh)
await get_tree().create_timer(0.2).timeout
func shoot_tornado():
var target = get_nearest_enemy(global_position)
var tw = tornado.instantiate()
tw.global_position = target.global_position if target != null else global_position
get_parent().add_child(tw)
camera.shake(0.3, 0.8)
func take_damage(amount: int) -> void:
if is_invincible: