Skip to content
thinkingdev923Public

About

A satisfying interactive browser game built with vanilla JavaScript, HTML, and CSS, featuring smooth animations, dynamic DOM manipulation, responsive UI, event-driven gameplay, performance-focused rendering, and a lightweight zero-dependency architecture.

Topics

Resources

Stars

6 stars

Watchers

0 watching

Forks

Latest commit

ย 

History

419 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽฎ Bubbles

Bubbles is a browser-based interactive bubble-popping game built with vanilla JavaScript, ES modules, HTML5 Canvas, and browser APIs.

The game uses a custom real-time rendering and physics loop to simulate falling bubbles, collisions, popping effects, particles, touch/mouse interactions, scoring, lives, levels, tutorials, audio feedback, and animated UI elements.

The project is designed around small, focused JavaScript modules rather than a large framework. Game systems such as rendering, physics, input handling, level management, scoring, audio, animation, and visual effects are separated into individual modules.


โœจ Features

  • Interactive bubble-popping gameplay
  • HTML5 Canvas-based rendering
  • Real-time animation loop
  • Mouse, touch, and pointer-event support
  • Multi-pointer input handling
  • Falling bubble physics
  • Gravity and terminal velocity
  • Bubble-to-bubble collision detection
  • Collision response and bouncing
  • Tap-to-pop interaction
  • Slingshot-style interaction
  • Hold/blast interaction
  • Particle-based bubble explosion effects
  • Ripple effects for missed taps
  • Firework effects
  • Combo scoring
  • Lives system
  • Level progression
  • Tutorial system
  • Level countdowns
  • Level interstitial screens
  • Game-over state
  • Audio feedback and procedural sound sequencing
  • Level preview through URL parameters
  • Custom level data encoding/decoding
  • Share-image generation
  • Responsive Canvas sizing
  • Camera shake effects
  • Animated text and UI transitions
  • Modular ES6 architecture

๐Ÿ—๏ธ Technical Architecture

The application is implemented as a client-side game engine running entirely inside the browser.

There is no application server required for the core gameplay.

The high-level runtime architecture is:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 Browser                       โ”‚
โ”‚                                               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚            HTML / Canvas UI             โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                       โ”‚                       โ”‚
โ”‚                       โ–ผ                       โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚              index.js                   โ”‚  โ”‚
โ”‚  โ”‚         Game/Application Loop           โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                  โ”‚                            โ”‚
โ”‚       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚       โ–ผ          โ–ผ           โ–ผ           โ–ผ    โ”‚
โ”‚    Levels      Input       Physics      Score โ”‚
โ”‚       โ”‚          โ”‚           โ”‚           โ”‚    โ”‚
โ”‚       โ–ผ          โ–ผ           โ–ผ           โ–ผ    โ”‚
โ”‚    Ball.js   Pointer.js   Particle.js  Store  โ”‚
โ”‚       โ”‚                      โ”‚                โ”‚
โ”‚       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                  โ–ผ                            โ”‚
โ”‚          Canvas Rendering                     โ”‚
โ”‚                  โ”‚                            โ”‚
โ”‚                  โ–ผ                            โ”‚
โ”‚          Visual / Audio Effects               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The main orchestration layer is index.js. It creates the Canvas manager and initializes the audio, life, level, score, tutorial, pointer, interstitial, and sharing systems.


๐Ÿงฉ Core Technologies

Technology Purpose
JavaScript Core application and game logic
ES Modules Modular dependency management
HTML5 Canvas Real-time 2D rendering
Canvas 2D API Drawing game objects and effects
Pointer Events API Mouse/touch/stylus interaction
Web Audio / browser audio APIs Game sound effects
Browser URL APIs Level preview parameters
CSS Page-level presentation
HTML Application shell

The repository does not require a frontend framework such as React or Vue for the game engine.


๐Ÿ“ Project Structure

The main source files are organized around individual game responsibilities.

