-
Notifications
You must be signed in to change notification settings - Fork 4
Space Shooter Tutorial
This tutorial will show you how to use the NEAR SDK in an existing space shooter game.
- Clone the project from here: https://github.com/svntax/near-space-shooter
- Open the project using the C# Mono version of Godot 3.3.3.
- Have Godot generate the C# project files by adding a C# script (you can delete it afterwards). See here for more info.
You should now have a simple space shooter game working.
TODO screenshot here
TODO
The project already comes with the NEAR SDK, so the rest of the tutorial will be about implementation.
The game is missing a high scores screen, so let's add one. First, we can duplicate one of the existing buttons in the main menu, rename it, and set up a new function in MainMenu.gd
for its pressed()
signal.
TODO screenshot of new high scores button
Next, let's create a new scene for the high scores screen, name it HighScoresMenu
, and save it in the root project folder, the same place where the main menu scene is saved. We'll also create a new script for it with the same name, which later on will handle fetching the high scores from NEAR.
TODO screenshot of new files for high score menu
Now we can go back to the MainMenu.gd
script, and make the game change to this new scene when the high scores button is pressed. The script should now look something like the following:
extends Node2D
func _on_StartButton_pressed():
get_tree().change_scene("res://Gameplay.tscn")
func _on_ExitButton_pressed():
get_tree().quit()
func _on_HighScoresButton_pressed():
get_tree().change_scene("res://HighScoresMenu.tscn")
We can start setting up the high scores menu by adding backgrounds, text labels, buttons, and other necessary UI elements. At this point, it's up to you how you want to set up the menu. As long as there's a button to go back and a table or container of some sort with rows for the high scores, the setup will work fine.
Here is how I'll be setting up the scene:
TODO screenshot of high scores menu with UI elements
I copied the background and header label from the main menu, added a button for going back to the main menu, and then added a new GridContainer
node with 2 columns and two placeholder Label
nodes for the player's name and score. These label nodes have their horizontal size flags set to Fill and Expand in order to make them take up the entire width of the column. The player label is left-aligned, and the score label is right-aligned.
Now we can start working on the high scores script. To start, we need to connect to the NEAR network. In our MainMenu.gd
script, let's check if a connection exists, and if not, connect to the testnet.
extends Node2D
var config = {
"network_id": "testnet",
"node_url": "https://rpc.testnet.near.org",
"wallet_url": "https://wallet.testnet.near.org",
}
func _ready():
if Near.near_connection == null:
Near.start_connection(config)
func _on_StartButton_pressed():
get_tree().change_scene("res://Gameplay.tscn")
func _on_ExitButton_pressed():
get_tree().quit()
func _on_HighScoresButton_pressed():
get_tree().change_scene("res://HighScoresMenu.tscn")
Then in our high scores menu script, we'll call the getScores()
method from our smart contract to retrieve the high scores. The return value will be a JSON string, which when parsed, will be an array of dictionaries, each with a username
and value
field. Our strategy here is to use the placeholder label nodes as templates by hiding them, duplicating them and setting their respective values for each score in the array, and at the end, add them to the grid container node.
The HighScoresMenu.gd
script should now look something like the following, including a new function for the back button:
extends Node2D
const CONTRACT_NAME = "name of your smart contract here"
onready var scores_grid = $ScoresGrid
onready var player_name_label = $ScoresGrid/PlayerName
onready var player_score_label = $ScoresGrid/PlayerScore
func _ready():
# First, hide the placeholder labels
player_name_label.hide()
player_score_label.hide()
# Next, fetch the high scores and create new labels for each score
var result = Near.call_view_method(CONTRACT_NAME, "getScores")
if result is GDScriptFunctionState:
result = yield(result, "completed")
if result.has("error"):
pass # Error handling here
else:
var data = result.data
var json_data = JSON.parse(data)
var high_scores: Array = json_data.result
for score in high_scores:
var name_label = player_name_label.duplicate()
name_label.set_text(score.username)
scores_grid.add_child(name_label)
name_label.show()
var score_label = player_score_label.duplicate()
score_label.set_text(str(score.value))
scores_grid.add_child(score_label)
score_label.show()
func _on_BackButton_pressed():
get_tree().change_scene("res://MainMenu.tscn")
Now when you run the game and go to the high scores screen, you should see something like this:
TODO screenshot of high scores after being fetched
TODO
TODO