Hextris

Rotate the hexagon to line up falling colour blocks.

▶ Run in browser

Upstream: https://github.com/Hextris/hextris

Licence: this port's own code is offered under GPL-3.0-or-later, not the SimVX Examples Licence the rest of the gallery carries. See ATTRIBUTION.md for the upstream it re-implements, the terms of anything it bundles, and the credit each one requires.

Ports live in the repository only, not in the simvx-examples distribution, because each is a derivative work licensed individually against the game it re-implements. Read it with git clone https://git.simvx.com/simvx/simvx.

Tags: port tier-0

Hextris (SimVX port)

SimVX port of Hextris, the hexagonal falling-block puzzle. Coloured blocks fall from six directions toward a central hexagon: rotate the hexagon so three or more blocks of one colour stack on a single face and they clear. Let any face stack eight blocks deep and the run ends.

Licensing: GPL-3.0-or-later, matching upstream. No upstream art is reused: the board, blocks and HUD are drawn procedurally. See ATTRIBUTION.md.

Run

uv run python examples/ports/hextris/main.py
uv run simvx export web examples/ports/hextris/main.py -o /tmp/hextris.html

Controls

Action

Binding

Rotate anticlockwise

Left / A, or tap the left half

Rotate clockwise

Right / D, or tap the right half

Speed the blocks up

Down / S, or hold the pointer near the bottom

Pause

P

Start / restart

Enter / Space / R, or tap

What this shows about SimVX

  • Immediate-mode 2D drawing. The whole board (hexagon, slices, block trapezoids, HUD, overlays) is one on_draw body using draw_polygon, draw_lines, draw_rect and draw_text. No sprites, no assets.

  • Rect-aligned text. Titles, prompts and the controls strip are positioned with draw_text(rect=..., alignment="centre", fit_to_width=True) instead of hand-measured offsets, so they stay centred and readable at any size.

  • A resize-aware layout. Drawing and hit-testing both derive from tree.screen_size, with a uniform scale from the 800x800 design size, so the responsive web export stays centred at any aspect ratio.

  • One input path for mouse and touch. The web runtime reports a touch as a left mouse button press at the touch position, so Input.is_mouse_button_just_pressed(MouseButton.LEFT) plus the pointer position covers desktop and mobile without a separate touch branch.

  • Actions registered in the root’s ready path. InputMap.add_action calls live in HextrisRoot.on_ready, not in main(), because the web export instantiates the root directly.

Upstream

The upstream JavaScript was used as a design reference only; all Python here was written from scratch.

Source files

File

Summary

Lines

main.py

Hextris: Rotate the hexagon to line up falling colour blocks.

61

capture.py

Headless screenshot capture for Hextris.

22

nodes/__init__.py

0

nodes/game.py

HextrisGame: the whole game in one immediate-mode 2D scene node.

433

nodes/hex_math.py

Hex geometry helpers for the board: angles, vertices, slices and blocks.

89

Source

 1#!/usr/bin/env python3
 2"""Hextris: Rotate the hexagon to line up falling colour blocks.
 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
10Port of Hextris (https://github.com/Hextris/hextris, GPL-3.0-or-later) rebuilt
11on SimVX. Coloured blocks fall from six directions toward a central hexagon:
12rotate the hexagon so three or more blocks of one colour stack on a single face
13and they clear. Let any face stack eight blocks deep and the run ends.
14
15The board, blocks and HUD are drawn procedurally in ``on_draw`` (polygons,
16lines and rect-aligned text), the layout follows the live viewport size so the
17responsive web export stays centred, and every control has a pointer
18equivalent: web touches arrive as left clicks, so one code path serves mouse
19and touch.
20
21Run:           uv run python examples/ports/hextris/main.py
22Web export:    uv run simvx export web examples/ports/hextris/main.py -o /tmp/hextris.html
23
24Controls:
25    Left / A, or tap the left half      Rotate anticlockwise
26    Right / D, or tap the right half    Rotate clockwise
27    Down / S, or hold near the bottom   Speed the blocks up
28    P                                   Pause
29    Enter / Space / R, or tap           Start, and restart after a game over
30"""
31
32import sys
33from pathlib import Path
34
35# Allow `uv run python main.py` from this folder by adding the parent on path.
36sys.path.insert(0, str(Path(__file__).parent))
37
38from nodes.game import HextrisGame  # noqa: E402
39
40from simvx.core import InputMap, Key, Node  # noqa: E402
41from simvx.graphics import App  # noqa: E402
42
43WIDTH, HEIGHT = 800, 800
44
45
46class HextrisRoot(Node):
47    """Root node: registers actions and hosts the game scene."""
48
49    def on_ready(self):
50        # Actions are registered here rather than in main(): the web export
51        # instantiates the root directly and never calls main().
52        InputMap.add_action("rotate_left", [Key.LEFT, Key.A])
53        InputMap.add_action("rotate_right", [Key.RIGHT, Key.D])
54        InputMap.add_action("speed_up", [Key.DOWN, Key.S])
55        InputMap.add_action("start", [Key.ENTER, Key.SPACE, Key.R])
56        InputMap.add_action("pause", [Key.P])
57        self.add_child(HextrisGame(name="HextrisGame"))
58
59
60if __name__ == "__main__":
61    App(width=WIDTH, height=HEIGHT, title="Hextris (SimVX port)").run(HextrisRoot())