Bubbles/
โ”‚
โ”œโ”€โ”€ index.html
โ”œโ”€โ”€ index.css
โ”œโ”€โ”€ index.js
โ”‚
โ”œโ”€โ”€ activePointer.js
โ”œโ”€โ”€ audio.js
โ”œโ”€โ”€ ball.js
โ”œโ”€โ”€ canvas.js
โ”œโ”€โ”€ colors.js
โ”œโ”€โ”€ constants.js
โ”œโ”€โ”€ easings.js
โ”œโ”€โ”€ firework.js
โ”œโ”€โ”€ grid.js
โ”œโ”€โ”€ helpers.js
โ”œโ”€โ”€ holdBlast.js
โ”œโ”€โ”€ interstitialButton.js
โ”œโ”€โ”€ level.js
โ”œโ”€โ”€ levelData.js
โ”œโ”€โ”€ lifeManager.js
โ”œโ”€โ”€ particle.js
โ”œโ”€โ”€ ripple.js
โ”œโ”€โ”€ scoreDisplay.js
โ”œโ”€โ”€ scoreStore.js
โ”œโ”€โ”€ shareImage.js
โ”œโ”€โ”€ slingshot.js
โ”œโ”€โ”€ spring.js
โ”œโ”€โ”€ textBlock.js
โ”œโ”€โ”€ textRotate.js
โ”œโ”€โ”€ trajectory.js
โ”œโ”€โ”€ tutorial.js
โ”‚
โ”œโ”€โ”€ builder/
โ”œโ”€โ”€ images/
โ”œโ”€โ”€ sounds/
โ”‚
โ”œโ”€โ”€ notes.md
โ””โ”€โ”€ README.md

The repository currently contains hundreds of commits and the game logic is split across these specialized modules.


๐ŸŽฏ Application Entry Point

index.html

index.html provides the browser document and Canvas mounting point used by the game.

The JavaScript application is loaded from the HTML page and operates directly against the Canvas element.


๐Ÿง  Main Game Controller

index.js

index.js is the primary orchestration module.

It imports and initializes the major game systems:

Canvas
Audio
Lives
Levels
Score
Tutorial
Pointer input
Interstitial UI
Share image
Level data
Particles
Visual effects

The game state is coordinated through the main animation loop.

Important runtime state includes:

  • Active pointers
  • Current bubbles
  • Previous-level bubbles
  • Ripple effects
  • Fireworks
  • Pointer-triggered effects
  • Interstitial timers

The game is reset through a centralized resetGame() function, which resets gameplay state, lives, level state, tutorial state, audio sequencing, and score.


๐ŸŽจ Canvas Rendering

canvas.js

The Canvas manager abstracts the HTML5 Canvas element and its 2D rendering context.

The game obtains the rendering context once and uses it throughout the runtime:

const CTX = canvasManager.getContext();

Rendering is performed continuously through the application's animation loop.

The Canvas is also initialized using the current browser viewport dimensions, with a configured maximum width.


๐Ÿ”„ Game Loop

The game uses a continuous animation loop rather than DOM-driven rendering.

Conceptually:

Browser Animation Frame
        โ”‚
        โ–ผ
Calculate delta time
        โ”‚
        โ–ผ
Clear / paint background
        โ”‚
        โ–ผ
Process timed interactions
        โ”‚
        โ–ผ
Detect collisions
        โ”‚
        โ–ผ
Update game objects
        โ”‚
        โ–ผ
Render UI
        โ”‚
        โ–ผ
Render bubbles
        โ”‚
        โ–ผ
Render particles/effects
        โ”‚
        โ–ผ
Render pointer effects
        โ”‚
        โ–ผ
Render combo messages
        โ”‚
        โ–ผ
Next animation frame

The main loop receives deltaTime, which is passed to animated game objects so their visual state can progress based on elapsed time.


๐ŸŽˆ Bubble System

ball.js

The bubble implementation is one of the primary gameplay systems.

Each bubble is created with properties such as:

Start position
Start velocity
Radius
Color/fill
Gravity
Spawn delay
Terminal velocity

A bubble internally uses a particle implementation for its physical movement.

The bubble tracks states such as:

In play
Popped
Missed
Popping
Inside viewport

The bubble also responds to Canvas boundaries.

For example, when it reaches the left or right boundary, its horizontal velocity is reversed with damping. When it passes below the playable area, it is marked as missed and notifies the game controller.


๐Ÿ’ฅ Bubble Pop Physics

Popping is implemented as a particle explosion rather than simply removing the bubble.

When a bubble is popped:

  1. The original bubble enters the popped state.
  2. A randomized number of particles is generated.
  3. Outer particles are distributed around the bubble.
  4. Inner particles are generated closer to the center.
  5. Existing bubble velocity is partially transferred to the particles.
  6. Particles receive radial velocities.
  7. Additional spark particles are created.
  8. The particles are animated independently.

