lukehaas /
RunJS
RunJS is a JavaScript playground for macOS, Windows and Linux. Write code with instant feedback and access to Node.js and browser APIs.
Loading repository data…
onepal-was-taken / repository
A playground for experimenting and prototyping real-time 3D graphics in Three.js. Mainly based on a top-down rogue-like game, developed for the "Interactive Graphics" course in Sapienza University of Rome, a.y. 2024-2025.
A playground for experimenting and prototyping real-time 3D graphics in Three.js. Mainly based on a top-down rogue-like game, developed for the "Interactive Graphics" course in Sapienza University of Rome, a.y. 2024-2025. The game was build from scratch, mixing arcade action with light RPG mechanics (XP, levels, power-ups) while showcasing several real-time graphics techniques and gameplay systems.
Here, or clone the repo and launch index.html.
.
├── assets/ # GLTFs, textures, UI icons, fonts ...
├── src/
│ ├── Bullet.js
│ ├── constants.js
│ ├── Enemy.js
│ ├── EnemySpawner.js
│ ├── Game.js # main game loop & orchestration
│ ├── getParticles.js # GPU sprite system
│ ├── GridPathFinder.js # A* on a binary grid
│ ├── HeartPickup.js
│ ├── LaserTextures.js
│ ├── LoadingMgr.js
│ ├── LoadingScreen.js
│ ├── main.js # entry point
│ ├── Minimap.js
│ ├── Molotov.js
│ ├── Player.js
│ ├── Turret.js
│ └── UI.js # DOM & CSS-only HUD
└── index.html
Two modes, toggled with C:
Follow – camera chases the player by simulating a mass–spring–damper:
$$ \mathbf a = -k(\mathbf x - \mathbf x_t);-;c\mathbf v \quad\Longrightarrow\quad \mathbf v \leftarrow \mathbf v + \mathbf a,\Delta t,; \mathbf x \leftarrow \mathbf x + \mathbf v,\Delta t $$
k = 12 → stiffness; c = 8 → damping.Fixed – user pans with RMB drags; the camera orbits a frozen centre.
Keyboard shortcuts
| Key | Action |
|---|---|
Q / E | Rotate camera ± about Y |
| Mouse wheel | Zoom (orthographic scale) |
| RMB drag | Pan in Fixed mode |
Game.loadStaticRocks() shows how to control RNG with statistics:
const t = Math.random() ** 3; // cubic bias → many small rocks
const scale = lerp(min, max, t);
Because $\small t=u^{3}$ (with $u\sim U(0,1)$), the PDF becomes $p(t)=\frac13t^{-2/3}$, sharply skewed toward 0 ⇒ most samples are tiny.
A similar approach is used for fences & trees – each tries up to maxAttempts times before giving up to avoid overlaps (simple Poisson disk).
Each projectile is a 3‑part composite (tiny cylinder core + glow sprite + pooled trail) yet costs <1 ms per frame for hundreds of rounds.
const E = 0.5 * m * v.lengthSq(); // kinetic energy (no costly sqrt)
const dmg = 0.02 * E; // linear damage scale
| Property | Value / behaviour |
|---|---|
| Muzzle speed | 300 m s⁻¹ |
| Mass | 0.05 kg |
| Gravity | Applied every frame → true parabolic drop (g = 9.81 m s⁻²). |
| Drag | None (commented out) – horizontal speed stays constant. |
| Cull distance | Deleted after travelling ≈ 200 m (squared radius = 40000). |
| Collision | Sphere‑sphere (full 3‑D distance). |
| Damage | Proportional to kinetic energy ⇒ quadratic boost if bullet speed is buffed. |
| Tracer | 64‑sprite additive pool, stamped every 0.015 s and faded out. |
Gameplay implications
this.velocity.multiplyScalar(1 - 0.01 * dt).Knife hits and explosions impart a horizontal impulse $J$:
$$ \Delta\mathbf v = \frac{J}{m},\hat{\mathbf d},\qquad \hat{\mathbf d}\in\mathbb R^{2} $$
Vertical components are nulled for simplicity (enemies aren’t true rigid bodies).
A small exponential air drag keeps velocity bounded:
this.velocity.multiplyScalar(Math.exp(-4 * dt)); // τ ≈ 0.25 s
GridPathFinder.js is a minimalist 8-neighbour A* on a Uint8Array.
Convex hull of every static prop is rasterised once.
Heuristic: octile distance
$$h = (\sqrt2-1)\min(|dx|,|dz|) + \max(|dx|,|dz|)$$
Distance-based adaptive repath timer
const distFactor = clamp(dist² / 100, 0.5, 2.0);
this.repathTimer = baseTime * distFactor * rand(0.8,1.2);
Enemies far away waste fewer cycles on path refreshes.
getParticles() is a GPU billboarding engine with custom shaders:
THREE.Points draw call – thousands of quads at <1 msUsed by:
| Effect | Preset | Notes |
|---|---|---|
| Molotov flames | fire | 120 pps, additive blend |
| Potion buff aura | aura | Cyan orbits around the player |
| Molotov smoke | smoke | Normal blend, depth-tested |
Each bottle spawns a burn pool (radius = 30 m, lifetime = 8 s). Every frame we iterate over enemies inside the ring and apply a quadratic heat fall‑off:
$$ \bigl\langle \text{DPS}_{\text{centre}}\bigr\rangle;t^{2};\Delta t, \qquad t = 1 - \frac{d}{R},;0\le d\le R $$
const dist = enemy.pos.distanceTo(centre);
const t = 1 - dist / radius; // 0 … 1
const dmg = damagePerSec * t * t * dt; // quadratic drop‑off
dt → frame‑rate independentTweakable knobs:
| Parameter | Purpose |
|---|---|
radius | Footprint of the fire puddle |
damagePerSec | Peak DPS at the epicentre |
power in t^n | 1 = linear, 2 = quadratic (default), 3+ steeper |
A scorch decal plus GPU‑particle fire & smoke presets sell the effect visually.
LoadingMgr mirrors THREE.LoadingManager progress → animated “xxx %”.I started from @bobbyroe/animated-text-effect for the outline animation effect.
Pure <canvas> overlay:
drawPlayerArrow() draws a little isosceles triangle oriented with the projected facing vector.imageRendering: pixelated).Mouse & keyboard listeners are registered once in Game.registerEventListeners().
Flags live in this.input → tight update() loops have zero DOM queries.
pointermove to reuse the same logic paths.first-render-complete allows LoadingMgr to finish only after the very first renderer.render() – reliable even on low-end hardware.setPath() to cut URL spam.Browsers parallelise fetches – main thread never stalls.
| Key / Mouse | Action |
|---|---|
| W A S D | Move / run (always sprint) |
| Mouse L | Knife attack |
| Mouse R | Drag to move camera in fixed mode |
| 1 | Place Turret (drag & release) |
| 2 | Throw Molotov (drag) |
| 3 | Drink Potion |
| Q / E | Rotate camera |
| C | Toggle follow / fixed camera |
| R | Restart after death |
| P | Pause |
Enjoy hacking and extend as you please :)
Selected from shared topics, language and repository description—not editorial ratings.
lukehaas /
RunJS is a JavaScript playground for macOS, Windows and Linux. Write code with instant feedback and access to Node.js and browser APIs.
momotech /
高性能、小巧、易上手的移动跨平台开发框架. A framework for building Mobile cross-platform apps with Lua
FormidableLabs /
A component for rendering React components with editable source and live preview
agneym /
A simple playground for HTML, CSS and JavaScript supporting module imports.
victordiaz /
PHONK is a coding playground for new and old Android devices
rezoner /
Playground.js is a framework for your javascript based games. It gives you out-of-box access to essentials like mouse, keyboard, sound and well designed architecture that you can expand to your needs.