Creating a game "Like Coins" on Godot Engine. Part 2
3r? 3522. 3r3-31.
I hope you were waiting for the second part of the article covering the aspects of game development with the help of "Godot Engine", using the example of the game "Like Coins"? On the agenda cooked a lot of "tasty" and "healthy." Immediately, I’ll make a reservation that in this article we will complete the game we started earlier, the beginning of which you can read 3r333. here
, but the series of articles will continue, because There was so much material that made me put some of it aside, but we will definitely return to it later. Let gamedev begin! 3r33510.
3r? 3522.
The scene "Main"
3r? 3522.
In the previous part of the article we stopped at the main stage (3r3496. Main 3r3-3505.), From it, perhaps, we will continue. We delete everything that was added earlier (if you of course added something to check how everything works), if nothing was loaded into the scene, then 3r3496 should be added. Node which will be the parent for the nodes listed below, which in turn should also be added to the scene: 3r?535.
3r? 3522. ColorRect 3r3505. ("Background") - fill the background color;
3r? 3522. Player
- the object "Player" (I hope you are not confused, because of what I call the scene Player 3r3505. Object?);
3r? 3522. Node
("Container") - "container" for temporary storage of coins;
3r? 3522. Position2D
("PlayerStart") - at the start of the game sets the initial position of the object "Player";
3r? 3522. Timer
("GameTimer") - time limit counter; 3r33510.
3r? 3522.
Select
ColorRect 3r3505. and on the toolbar, select:
) . You can do the same with Layout -> Full Rect
in order to stretch it to the whole area of the screen (in the future we will often resort to this function, therefore I advise you to study independently and other operations listed in the list 3r3496. Layout TextureRect
, but instead of filling you will need to upload an image through the "Texture" property. For Position2D
, in the "position" property, we specify the values of "x" and "y" - this will serve as the starting position for 3r3496. Player
. Of course, using the script, you can set the positioning values directly in the itself. Player
, but we are not only learning how to develop games, but also learning "Godot", so consideration of different options for solving one task will not be superfluous. 3r33510.
3r? 3522.
Script for "Main"
3r? 3522.
Add a script for
Node
and print the following: 3r33510.
3r33535. 3r301501. 3r3502. extends Node
#PackedScene provides simplified access to the serialized object of the scene
export (PackedScene) var Coin
export (int) var playtime
3r? 3522. var level # current level
var score # points
var left_time # time for which the game lasts
var window_size # game window size
var playing = false # the game session is not running
3r? 3522.
The properties "Coin" and "playtime" will be displayed in 3r3496. Inspector . Drag the "Coin.tscn" scene into the "Coin" property, and set the "playtime" value to "40" (the duration of the game in seconds). 3r33510.
3r? 3522.
When starting the game, initialization should occur each time - preparation for work, determination of the required parameters for high-quality and error-free operation of the application. This is a mandatory step, so care should be taken first. 3r33510.
3r? 3522. 3r301501. 3r3502. func _ready ():
randomize () # initialize a random number generator with a random variable
window_size = get_viewport (). get_visible_rect (). size # Determine the visible area of the application 3r32222. $ Player.window_size = window_size # area of limitation for the Player object
$ Player.hide () # make the player invisible
3r? 3522.
Notice that when specifying the object name Player
the "$" character is used - it is "syntactic sugar" that allows you to directly access the node in the current scene, a good alternative to the method. get_node ("Node1")
(although the use of the latter is not forbidden). If "Node1" has a descendant of "Node2", you can also use this method - 3r3493. $ Node1 /Node2 . Note that in "Godot" autofilling works fine, so do not neglect to use it. Using spaces in node names is undesirable, but still acceptable, in this case, use quotation marks - 3r3496. $ "My best Node1" . 3r33510.
3r? 3522.
New game
3r? 3522.
To start a new game, we define for this an appropriate function, which we can then call, for example, by pressing a button. 3r33510.
3r? 3522. 3r301501. 3r3502. func new_game ():
playing = true # game session running
level = 1
score = 0
time_left = playtime
$ Player.start ($ PlayerStart.position)
$ Player.show ()
$ GameTimer.start () # start countdown timer 3r3353522. spawn_coins () # spawn coins
3r? 3522.
The function "start ()" whose argument is $ Playerstart.position
, will move the player to the initial location, and the "spawn_coins ()" function answers, as it is not difficult to guess, for spawning coins on the playing field. 3r33510.
3r? 3522. 3r301501. 3r3502. func spawn_coins ():
for i in range (4 + level):
var c = Coin.instance () 3r3353522. $ CoinContainer.add_child (c)
c.window_size = window_size
c.position = Vector2 (rand_range (? window_size.x),
rand_range (? window_size.y))
3r? 3522.
Function range (4 + level)
returns an array with the specified range, the value of which is equal to the sum of the number of coins and the value of the current level. A range can contain one argument, as in our case, either two arguments or three arguments (the third argument will be an array step). In this function, we create several instances of the "Coin" object and add as children for the node. CoinContainer
(I hope you did not forget that we already have access to the object, thanks to PackedScene
). Remember that whenever creating an instance of a new node (method Instance ()
), It must be added to the tree with the help of 3r3496. add_child () . Next, we set the area for the possible spawn of coins so that they do not accidentally appear behind the screen, and then we randomly assign a position. The last line does not look a bit aesthetically pleasing, so I propose to simplify it by resorting to the help of Singletons. 3r33510.
3r? 3522. 3r33175. Singltons
3r? 3522.
The second name of "Singltonov" - "Startup". Already leads to some thoughts, right? I tell you, Singleton works as follows: a script in which we can record anything (starting from declaring variables and ending with “switches” of scenes, including loading and unloading them) is loaded first, with the launch of the application, and all its contents are accessible from any project points. In its own way, it is some kind of user global storage of "anything and everything" available at any given time. 3r33510.
3r? 3522. 3r3183. Note that the project has its own global repository, the contents of which we can also use, and you can access it using 3r3496. ProjectSettings.get_setting (name) where name
Is the name of the required parameter. 3r3188.
So, to use something from the storage "_G", it is enough to call it by name, and then specify the called method or whatever we will have. 3r33510.
3r? 3522.
3r3194. 3r33510.
3r? 3522.
So, create an empty script and write the function listed below in it: 3r-3510.
3r? 3522. 3r301501. 3r3502. extends Node
3r? 3522. func rand ():
var rrand = Vector2 (rand_range (4? 760),
rand_range (4? 540))
return rrand # return the resulting value
3r? 3522.
Next, save it and go to the project settings: Project -> Project Settings -> AutoLoad
. Select our newly created script, set a name for it, for example, "_G", and go back to the function "spawn_coins ()" to correct the last date a little, replacing it with the following code:
3r? 3522. 3r301501. 3r3502. 3r33522. c.position = _G.rand ()
3r? 3522.
Now you can check what happened by putting "spawn_coins ()" in the "_ready ()" block and running the application on F5. And do not forget to choose as the main scene Main.tscn
If for some reason you made a wrong choice, you can change the main scene manually. To do this, go to the project settings: General -> Run -> MainScene
. Works? Then we go further. 3r33510.
3r? 3522.
How many coins are left?
3r? 3522.
Let's continue. Next, you need to check how many coins are left to transfer the player to the next level, give him a small "bonus" in the form of an increase in time by 4 seconds and re-collapse the coins. 3r33510.
3r? 3522. 3r301501. 3r3502. func _process (delta): 3r3353522. # are we still playing? and the number of coins is zero? 3r? 3522. if playing and $ CoinContainer.get_child_count () == 0:
# then you need to increase the level
level + = 1
# slightly "sweeten" the gameplay 3r3353522. time_left + = 5
# spawn coins
spawn_coins ()
3r? 3522.
User Interface 3r3409.
3r? 3522.
Our entire interface will consist of the following elements: score, current level, time, name of the game and a button, by pressing which the game will start. Create a scene ( HUD.tscn
) With parent CanvasLayer
(allows you to draw the user interface on top of the playing field). Looking ahead, I’ll say that it’s not very convenient to manage the elements of the user interface, at least I feel that way, but the rather wide list of elements and active development instills a positive attitude in the bright future of this aspect of the engine. 3r33510.
3r? 3522.
3r? 3522.
In "Godot" there are so-called "control nodes" that allow you to automatically format the child elements relative to the specified parameters of the parent. Each type of "control node" has special properties that control how they will manage the location of their descendants. A vivid representative of this type is MarginContainer
to add to the scene. With the help of 3r3496. Layout -> Top Wide stretch it at the top of the window, and in the properties of this object, in section Margin
specify indents from edges: left, top and right. At MarginContainer
There should be three subsidiaries of 3r3496. Label 3r3505. with the following names: ScoreLabel
, LevelLabel
and 3r3496. TimeLabel . Add them to the scene. Using property Align 3r3505. make it so that they are located on the left, center and right. It remains to add another
). 3r33510. Label 3r3505. (
, and just below place the button (3r3496. StartButton Messagelabel
), Placing it in the center, all with the help of 3r3496. Layout
3r33535.
3r3304. 3r33510.
3r33535.
Now we will make the interface responsive, we need to update the time, the number of collected coins and highlight the current level. Add a script for node HUD
. 3r33510.
3r? 3522. 3r301501. 3r3502. extends CanvasLayer
3r? 3522. signal start_game
3r? 3522. func update_score (value):
$ MarginContainer /ScoreLabel.text = str (value)
func update_level (value):
if len (str (value)) == 1:
$ MarginContainer /TimeLabel.text = "0: 0" + str (value)
else:
$ MarginContainer /TimeLabel.text = "0:" + str (value)
func update_timer (value):
$ MarginContainer /TimeLabel.txt = str (value)
3r? 3522.
For MessageLabel
we will need a timer in order to change the message text for a short period. Add the node Timer
and replace his name with MessageTimer
. In the inspector, you should set a wait time of 2 seconds and check the box in 3r3496. One Shot . This ensures that when you start the timer will work only once. 3r33510.
3r? 3522. 3r301501. 3r3502. func show_message (text): 3r3353522. $ MessageLabel.text = text 3r3353522. $ MessageLabel.show () 3r3353522. $ MessageTimer.start ()
3r? 3522.
Connect the signal. timeout () 3r3505. c "MessageTimer" and add the following: 3r33510.
3r? 3522. 3r301501. 3r3502. func _on_MessageTimer_timeout ():
$ MessageLabel.hide ()
3r? 3522.
On the "Node" tab for StartButton
connect the signal 3r3496. pressed () 3r3505. . When you press the button StartButton
she should hide with r3r3496. MessageLabel then send the signal to the main scene where we are in onnext, we intercept the function for execution at the same time - "new_game ()". We do this with the code below. Do not forget for the button, in the property Text
install any text calling to start the game. 3r33510.
3r? 3522. 3r301501. 3r3502. func _on_StartButton_pressed ():
$ StartButton.hide () 3r3353522. $ MessageLabel.hide () 3r3353522. emit_signal ("start_game")
3r? 3522.
To finally finish the interface, we will write the last, final function - the function of the end of the game. In this function, we need to show “Game Over” for no more than two seconds and then disappear, which is possible thanks to the “show_message ()” function. However, it is necessary to show the launch button of the new game again, as soon as the message notifying that the game is over will disappear. yield () 3r3505. suspend the function until a signal from 3r3496 is received. MessageTimer
In this case, the function will continue execution, returning us to its original state, so that we can again start a new game. 3r33510.
3r? 3522. 3r301501. 3r3502. func show_game_over ():
show_message ("Game Over") 3r33535. yield ($ MessageTimer, "timeout") 3r33522. $ StartButton.show () 3r3353522. $ MessageLabel.text = "LIKE COINS!" 3r? 3522. $ MessageLabel.show ()
3r? 3522. 3r3408. Ending? 3r3409.
3r? 3522.
Let's set up the feedback between HUD
and 3r3496. Main . Add a scene HUD
in the main stage and on the main stage we connect the signal 3r3496. GameTimer through timeout () 3r3505. adding the following: 3r33510.
3r? 3522. 3r301501. 3r3502. func _on_GameTimer_timeout ():
time_left - = 1 # countdown counter
$ HUD.update_timer (time_left) # update the counter interface
if time_left <= 0:
game_over () # end of the game at the end of the counter
3r? 3522.
Then connect the signals pickup () 3r3505. and 3r3496. die () 3r3505. player. 3r33510.
3r? 3522. 3r301501. 3r3502. func _on_Player_pickup ():
score + = 1 3r32222. $ HUD.update_score (score) 3r3353522. 3r? 3522. func _on_Player_die ():
game_over ()
3r? 3522.
At the end of the game must happen a few things that can not be overlooked. Write down the following code, and I will explain. 3r33510.
3r? 3522. 3r301501. 3r3502. func game_over ():
playing = false
$ GameTimer.stop ()
for coin in $ CoinContainer.get_children ():
coin.queue_free ()
$ HUD.show_game_over ()
$ Player.die ()
3r? 3522.
This function will stop the game, and then the remaining coins will be recounted and will remove the remaining coins, then a call will be made to 3r3496. show_game_over () for HUD
. Finally, you should activate StartButton
which should be connected to function new_game ()
. Click on node HUD
and in the connection dialog box, click on Make Function to Off
(This will prohibit the creation of a new function) and in the field 3-33-3496. Method In Node specify the name of the function to be connected - 3r3496. new_game . This will connect the signal to an existing function, rather than create a new one. 3r33510.
3r? 3522.
Finishing touches - remove new_game ()
from function 3r3496. _ready () and add the following two lines to function new_game ()
: 3r33510.
3r? 3522. 3r301501. 3r3502. 3r33522. $ HUD.update_score (score) 3r3353522. $ HUD.update_timer (time_left)
3r? 3522.
Now you can say with confidence that the game is ready, now it is quite a "playable", but without effects. We will look at the latter in the next article paying great attention to various kinds of "embellishments" in order to diversify the gameplay and further explore the possibilities of "Godot". So do not forget to follow the release of articles. Successes! 3r33510. 3r33518. 3r? 3522. 3r? 3522. 3r? 3522. 3r33515. ! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o-- ;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d,! 1): e.attachEvent ("onload", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () (); 3r? 3516. 3r? 3522. 3r33518. 3r? 3522. 3r? 3522. 3r? 3522. 3r? 3522.
It may be interesting
weber
Author24-11-2018, 09:24
Publication DateProgramming / Game development
Category- Comments: 0
- Views: 402
Helpful information. Fortunate me I discovered your web site accidentally,
and I am stunned why this accident did not happen earlier! I bookmarked it. Thanks, I've recently been looking for information about this topic for [hide]a[https://www.pizzahutcouponcode.com/pizza-hut-coupons-code/
] long time and yours is the greatest I've discovered so far. But, what concerning the conclusion? Are you positive about the source?
entegrasyon programları
entegrasyon programları