This produces a visually rich explosion while retaining some physical continuity from the original bubble.

The implementation dynamically generates approximately 10โ€“80 outer particles, plus a second inner-particle group, with randomized sizes, directions, and velocity multipliers.


โš™๏ธ Particle Physics

particle.js

The particle system provides the lower-level physics behavior used by bubbles and visual effects.

Responsibilities include:

  • Position updates
  • Velocity updates
  • Gravity
  • Terminal velocity
  • Boundary callbacks
  • Collision support
  • Particle movement
  • Particle lifecycle

The main game controller uses the particle collision utilities to resolve collisions between active bubbles and interactive effects.


๐Ÿ’ซ Collision Detection

Collision processing is centralized in index.js but implemented using helpers from particle.js.

The collision system handles two major categories:

Bubble-to-bubble

Bubble A
   โ†•
Collision detection
   โ†•
Bubble B

When two bubbles collide:

  1. Collision is detected.
  2. Their positions are adjusted.
  3. Collision response is calculated.
  4. Their velocities are updated.

Bubble-to-interaction

Interactive effects such as blasts and slingshots can collide with bubbles.

When a collision occurs, the bubble is popped using the velocity of the triggering object.

The game also triggers sequential audio feedback after successful collisions.


๐Ÿ–ฑ๏ธ Input System

The application uses the browser's Pointer Events API.

Supported events include:

pointerdown
pointermove
pointerup
pointercancel

This provides a unified interaction model for:

  • Mouse
  • Touch
  • Pen/stylus
  • Multiple simultaneous pointers

Each active pointer is represented by an activePointer object.

The pointer lifecycle is roughly:

pointerdown
    โ”‚
    โ–ผ
Create ActivePointer
    โ”‚
    โ–ผ
Track movement
    โ”‚
    โ–ผ
Determine interaction type
    โ”‚
    โ”œโ”€โ”€ Tap
    โ”œโ”€โ”€ Slingshot
    โ””โ”€โ”€ Hold Blast
    โ”‚
    โ–ผ
Trigger game action
    โ”‚
    โ–ผ
pointerup / pointercancel

Pointer capture is used where supported so interactions remain associated with the Canvas while the pointer moves.


๐Ÿ‘† Tap Interaction

A normal tap attempts to find a bubble at the interaction point.

The game checks both the initial pointer position and the final pointer position.

This prevents a fast-moving bubble from making an interaction feel unresponsive.

If a bubble is found:

Record successful tap
       โ†“
Pop bubble
       โ†“
Increase score
       โ†“
Play sound

If no bubble is found:

Record miss
       โ†“
Create ripple
       โ†“
Play miss sound
       โ†“
Potentially subtract life

This logic is implemented in handleGameClick() inside index.js.


๐Ÿน Slingshot Interaction

slingshot.js

The slingshot interaction provides a gesture-based way of interacting with bubbles.

It uses pointer movement and trajectory information to calculate the resulting interaction.

Related modules include:

  • slingshot.js
  • trajectory.js
  • spring.js
  • activePointer.js

This separates gesture calculation from the central game loop.


๐Ÿ’ฅ Hold Blast

holdBlast.js

The game supports a hold-based interaction.

When a pointer is held for a defined duration, the system can convert the interaction into a blast.

The main game controller monitors active hold pointers and automatically triggers those that exceed the configured maximum blast duration.


๐ŸŽฎ Level Management

level.js

The level manager controls the game's progression state.

Responsibilities include:

  • Current level
  • Level transitions
  • Interstitial screens
  • Game-over state
  • Level countdown
  • Last-level detection
  • First-level miss handling
  • Level advancement

A typical level lifecycle is:

Load Level
    โ”‚
    โ–ผ
Countdown
    โ”‚
    โ–ผ
Spawn Bubbles
    โ”‚
    โ–ผ
Player Interaction
    โ”‚
    โ”œโ”€โ”€ Pop all bubbles
    โ”‚       โ”‚
    โ”‚       โ–ผ
    โ”‚   Level complete
    โ”‚
    โ””โ”€โ”€ Miss bubbles
            โ”‚
            โ–ผ
        Lose life
            โ”‚
            โ–ผ
       Continue / Game Over

