Hextris¶
Hex puzzle, engine test for touch input (GPLv3 upstream).
▶ Run in browserUpstream: https://github.com/Hextris/hextris
Tags: port tier-0
Hextris: SimVX port¶
Engine test only. Upstream is GPLv3, do not promote this to a SimVX example.
Run (desktop)¶
uv run python ported_games/hextris/simvx_port/main.py
Controls¶
Left arrow / A rotate hex left
Right arrow / D rotate hex right
Down / S speed up falling blocks
Enter / R restart (when game over)
Tap left half rotate left (mouse + touch)
Tap right half rotate right (mouse + touch)
Web export (touch test)¶
uv run simvx export web ported_games/hextris/simvx_port/main.py \
-o ported_games/hextris/simvx_port/web/index.html
Open web/index.html in Chrome 113+ or Edge 113+.
See ../NOTES.md for the touch-input validation findings; that is the
headline of this port.
Upstream¶
../source/ is a shallow clone of https://github.com/Hextris/hextris (GPLv3).
JavaScript was used as a design reference; all Python here was written
from scratch.
Source¶
1#!/usr/bin/env python3
2"""Hextris: Hex puzzle, engine test for touch input (GPLv3 upstream).
3
4# /// simvx
5# tags = ["port", "tier-0"]
6# upstream = "https://github.com/Hextris/hextris"
7# web = { width = 800, height = 800, responsive = true }
8# ///
9
10Upstream: https://github.com/Hextris/hextris (GPLv3).
11Port goal: smoke-test SimVX touch input + mobile web export.
12
13Run desktop:
14 uv run python ported_games/hextris/simvx_port/main.py
15
16Web export:
17 uv run simvx export web ported_games/hextris/simvx_port/main.py -o ported_games/hextris/simvx_port/web/index.html
18"""
19
20import math
21import random
22import sys
23from pathlib import Path
24
25# Allow `uv run python main.py` from this folder by adding the parent on path.
26sys.path.insert(0, str(Path(__file__).parent))
27
28from simvx.core import Input, InputMap, Key, Node, Node2D, Property, Vec2 # noqa: E402
29from simvx.graphics import App # noqa: E402
30
31from nodes.game import HextrisGame # noqa: E402
32
33WIDTH, HEIGHT = 800, 800
34
35
36class HextrisRoot(Node):
37 """Root node: registers actions and hosts the game scene."""
38
39 def on_ready(self):
40 # Per CLAUDE.md: InputMap.add_action MUST live in root on_ready
41 # (web exporter skips main(), and module-time actions are silently lost).
42 InputMap.add_action("rotate_left", [Key.LEFT, Key.A])
43 InputMap.add_action("rotate_right", [Key.RIGHT, Key.D])
44 InputMap.add_action("speed_up", [Key.DOWN, Key.S])
45 InputMap.add_action("restart", [Key.ENTER, Key.R])
46 InputMap.add_action("pause", [Key.P, Key.SPACE])
47 self.add_child(HextrisGame(name="HextrisGame"))
48
49
50if __name__ == "__main__":
51 App(width=WIDTH, height=HEIGHT, title="Hextris (SimVX port)").run(HextrisRoot())