⚔️ TCJSgame v2 vs v3 — Accurate comparison, code diffs, and ratings
If you've been working with TCJSgame, you probably use v2 and are testing or migrating to v3. I dug into the actual v2 code and compared it to v3 changes. This article shows what changed, why it matters, and gives a numeric rating (out of 100) for each version across features, ease of use, and performance.
TL;DR
- v2 is simple, compact, and easy to learn — excellent for small demos and prototypes.
- v3 adds camera support, tilemaps, sprites, angle-based movement, and better utilities — a step toward a proper 2D engine.
- Recommendation: For new projects start with v3. For tiny demos or compatibility needs, v2 still works.
1) Precise comparison (based on v2 code)
Loop & Timing
v2
- Uses
setInterval(() => this.updat(), 20)(~50 FPS). - Movement is pixels per frame, not time-based.
v3
- Designed to work with
requestAnimationFrame(rAF). - Supports delta-time (dt) so movement is pixels per second.
- Compatible with the
tcjsgame-perf.jsextension for smoother gameplay.
Camera
v2
-
Cameraclass exists. -
Display.updat()translates by-camera.x, -camera.y.
v3
- Camera is integrated with scenes and tilemaps.
- Works better with optimizations (culling, caching).
Components & Movement
v2
-
ComponenthasspeedX,speedY,gravity,bounce,physics,changeAngle. -
move()is per-frame. -
moveAngle()exists but less commonly used.
v3
- Adds richer movement utilities:
project,glideTo,accelerate,decelerate. - Designed to support dt-based movement for consistent speeds.
Tilemap & Sprites
v2
- No
TileMap. - Has a basic
Spriteclass for frame-based animation.
v3
- New
TileMapandTileclasses. - Tile collision, add/remove tiles, caching support.
- Sprites integrate better with scenes.
Input & Mouse
v2
- Handles
keydown,keyup,mousedown,mouseup,touchstart,touchend. - Basic
Mousecomponent exists.
v3
- Improves pointer tracking.
- Handles rotation and camera when checking clicks.
2) Side-by-side code snippets
A) Game Loop
v2
start(width = 480, height = 270) {
this.canvas.width = width;
this.canvas.height = height;
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(() => this.updat(), 20);
this.addEventListeners();
}
updat() {
this.clear();
this.context.save();
this.context.translate(-this.camera.x, -this.camera.y);
update(); // global update
comm.forEach(c => { c.move(); c.update(this.context); });
this.context.restore();
}
v3
start(width = 480, height = 270) {
this.canvas.width = width;
this.canvas.height = height;
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this._lastTime = performance.now();
requestAnimationFrame(this._loop.bind(this));
}
_loop(timestamp) {
let dt = (timestamp - this._lastTime) / 1000;
this._lastTime = timestamp;
this.clear();
this.context.save();
this.context.translate(-this.camera.x, -this.camera.y);
if (typeof update === "function") update(dt);
comm.forEach(c => { c.move(dt); c.update(this.context); });
this.context.restore();
requestAnimationFrame(this._loop.bind(this));
}
B) Component Movement
v2
move() {
if (this.physics) {
this.gravitySpeed += this.gravity;
this.x += this.speedX;
this.y += this.speedY + this.gravitySpeed;
} else {
this.x += this.speedX;
this.y += this.speedY;
}
}
v3
move(dt = 1/60) {
if (this.physics) {
this.gravitySpeed += this.gravity * dt;
this.x += this.speedX * dt;
this.y += (this.speedY + this.gravitySpeed) * dt;
} else {
this.x += this.speedX * dt;
this.y += this.speedY * dt;
}
}
C) Tilemap
v2
❌ None
v3
class TileMap {
constructor(render, map, tile, width, height) { ... }
show() { ... }
tiles(id = 0) { ... }
crashWith(obj, id = 0) { ... }
add(id, tx, ty) { ... }
remove(tx, ty) { ... }
}
3) Ratings (0–100)
| Engine | Features | Ease of Use | Performance | Final Score |
|---|---|---|---|---|
| v2 | 60 | 80 | 55 | 65/100 |
| v3 | 88 | 75 | 80 | 81/100 |
Why v2 scores lower
- Simple and easy to use, but lacks tilemaps and modern loop handling.
- Performance suffers because it uses
setInterval.
Why v3 scores higher
- Adds TileMap, better camera, more movement utilities, and delta-time support.
- Higher performance with
requestAnimationFrame+ perf extension. - Slightly harder to learn but worth it for serious projects.
Migration notes
- Old code still works in v3 if you keep
useDelta: falsein the perf extension. - To upgrade, rewrite movement to use
dt(pixels/second). - Use
display.add(component, scene)anddisplay.camera.follow(player)in v3.
Conclusion
- v2 is great for quick prototypes and learning.
- v3 is better for real games: smoother, faster, and feature-rich.
- For best results: combine v3 with the
tcjsgame-perf.jsextension.
🚀 TCJSgame is evolving — and v3 is a huge step forward.
Top comments (0)