The level manager also controls the interstitial messages shown between gameplay states.


๐Ÿ—บ๏ธ Level Data

levelData.js

Level configuration is separated from the level runtime logic.

This allows level definitions to describe bubble configurations independently from the systems responsible for executing the level.

The main application obtains level data from the level manager and converts it into active bubble objects.

The same system also provides level decoding used for custom level previews.


๐Ÿ”— Custom Level Preview

The game supports previewing encoded level data through a URL parameter.

The application reads:

?level=<encoded-level>

The parameter is decoded and validated before being used.

The flow is:

URL
 โ”‚
 โ–ผ
URLSearchParams
 โ”‚
 โ–ผ
Decode level data
 โ”‚
 โ–ผ
Validate decoded structure
 โ”‚
 โ–ผ
Create preview mode
 โ”‚
 โ–ผ
Display preview metadata
 โ”‚
 โ–ผ
Play custom level

If valid preview data exists, the browser document title and Open Graph metadata are dynamically updated to reflect the custom level name.

This makes the application capable of sharing or previewing custom levels without requiring a backend service.


โค๏ธ Life Management

lifeManager.js

The life manager maintains the player's remaining lives.

A missed bubble can cause a life to be removed.

When the player reaches zero lives:

Lives = 0
   โ†“
Game End
   โ†“
Lose sound
   โ†“
Game-over state

The life system is reset when starting a new game.


๐Ÿ† Scoring System

scoreStore.js

The score store is responsible for maintaining gameplay scoring information.

It records:

  • Successful taps
  • Missed interactions
  • Bubble counts
  • Combo information
  • Positions associated with scoring events

The game records successful taps with the current pointer position and bubble color/fill information.

Combo messages are then rendered above the gameplay area using animated transitions.


๐Ÿ“Š Score Display

scoreDisplay.js

The score display provides the visual representation of the player's current score and related game statistics.

It is coordinated with:

Score Store
Level Manager
Canvas Manager

This keeps score calculation separate from score presentation.


๐ŸŽ“ Tutorial System

tutorial.js

The tutorial system provides the initial player onboarding experience.

The application determines whether the tutorial has been completed and changes the initial game flow accordingly.

The tutorial can:

  • Generate tutorial bubbles
  • Display instructional messages
  • Wait for player interaction
  • Advance through tutorial steps
  • Reset the game when required

After tutorial completion, the normal level progression system takes over.


๐Ÿ”Š Audio System

audio.js

Audio is managed independently from the main gameplay logic.

The game uses audio feedback for events such as:

  • Bubble popping
  • Misses
  • Level transitions
  • Fireworks
  • Losing
  • Sequential bubble interactions

The audio manager also maintains a pluck sequence and is initialized after user interaction to comply with browser restrictions around automatic audio playback.

Audio assets are stored under:

sounds/

๐ŸŽ† Visual Effects

The game contains several dedicated visual-effect modules.

ripple.js

Creates a visual ripple after a missed interaction.

firework.js

Creates celebratory fireworks, particularly around major game transitions.

particle.js

Provides the low-level particle behavior used by bubble explosions and other effects.

spring.js

Provides spring-style interpolation for animated UI and game effects.

easings.js

Contains easing functions used to create smooth animation transitions.

textBlock.js

Handles animated text rendering.

textRotate.js

Provides text rotation behavior.


๐Ÿ“ธ Share Image Generation

shareImage.js

The game includes a share-image manager that integrates with the score and level systems.

It is used on interstitial and end-game screens and is updated when the player's game state changes.

The intended flow is:

Game Result
    โ”‚
    โ–ผ
Score Store
    โ”‚
    โ–ผ
Level Manager
    โ”‚
    โ–ผ
Share Image Manager
    โ”‚
    โ–ผ
Generated share representation

๐Ÿ“ Grid / Layout Utilities

grid.js

The grid module provides grid-related calculations used by the game or its supporting systems.

The project keeps these calculations separate rather than embedding layout logic throughout the rendering code.


๐ŸŽจ Color System

colors.js

The color module centralizes color-related functionality.

It is also responsible for creating gradient bitmap representations used by bubble rendering.

Bubble appearance is therefore separated from the lower-level physics implementation.


๐Ÿงฎ Utility and Math Layer

helpers.js

The helper module contains reusable game calculations.

