|
|
|
|
Reply From: |
njamster |
how can I add them to groups?
Explained here.
What is that index number in groups?
get_nodes_in_group
returns an Array (as documented here). The index number is used to access a certain element in that list, in your case: the first. Programming languages often start counting elements from 0 - that’s called 0-indexing.
What is pizza
Italian food. Very taste, you should try it…
if someone can explain me this code
Jokes aside: the script is attached to a node of type Area2D, apparently representing a food-item (namely: a pizza). If a body (i.e. a KinematicBody2D, a RigidBody2D or a StaticBody2D) named “Player” (exactly like this, names are case-sensitive, a node called “player” or “PLAYER” will not match!) enters that area, the pizza is deleted as soon as that is possible without breaking something else (that’s what’s queue_free()
is doing, on the other hand free
would delete the node immediately but make break things in your game, if other nodes still rely on this node being there) and emits a signal called “hit” that other nodes can connect to, if they want to react to this event. For example your player could play an animation when that signal is emitted or a counter could increase it’s value by 1 each time. Last but not least the collision shape of the pizza is disabled. So even if it isn’t deleted immediately, it cannot trigger the _on_Food_body_entered
-method again. Now the pizza is gone for good!
The second part is then ordering the node saved in the player
-variable to delete itself as soon as possible, sets the position of the node saved in the player2
-variable to the position of the node saved in the player
-variable and then makes that node visible. That’s the part where the player characters are swapped out.
In order for this code to work you…
- need to make sure the Area2D’s
body_entered
-signal is connected to the method _on_Food_body_entered
- the root-node of your default player-scene is in the group
action_when_body_is_touched
(again: exactly like this, case-sensitive)
- the root-node of your alternative player-scene is in the group
SimpleG
That being said I don’t think it’s a very good example to learn from. Here’s what I would do: Create a new scene for the item, make it an Area2D. Add a Sprite and a CollisionShape2D as children. Your tree should look like this now:
- Area2D
- Sprite
- CollisionShape2D
Next, add the following script to the Area2D-node:
extends Area2D
func _ready():
connect("body_entered", self, "_on_body_entered")
func _on_body_entered(body):
if body.name = "Player":
$CollisionShape2D.disabled = true
self.hide()
if body.has_method("transform"):
body.transform()
queue_free()
Now create a default player-scene, let’s say a KinematicBody2D, again with a Sprite and a CollisionShape2D, and attach the following script to it:
extends KinematicBody2D
var transformed = false
# ... other stuff like the movement code
func transform():
if not transformed:
transformed = true
# change what you want to change here, e.g.:
$Sprite.texture = load("res://icon.png")
I would like to destroy the old player and add a new one.
Switching out the entire player-character is a radical measure that is (imho) rarely justified. And judging from your description, it isn’t in your case as well! Chances are you want to change only certain aspects and keep everything else intact.
However, if you really want to do this, there’s is no need for groups:
extends Area2D
var transformed_player = preload("<PathToAlternativePlayerScene>")
func _ready():
connect("body_entered", self, "_on_body_entered")
func _on_body_entered(body):
if body.name == "Player":
$CollisionShape2D.disabled = true
self.hide()
body.hide()
body.get_node("CollisionShape2D").disabled = true
var new_player = transformed_player.instance()
new_player.global_position = body.global_position
get_parent().add_child(new_player)
body.queue_free()
queue_free()
I would love a “slow” explanation
I hope this qualifies as one. It certainly is a long one… ;D
Wow! Thanks man!
MightyRat | 2020-05-16 00:28
Maybe a bit late, but what would happen to all the functions where I wrote if body name == (“player”) ? Will the new trasformed one cause problems?
MightyRat | 2020-05-22 16:58
Not sure if I can follow… What do you mean by “all the functions” and “the new transformed one”? If you wrote if body.name == "Player"
, that won’t cause problems. Unless of course you rename your player node.
njamster | 2020-05-23 10:48
I made a portal with if body.name == “player” …
And when the player get trasformed the portal doesn ‘t work anymore
MightyRat | 2020-05-24 00:01
Then your transformed player scene isn’t named “player”!
Note that the names of nodes on the same layer have to be unique, so if you already have an instance called “player” and add another instance called “player”, the second one will be renamed by Godot in order to fulfill this constraint.
That’s why in many case it’s a bad idea to check a node’s name. Add both player nodes (the original and the transformed one) to a group “Player Character” and then check if a body is in that group with body.is_in_group("Player Character")
.
njamster | 2020-05-24 11:47
An other problem is how to access to the node of the new player, maybe it’s too much
complexity for my game…
MightyRat | 2020-05-25 09:50
When you instance the transformed player scene, the instance is returned and stored in new_player
. As long as you keep that variable around, you can use it to access the node. You could for example store it in a singleton. And as long as you now the name of the instance (you can print it after instancing using print(new_player.name)
), you can simply search for that node by its name (starting from the root of the tree) as well: get_tree().get_root().find_node("<NodeName>")
. However, that shouldn’t really be necessary: you know where you added the node and how it is named.
njamster | 2020-05-25 12:16