274 lines
5 KiB
Markdown
274 lines
5 KiB
Markdown
# Your First AeThex Game - Multiplayer Pong
|
|
|
|
Build a simple multiplayer Pong game in 30 minutes. Learn core AeThex features: multiplayer, cloud saves, and the Studio IDE.
|
|
|
|
**What you'll build:** Real-time multiplayer Pong where 2 players compete, with automatic cloud save of high scores.
|
|
|
|
**Time required:** 30 minutes
|
|
**Difficulty:** Beginner
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- AeThex Engine installed
|
|
- Text editor or Studio IDE
|
|
- Basic programming knowledge (any language)
|
|
|
|
---
|
|
|
|
## Part 1: Project Setup (5 min)
|
|
|
|
### 1. Create New Project
|
|
|
|
In Studio IDE:
|
|
1. Click **File → New Project**
|
|
2. Name: `MultiplayerPong`
|
|
3. Location: Choose folder
|
|
4. Click **Create & Open**
|
|
|
|
<function_calls>
|
|
<invoke name="create_file">
|
|
<parameter name="content"># GDScript Basics
|
|
|
|
Quick reference for developers new to GDScript.
|
|
|
|
## What is GDScript?
|
|
|
|
GDScript is Python-like scripting language designed for game development. Easy to learn, powerful for games.
|
|
|
|
## Basic Syntax
|
|
|
|
### Variables
|
|
```gdscript
|
|
var health = 100 # Integer
|
|
var speed = 5.5 # Float
|
|
var name = "Player" # String
|
|
var is_alive = true # Boolean
|
|
var position = Vector2(0, 0) # Object
|
|
```
|
|
|
|
### Constants
|
|
```gdscript
|
|
const MAX_HEALTH = 100
|
|
const GRAVITY = 980
|
|
```
|
|
|
|
### Functions
|
|
```gdscript
|
|
func take_damage(amount):
|
|
health -= amount
|
|
if health <= 0:
|
|
die()
|
|
|
|
func die():
|
|
print("Game Over")
|
|
queue_free()
|
|
```
|
|
|
|
### If Statements
|
|
```gdscript
|
|
if health > 50:
|
|
print("Healthy")
|
|
elif health > 20:
|
|
print("Low health")
|
|
else:
|
|
print("Critical")
|
|
```
|
|
|
|
### Loops
|
|
```gdscript
|
|
# For loop
|
|
for i in range(10):
|
|
print(i)
|
|
|
|
# While loop
|
|
while health > 0:
|
|
take_damage(10)
|
|
|
|
# Iterate array
|
|
for item in inventory:
|
|
print(item.name)
|
|
```
|
|
|
|
### Arrays
|
|
```gdscript
|
|
var fruits = ["apple", "banana", "orange"]
|
|
fruits.append("grape")
|
|
print(fruits[0]) # "apple"
|
|
print(fruits.size()) # 4
|
|
```
|
|
|
|
### Dictionaries
|
|
```gdscript
|
|
var player = {
|
|
"name": "Alex",
|
|
"level": 5,
|
|
"health": 100
|
|
}
|
|
|
|
print(player["name"]) # "Alex"
|
|
player.health = 90
|
|
```
|
|
|
|
## Common Lifecycle Functions
|
|
|
|
### _ready()
|
|
Called when node is added to scene.
|
|
```gdscript
|
|
func _ready():
|
|
print("Node is ready")
|
|
health = MAX_HEALTH
|
|
```
|
|
|
|
### _process(delta)
|
|
Called every frame.
|
|
```gdscript
|
|
func _process(delta):
|
|
# delta = time since last frame (seconds)
|
|
position.x += speed * delta
|
|
```
|
|
|
|
### _physics_process(delta)
|
|
Called every physics frame (fixed timestep).
|
|
```gdscript
|
|
func _physics_process(delta):
|
|
velocity.y += gravity * delta
|
|
move_and_slide(velocity)
|
|
```
|
|
|
|
### _input(event)
|
|
Called on input events.
|
|
```gdscript
|
|
func _input(event):
|
|
if event is InputEventKey:
|
|
if event.pressed and event.keycode == KEY_SPACE:
|
|
jump()
|
|
```
|
|
|
|
## Node Management
|
|
|
|
### Get child nodes
|
|
```gdscript
|
|
var player = $Player # Direct child
|
|
var health_bar = $UI/HealthBar # Nested
|
|
var enemy = get_node("Enemy") # Alternative
|
|
```
|
|
|
|
### Create nodes
|
|
```gdscript
|
|
var bullet = preload("res://bullet.tscn").instantiate()
|
|
bullet.position = global_position
|
|
get_parent().add_child(bullet)
|
|
```
|
|
|
|
### Remove nodes
|
|
```gdscript
|
|
queue_free() # Remove this node
|
|
$Bullet.queue_free() # Remove child
|
|
```
|
|
|
|
## Signals
|
|
|
|
### Define signal
|
|
```gdscript
|
|
signal health_changed(new_health)
|
|
signal died
|
|
|
|
func take_damage(amount):
|
|
health -= amount
|
|
health_changed.emit(health)
|
|
if health <= 0:
|
|
died.emit()
|
|
```
|
|
|
|
### Connect signal
|
|
```gdscript
|
|
func _ready():
|
|
$Player.connect("died", self, "_on_player_died")
|
|
|
|
func _on_player_died():
|
|
print("Player died!")
|
|
```
|
|
|
|
## Classes
|
|
|
|
```gdscript
|
|
class_name Player extends CharacterBody2D
|
|
|
|
var health = 100
|
|
var speed = 200
|
|
|
|
func _ready():
|
|
print("Player ready")
|
|
|
|
func move(direction: Vector2):
|
|
velocity = direction * speed
|
|
move_and_slide()
|
|
```
|
|
|
|
## Exports (Inspector Variables)
|
|
|
|
```gdscript
|
|
@export var max_health = 100
|
|
@export var speed = 5.0
|
|
@export var player_name = "Hero"
|
|
@export var sprite: Texture2D
|
|
```
|
|
|
|
These appear in the Inspector and can be edited visually.
|
|
|
|
## Common Types
|
|
|
|
```gdscript
|
|
# Numbers
|
|
var integer: int = 5
|
|
var floating: float = 3.14
|
|
|
|
# Vectors
|
|
var pos2d: Vector2 = Vector2(10, 20)
|
|
var pos3d: Vector3 = Vector3(1, 2, 3)
|
|
|
|
# Colors
|
|
var red = Color.RED
|
|
var custom = Color(1.0, 0.5, 0.0) # RGB
|
|
|
|
# Nodes
|
|
var player: CharacterBody2D
|
|
var sprite: Sprite2D
|
|
```
|
|
|
|
## Tips for Beginners
|
|
|
|
1. **Use typed variables** for better autocomplete:
|
|
```gdscript
|
|
var speed: float = 5.0
|
|
var player: Node2D
|
|
```
|
|
|
|
2. **$ is shorthand** for get_node():
|
|
```gdscript
|
|
$Player == get_node("Player")
|
|
```
|
|
|
|
3. **Connect signals in Inspector** or code - both work
|
|
|
|
4. **Use @export** to expose variables to Inspector
|
|
|
|
5. **Always null-check** before using nodes:
|
|
```gdscript
|
|
if player != null:
|
|
player.take_damage(10)
|
|
```
|
|
|
|
6. **Use preload** for resources:
|
|
```gdscript
|
|
const Bullet = preload("res://bullet.tscn")
|
|
var bullet = Bullet.instantiate()
|
|
```
|
|
|
|
## Next Steps
|
|
|
|
- [Your First AeThex Game](tutorials/FIRST_GAME_TUTORIAL.md)
|
|
- [GDScript Official Docs](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/index.html)
|
|
- [AeThex API Reference](API_REFERENCE.md)
|