Examples include:

  • Random value generation
  • Progress calculations
  • Interpolation
  • Position bounding
  • Ball lookup
  • Angle calculations
  • Animation helpers

This avoids duplicating common mathematical operations throughout the game.


โฑ๏ธ Animation and Timing

The application is heavily animation-driven.

Rather than relying on CSS animations for gameplay objects, the game calculates visual states inside the Canvas rendering loop.

The animation architecture uses:

deltaTime
   +
progress functions
   +
easing functions
   +
spring interpolation
   +
Canvas transformations

This allows game objects to have precise control over position, scale, rotation, opacity, and lifecycle.


๐Ÿ“ท Camera Effects

The main rendering layer includes a camera wrapper capable of applying screen shake.

When specific interactions occur, the Canvas is:

  1. Translated to its center.
  2. Rotated by a randomized amount.
  3. Translated back.
  4. Offset randomly.
  5. Rendered.
  6. Restored to the original transformation.

This creates impact feedback without changing the underlying game-object coordinates.


โŒจ๏ธ Keyboard Controls

The application also supports keyboard interaction for progressing through interstitial screens.

The following keys are recognized:

Space
Enter

This allows players to advance through appropriate game-state screens without using a pointer.


๐Ÿ”„ Game State Lifecycle

The primary gameplay state can be summarized as:

Application Start
       โ”‚
       โ–ผ
Initialize Managers
       โ”‚
       โ–ผ
Reset Game
       โ”‚
       โ–ผ
Tutorial / Level Intro
       โ”‚
       โ–ผ
Spawn Level
       โ”‚
       โ–ผ
Game Loop
       โ”‚
       โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
       โ”‚               โ”‚
       โ–ผ               โ–ผ
   Successful       Missed
   interaction      bubble
       โ”‚               โ”‚
       โ–ผ               โ–ผ
   Pop bubble       Lose life
       โ”‚               โ”‚
       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
               โ–ผ
       Check remaining
          bubbles
               โ”‚
       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
       โ”‚                โ”‚
       โ–ผ                โ–ผ
    Complete           Continue
       โ”‚
       โ–ผ
  Interstitial
       โ”‚
       โ–ผ
 Next Level
       โ”‚
       โ–ผ
 Final Level
       โ”‚
       โ–ผ
  Game Complete

๐Ÿงต Module Responsibilities

Module Responsibility
index.js Main application controller and game loop
canvas.js Canvas setup and rendering context
ball.js Bubble lifecycle and pop behavior
particle.js Physics and particle behavior
activePointer.js Pointer interaction state
slingshot.js Slingshot gesture
holdBlast.js Hold/blast gesture
trajectory.js Trajectory calculations
level.js Level state and progression
levelData.js Level definitions and encoding/decoding
lifeManager.js Player lives
scoreStore.js Score and combo state
scoreDisplay.js Score rendering
tutorial.js Tutorial flow
audio.js Audio playback
ripple.js Miss/tap ripple effect
firework.js Firework effect
spring.js Spring-based animation
easings.js Animation easing functions
colors.js Colors and gradients
helpers.js Shared calculations and utility functions
constants.js Shared configuration constants
interstitialButton.js Interstitial controls
textBlock.js Text rendering
textRotate.js Rotating text animation
shareImage.js Score/share visual generation
grid.js Grid/layout calculations

๐Ÿš€ Running the Project

Because the application is a browser-based ES-module project, it should be served through a local HTTP server rather than opened directly with file://.

For example, using a simple local server:

python -m http.server 8000

Then open:

http://localhost:8000

Alternatively, any static web server capable of serving ES modules can be used.


๐ŸŒ Deployment

The project can be deployed as a static website because the core game logic executes entirely in the browser.

Possible deployment environments include:

  • GitHub Pages
  • Netlify
  • Vercel static hosting
  • Cloudflare Pages
  • Nginx
  • Apache
  • Any static HTTP server

A production deployment only needs to serve the project files with correct MIME types and ES-module support.


๐Ÿ” Security Considerations

Since the application is primarily client-side:

  • No server-side authentication is required for the core game.
  • No backend database is required for gameplay.
  • Level preview data should be treated as untrusted client input.
  • Encoded level data should always be validated before use.
  • External resources should use HTTPS in production.
  • Any future server-side leaderboard or account functionality should validate all score and level data on the server.

