diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml new file mode 100644 index 0000000..a525a64 --- /dev/null +++ b/.github/workflows/deploy-pages.yml @@ -0,0 +1,65 @@ +name: Deploy SpaceWar to GitHub Pages + +on: + push: + branches: [master] + paths: + - 'spacewar-wasm/**' + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + build: + name: Build WASM + package site + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Rust (stable + wasm32 target) + uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-unknown + + - name: Cache Cargo registry + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-cargo-${{ hashFiles('spacewar-wasm/Cargo.lock') }} + restore-keys: ${{ runner.os }}-cargo- + + - name: Install wasm-pack + run: cargo install wasm-pack --locked + + - name: Build WebAssembly + working-directory: spacewar-wasm + run: wasm-pack build --target web --out-dir www/pkg + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: spacewar-wasm/www + + deploy: + name: Deploy to GitHub Pages + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + steps: + - name: Deploy + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index a1c2a23..b90783a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,9 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +# Rust build artifacts +spacewar-wasm/target/ + +# wasm-pack output (generated during CI/CD build; not stored in Git) +spacewar-wasm/www/pkg/ diff --git a/README.md b/README.md index 9e83d67..89bc9b2 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,112 @@ ![Gameplay](spacewar.gif) -### ๐Ÿš€ A space odyssey written in Java! +### ๐Ÿš€ A space odyssey โ€” originally written in Java, now playable in the browser via Rust + WebAssembly! --- Java Beer + +--- + +## ๐ŸŒ Play Online + +The game is deployed to **GitHub Pages** and is playable directly in your browser โ€” no install required. + +> **[โ–ถ Play Space War](https://lassault.github.io/SpaceWar/)** + +--- + +## ๐ŸŽฎ How to Play + +| Action | Control | +|---|---| +| Move ship | Mouse (or touch-drag on mobile) | +| Fire | Spacebar (or tap on mobile) | +| Select ship | Keys **1 โ€“ 8** | + +The ship upgrades automatically as your score increases every 250 points (up to level 8). Destroy enemies to earn points; survive with your 3 lives! + +--- + +## ๐Ÿ—‚๏ธ Repository Structure + +``` +SpaceWar/ +โ”œโ”€โ”€ src/lassa/net/ # Original Java source (Swing/AWT desktop app) +โ”‚ โ””โ”€โ”€ imagenes/ # All game sprites (shared with web version) +โ”œโ”€โ”€ spacewar-wasm/ # Rust + WebAssembly rewrite +โ”‚ โ”œโ”€โ”€ src/lib.rs # Complete game logic in Rust +โ”‚ โ”œโ”€โ”€ Cargo.toml +โ”‚ โ””โ”€โ”€ www/ # Web-deployable folder +โ”‚ โ”œโ”€โ”€ index.html # Game page (single file, no bundler needed) +โ”‚ โ””โ”€โ”€ assets/ # Sprites served as static files +โ””โ”€โ”€ .github/workflows/ + โ””โ”€โ”€ deploy-pages.yml # CI/CD: builds WASM โ†’ deploys to GitHub Pages +``` + +--- + +## ๐Ÿฆ€ Web Version โ€” Rust + WebAssembly + +### Why Rust + WebAssembly? + +| Concern | Answer | +|---|---| +| **Performance** | Rust compiles to near-native speed WASM; no GC pauses | +| **Safety** | Memory-safe by default โ€” no null-pointer crashes | +| **Portability** | Runs in any modern browser without plugins | +| **Portfolio fit** | Demonstrates both systems programming and web skills | + +### Architecture + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Browser โ”‚ +โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ +โ”‚ โ”‚ index.html โ”‚ โ”‚ spacewar_wasm โ”‚ โ”‚ +โ”‚ โ”‚ (JS glue) โ”‚โ—„โ”€โ”‚ .wasm (54 KB)โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ€ข load imgs โ”‚ โ”‚ โ€ข game state โ”‚ โ”‚ +โ”‚ โ”‚ โ€ข RAF loop โ”‚ โ”‚ โ€ข physics โ”‚ โ”‚ +โ”‚ โ”‚ โ€ข events โ”‚ โ”‚ โ€ข collisions โ”‚ โ”‚ +โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ€ข rendering โ”‚ โ”‚ +โ”‚ โ”‚ Canvas โ”‚ (web-sys) โ”‚ โ”‚ +โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +- **`SpaceWarGame::tick(timestamp)`** โ€” called each animation frame; runs all physics, AI, and renders to the HTML5 Canvas. +- **`SpaceWarGame::on_key_down(key, code)`** โ€” keyboard input forwarded from JS. +- **`SpaceWarGame::on_mouse_move(x, y)`** โ€” mouse/touch position forwarded from JS. + +### Building Locally + +```bash +# Prerequisites: Rust stable, wasm-pack +rustup target add wasm32-unknown-unknown +cargo install wasm-pack + +# Build +cd spacewar-wasm +wasm-pack build --target web --out-dir www/pkg + +# Serve (any static file server works) +cd www +python3 -m http.server 8080 +# Open http://localhost:8080 +``` + +--- + +## โ˜• Original Java Version + +The original desktop game (`src/`) is a pure **Java Swing/AWT** application using multi-threading for movement, collision detection, enemy generation, and rendering. + +```bash +# Run the pre-built JAR +java -jar SpaceWar.jar +``` + diff --git a/spacewar-wasm/.gitignore b/spacewar-wasm/.gitignore new file mode 100644 index 0000000..4d5793d --- /dev/null +++ b/spacewar-wasm/.gitignore @@ -0,0 +1,5 @@ +# Rust build artifacts +target/ + +# wasm-pack generated package (rebuilt on deploy) +www/pkg/ diff --git a/spacewar-wasm/Cargo.lock b/spacewar-wasm/Cargo.lock new file mode 100644 index 0000000..f807595 --- /dev/null +++ b/spacewar-wasm/Cargo.lock @@ -0,0 +1,136 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bumpalo" +version = "3.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "js-sys" +version = "0.3.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "spacewar-wasm" +version = "0.1.0" +dependencies = [ + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "wasm-bindgen" +version = "0.2.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" +dependencies = [ + "js-sys", + "wasm-bindgen", +] diff --git a/spacewar-wasm/Cargo.toml b/spacewar-wasm/Cargo.toml new file mode 100644 index 0000000..317b641 --- /dev/null +++ b/spacewar-wasm/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "spacewar-wasm" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +wasm-bindgen = "0.2" +js-sys = "0.3" + +[dependencies.web-sys] +version = "0.3" +features = [ + "CanvasRenderingContext2d", + "Document", + "Element", + "HtmlCanvasElement", + "HtmlImageElement", + "Window", + "console", +] + +[profile.release] +opt-level = "s" +lto = true + +[package.metadata.wasm-pack.profile.release] +wasm-opt = false diff --git a/spacewar-wasm/src/lib.rs b/spacewar-wasm/src/lib.rs new file mode 100644 index 0000000..d4cdf9f --- /dev/null +++ b/spacewar-wasm/src/lib.rs @@ -0,0 +1,712 @@ +use js_sys::Array; +use wasm_bindgen::prelude::*; +use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement, HtmlImageElement}; + +// โ”€โ”€โ”€ Canvas dimensions โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +const CANVAS_W: f64 = 1300.0; +const CANVAS_H: f64 = 720.0; + +// โ”€โ”€โ”€ Game balance constants โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +const NUM_STARS: usize = 500; +const INITIAL_ENEMIES: usize = 5; +const MAX_ENEMIES: usize = 10; +const SCORE_PER_LEVEL: i32 = 250; +const MAX_SHIP_LEVEL: usize = 8; +const BULLET_DAMAGE_BASE: i32 = 75; +const ENEMY_BULLET_DAMAGE_MULTIPLIER: i32 = 5; + +// โ”€โ”€โ”€ Image index layout (100 images, loaded by JS in this exact order) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +// 0-2 stars (estrella1-3) +// 3-7 enemies (enemigo01-05) +// 8-10 player bullets (disparo1-3) +// 11 enemy bullet (disparo4) +// 12 life heart (vida) +// 13-20 player thruster frames (fuego1-8) +// 21-28 enemy thruster frames (fuegoenemigo1-8) +// 29-35 explosion frames (explosion-01 through -07) +// 36-99 ships: ship s (0-based), upgrade frame f (0-based) โ†’ 36 + s*8 + f +const IMG_STAR: usize = 0; +const IMG_ENEMY: usize = 3; +const IMG_BULLET_PLAYER: usize = 8; +const IMG_BULLET_ENEMY: usize = 11; +const IMG_LIFE: usize = 12; +const IMG_FIRE_PLAYER: usize = 13; +const IMG_FIRE_ENEMY: usize = 21; +const IMG_EXPLOSION: usize = 29; +const IMG_SHIP: usize = 36; + +fn ship_img(ship: usize, frame: usize) -> usize { + IMG_SHIP + ship * 8 + frame +} + +// โ”€โ”€โ”€ Pseudo-random helpers (delegates to JS Math.random) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ +fn rng() -> f64 { + js_sys::Math::random() +} + +fn rand_range(lo: f64, hi: f64) -> f64 { + lo + rng() * (hi - lo) +} + +// โ”€โ”€โ”€ Game entities โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +struct Star { + x: f64, + y: f64, + /// 1-3 (controls size/speed, matching original tipo field) + kind: usize, +} + +impl Star { + fn random() -> Self { + Star { + x: rand_range(0.0, CANVAS_W), + y: rand_range(0.0, CANVAS_H), + kind: (rng() * 3.0) as usize + 1, + } + } + + fn spawn_at_top() -> Self { + Star { + x: rand_range(0.0, CANVAS_W), + y: 0.0, + kind: (rng() * 3.0) as usize + 1, + } + } +} + +struct Ship { + x: f64, + y: f64, + /// Current HP (0-100) + health: i32, + /// Remaining lives (starts at 3) + lives: i32, + /// Upgrade level 1-8 (determines sprite and bullet count) + level: usize, +} + +struct Enemy { + x: f64, + y: f64, + health: i32, + /// Enemy tier 1-5 (higher = faster but less HP) + level: usize, +} + +impl Enemy { + fn random() -> Self { + let level = (rng() * 5.0) as usize + 1; + Enemy { + x: rand_range(100.0, 1100.0), + y: 0.0, + health: (6 - level as i32) * 100, + level, + } + } +} + +struct Bullet { + x: f64, + y: f64, + /// For enemy bullets this is the enemy's level, used for damage calculation + kind: i32, +} + +struct Explosion { + x: f64, + y: f64, + /// Animation frame index 1-7 + progress: usize, +} + +#[derive(PartialEq)] +enum Phase { + Menu, + Playing, + GameOver, +} + +// โ”€โ”€โ”€ Main game struct (exported to JavaScript) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +#[wasm_bindgen] +pub struct SpaceWarGame { + ctx: CanvasRenderingContext2d, + images: Vec, + + phase: Phase, + ship: Ship, + /// 0-based index into ships 0..7 (player choice) + chosen_ship: usize, + + enemies: Vec, + bullets: Vec, + enemy_bullets: Vec, + stars: Vec, + explosions: Vec, + + score: i32, + /// Current animation frame for thruster fire (0-7, cycles at 50 ms) + fire_frame: usize, + last_ts: f64, + + // โ”€โ”€ ms accumulators for sub-systems โ”€โ”€ + star_acc: f64, + fire_acc: f64, + spawn_acc: f64, + spawn_interval: f64, + shoot_acc: f64, + shoot_interval: f64, + + // โ”€โ”€ game-over ship explosion animation โ”€โ”€ + over_counter: u32, + over_progress: usize, +} + +#[wasm_bindgen] +impl SpaceWarGame { + /// Create a new game from a canvas element and a flat JS Array of + /// pre-loaded HTMLImageElement objects (see image layout above). + #[wasm_bindgen(constructor)] + pub fn new(canvas: HtmlCanvasElement, images_js: Array) -> SpaceWarGame { + // Extract typed image elements from the JS Array + let images: Vec = (0..images_js.length()) + .filter_map(|i| images_js.get(i).dyn_into::().ok()) + .collect(); + + let ctx = canvas + .get_context("2d") + .unwrap_throw() + .unwrap_throw() + .dyn_into::() + .unwrap_throw(); + + // Initialise starfield + let mut stars = Vec::with_capacity(NUM_STARS); + for _ in 0..NUM_STARS { + stars.push(Star::random()); + } + + SpaceWarGame { + ctx, + images, + phase: Phase::Menu, + ship: Ship { x: 620.0, y: 600.0, health: 100, lives: 3, level: 1 }, + chosen_ship: 0, + enemies: Vec::new(), + bullets: Vec::new(), + enemy_bullets: Vec::new(), + stars, + explosions: Vec::new(), + score: 0, + fire_frame: 0, + last_ts: 0.0, + star_acc: 0.0, + fire_acc: 0.0, + spawn_acc: 0.0, + spawn_interval: rand_range(500.0, 1500.0), + shoot_acc: 0.0, + shoot_interval: rand_range(250.0, 950.0), + over_counter: 0, + over_progress: 0, + } + } + + // โ”€โ”€ Input handlers โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + + /// Called on every keydown event. `key` is KeyboardEvent.key. + pub fn on_key_down(&mut self, key: String, key_code: u32) { + match self.phase { + Phase::Menu => { + // Keys 1-8 (top row or numpad) choose a ship + let choice: Option = match key_code { + 49..=56 => Some((key_code - 48) as usize), // top-row 1-8 + 97..=104 => Some((key_code - 96) as usize), // numpad 1-8 + _ => None, + }; + if let Some(c) = choice { + self.start_game(c); + } + } + Phase::Playing => { + if key == " " || key_code == 32 { + self.fire_player_bullets(); + } + } + Phase::GameOver => { + if self.over_counter >= 25 { + self.phase = Phase::Menu; + } + } + } + } + + /// Called on every mousemove event with canvas-relative coordinates. + pub fn on_mouse_move(&mut self, x: f64, y: f64) { + if self.phase == Phase::Playing { + // Centre the sprite on the cursor (ship sprite is 60ร—60) + self.ship.x = x - 30.0; + self.ship.y = y - 60.0; + } + } + + /// Main per-frame update + render, called from requestAnimationFrame. + pub fn tick(&mut self, timestamp: f64) { + // Compute delta-time in ms; cap to 100 ms to survive tab-switching + let dt = if self.last_ts == 0.0 { + 16.667 + } else { + (timestamp - self.last_ts).min(100.0) + }; + self.last_ts = timestamp; + + self.update(dt); + self.render(); + } +} + +// โ”€โ”€โ”€ Private game logic โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +impl SpaceWarGame { + fn start_game(&mut self, ship_number: usize) { + // ship_number is 1-based; clamp to valid range + self.chosen_ship = ship_number.saturating_sub(1).min(7); + + self.ship = Ship { x: 620.0, y: 600.0, health: 100, lives: 3, level: 1 }; + self.enemies.clear(); + self.bullets.clear(); + self.enemy_bullets.clear(); + self.explosions.clear(); + self.score = 0; + self.fire_frame = 0; + self.last_ts = 0.0; + self.star_acc = 0.0; + self.fire_acc = 0.0; + self.spawn_acc = 0.0; + self.spawn_interval = rand_range(500.0, 1500.0); + self.shoot_acc = 0.0; + self.shoot_interval = rand_range(250.0, 950.0); + self.over_counter = 0; + self.over_progress = 0; + + for _ in 0..INITIAL_ENEMIES { + self.enemies.push(Enemy::random()); + } + + self.phase = Phase::Playing; + } + + // โ”€โ”€ Update โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + + fn update(&mut self, dt: f64) { + // Stars always scroll, regardless of game phase + self.update_stars(dt); + + match self.phase { + Phase::Playing => { + self.update_ship_level(); + self.update_bullets(dt); + self.update_enemies(dt); + self.update_fire_and_explosions(dt); + self.check_collisions(); + self.maybe_spawn_enemy(dt); + self.maybe_enemy_shoot(dt); + } + Phase::GameOver => { + self.update_fire_and_explosions(dt); + } + Phase::Menu => {} + } + } + + /// Raise the ship's upgrade level based on score thresholds. + fn update_ship_level(&mut self) { + let new_level = ((self.score / SCORE_PER_LEVEL) as usize + 1).min(MAX_SHIP_LEVEL); + self.ship.level = new_level; + } + + /// Scroll the starfield downward. Original: y += kind*2 every 30 ms. + fn update_stars(&mut self, dt: f64) { + self.star_acc += dt; + if self.star_acc < 30.0 { + return; + } + let ticks = self.star_acc / 30.0; + self.star_acc %= 30.0; + + for star in &mut self.stars { + star.y += star.kind as f64 * 2.0 * ticks; + if star.y > CANVAS_H { + *star = Star::spawn_at_top(); + } + } + } + + /// Move bullets. Original: player bullets y-=10, enemy bullets y+=10, every 15 ms. + fn update_bullets(&mut self, dt: f64) { + let ticks = dt / 15.0; + let mut i = self.bullets.len(); + while i > 0 { + i -= 1; + self.bullets[i].y -= 10.0 * ticks; + if self.bullets[i].y < 0.0 { + self.bullets.swap_remove(i); + } + } + + let mut i = self.enemy_bullets.len(); + while i > 0 { + i -= 1; + self.enemy_bullets[i].y += 10.0 * ticks; + if self.enemy_bullets[i].y > CANVAS_H { + self.enemy_bullets.swap_remove(i); + } + } + } + + /// Drop enemies downward. Original: y += level every 15 ms. + fn update_enemies(&mut self, dt: f64) { + let ticks = dt / 15.0; + for enemy in &mut self.enemies { + enemy.y += enemy.level as f64 * ticks; + if enemy.y > CANVAS_H { + // Recycle off-screen enemies immediately + *enemy = Enemy::random(); + } + } + } + + /// Advance the shared thruster fire animation (every 50 ms) and explosion + /// progress (each explosion frame also advances every 50 ms). + fn update_fire_and_explosions(&mut self, dt: f64) { + self.fire_acc += dt; + if self.fire_acc < 50.0 { + return; + } + self.fire_acc %= 50.0; + + self.fire_frame = (self.fire_frame + 1) % 8; + + // Advance explosion animation; remove finished ones + let mut i = self.explosions.len(); + while i > 0 { + i -= 1; + self.explosions[i].progress += 1; + if self.explosions[i].progress > 7 { + self.explosions.swap_remove(i); + } + } + + // Game-over ship explosion counter + if self.phase == Phase::GameOver && self.over_counter < 25 { + self.over_progress += 1; + if self.over_progress >= 7 { + self.over_progress = 0; + } + self.over_counter += 1; + } + } + + fn maybe_spawn_enemy(&mut self, dt: f64) { + self.spawn_acc += dt; + if self.spawn_acc >= self.spawn_interval { + self.spawn_acc -= self.spawn_interval; + self.spawn_interval = rand_range(500.0, 1500.0); + if self.enemies.len() < MAX_ENEMIES { + self.enemies.push(Enemy::random()); + } + } + } + + fn maybe_enemy_shoot(&mut self, dt: f64) { + self.shoot_acc += dt; + if self.shoot_acc < self.shoot_interval { + return; + } + self.shoot_acc -= self.shoot_interval; + let player_level = (self.score / SCORE_PER_LEVEL).min(8); + // Shooting becomes more frequent as the player progresses + let max_interval = 100.0 * (9 - player_level) as f64; + self.shoot_interval = rand_range(250.0, max_interval + 250.0); + + // Every visible enemy fires a bullet + let shots: Vec = self + .enemies + .iter() + .map(|e| Bullet { x: e.x + 17.0, y: e.y + 40.0, kind: e.level as i32 }) + .collect(); + self.enemy_bullets.extend(shots); + } + + /// AABB collision detection matching the original Java logic. + fn check_collisions(&mut self) { + let sx = self.ship.x; + let sy = self.ship.y; + let ship_level = self.ship.level as i32; + + // โ”€โ”€ Player bullets vs enemies โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + let mut j = self.bullets.len(); + 'bullet_loop: while j > 0 { + j -= 1; + let bx = self.bullets[j].x; + let by = self.bullets[j].y; + + let mut i = self.enemies.len(); + while i > 0 { + i -= 1; + let ex = self.enemies[i].x; + let ey = self.enemies[i].y; + + let hit_x = (bx > ex && bx < ex + 60.0) + || (bx + 26.0 > ex && bx + 26.0 < ex + 60.0); + let hit_y = by - 12.0 < ey + 30.0; + + if hit_x && hit_y { + self.bullets.swap_remove(j); + self.enemies[i].health -= ship_level * BULLET_DAMAGE_BASE; + + if self.enemies[i].health <= 0 { + let (ex, ey, elv) = + (self.enemies[i].x, self.enemies[i].y, self.enemies[i].level); + self.score += elv as i32 * 10; + self.explosions + .push(Explosion { x: ex - 16.0, y: ey - 14.0, progress: 1 }); + self.enemies.swap_remove(i); + + if self.enemies.len() < 5 { + self.enemies.push(Enemy::random()); + } + } + continue 'bullet_loop; + } + } + } + + // โ”€โ”€ Enemy bullets vs player โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + let mut i = self.enemy_bullets.len(); + while i > 0 { + i -= 1; + let bx = self.enemy_bullets[i].x; + let by = self.enemy_bullets[i].y; + let bk = self.enemy_bullets[i].kind; + + let hit_x = (bx > sx && bx < sx + 60.0) + || (bx + 26.0 > sx && bx + 26.0 < sx + 60.0); + let hit_y = by - 12.0 > sy + 30.0; + + if hit_x && hit_y { + self.enemy_bullets.swap_remove(i); + self.ship.health -= bk * ENEMY_BULLET_DAMAGE_MULTIPLIER; + + if self.ship.health <= 0 { + self.ship.health = 100; + self.ship.lives -= 1; + if self.ship.lives <= 0 { + self.phase = Phase::GameOver; + } + } + break; // one hit per frame is enough + } + } + } + + fn fire_player_bullets(&mut self) { + let num = if self.ship.level == MAX_SHIP_LEVEL { + 3 + } else if self.ship.level >= 4 { + 2 + } else { + 1 + }; + + match num { + 2 => { + for i in 0..2usize { + self.bullets.push(Bullet { + x: self.ship.x + 15.0 + 30.0 * i as f64 - 13.0, + y: self.ship.y - 40.0, + kind: 0, + }); + } + } + 3 => { + for i in 0..3usize { + self.bullets.push(Bullet { + x: self.ship.x + 30.0 * i as f64 - 13.0, + y: self.ship.y - 40.0, + kind: 0, + }); + } + } + _ => { + self.bullets.push(Bullet { + x: self.ship.x + 17.0, + y: self.ship.y - 40.0, + kind: 0, + }); + } + } + } + + // โ”€โ”€ Rendering โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + + fn render(&self) { + let ctx = &self.ctx; + + // Background + ctx.set_fill_style_str("black"); + ctx.fill_rect(0.0, 0.0, CANVAS_W, CANVAS_H); + + // Stars are always visible + for star in &self.stars { + self.draw_image(ctx, IMG_STAR + star.kind - 1, star.x, star.y); + } + + match self.phase { + Phase::Menu => self.render_menu(ctx), + Phase::Playing => self.render_game(ctx), + Phase::GameOver => self.render_game_over(ctx), + } + } + + fn render_menu(&self, ctx: &CanvasRenderingContext2d) { + ctx.set_fill_style_str("white"); + ctx.set_font("bold 24px Arial, sans-serif"); + let _ = ctx.fill_text("Choose your ship (press 1 โ€“ 8)", 430.0, 75.0); + + ctx.set_font("italic 14px Arial, sans-serif"); + + let mut col: usize = 0; + let mut row: usize = 0; + for i in 0..8usize { + let x = 150.0 + col as f64 * 300.0; + let y = 180.0 + row as f64 * 300.0; + let _ = ctx.fill_text(&format!("Ship {} [{}]", i + 1, i + 1), x + 15.0, y); + // Use the first upgrade frame (index 0) as the menu preview + self.draw_image_scaled(ctx, ship_img(i, 0), x, y + 20.0, 80.0, 80.0); + col += 1; + if i == 3 { + row = 1; + col = 0; + } + } + } + + fn render_game(&self, ctx: &CanvasRenderingContext2d) { + // Player bullets โ€” bullet sprite is selected by bullet count tier + let bullet_sprite = IMG_BULLET_PLAYER + + if self.ship.level == MAX_SHIP_LEVEL { + 2 + } else if self.ship.level >= 4 { + 1 + } else { + 0 + }; + for b in &self.bullets { + self.draw_image(ctx, bullet_sprite, b.x, b.y); + } + + // Enemy bullets + for b in &self.enemy_bullets { + self.draw_image(ctx, IMG_BULLET_ENEMY, b.x, b.y); + } + + // Enemies + their thruster fire + for e in &self.enemies { + self.draw_image_scaled(ctx, IMG_ENEMY + e.level - 1, e.x, e.y, 60.0, 60.0); + self.draw_image(ctx, IMG_FIRE_ENEMY + self.fire_frame, e.x + 15.0, e.y - 30.0); + } + + // Explosion effects + for exp in &self.explosions { + if exp.progress >= 1 && exp.progress <= 7 { + self.draw_image(ctx, IMG_EXPLOSION + exp.progress - 1, exp.x, exp.y); + } + } + + // Player ship โ€” sprite is driven by upgrade level (1-8) + self.draw_image_scaled( + ctx, + ship_img(self.chosen_ship, self.ship.level - 1), + self.ship.x, + self.ship.y, + 60.0, + 60.0, + ); + // Player thruster fire + self.draw_image( + ctx, + IMG_FIRE_PLAYER + self.fire_frame, + self.ship.x + 15.0, + self.ship.y + 50.0, + ); + + self.render_hud(ctx); + } + + fn render_hud(&self, ctx: &CanvasRenderingContext2d) { + ctx.set_stroke_style_str("lime"); + ctx.set_fill_style_str("lime"); + ctx.set_font("italic 14px Arial, sans-serif"); + + // Health bar outline + fill + ctx.stroke_rect(1215.0, 75.0, 25.0, 500.0); + let health_h = self.ship.health as f64 * 5.0; + ctx.fill_rect(1215.0, 500.0 + 75.0 - health_h, 25.0, health_h); + + // Text labels + let _ = ctx.fill_text(&format!("HP: {}", self.ship.health), 1200.0, 65.0); + let _ = ctx.fill_text(&format!("Level: {}", self.ship.level), 1205.0, 600.0); + let _ = ctx.fill_text(&format!("Lives: {}", self.ship.lives), 1200.0, 625.0); + let _ = ctx.fill_text(&format!("Score: {}", self.score), 1200.0, 650.0); + + // Life icons + for i in 0..self.ship.lives as usize { + self.draw_image_scaled(ctx, IMG_LIFE, 1185.0 + 30.0 * i as f64, 20.0, 25.0, 25.0); + } + } + + fn render_game_over(&self, ctx: &CanvasRenderingContext2d) { + ctx.set_fill_style_str("white"); + ctx.set_font("bold 70px Arial, sans-serif"); + let _ = ctx.fill_text("Game Over", 425.0, 300.0); + let _ = ctx.fill_text("Score: ", 425.0, 400.0); + let _ = ctx.fill_text(&self.score.to_string(), 675.0, 400.0); + + if self.over_counter < 25 && self.over_progress < 7 { + self.draw_image( + ctx, + IMG_EXPLOSION + self.over_progress, + self.ship.x, + self.ship.y, + ); + } + + if self.over_counter >= 25 { + ctx.set_font("italic 20px Arial, sans-serif"); + let _ = ctx.fill_text("Press any key to return to menu", 480.0, 500.0); + } + } + + // โ”€โ”€ Drawing helpers โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + + fn draw_image(&self, ctx: &CanvasRenderingContext2d, idx: usize, x: f64, y: f64) { + if let Some(img) = self.images.get(idx) { + let _ = ctx.draw_image_with_html_image_element(img, x, y); + } + } + + fn draw_image_scaled( + &self, + ctx: &CanvasRenderingContext2d, + idx: usize, + x: f64, + y: f64, + w: f64, + h: f64, + ) { + if let Some(img) = self.images.get(idx) { + let _ = ctx.draw_image_with_html_image_element_and_dw_and_dh(img, x, y, w, h); + } + } +} diff --git a/spacewar-wasm/www/assets/disparos/disparo1-1.png b/spacewar-wasm/www/assets/disparos/disparo1-1.png new file mode 100644 index 0000000..a3a7222 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo1-1.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo1-2.png b/spacewar-wasm/www/assets/disparos/disparo1-2.png new file mode 100644 index 0000000..116c5c0 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo1-2.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo1.png b/spacewar-wasm/www/assets/disparos/disparo1.png new file mode 100644 index 0000000..962cf6f Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo1.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo2-1.png b/spacewar-wasm/www/assets/disparos/disparo2-1.png new file mode 100644 index 0000000..d36c19a Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo2-1.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo2-2.png b/spacewar-wasm/www/assets/disparos/disparo2-2.png new file mode 100644 index 0000000..44f8a09 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo2-2.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo2.png b/spacewar-wasm/www/assets/disparos/disparo2.png new file mode 100644 index 0000000..4c9341c Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo2.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo3-1.png b/spacewar-wasm/www/assets/disparos/disparo3-1.png new file mode 100644 index 0000000..6870400 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo3-1.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo3-2.png b/spacewar-wasm/www/assets/disparos/disparo3-2.png new file mode 100644 index 0000000..1e04330 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo3-2.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo3-3.png b/spacewar-wasm/www/assets/disparos/disparo3-3.png new file mode 100644 index 0000000..02f28d5 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo3-3.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo3.png b/spacewar-wasm/www/assets/disparos/disparo3.png new file mode 100644 index 0000000..f6b16a5 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo3.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo4-1.png b/spacewar-wasm/www/assets/disparos/disparo4-1.png new file mode 100644 index 0000000..1da5872 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo4-1.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo4-2.png b/spacewar-wasm/www/assets/disparos/disparo4-2.png new file mode 100644 index 0000000..b64d840 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo4-2.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo4-3.png b/spacewar-wasm/www/assets/disparos/disparo4-3.png new file mode 100644 index 0000000..5a8299c Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo4-3.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo4-4.png b/spacewar-wasm/www/assets/disparos/disparo4-4.png new file mode 100644 index 0000000..6ee1dc0 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo4-4.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparo4.png b/spacewar-wasm/www/assets/disparos/disparo4.png new file mode 100644 index 0000000..6962bc2 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparo4.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparoenemigo1-1.png b/spacewar-wasm/www/assets/disparos/disparoenemigo1-1.png new file mode 100644 index 0000000..4f63ba7 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparoenemigo1-1.png differ diff --git a/spacewar-wasm/www/assets/disparos/disparoenemigo1-2.png b/spacewar-wasm/www/assets/disparos/disparoenemigo1-2.png new file mode 100644 index 0000000..236eef0 Binary files /dev/null and b/spacewar-wasm/www/assets/disparos/disparoenemigo1-2.png differ diff --git a/spacewar-wasm/www/assets/enemigos/enemigo01.png b/spacewar-wasm/www/assets/enemigos/enemigo01.png new file mode 100644 index 0000000..742a114 Binary files /dev/null and b/spacewar-wasm/www/assets/enemigos/enemigo01.png differ diff --git a/spacewar-wasm/www/assets/enemigos/enemigo02.png b/spacewar-wasm/www/assets/enemigos/enemigo02.png new file mode 100644 index 0000000..6079908 Binary files /dev/null and b/spacewar-wasm/www/assets/enemigos/enemigo02.png differ diff --git a/spacewar-wasm/www/assets/enemigos/enemigo03.png b/spacewar-wasm/www/assets/enemigos/enemigo03.png new file mode 100644 index 0000000..23a1d24 Binary files /dev/null and b/spacewar-wasm/www/assets/enemigos/enemigo03.png differ diff --git a/spacewar-wasm/www/assets/enemigos/enemigo04.png b/spacewar-wasm/www/assets/enemigos/enemigo04.png new file mode 100644 index 0000000..df97136 Binary files /dev/null and b/spacewar-wasm/www/assets/enemigos/enemigo04.png differ diff --git a/spacewar-wasm/www/assets/enemigos/enemigo05.png b/spacewar-wasm/www/assets/enemigos/enemigo05.png new file mode 100644 index 0000000..a4ac448 Binary files /dev/null and b/spacewar-wasm/www/assets/enemigos/enemigo05.png differ diff --git a/spacewar-wasm/www/assets/estrellas/estrella1.png b/spacewar-wasm/www/assets/estrellas/estrella1.png new file mode 100644 index 0000000..032d539 Binary files /dev/null and b/spacewar-wasm/www/assets/estrellas/estrella1.png differ diff --git a/spacewar-wasm/www/assets/estrellas/estrella2.png b/spacewar-wasm/www/assets/estrellas/estrella2.png new file mode 100644 index 0000000..235c071 Binary files /dev/null and b/spacewar-wasm/www/assets/estrellas/estrella2.png differ diff --git a/spacewar-wasm/www/assets/estrellas/estrella3.png b/spacewar-wasm/www/assets/estrellas/estrella3.png new file mode 100644 index 0000000..7111a8d Binary files /dev/null and b/spacewar-wasm/www/assets/estrellas/estrella3.png differ diff --git a/spacewar-wasm/www/assets/explosion/explosion-01.png b/spacewar-wasm/www/assets/explosion/explosion-01.png new file mode 100644 index 0000000..08945ca Binary files /dev/null and b/spacewar-wasm/www/assets/explosion/explosion-01.png differ diff --git a/spacewar-wasm/www/assets/explosion/explosion-02.png b/spacewar-wasm/www/assets/explosion/explosion-02.png new file mode 100644 index 0000000..c897b19 Binary files /dev/null and b/spacewar-wasm/www/assets/explosion/explosion-02.png differ diff --git a/spacewar-wasm/www/assets/explosion/explosion-03.png b/spacewar-wasm/www/assets/explosion/explosion-03.png new file mode 100644 index 0000000..f98eb6b Binary files /dev/null and b/spacewar-wasm/www/assets/explosion/explosion-03.png differ diff --git a/spacewar-wasm/www/assets/explosion/explosion-04.png b/spacewar-wasm/www/assets/explosion/explosion-04.png new file mode 100644 index 0000000..3861e2b Binary files /dev/null and b/spacewar-wasm/www/assets/explosion/explosion-04.png differ diff --git a/spacewar-wasm/www/assets/explosion/explosion-05.png b/spacewar-wasm/www/assets/explosion/explosion-05.png new file mode 100644 index 0000000..8d3263e Binary files /dev/null and b/spacewar-wasm/www/assets/explosion/explosion-05.png differ diff --git a/spacewar-wasm/www/assets/explosion/explosion-06.png b/spacewar-wasm/www/assets/explosion/explosion-06.png new file mode 100644 index 0000000..783049a Binary files /dev/null and b/spacewar-wasm/www/assets/explosion/explosion-06.png differ diff --git a/spacewar-wasm/www/assets/explosion/explosion-07.png b/spacewar-wasm/www/assets/explosion/explosion-07.png new file mode 100644 index 0000000..338ba4b Binary files /dev/null and b/spacewar-wasm/www/assets/explosion/explosion-07.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuego1.png b/spacewar-wasm/www/assets/fuegotrasero/fuego1.png new file mode 100644 index 0000000..2ff7702 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuego1.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuego2.png b/spacewar-wasm/www/assets/fuegotrasero/fuego2.png new file mode 100644 index 0000000..df4085e Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuego2.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuego3.png b/spacewar-wasm/www/assets/fuegotrasero/fuego3.png new file mode 100644 index 0000000..0917ddd Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuego3.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuego4.png b/spacewar-wasm/www/assets/fuegotrasero/fuego4.png new file mode 100644 index 0000000..ada2b52 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuego4.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuego5.png b/spacewar-wasm/www/assets/fuegotrasero/fuego5.png new file mode 100644 index 0000000..aa23890 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuego5.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuego6.png b/spacewar-wasm/www/assets/fuegotrasero/fuego6.png new file mode 100644 index 0000000..b0ed3d8 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuego6.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuego7.png b/spacewar-wasm/www/assets/fuegotrasero/fuego7.png new file mode 100644 index 0000000..b556246 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuego7.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuego8.png b/spacewar-wasm/www/assets/fuegotrasero/fuego8.png new file mode 100644 index 0000000..5e632e6 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuego8.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo1.png b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo1.png new file mode 100644 index 0000000..0dc2189 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo1.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo2.png b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo2.png new file mode 100644 index 0000000..2d1d206 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo2.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo3.png b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo3.png new file mode 100644 index 0000000..f6097bc Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo3.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo4.png b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo4.png new file mode 100644 index 0000000..c103313 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo4.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo5.png b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo5.png new file mode 100644 index 0000000..81f6f8b Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo5.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo6.png b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo6.png new file mode 100644 index 0000000..c1ebe3f Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo6.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo7.png b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo7.png new file mode 100644 index 0000000..c8d0e79 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo7.png differ diff --git a/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo8.png b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo8.png new file mode 100644 index 0000000..444f367 Binary files /dev/null and b/spacewar-wasm/www/assets/fuegotrasero/fuegoenemigo8.png differ diff --git a/spacewar-wasm/www/assets/nave1/nave1-1.png b/spacewar-wasm/www/assets/nave1/nave1-1.png new file mode 100644 index 0000000..442daec Binary files /dev/null and b/spacewar-wasm/www/assets/nave1/nave1-1.png differ diff --git a/spacewar-wasm/www/assets/nave1/nave1-2.png b/spacewar-wasm/www/assets/nave1/nave1-2.png new file mode 100644 index 0000000..46c9bcb Binary files /dev/null and b/spacewar-wasm/www/assets/nave1/nave1-2.png differ diff --git a/spacewar-wasm/www/assets/nave1/nave1-3.png b/spacewar-wasm/www/assets/nave1/nave1-3.png new file mode 100644 index 0000000..444907d Binary files /dev/null and b/spacewar-wasm/www/assets/nave1/nave1-3.png differ diff --git a/spacewar-wasm/www/assets/nave1/nave1-4.png b/spacewar-wasm/www/assets/nave1/nave1-4.png new file mode 100644 index 0000000..3571194 Binary files /dev/null and b/spacewar-wasm/www/assets/nave1/nave1-4.png differ diff --git a/spacewar-wasm/www/assets/nave1/nave1-5.png b/spacewar-wasm/www/assets/nave1/nave1-5.png new file mode 100644 index 0000000..ea2fd39 Binary files /dev/null and b/spacewar-wasm/www/assets/nave1/nave1-5.png differ diff --git a/spacewar-wasm/www/assets/nave1/nave1-6.png b/spacewar-wasm/www/assets/nave1/nave1-6.png new file mode 100644 index 0000000..7e43830 Binary files /dev/null and b/spacewar-wasm/www/assets/nave1/nave1-6.png differ diff --git a/spacewar-wasm/www/assets/nave1/nave1-7.png b/spacewar-wasm/www/assets/nave1/nave1-7.png new file mode 100644 index 0000000..fbff8f0 Binary files /dev/null and b/spacewar-wasm/www/assets/nave1/nave1-7.png differ diff --git a/spacewar-wasm/www/assets/nave1/nave1-8.png b/spacewar-wasm/www/assets/nave1/nave1-8.png new file mode 100644 index 0000000..2ea4bbd Binary files /dev/null and b/spacewar-wasm/www/assets/nave1/nave1-8.png differ diff --git a/spacewar-wasm/www/assets/nave2/nave2-1.png b/spacewar-wasm/www/assets/nave2/nave2-1.png new file mode 100644 index 0000000..5ef5b22 Binary files /dev/null and b/spacewar-wasm/www/assets/nave2/nave2-1.png differ diff --git a/spacewar-wasm/www/assets/nave2/nave2-2.png b/spacewar-wasm/www/assets/nave2/nave2-2.png new file mode 100644 index 0000000..6dbb5b0 Binary files /dev/null and b/spacewar-wasm/www/assets/nave2/nave2-2.png differ diff --git a/spacewar-wasm/www/assets/nave2/nave2-3.png b/spacewar-wasm/www/assets/nave2/nave2-3.png new file mode 100644 index 0000000..be59038 Binary files /dev/null and b/spacewar-wasm/www/assets/nave2/nave2-3.png differ diff --git a/spacewar-wasm/www/assets/nave2/nave2-4.png b/spacewar-wasm/www/assets/nave2/nave2-4.png new file mode 100644 index 0000000..5f185fe Binary files /dev/null and b/spacewar-wasm/www/assets/nave2/nave2-4.png differ diff --git a/spacewar-wasm/www/assets/nave2/nave2-5.png b/spacewar-wasm/www/assets/nave2/nave2-5.png new file mode 100644 index 0000000..6c987bf Binary files /dev/null and b/spacewar-wasm/www/assets/nave2/nave2-5.png differ diff --git a/spacewar-wasm/www/assets/nave2/nave2-6.png b/spacewar-wasm/www/assets/nave2/nave2-6.png new file mode 100644 index 0000000..4825fcd Binary files /dev/null and b/spacewar-wasm/www/assets/nave2/nave2-6.png differ diff --git a/spacewar-wasm/www/assets/nave2/nave2-7.png b/spacewar-wasm/www/assets/nave2/nave2-7.png new file mode 100644 index 0000000..b2ab680 Binary files /dev/null and b/spacewar-wasm/www/assets/nave2/nave2-7.png differ diff --git a/spacewar-wasm/www/assets/nave2/nave2-8.png b/spacewar-wasm/www/assets/nave2/nave2-8.png new file mode 100644 index 0000000..9fb8061 Binary files /dev/null and b/spacewar-wasm/www/assets/nave2/nave2-8.png differ diff --git a/spacewar-wasm/www/assets/nave3/nave3-1.png b/spacewar-wasm/www/assets/nave3/nave3-1.png new file mode 100644 index 0000000..de5098d Binary files /dev/null and b/spacewar-wasm/www/assets/nave3/nave3-1.png differ diff --git a/spacewar-wasm/www/assets/nave3/nave3-2.png b/spacewar-wasm/www/assets/nave3/nave3-2.png new file mode 100644 index 0000000..2efa4e4 Binary files /dev/null and b/spacewar-wasm/www/assets/nave3/nave3-2.png differ diff --git a/spacewar-wasm/www/assets/nave3/nave3-3.png b/spacewar-wasm/www/assets/nave3/nave3-3.png new file mode 100644 index 0000000..5bb29ca Binary files /dev/null and b/spacewar-wasm/www/assets/nave3/nave3-3.png differ diff --git a/spacewar-wasm/www/assets/nave3/nave3-4.png b/spacewar-wasm/www/assets/nave3/nave3-4.png new file mode 100644 index 0000000..8fa3e96 Binary files /dev/null and b/spacewar-wasm/www/assets/nave3/nave3-4.png differ diff --git a/spacewar-wasm/www/assets/nave3/nave3-5.png b/spacewar-wasm/www/assets/nave3/nave3-5.png new file mode 100644 index 0000000..cb2af87 Binary files /dev/null and b/spacewar-wasm/www/assets/nave3/nave3-5.png differ diff --git a/spacewar-wasm/www/assets/nave3/nave3-6.png b/spacewar-wasm/www/assets/nave3/nave3-6.png new file mode 100644 index 0000000..c61d6c4 Binary files /dev/null and b/spacewar-wasm/www/assets/nave3/nave3-6.png differ diff --git a/spacewar-wasm/www/assets/nave3/nave3-7.png b/spacewar-wasm/www/assets/nave3/nave3-7.png new file mode 100644 index 0000000..53f756f Binary files /dev/null and b/spacewar-wasm/www/assets/nave3/nave3-7.png differ diff --git a/spacewar-wasm/www/assets/nave3/nave3-8.png b/spacewar-wasm/www/assets/nave3/nave3-8.png new file mode 100644 index 0000000..adf5f69 Binary files /dev/null and b/spacewar-wasm/www/assets/nave3/nave3-8.png differ diff --git a/spacewar-wasm/www/assets/nave4/nave4-1.png b/spacewar-wasm/www/assets/nave4/nave4-1.png new file mode 100644 index 0000000..e560970 Binary files /dev/null and b/spacewar-wasm/www/assets/nave4/nave4-1.png differ diff --git a/spacewar-wasm/www/assets/nave4/nave4-2.png b/spacewar-wasm/www/assets/nave4/nave4-2.png new file mode 100644 index 0000000..8ea6483 Binary files /dev/null and b/spacewar-wasm/www/assets/nave4/nave4-2.png differ diff --git a/spacewar-wasm/www/assets/nave4/nave4-3.png b/spacewar-wasm/www/assets/nave4/nave4-3.png new file mode 100644 index 0000000..10d33b1 Binary files /dev/null and b/spacewar-wasm/www/assets/nave4/nave4-3.png differ diff --git a/spacewar-wasm/www/assets/nave4/nave4-4.png b/spacewar-wasm/www/assets/nave4/nave4-4.png new file mode 100644 index 0000000..2526b39 Binary files /dev/null and b/spacewar-wasm/www/assets/nave4/nave4-4.png differ diff --git a/spacewar-wasm/www/assets/nave4/nave4-5.png b/spacewar-wasm/www/assets/nave4/nave4-5.png new file mode 100644 index 0000000..ac0d83c Binary files /dev/null and b/spacewar-wasm/www/assets/nave4/nave4-5.png differ diff --git a/spacewar-wasm/www/assets/nave4/nave4-6.png b/spacewar-wasm/www/assets/nave4/nave4-6.png new file mode 100644 index 0000000..acfa84e Binary files /dev/null and b/spacewar-wasm/www/assets/nave4/nave4-6.png differ diff --git a/spacewar-wasm/www/assets/nave4/nave4-7.png b/spacewar-wasm/www/assets/nave4/nave4-7.png new file mode 100644 index 0000000..2348c81 Binary files /dev/null and b/spacewar-wasm/www/assets/nave4/nave4-7.png differ diff --git a/spacewar-wasm/www/assets/nave4/nave4-8.png b/spacewar-wasm/www/assets/nave4/nave4-8.png new file mode 100644 index 0000000..6639f56 Binary files /dev/null and b/spacewar-wasm/www/assets/nave4/nave4-8.png differ diff --git a/spacewar-wasm/www/assets/nave5/nave5-1.png b/spacewar-wasm/www/assets/nave5/nave5-1.png new file mode 100644 index 0000000..df1be76 Binary files /dev/null and b/spacewar-wasm/www/assets/nave5/nave5-1.png differ diff --git a/spacewar-wasm/www/assets/nave5/nave5-2.png b/spacewar-wasm/www/assets/nave5/nave5-2.png new file mode 100644 index 0000000..344a8fe Binary files /dev/null and b/spacewar-wasm/www/assets/nave5/nave5-2.png differ diff --git a/spacewar-wasm/www/assets/nave5/nave5-3.png b/spacewar-wasm/www/assets/nave5/nave5-3.png new file mode 100644 index 0000000..53c03a2 Binary files /dev/null and b/spacewar-wasm/www/assets/nave5/nave5-3.png differ diff --git a/spacewar-wasm/www/assets/nave5/nave5-4.png b/spacewar-wasm/www/assets/nave5/nave5-4.png new file mode 100644 index 0000000..838525d Binary files /dev/null and b/spacewar-wasm/www/assets/nave5/nave5-4.png differ diff --git a/spacewar-wasm/www/assets/nave5/nave5-5.png b/spacewar-wasm/www/assets/nave5/nave5-5.png new file mode 100644 index 0000000..4817068 Binary files /dev/null and b/spacewar-wasm/www/assets/nave5/nave5-5.png differ diff --git a/spacewar-wasm/www/assets/nave5/nave5-6.png b/spacewar-wasm/www/assets/nave5/nave5-6.png new file mode 100644 index 0000000..c9baaaf Binary files /dev/null and b/spacewar-wasm/www/assets/nave5/nave5-6.png differ diff --git a/spacewar-wasm/www/assets/nave5/nave5-7.png b/spacewar-wasm/www/assets/nave5/nave5-7.png new file mode 100644 index 0000000..d3940b8 Binary files /dev/null and b/spacewar-wasm/www/assets/nave5/nave5-7.png differ diff --git a/spacewar-wasm/www/assets/nave5/nave5-8.png b/spacewar-wasm/www/assets/nave5/nave5-8.png new file mode 100644 index 0000000..0ce6fe2 Binary files /dev/null and b/spacewar-wasm/www/assets/nave5/nave5-8.png differ diff --git a/spacewar-wasm/www/assets/nave6/nave6-1.png b/spacewar-wasm/www/assets/nave6/nave6-1.png new file mode 100644 index 0000000..3ddcc51 Binary files /dev/null and b/spacewar-wasm/www/assets/nave6/nave6-1.png differ diff --git a/spacewar-wasm/www/assets/nave6/nave6-2.png b/spacewar-wasm/www/assets/nave6/nave6-2.png new file mode 100644 index 0000000..430e61b Binary files /dev/null and b/spacewar-wasm/www/assets/nave6/nave6-2.png differ diff --git a/spacewar-wasm/www/assets/nave6/nave6-3.png b/spacewar-wasm/www/assets/nave6/nave6-3.png new file mode 100644 index 0000000..27f585b Binary files /dev/null and b/spacewar-wasm/www/assets/nave6/nave6-3.png differ diff --git a/spacewar-wasm/www/assets/nave6/nave6-4.png b/spacewar-wasm/www/assets/nave6/nave6-4.png new file mode 100644 index 0000000..4ce8518 Binary files /dev/null and b/spacewar-wasm/www/assets/nave6/nave6-4.png differ diff --git a/spacewar-wasm/www/assets/nave6/nave6-5.png b/spacewar-wasm/www/assets/nave6/nave6-5.png new file mode 100644 index 0000000..49678a7 Binary files /dev/null and b/spacewar-wasm/www/assets/nave6/nave6-5.png differ diff --git a/spacewar-wasm/www/assets/nave6/nave6-6.png b/spacewar-wasm/www/assets/nave6/nave6-6.png new file mode 100644 index 0000000..e1e8675 Binary files /dev/null and b/spacewar-wasm/www/assets/nave6/nave6-6.png differ diff --git a/spacewar-wasm/www/assets/nave6/nave6-7.png b/spacewar-wasm/www/assets/nave6/nave6-7.png new file mode 100644 index 0000000..54178ad Binary files /dev/null and b/spacewar-wasm/www/assets/nave6/nave6-7.png differ diff --git a/spacewar-wasm/www/assets/nave6/nave6-8.png b/spacewar-wasm/www/assets/nave6/nave6-8.png new file mode 100644 index 0000000..1ebf6c4 Binary files /dev/null and b/spacewar-wasm/www/assets/nave6/nave6-8.png differ diff --git a/spacewar-wasm/www/assets/nave7/nave7-1.png b/spacewar-wasm/www/assets/nave7/nave7-1.png new file mode 100644 index 0000000..ef146d9 Binary files /dev/null and b/spacewar-wasm/www/assets/nave7/nave7-1.png differ diff --git a/spacewar-wasm/www/assets/nave7/nave7-2.png b/spacewar-wasm/www/assets/nave7/nave7-2.png new file mode 100644 index 0000000..d575055 Binary files /dev/null and b/spacewar-wasm/www/assets/nave7/nave7-2.png differ diff --git a/spacewar-wasm/www/assets/nave7/nave7-3.png b/spacewar-wasm/www/assets/nave7/nave7-3.png new file mode 100644 index 0000000..0c70f06 Binary files /dev/null and b/spacewar-wasm/www/assets/nave7/nave7-3.png differ diff --git a/spacewar-wasm/www/assets/nave7/nave7-4.png b/spacewar-wasm/www/assets/nave7/nave7-4.png new file mode 100644 index 0000000..eff15e3 Binary files /dev/null and b/spacewar-wasm/www/assets/nave7/nave7-4.png differ diff --git a/spacewar-wasm/www/assets/nave7/nave7-5.png b/spacewar-wasm/www/assets/nave7/nave7-5.png new file mode 100644 index 0000000..2e5ef65 Binary files /dev/null and b/spacewar-wasm/www/assets/nave7/nave7-5.png differ diff --git a/spacewar-wasm/www/assets/nave7/nave7-6.png b/spacewar-wasm/www/assets/nave7/nave7-6.png new file mode 100644 index 0000000..fd86fdd Binary files /dev/null and b/spacewar-wasm/www/assets/nave7/nave7-6.png differ diff --git a/spacewar-wasm/www/assets/nave7/nave7-7.png b/spacewar-wasm/www/assets/nave7/nave7-7.png new file mode 100644 index 0000000..dfc4454 Binary files /dev/null and b/spacewar-wasm/www/assets/nave7/nave7-7.png differ diff --git a/spacewar-wasm/www/assets/nave7/nave7-8.png b/spacewar-wasm/www/assets/nave7/nave7-8.png new file mode 100644 index 0000000..55542d0 Binary files /dev/null and b/spacewar-wasm/www/assets/nave7/nave7-8.png differ diff --git a/spacewar-wasm/www/assets/nave8/nave8-1.png b/spacewar-wasm/www/assets/nave8/nave8-1.png new file mode 100644 index 0000000..6ecb6be Binary files /dev/null and b/spacewar-wasm/www/assets/nave8/nave8-1.png differ diff --git a/spacewar-wasm/www/assets/nave8/nave8-2.png b/spacewar-wasm/www/assets/nave8/nave8-2.png new file mode 100644 index 0000000..7b5f103 Binary files /dev/null and b/spacewar-wasm/www/assets/nave8/nave8-2.png differ diff --git a/spacewar-wasm/www/assets/nave8/nave8-3.png b/spacewar-wasm/www/assets/nave8/nave8-3.png new file mode 100644 index 0000000..d587c6d Binary files /dev/null and b/spacewar-wasm/www/assets/nave8/nave8-3.png differ diff --git a/spacewar-wasm/www/assets/nave8/nave8-4.png b/spacewar-wasm/www/assets/nave8/nave8-4.png new file mode 100644 index 0000000..8cb2854 Binary files /dev/null and b/spacewar-wasm/www/assets/nave8/nave8-4.png differ diff --git a/spacewar-wasm/www/assets/nave8/nave8-5.png b/spacewar-wasm/www/assets/nave8/nave8-5.png new file mode 100644 index 0000000..f307780 Binary files /dev/null and b/spacewar-wasm/www/assets/nave8/nave8-5.png differ diff --git a/spacewar-wasm/www/assets/nave8/nave8-6.png b/spacewar-wasm/www/assets/nave8/nave8-6.png new file mode 100644 index 0000000..bbcef7d Binary files /dev/null and b/spacewar-wasm/www/assets/nave8/nave8-6.png differ diff --git a/spacewar-wasm/www/assets/nave8/nave8-7.png b/spacewar-wasm/www/assets/nave8/nave8-7.png new file mode 100644 index 0000000..aa63d4b Binary files /dev/null and b/spacewar-wasm/www/assets/nave8/nave8-7.png differ diff --git a/spacewar-wasm/www/assets/nave8/nave8-8.png b/spacewar-wasm/www/assets/nave8/nave8-8.png new file mode 100644 index 0000000..baedcf8 Binary files /dev/null and b/spacewar-wasm/www/assets/nave8/nave8-8.png differ diff --git a/spacewar-wasm/www/assets/vidas/vida.png b/spacewar-wasm/www/assets/vidas/vida.png new file mode 100644 index 0000000..d91e64c Binary files /dev/null and b/spacewar-wasm/www/assets/vidas/vida.png differ diff --git a/spacewar-wasm/www/index.html b/spacewar-wasm/www/index.html new file mode 100644 index 0000000..7b7a2cd --- /dev/null +++ b/spacewar-wasm/www/index.html @@ -0,0 +1,232 @@ + + + + + + Space War + + + +

โญ Space War โญ

+ +
+ +
+ Loading assetsโ€ฆ +
+
+
+ + + + + +