Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | Robster | |
Old Version | Published before Godot 3 was released. |
Hi all,
Have a look at this complete code. I want to select a random powerup to display. I have an array or powerup names, one is randomly chosen. Then, based on the random choice, the system needs to draw the sprite.
I look at all the if elif statements and wonder if there’s not a more efficient method?
extends Node2D
onready var labeloutput = get_node("RichTextLabel")
var powerUpSprite
func _ready():
spawnRandomPowerup()
func spawnRandomPowerup():
#list of power ups
var powerUpArray = ["speedUpBat","slowDownBat","speedUpOtherBat","slowDownOtherBat","speedUpBall","slowDownBall","makeBatLarger","makeBatSmaller","freezeBat","doublePoints","randomObstacle","powerBall"]
#get like... totally random dude
randomize()
#pick randomly from the list of power ups
var theChosenOne = powerUpArray[randi()%powerUpArray.size()]
#print all the available choices
for choice in powerUpArray:
labeloutput.add_text(choice)
labeloutput.add_text("\n")
#print the chosen one
labeloutput.add_text("\n")
labeloutput.add_text(theChosenOne)
#render the chose powerup on screen
renderPowerup(theChosenOne)
func renderPowerup(powerUp):
powerUpSprite = Sprite.new() #create a new sprite
add_child(powerUpSprite) #add it as a child
var powerUpImage #the texture of the powerup will live here
#I wonder, there must be a more efficient way to do this?
if powerUp == "speedUpBat":
powerUpImage = load("res://textures/speedUpBat.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "slowDownBat":
powerUpImage = load("res://textures/slowDownBat.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "speedUpOtherBat":
powerUpImage = load("res://textures/speedUpOtherBat.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "slowDownOtherBat":
powerUpImage = load("res://textures/slowDownOtherBat.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "speedUpBall":
powerUpImage = load("res://textures/speedUpBall.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "slowDownBall":
powerUpImage = load("res://textures/slowDownBall.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "makeBatLarger":
powerUpImage = load("res://textures/makeBatLarger.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "makeBatSmaller":
powerUpImage = load("res://textures/makeBatSmaller.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "freezeBat":
powerUpImage = load("res://textures/freezeBat.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "doublePoints":
powerUpImage = load("res://textures/doublePoints.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "randomObstacle":
powerUpImage = load("res://textures/randomObstacle.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
elif powerUp == "powerBall":
powerUpImage = load("res://textures/powerBall.png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
func _on_Button_pressed():
labeloutput.clear()
powerUpSprite.hide()
spawnRandomPowerup()
if you keep the image file names the same as the powerUp names you could skip the if statement and do something like the following.
powerUpImage = load("res://textures/"+powerUp+".png")
powerUpSprite.set_texture(powerUpImage)
powerUpSprite.set_pos(Vector2(100,100))
D | 2017-03-24 22:56
that… is so simple and so obvious (slaps face).
Thank you
Robster | 2017-03-24 23:11
It would be nice to turn the D comment into an answer
DriNeo | 2017-03-26 09:32
although that solution works for that piece of code, it won’t do much when you actually need to change something in the game besides the sprites. I assume those powerups will change variable values or something like that, so you will still need to check each case.
One solution for this could be to make a dictionary, each entry would be one powerup and contain the imagefile, etc, plus a callback for a function to activate that powerup.
Nuno Donato | 2017-03-27 13:42
This has been playing on my mind as I’ve been considering the exact issue. I haven’t reached the effect of each power up yet but that’s the perfect solution (dictionary). I guess I’ll still need a huge if ELIF statement then. I can’t seem to find anything about case statements in Godot being implemented.
Robster | 2017-03-27 21:47
no, with the dictinary you dont need any if statements, you just access the dictionary entry directly like
var selected_powerup = powerups[my_selection]
image = selected_powerup.image
hpchange += selected_powerup.hp
Nuno Donato | 2017-03-27 21:50
Thank you for this. I have to say I’m quite new at programming in general so please excuse my ignorance. I’ve been having a go at this but I can’t seem to find out how to add all that data into a single dictionary to pull it out again as you’ve shown.
Imagine I have a dictionary called powerups
.
I can do this kind of thing:
var powerUpDict = {
powerUpName = "speedUpBat",
batSpeedChange = 10,
ballSpeedChange = 0,
freezeBat = false,
doublePoints = false,
spawnRandomPowerup = false
}
But how can I add ANOTHER powerup to that dictionary so I can have them all within it? My understanding is if I do something like:
var powerUpDict = {
powerUpName = "speedUpBat",
batSpeedChange = 10,
ballSpeedChange = 0,
freezeBat = false,
doublePoints = false,
spawnRandomPowerup = false,
powerUpName = "slowDownBat",
batSpeedChange = -10,
ballSpeedChange = 0,
freezeBat = false,
doublePoints = false,
spawnRandomPowerup = false
}
… then I will have overwritten the duplicate named entries. Is that correct? I wonder if someone wouldn’t mind pointing me in the right direction.
Anything to help, thank you
Robster | 2017-03-31 03:21
You can’t duplicate entries in a dictionary, what you need is a dictionary(powerups) of dictionaries(attributes of each powerup)
so, like
var powerUpDict = {
"speedUpBat" : {
batSpeedChange = 10,
ballSpeedChange = 0,
freezeBat = false,
doublePoints = false,
spawnRandomPowerup = false,
},
"slowDownBat" : {
batSpeedChange = -10,
ballSpeedChange = 0,
freezeBat = false,
doublePoints = false,
spawnRandomPowerup = false
}
}
Nuno Donato | 2017-03-31 06:48