Quickstart¶
Two short programs: a square you move in 2D, and a cube you steer in 3D. Install SimVX first
(Installation). Two imports cover a game: simvx.core for nodes, input, audio and UI, and
simvx.graphics for the window.
2D: a square you move¶
from simvx.core import Axis2D, Controller, Input, Node2D
from simvx.graphics import App
class Player(Node2D):
input_context = {"move": [Axis2D.WASD, Axis2D.ARROWS, Controller.LEFT_STICK]}
def on_ready(self):
self.position = self.viewport_size / 2
def on_update(self, dt):
self.position += Input.value("move") * 200 * dt
def on_draw(self, renderer):
renderer.rect((-30, -30), (60, 60), fill=(0.2, 0.4, 1.0))
if __name__ == "__main__":
App(title="Quickstart").run(Player())
Save it as quickstart.py and run python quickstart.py. WASD, the arrow keys or a controller’s
left stick move the square. From a source checkout, prefix commands with uv run.
3D: a cube you steer¶
from simvx.core import (Axis2D, Camera3D, Controller, DirectionalLight3D, Input, Material, Mesh,
MeshInstance3D, Node3D, TouchController)
from simvx.graphics import App
class Game(Node3D):
input_context = {"move": [Axis2D.WASD, Axis2D.ARROWS, Controller.LEFT_STICK]}
def on_ready(self):
self.add_child(Camera3D(position=(0, 4, 8), look_at=(0, 0, 0)))
self.add_child(DirectionalLight3D(direction=(-0.4, -1.0, -0.6)))
self.cube = self.add_child(
MeshInstance3D(mesh=Mesh.box(), material=Material(colour=(1.0, 0.3, 0.2, 1.0)))
)
self.add_child(TouchController()) # an on-screen stick for touch screens
def on_update(self, dt):
move = Input.value("move")
self.cube.position += (move.x * 4 * dt, 0, move.y * 4 * dt)
if __name__ == "__main__":
App(title="3D Quickstart").run(Game())
Save it as quickstart3d.py and run python quickstart3d.py: a red cube sits under a sun, and
WASD, the arrow keys, a left stick or the on-screen stick slide it across the view.
What is happening¶
A scene is a node.
on_ready()runs once when the node joins the tree,on_update(dt)every frame, andon_draw(renderer)draws in 2D.App(...).run(root)opens the window and runs the loop.Input is a typed action.
input_contextdeclaresmoveonce. Its bindings make it aVec2, soInput.value("move")returns the direction from whichever device is driving it.Children are nodes too. The camera, light and cube are added with
add_child, with their settings passed as constructor keywords.
Next steps¶
Your first 2D game: build Pong
Your first 3D game: build a 3D gem collector
API cheat sheet: the common API on one page
Examples gallery:
simvx examples copy <id> --to <dir>starts you from any of them