Build an Angry‑Birds‑Style Game in Under 100 Lines with Dora SSR and TSX
This tutorial shows how front‑end developers can use the Dora SSR game engine’s TSX support to create a simple Angry‑Birds‑like game in fewer than 100 lines of code, covering scene setup, physics, UI components, touch controls, scoring logic, and cross‑platform deployment.
Overview
Dora SSR is a cross‑platform game engine that mirrors the DOM tree and lets front‑end developers write game logic with TSX. TSX is compiled to Lua via TypeScriptToLua, running on a Lua/WASM VM.
Setup
Install the Dora SSR package, open the Web IDE and start coding. Quick‑start guide: https://dora-ssr.net/zh-Hans/docs/tutorial/quick-start
1. Minimal scene
Add preview comment for hot‑reload: // @preview-file on Import core modules:
import { React, toNode, useRef } from 'DoraX';
import { Body, BodyMoveType, Ease, Label, Line, Scale, TypeName, Vec2, tolua } from 'Dora';Show a sprite:
toNode(<sprite file='Image/logo.png' scaleX={0.2} scaleY={0.2}/>);2. Box component
Reusable component that creates a dynamic physics body, a rectangular fixture, visual rectangle and a score label.
interface BoxProps {
num: number;
x?: number;
y?: number;
children?: any | any[];
}
const Box = (props: BoxProps) => {
const numText = props.num.toString();
return (
<body type={BodyMoveType.Dynamic} scaleX={0} scaleY={0} x={props.x} y={props.y} tag={numText}>
<rect-fixture width={100} height={100}/>
<draw-node>
<rect-shape width={100} height={100} fillColor={0x8800ffff} borderWidth={1} borderColor={0xff00ffff}/>
</draw-node>
<label fontName='sarasa-mono-sc-regular' fontSize={40}>{numText}</label>
{props.children}
</body>
);
}; tag: stores the box’s score. rect-fixture: defines collision shape. draw-node: draws rectangle. label: displays score.
3. References
useRef to keep handles to the bird body and the score label:
const bird = useRef<Body.Type>();
const score = useRef<Label.Type>();4. Launch line
Track touch/mouse drag to draw a line and set bird velocity on release.
let start = Vec2.zero;
let delta = Vec2.zero;
const line = Line();
toNode(
<physics-world
onTapBegan={(touch) => { start = touch.location; line.clear(); }}
onTapMoved={(touch) => { delta = delta.add(touch.delta); line.set([start, start.add(delta)]); }}
onTapEnded={() => {
if (!bird.current) return;
bird.current.velocity = delta.mul(Vec2(10, 10));
start = Vec2.zero; delta = Vec2.zero; line.clear();
}}>
{/* other game objects */}
</physics-world>
);onTapBegan records start point and clears line.
onTapMoved updates line.
onTapEnded applies velocity to bird.
5. Game objects
5.1 Ground
<body type={BodyMoveType.Static}>
<rect-fixture centerY={-200} width={2000} height={10}/>
<draw-node>
<rect-shape centerY={-200} width={2000} height={10} fillColor={0xfffbc400}/>
</draw-node>
</body>5.2 Boxes
Instantiate five boxes with scores 10‑50 and staggered entrance animation:
{[10,20,30,40,50].map((num,i) => (
<Box num={num} x={200} y={-150 + i*100}>
<sequence>
<delay time={i*0.2}/>
<scale time={0.3} start={0} stop={1}/>
</sequence>
</Box>
))}5.3 Bird
<body ref={bird} type={BodyMoveType.Dynamic} x={-200} y={-150}
onContactStart={(other) => {
if (other.tag && score.current) {
const sc = parseFloat(score.current.text) + parseFloat(other.tag);
score.current.text = sc.toString();
const label = tolua.cast(other.children?.last, TypeName.Label);
if (label) label.text = '';
other.tag = '';
other.perform(Scale(0.2, 0.7, 1.0));
}
}}>
<disk-fixture radius={50}/>
<draw-node>
<dot-shape radius={50} color={0xffff0088}/>
</draw-node>
<label ref={score} fontName='sarasa-mono-sc-regular' fontSize={40}>0</label>
<scale time={0.4} start={0.3} stop={1.0} easing={Ease.OutBack}/>
</body>6. Full demo
The code above produces a functional Angry‑Birds‑style game. Extend it with more levels or UI as needed.
Full source: https://github.com/IppClub/Dora-SSR/blob/main/Assets/Script/Test/Birdy.tsx
Technical details
Dora SSR runs on a Lua/WASM virtual machine. TypeScript support is provided by the TypeScriptToLua compiler, which translates TS/TSX into Lua bytecode. The current engine builds the scene once; there is no virtual‑DOM diffing, so TSX is used only for static scene construction.
Future work may add React‑like state synchronization or Solid‑style fine‑grained updates for game UI.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
