I made a game y’all!
- It’s got a menu!
- And a demo mode!
- PLANTS GROW BY THEMSELVES!
- And win/lose screens!
I set up most of the menu in the Godot UI editor:
One trick that took a while was having some issues with Z-indexing (I’m using that in the
PixelEngine). All I had to do to fix it was put all the UI elements in a
Foreground) and voila.
Then a bit of code to hook things up:
# Main.gd func _on_play(): get_tree().change_scene("res://scenes/Main.tscn") func _on_options(): $Foreground/Buttons.visible = false $Foreground/Options.visible = true $Foreground/StatusBox.visible = false func _on_options_done(): $Foreground/Buttons.visible = true $Foreground/Options.visible = false $Foreground/StatusBox.visible = true func _on_quit(): get_tree().quit()
To get demo mode working, I just added a
demo variable to the
Main.gd script and tweaked a few things (I’ll talk about
return_to_menu in a moment):
# Main.gd func _on_Scores_timeout(): ... if count == 0: if demo: reset_sand() else: return_to_menu("All the plants died!\nYou lost.\n:(") elif highest <= TARGET: if demo: reset_sand() else: return_to_menu("You grew a plant to the top.\nYOU WIN!") # Tetromino # Keyboard controls if get_parent().get_parent().demo: if randf() < 0.1: var impulse = IMPULSE * (randf() - 0.5) var torque = TORQUE * (randf() - 0.5) for body in bodies: body.apply_central_impulse(impulse) body.apply_torque_impulse(torque) else: for body in bodies: if Input.is_action_pressed("ui_right"): body.apply_central_impulse(IMPULSE) ...
It was taking forever to grow plants with just water to help them grow, so I added the ability for them to grow by themselves:
# PixelEngine.gd # Try to react with neighboring particles if current == CELL.plant: var hot_neighbors = count_neighbors_of(x, y, CELL.fire) + count_neighbors_of(x, y, CELL.lava) var empty_neighbors = count_neighbors_of(x, y, CELL.empty) var plant_neighbors = count_neighbors_of(x, y, CELL.plant) # Fire/lava ignite plants if randf() < hot_neighbors * BURN_CHANCE_PER_FIRE: data[x][y] = CELL.fire updated[x][y] = true # Plants try to grow elif empty_neighbors > 0 and plant_neighbors <= PLANT_GROWTH_LIMITER: for xi in range(x - 1, x + 2): for yi in range(y - 1, y + 2): if not in_range(xi, yi) or (xi == x and yi == y): continue if data[xi][yi] != CELL.empty: continue if randf() < PLANT_GROWTH_PER_EMPTY: data[xi][yi] = CELL.plant updated[xi][yi] = true
Last but not least, I updated the code to include win/lose screens (as seen in the
return_to_menu function above). I did that so that I can go right back to the menu, but also display a message:
# Main.gd func return_to_menu(message): var menu = load("res://scenes/Menu.tscn").instance() menu.set_text(message) get_tree().get_root().add_child(menu) queue_free()
I can’t directly use
get_tree().change_scene here, since that doesn’t let me pass along any state, but this works well enough. I may use that for options/difficulty settings before too long.
Next up: MUSIC!
You need music to really sell a game.
And hey, I already have a menu option for it. :D
If I have the time, after that I will work on:
- Difficulty / options
- Turn on/off spawn types
- Make plants grow easier (allow 1-4 neighbors) or harder (exactly 1)
- Two block mode (I accidently did this in testing, it was neat)
- Wall spawners
- New block types
- Agent X
- Submit high scores