Godot 4 Intermediate Card Game: MainMenu & Run (S02E02)
Vložit
- čas přidán 25. 06. 2024
- Welcome to the second season of the "Godot 4 Card Game Course" using the powerful Godot engine! 🎮
In this beginner-intermediate tutorial, we'll implement the MainMenu and the ‘brain’ of the whole operation, the almighty Run Scene.
☕ If you want to support me, buy me a coffee at:
ko-fi.com/godotgamelab
🃏 Part 1: MainMenu, CharacterSelector & Run Scene
00:00 - Intro & Demo
02:21 - Code Changes From Season 1
05:47 - Main Menu: Visuals
15:49 - Main Menu Script + Signal Connections
16:49 - Main Menu Code
18:41 - Polished Menus and UI
19:24 - Character Selector Visuals
31:13 - Changing the CharacterStats Resource
32:44 - Creating New Resources for the Characters
36:06 - Coding the CharacterSelector
39:38 - Hooking Up the Character Selector from the Main Menu
41:45 - Ko-Fi Page Promotion
41:55 - Run Scene Preparation 1: New Events
42:52 - Run Scene Preparation 2: BattleOverPanel Change
43:55 - Run Scene Preparation 3: Placeholder Scenes for the Views
48:50 - Creating the Run Scene
53:40 - Coding the Run
58:34 - Testing the Run Scene
01:00:35 - Hooking Up the Run Scene: Discussion
01:03:23 - Creating the RunStartup Resource
01:05:16 - Modifying the Character Selector
01:07:02 - Modifying the Run Scene
01:09:26 - Final Test
01:11:22 - Outro & Credits
📽 Videos on Menu Design
• Menus Define Your Worl...
• So You Wanna Make Game...
📽 Videos on Scene Transitions
• Scene transition effec...
• Amazing Screen Transit...
• Godot 4 Smooth Scene T...
👩💻 Season 2 Starter Project on GitHub:
github.com/guladam/deck_build...
🎓 Learn More About Godot:
Godot Docs:
docs.godotengine.org/en/stabl...
docs.godotengine.org/en/stabl...
🔥 Connect with Me:
Instagram: / adamgulacsi
Twitter: / adam_gulacsi
Mastodon: mastodon.gamedev.place/@guladev
#godot #godot4 #cardgames #gamedev #indiedev
I just want to say, this is a gold mine for a new dev like myself. It shows that you have some serious experience with software dev with the considerations you give to architecture and modularity. I can't believe this is free. Thank you for being so generous with your knowledge.
Glad you like it, I really appreciate feedback and comments like yours 😌👌it's a super rewarding feeling to know it's helpful
Adam, do you realize you're a genius?
Really, thanks so much for this series. I've learned so much already. I'm happy I finally have the time to continue with season 2!
Thank you so much, glad to see you back! Let me know what you think about season 2 as you follow along! ☺️
@@godotgamelabWill do 😉 but I can already tell you I am super impressed by how polished the architecture + code are. I'm a total noob and am infinitely grateful to have found such a high level resource to develop those 2 pro-skills early on!
Great video, thanks!
Awesome video man! Thanks again for all this work.
Im loving this series, you appeared just when I was starting to code a DeckBuilder game as a beginner with no experience.
At the end of season 1 I modified some parts of the code from season 1 to adjust it to my idea of game and WOW how much i learned by doing that. Now at least this video felt a lot simpler and logical than the whole S1 to me.
Thanks for the feedback and good luck with your project 😌
Wow, I was beating my head against the wall trying to solve this exact issue the day before you posted this. Thank you so much for this, I'll have to go back and watch the first series now!
Glad that the video was helpful! ☺ Good luck with your journey :)
Adam I fucking love you !!! you are the best teacher !!!
Love that intensity! Thanks mate ❤
the run start up resource is great way to implement. I was struggling with that problem a lot
Glad you like it! Honestly, it took me a couple days to come up with the solution but I was pretty happy with it 👌
Would it have been better to make the character selector data-driven rather than hard coded? (e.g. assign N character resources to an array and fill out the buttons based on the array elements) Same thing for the run (i.e. to retain the ability to add new rooms later). That might require adding new signals at runtime, which apparently (I haven't tried it) can be done with add_user_signal - that way the rooms can register their own signals as needed.
Also, since you are using texture rects, is there a good way to replace the static images with animations / animated sprites?
Looking forward to more videos!
Hey, good questions let me give you my answers:
Character Selector: yes, that's an absolutely valid way to do it but to be honest I don't really see the benefit here. Don't get me wrong, the clean and flexible way to do it would be what you suggest. In my opinion though, indie devs need to be mindful of the over-engineering rabbithole. Think about it: realistically speaking it takes MONTHS to add a new character to the game: design all the cards, the relics, the art and so on. The Character Selector itself is very self-contained and adding a new character to the current solution is: duplicating a button and adding 2 lines of code. How much benefit would it provide to abstact it out? If you're a perfectionist I'd say go for it but for the sake of the tutorial I went for an easier solution.
Regarding the animations, I would add a Sprite2D and an AnimationPlayer node to the Button and save it as its own scene. Connect the Button mouse_entered and mouse_exited signals to the code and play/stop the animation. It's a simple and elegant solution in my opinion.
For the Run: I don't think its worth abstracting it out either because you need to implement custom logic anyways in the Run script to provide interactions between them. Right now, a lot of what we have is just placeholder code but later on you'll see that we need to do very specific things when we enter / exit the different rooms. This is all the responsibility of the Run class itself so you can't avoid having to touch this code when you want to add new room types.
Hope this makes sense! Thanks for your feedback ☺
Great Video yet again! I was stumped trying to do this myself with 0 prior exp in Godot after finishing your first season so thought I should wait, and I'm so glad I did!
I had a weird issue that took me about a week to fix when changing my character names in the file explorer that caused the game to try and reimport all the assets and crash everytime I tried to launch the project. I fixed it eventually by making a new project, copying all the parts over and reconnecting everything ... Then it seems that the .project file was all I needed to fix in the original file, I copied the new project file contents into the original file and everything worked fine again!
Is it possible that this file was corrupted somehow while I was moving and renaming files around? I was doing this in windows and not Godot, which I've learned since is a great sin.
Yeah, it's one of the biggest drawbacks of Godot right now I'd say. They are working on making renaming and refactoring smoother though!
I'd suggest using a version control system. Saved me countless times 😅
Hi Adam.Great video.I really love your tutorial.Just one question,in the character selector,why cant i switch to other characters like wizard and assassin in the battle scene ?
Bro please help me on this
they havent been implemented to switch to character stats data for each character
Hello !!! It's me again. I've a little issue I can't fix :
When my text is 16 px sized, things are cut 1px at the top.
When I change the font to be 12 px size, there's no problem.
I see that you don't have this issue (W and I letters from Warriors at 27:44 are perfectly fine for you, mine are cutted).
Do you know where I can search the solution ? I already tried to reimport the font using all the settings possible and the only one working is multichannel_signed_distance_field but it makes my text goes outside the label frame.
Thank you for your help.
At 58:42 I don't get printed anything and clicking buttons changes nothing. no error, code seems the same. gave code to ChatGPT, it didn't find anything, just suggested some things that weren't relevant I think. 4.3 dev2.
EDIT: found the bug. I did "var character = CharacterStats" instead of "var character: CharacterStats", so I like set the character and "if not character:" under _ready didn't work.
Hard to tell what's wrong without seeing the code you have... Might have something to do with the _change_view() function? That's where we instantiate those new Scenes.
Did you create all the placeholder Scenes? Also you need to change the label texts in those placeholder Scenes so you can actually see the difference. These are my best guesses 😅
@@godotgamelab Yeah pretty sure all placeholder scenes are in order. [deleted part] Will try more later and also with 4.2, will report what I find out eventually.
@@dimtool4183 yeah something seems super off...
If you still can't find it you can always zip up the project and email it to me. I'll try my best to debug it. Hopefully you'll find out what's wrong sooner though!
@@godotgamelab I found the bug. I did "var character = CharacterStats" instead of "var character: CharacterStats", so I like set the character and "if not character:" under _ready didn't work.
@@dimtool4183 uhhh that's a tough and pretty hard to spot! Good finding and squashing that annoying little 🪲!
Wow.. It's been a while since I've put so much in my head, so I'm a little dizzy. But it was nice to learn something new.
I don't understand it perfectly yet, but I'll have to take my time to rewatch it and get it! It's a really elegant system configuration, which is a bit confusing for me as a beginner.
But this isn't to say that I don't understand your explanation! It just coding itself is a bit confusing.😂
I'm really looking forward to the next video! I'll have to practice until the next video is uploaded! Thank you again for today!
Haha, you need to get back in shape for the spicy stuff! ☺
I feel you, coding CAN be confusing... Keep trying though, you'll get better, I promise! 💪
Does anyone know any possible solution to the problem of corruption of the run.tscn scene. I tried creating it two times already and every time then saved and closed project, after this, when i open the project again, godot sends me a message that scene run.tscn appears to be invalid/corrupt and i cant open that scene.
Edit: i have next errors in debugger:
1) E 0:00:00:0640 _parse_ext_resource: res://scenes/ui/main_menu.tscn:24 - Parse Error: [ext_resource] referenced non-existent resource at: res://scenes/ui/main_menu.gd scene/resources/resource_format_text.cpp:163 @ _parse_ext_resource()
2) E 0:00:00:0730 set_path: Another resource is loaded from path 'res://scenes/ui/main_menu.tscn' (possible cyclic resource inclusion). Method/function failed. core/io/resource.cpp:75 @ set_path()
I have this error as well, and I cant find a solution yet
Hi, love your tutorials. your code is so clean. i have a question is my code optimize or do i just make myself do more work?
extends CanvasLayer
const SWORDSMAN_STATS := preload("res://scenes/game_object/character/player/warrior/swordsman.tres")
const ARCHER_STATS := preload("res://scenes/game_object/character/player/archer/archer.tres")
const MAGE_STATS := preload("res://scenes/game_object/character/player/mage/mage.tres")
@onready var swordsman_button = %SwordsmanButton
@onready var archer_button = %ArcherButton
@onready var mage_button = %MageButton
@onready var title = %Title
@onready var description = %Description
@onready var character_portrait = $CharacterPortrait
@onready var start_button = $StartButton
@onready var back_button = $BackButton
var current_character: CharacterStats: set = set_current_character
func _ready():
swordsman_button.pressed.connect(on_swordsman_button_pressed)
archer_button.pressed.connect(on_archer_button_pressed)
mage_button.pressed.connect(on_mage_button_pressed)
start_button.pressed.connect(on_start_button_pressed)
back_button.pressed.connect(on_back_button_pressed)
set_current_character(SWORDSMAN_STATS)
func set_current_character(new_character: CharacterStats):
current_character = new_character
title.text = current_character.character_name
description.text = current_character.description
character_portrait.texture = current_character.portrait
func on_swordsman_button_pressed():
current_character = SWORDSMAN_STATS
func on_archer_button_pressed():
current_character = ARCHER_STATS
func on_mage_button_pressed():
current_character = MAGE_STATS
func on_start_button_pressed():
print("start new Run with %s" % current_character.character_name)
func on_back_button_pressed():
pass
Hey,
Not sure I understand your question. Whhat am I looking at exactly?
@@godotgamelab What I want to ask is the way I code is it optimized or should i copy the way you code that you directly connect the node rather than the need to hardcode the signals the way I do. Thanks