Client-side score values should not be considered trustworthy if competitive leaderboards are added later, because users can modify browser-side JavaScript.


โšก Performance Considerations

The application is designed around a Canvas rendering loop rather than creating large numbers of DOM nodes.

Performance-sensitive areas include:

Collision Detection

Bubble-to-bubble collision checking uses pairwise comparisons:

Bubble A โ†’ Bubble B
Bubble A โ†’ Bubble C
Bubble A โ†’ Bubble D
...

As the number of active bubbles increases, this can approach O(nยฒ) collision complexity.

For significantly larger levels, a spatial partitioning strategy such as:

  • Uniform grid
  • Spatial hash
  • Quadtree

could reduce unnecessary collision checks.

Particle Effects

Bubble explosions dynamically create many particles.

Large numbers of simultaneous explosions can increase:

  • Object allocation
  • Canvas draw operations
  • Garbage collection
  • Per-frame physics calculations

Potential future optimization could include object pooling for frequently created particles.

Rendering

Canvas transformations and effects such as camera shake, alpha blending, gradients, and large particle counts should be monitored on lower-powered mobile devices.


๐Ÿงช Debugging

Useful areas to inspect when debugging gameplay include:

index.js
ball.js
particle.js
level.js
activePointer.js
scoreStore.js

Interaction bugs

Start with:

activePointer.js
slingshot.js
holdBlast.js
trajectory.js
index.js

Physics bugs

Start with:

ball.js
particle.js
helpers.js
constants.js

Level progression bugs

Start with:

level.js
levelData.js
index.js
lifeManager.js

Visual effects

Start with:

particle.js
ripple.js
firework.js
spring.js
easings.js

Scoring bugs

Start with:

scoreStore.js
scoreDisplay.js
index.js

๐Ÿ› ๏ธ Development Guidelines

When modifying the game, keep game responsibilities separated.

For example:

Do

Physics change
โ†’ particle.js / ball.js

Input change
โ†’ activePointer.js / slingshot.js

Level behavior
โ†’ level.js / levelData.js

Scoring behavior
โ†’ scoreStore.js

Visual effect
โ†’ dedicated effect module

Audio behavior
โ†’ audio.js

Avoid

Putting all gameplay behavior into index.js.

index.js should primarily coordinate systems rather than becoming the implementation location for every feature.


๐Ÿ”ง Extending the Game

The modular architecture makes it possible to add new mechanics without rewriting the complete game loop.

Potential extensions include:

  • New bubble types
  • Special bubbles
  • Power-ups
  • Time-limited levels
  • Obstacles
  • Moving targets
  • Combo multipliers
  • Additional gesture mechanics
  • New particle effects
  • New sound effects
  • Procedural levels
  • Level editor improvements
  • Persistent player profiles
  • Online leaderboards
  • Multiplayer gameplay
  • Analytics
  • Mobile-specific optimization

A new gameplay mechanic should ideally be implemented as an independent module and connected to the existing lifecycle through the main controller.


๐Ÿ“Œ Important Architectural Note

The current repository is fundamentally a client-side Canvas game, despite the previous README describing a React/TypeScript + FastAPI + Redis + PostgreSQL architecture.

The actual repository structure and source code show:

Vanilla JavaScript
        +
ES Modules
        +
HTML5 Canvas
        +
Custom Physics
        +
Browser Pointer Events
        +
Client-side Game State
        +
Audio / Visual Effects

The main runtime imports modules such as canvas.js, ball.js, particle.js, level.js, scoreStore.js, tutorial.js, audio.js, and other gameplay systems directly from the JavaScript source tree.

Therefore, this README intentionally documents the implementation that exists in the repository, rather than describing technologies that are not currently represented in the source tree.


๐Ÿ“„ License

See the repository license file for the applicable licensing terms.


๐Ÿ‘จโ€๐Ÿ’ป Project

Bubbles

Repository:

github.com/thinkingdev923/Bubbles

The project currently contains the complete browser-side game implementation, including the rendering engine, physics, interaction system, level management, scoring, tutorials, audio, and visual effects.

About

A satisfying interactive browser game built with vanilla JavaScript, HTML, and CSS, featuring smooth animations, dynamic DOM manipulation, responsive UI, event-driven gameplay, performance-focused rendering, and a lightweight zero-dependency architecture.

Topics

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages