A space shooter game made with Amethyst and Rust.

Overview

Theta Wave

Project Introduction

This game was made with the Amethyst engine. It is inspired by games like Raiden and The Binding of Isaac.

Game Introduction

In Theta Wave, you play as a spaceship defending an objective. The goal of the game is to survive levels by destroying enemies, collecting consumables, buying helpful things, and defeating the final boss.

gameplay of theta wave

Documentation

Documentation for Theta Wave is available online.

You can find out more about the game from its gameplay to contributing code.

Build and Run

If you are on macOS remove the vulkan feature in Cargo.toml and replace with metal.

To build and run: cargo run --release

Credits

Comments
  • Load game data from files

    Load game data from files

    Hello, This includes multiple changes:

    1. updated cargo.toml file, to only use amethyst features that are required (much faster build time).
    2. load items, enemies and consumables from ./assets/data/* files at startup.
    3. updated item spawn logic, now accepts list of items with probabilities.

    that's pretty much it ;)

    opened by fraillt 7
  • Add Motion2DComponent

    Add Motion2DComponent

    For #28

    I think this work should be reviewed and merged after the feature-hitbox2d branch is merged into cdsupina-dev since there is already a lot of changes happening to the enemy component, entities, and related systems that should follow the same patterns introduced in feature-hitbox2d.

    opened by tigleym 4
  • Look into baking the ron files into the binary with `Config::load_bytes`

    Look into baking the ron files into the binary with `Config::load_bytes`

    The ron config and data files are currently not baked into the binary. When the build is compiled, the user should not have access to these files to modify.

    https://www.reddit.com/r/rust/comments/m6a3yx/theta_wave_v014_foundations_update/gr6blwt/?context=3

    enhancement 
    opened by cdsupina 3
  • Binary does not work for Ubuntu 16.04

    Binary does not work for Ubuntu 16.04

    $ ./space_shooter 
    ./space_shooter: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.27' not found (required by ./space_shooter)
    
    $ cat /etc/lsb-release 
    DISTRIB_ID=Ubuntu
    DISTRIB_RELEASE=16.04
    DISTRIB_CODENAME=xenial
    DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"
    
    opened by eleidan 3
  • Give blasts a

    Give blasts a "range" using a TimeLimitComponent

    Currently blasts will travel until they reach a "despawn line" at a y-value above or below the arena. This is effectively inifinite range. Let's make the game more interesting by adding a finite range to fired blasts by giving them a TimeLimitComponent.

    This will also allow us to add items to increase range in the future.

    enhancement good first issue 
    opened by cdsupina 2
  • Add a repel item for enemy blasts

    Add a repel item for enemy blasts

    This PR introduces a player item that repels incoming enemy projectiles. Since this touches several files, I've broken it down into two separate commits.

    The first part goes through adding a Blast enum variant to the SpawnableCategory and attaching it to the player's spaceship component.

    The second adds the actual item: BlastRepeller, which is responsible for turning on the should_repel field for the spaceship's attractor data for a Blast spawnable.

    item 
    opened by tigleym 2
  • Panic ` uninitialized, which is invalid"">

    Panic "attempted to leave type `linked_hash_map::Node` uninitialized, which is invalid"

    I'm super new to Rust so let me know if there's more info required. I have just cloned and run cargo run, but the program panics before a window opens.

    Version: 3276c8e81de6397adf399ba56b3a4686ae43015e OS: Windows 10 rustc 1.48.0 (7eac88abb 2020-11-16) cargo 1.48.0 (65cbdd2dc 2020-10-14)

    thread '<unnamed>' panicked at 'attempted to leave type `linked_hash_map::Node<u32, rusttype::gpu_cache::Row>` uninitialized, which is invalid', C:\Users\rhysv\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\mem\mod.rs:658:9
    stack backtrace:
       0: std::panicking::begin_panic_handler
                 at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4\/library\std\src\panicking.rs:483
       1: core::panicking::panic_fmt
                 at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4\/library\core\src\panicking.rs:85
       2: core::panicking::panic
                 at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4\/library\core\src\panicking.rs:50
       3: core::mem::uninitialized
                 at C:\Users\rhysv\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\mem\mod.rs:658
       4: linked_hash_map::LinkedHashMap<u32, rusttype::gpu_cache::Row, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>::ensure_guard_node<u32,rusttype::gpu_cache::Row,core::hash::BuildHasherDefault<rustc_hash::FxHasher>>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\linked-hash-map-0.5.2\src\lib.rs:174
       5: linked_hash_map::LinkedHashMap<u32, rusttype::gpu_cache::Row, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>::insert<u32,rusttype::gpu_cache::Row,core::hash::BuildHasherDefault<rustc_hash::FxHasher>>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\linked-hash-map-0.5.2\src\lib.rs:304
       6: rusttype::gpu_cache::Cache::cache_queued<closure-7>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rusttype-0.8.3\src\gpu_cache.rs:778
       7: glyph_brush::glyph_brush::GlyphBrush<tuple<u32, amethyst_ui::pass::UiArgs>, twox_hash::std_support::sixty_four::RandomXxHashBuilder64>::process_queued<tuple<u32, amethyst_ui::pass::UiArgs>,twox_hash::std_support::sixty_four::RandomXxHashBuilder64,closure-
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\glyph_brush-0.6.3\src\glyph_brush.rs:336
       8: amethyst_ui::glyphs::{{impl}}::run<gfx_backend_vulkan::Backend>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\amethyst_ui-0.15.3\src\glyphs.rs:368
       9: shred::system::{{impl}}::run_now<amethyst_ui::glyphs::UiGlyphsSystem<gfx_backend_vulkan::Backend>>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\shred-0.10.2\src\system.rs:140
      10: shred::dispatch::stage::{{impl}}::execute::{{closure}}
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\shred-0.10.2\src\dispatch\stage.rs:111
      11: core::ops::function::impls::{{impl}}::call_mut<tuple<mut arrayvec::ArrayVec<[alloc::boxed::Box<RunNow>; 5]>*>,closure-0>
                 at C:\Users\rhysv\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:247
      12: core::slice::iter::{{impl}}::for_each<arrayvec::ArrayVec<[alloc::boxed::Box<RunNow>; 5]>,closure-0*>
                 at C:\Users\rhysv\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\slice\iter\macros.rs:203     
      13: rayon::iter::for_each::{{impl}}::consume_iter<closure-0,mut arrayvec::ArrayVec<[alloc::boxed::Box<RunNow>; 5]>*,core::slice::iter::IterMut<arrayvec::ArrayVec<[alloc::boxed::Box<RunNow>; 5]>>>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-1.3.0\src\iter\for_each.rs:55
      14: rayon::iter::plumbing::Producer::fold_with<rayon::slice::IterMutProducer<arrayvec::ArrayVec<[alloc::boxed::Box<RunNow>; 5]>>,rayon::iter::for_each::ForEachConsumer<closure-0>>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-1.3.0\src\iter\plumbing\mod.rs:110
      15: rayon::iter::plumbing::bridge_producer_consumer::helper<rayon::slice::IterMutProducer<arrayvec::ArrayVec<[alloc::boxed::Box<RunNow>; 5]>>,rayon::iter::for_each::ForEachConsumer<closure-0>>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-1.3.0\src\iter\plumbing\mod.rs:438
      16: rayon::iter::plumbing::bridge_producer_consumer::helper::{{closure}}<rayon::slice::IterMutProducer<arrayvec::ArrayVec<[alloc::boxed::Box<RunNow>; 5]>>,rayon::iter::for_each::ForEachConsumer<closure-0>>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-1.3.0\src\iter\plumbing\mod.rs:427
      17: rayon_core::join::join_context::call_b::{{closure}}<tuple<>,closure-1>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\join\mod.rs:130
      18: rayon_core::job::{{impl}}::execute::call::{{closure}}<tuple<>,closure-0>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\job.rs:113
      19: std::panic::{{impl}}::call_once<tuple<>,closure-0>
                 at C:\Users\rhysv\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:308
      20: std::panicking::try::do_call<std::panic::AssertUnwindSafe<closure-0>,tuple<>>
                 at C:\Users\rhysv\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:381
      21: std::sync::rwlock::{{impl}}::deref_mut<core::option::Option<alloc::sync::Arc<rayon_core::thread_pool::ThreadPool>>>
      22: std::panicking::try<tuple<>,std::panic::AssertUnwindSafe<closure-0>>
                 at C:\Users\rhysv\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:345
      23: std::panic::catch_unwind<std::panic::AssertUnwindSafe<closure-0>,tuple<>>
                 at C:\Users\rhysv\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:382
      24: rayon_core::unwind::halt_unwinding<closure-0,tuple<>>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\unwind.rs:17
      25: rayon_core::job::{{impl}}::execute<rayon_core::latch::SpinLatch,closure-0,tuple<>>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\job.rs:119
      26: rayon_core::job::JobRef::execute
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\job.rs:59
      27: rayon_core::registry::WorkerThread::execute
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\registry.rs:681
      28: rayon_core::registry::WorkerThread::wait_until_cold<rayon_core::latch::CountLatch>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\registry.rs:665
      29: rayon_core::registry::WorkerThread::wait_until<rayon_core::latch::CountLatch>
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\registry.rs:639
      30: rayon_core::registry::main_loop
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\registry.rs:759
      31: rayon_core::registry::ThreadBuilder::run
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\registry.rs:56
      32: rayon_core::registry::{{impl}}::spawn::{{closure}}
                 at C:\Users\rhysv\.cargo\registry\src\github.com-1ecc6299db9ec823\rayon-core-1.7.0\src\registry.rs:101
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    
    opened by rhys-vdw 2
  • Refactoring Motion2D

    Refactoring Motion2D

    Entities whose Motion2D components with a rigid_body property set to true should be able to neglect any forces exerted on it. So if entity 'A' collides with an entity 'B' with rigid_body, entity B's Motion2D component will not be affected by the collision.

    refactoring 
    opened by tigleym 2
  • Phase out `fire_blast` for Spaceship

    Phase out `fire_blast` for Spaceship

    opened by tigleym 2
  • Feature hitbox2d

    Feature hitbox2d

    For #27

    I also added detection for hitboxes with an angle offset from lines up with the x and y axes. I used the separating axis theorem implementation in rust from this repository: https://github.com/JoelEager/Rust-Collision-Detector.

    Currently, collisions between the player (Spaceship) and enemies are still handled using the old hitbox_collide function in systems/mod.rs. However, the hitbox data used in the function parameters come from their respective Hitbox2DComponents. I think that collisions between enemies and players need to be reworked in a separate issue and at that time they should be switched over to using the is_colliding function in Hitbox2DComponent.

    opened by cdsupina 2
  • Remove internal animation fields from the Enemy component

    Remove internal animation fields from the Enemy component

    The Enemy component currently stores data about its Animation component. We can clean up the Enemy component by only specifying this data for the Animation component that's added to the entity created for an enemy.

    Relevant files:

    refactoring 
    opened by tigleym 2
  • Complete Repeater Boss

    Complete Repeater Boss

    Repeater boss is currently in the game but incomplete. Let's finish the boss by giving it the following behaviors.

    • Block weak spot with arms
    • Shoot blasts and maybe missiles
    • Shoot laser from eye
    • Adapt behavior if both forearms are gone
    • Boss is destroyed when eye part is destroyed
    boss 
    opened by cdsupina 0
  • Refactor abilities for characters

    Refactor abilities for characters

    Refactor abilities into "trait objects" https://doc.rust-lang.org/book/ch17-02-trait-objects.html#defining-a-trait-for-common-behavior

    Character components can each have an ability property containing a struct that implements the ability trait. It would resemble the following.

    pub struct CharacterComponent {
        pub ability: Box<dyn Ability> ,
        ...
    }
    

    Structs implementing the ability trait could share common functions related to cooldowns and execution.

    refactoring 
    opened by cdsupina 0
  • Rebuild config folder before recompiling project

    Rebuild config folder before recompiling project

    Right now we need to manually delete the generated config folder that is responsible for containing some of the RON file assets.

    It would be nice if we could run a script as part of the build process where it checks for any changes to the data_include/config folder and rebuild it with the new changes

    dev-workflow 
    opened by tigleym 0
  • Add delayed spawn functionality for formations

    Add delayed spawn functionality for formations

    Currently all formation spawnables are spawned in at once. Let's add the ability for formations' spawnables to be spawned in after a delay rather than all having to be spawned in at the beginning of the formation.

    enhancement 
    opened by cdsupina 0
  • keep crashing on Arch Linux (Image count not supported. Supported: 4..=4294967295, requested: 3)

    keep crashing on Arch Linux (Image count not supported. Supported: 4..=4294967295, requested: 3)

    Here the log

    [19:16:39] baba99j@baba /home/baba99j/Downloads/theta-wave
    > cargo run --release
       Finished release [optimized] target(s) in 0.30s
       Running `target/release/theta-wave`
    [INFO][amethyst::app] Initializing Amethyst...
    [INFO][amethyst::app] Version: 0.15.3
    [INFO][amethyst::app] Platform: x86_64-unknown-linux-gnu
    [INFO][amethyst::app] Amethyst git commit: UNKNOWN
    [INFO][amethyst::app] Rustc version: 1.51.0 Stable
    [WARN][rendy_factory::factory] Slow safety checks are enabled! Disable them in production by enabling the 'no-slow-safety-checks' feature!
    [INFO][rendy_util::wrap] Slow safety checks are enabled! You can disable them in production by enabling the 'no-slow-safety-checks' feature!
    [WARN][rendy_wsi] Image count not supported. Supported: 4..=4294967295, requested: 3
    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ErrorMessage { msg: "Image count not supported." }
    
       0: failure::backtrace::internal::InternalBacktrace::new
       1: <failure::backtrace::Backtrace as core::default::Default>::default
       2: rendy_wsi::Surface<B>::into_target
       3: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::try_fold
       4: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
       5: core::iter::adapters::process_results
       6: <rendy_graph::node::render::pass::RenderPassNodeBuilder<B,T> as rendy_graph::node::NodeBuilder<B,T>>::build
       7: rendy_graph::graph::GraphBuilder<B,T>::build
       8: <amethyst_rendy::system::RenderingSystem<B,G> as shred::system::RunNow>::run_now
       9: <shred::dispatch::dispatcher::Dispatcher as shred::system::RunNow>::run_now
      10: <T as amethyst::state::State<amethyst::game_data::GameData,amethyst::state_event::StateEvent>>::update
      11: theta_wave::main
      12: std::sys_common::backtrace::__rust_begin_short_backtrace
      13: std::rt::lang_start::{{closure}}
      14: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
                 at /build/rust/src/rustc-1.51.0-src/library/core/src/ops/function.rs:259:13
          std::panicking::try::do_call
                 at /build/rust/src/rustc-1.51.0-src/library/std/src/panicking.rs:379:40
          std::panicking::try
                 at /build/rust/src/rustc-1.51.0-src/library/std/src/panicking.rs:343:19
          std::panic::catch_unwind
                 at /build/rust/src/rustc-1.51.0-src/library/std/src/panic.rs:431:14
          std::rt::lang_start_internal
                 at /build/rust/src/rustc-1.51.0-src/library/std/src/rt.rs:51:25
      15: main
      16: __libc_start_main
      17: _start
    ', /home/baba99j/.cargo/registry/src/github.com-1ecc6299db9ec823/amethyst_rendy-0.15.3/src/system.rs:117:18
    stack backtrace:
       0: rust_begin_unwind
                 at /build/rust/src/rustc-1.51.0-src/library/std/src/panicking.rs:493:5
       1: core::panicking::panic_fmt
                 at /build/rust/src/rustc-1.51.0-src/library/core/src/panicking.rs:92:14
       2: core::option::expect_none_failed
                 at /build/rust/src/rustc-1.51.0-src/library/core/src/option.rs:1300:5
       3: <amethyst_rendy::system::RenderingSystem<B,G> as shred::system::RunNow>::run_now
       4: <shred::dispatch::dispatcher::Dispatcher as shred::system::RunNow>::run_now
       5: <T as amethyst::state::State<amethyst::game_data::GameData,amethyst::state_event::StateEvent>>::update
       6: theta_wave::main
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    
    opened by baba99j 11
Releases(v0.1.7)
  • v0.1.7(Jul 16, 2021)

    The primary focus of this release was to organize how source files are categorized into directories and modules.

    Organization

    • Divided project into thetawave_lib and thetawave_game workspaces
    • Removed components directory
    • Removed resources directory
    • Removed systems directory
    • Removed entities directory
    • Added boss directory/module
    • Added misc directory/module
    • Added motion directory/module
    • Added phases directory/module
    • Added player directory/module
    • Added spawn directory/module
    • Added spawnable directory/module
    • Added store directory/module
    • Added visual directory/module
    • Added weapons directory/module

    Misc

    • Added blast range for mobs and players
    • Added Timer for managing periodic events
    • Added Health for managing health of players and mobs
    • Began adding comments for everything in the game
    Source code(tar.gz)
    Source code(zip)
    thetawave-win.zip(15.45 MB)
  • v0.1.6(May 20, 2021)

    Items

    • Blast Repeller
    • Tractor Beam

    Mobs

    • Money Asteroid

    Misc

    • Fixed bug: index out of bounds error when there are less than two phases in level
    • Added Modifier enum for implementing item and consumable effects
    • Items and Consumables are now a collection of "Modifier" enums
    • Added DropRolls for defining how many loot rolls a mob has and different drop tables to hold different types of loot odds
    • Consumable drops from enemies now have random initial movement and spin
    • Items and consumables now attract to the player when nearby

    Controls for playing the game are here.

    Source code(tar.gz)
    Source code(zip)
    theta-wave-macos.zip(16.68 MB)
    theta-wave-win.zip(15.43 MB)
  • v0.1.5(Apr 15, 2021)

    Focus

    The focus of this release was to organize how Spawnables are spawned into the level. Previously, levels only contained a phase of randomly spawning enemies and a boss. In the Formations update there are four types of phases that can be used to construct a level:

    • InvasionRandom
    • InvasionFormation
    • Rest
    • Boss

    The InvasionRandom phase takes in an InvasionRandomPool parameter and spawns Spawnables from that pool at random. Below is an example of an InvasionRandomPool called Level1Easy defined in spawner.ron.

    Level1Easy: [
                (
                    spawnable_type: Some(Mob(Enemy(Drone))),
                    weight: 1.0,
                    period: 1.5,
                ),
                (
                    spawnable_type: Some(Mob(Enemy(Pawn))),
                    weight: 0.9,
                    period: 2.0,
                ),
                (
                    spawnable_type: Some(Consumable(Money1)),
                    weight: 0.2,
                    period: 0.3,
                ),
                (
                    spawnable_type: None,
                    weight: 0.5,
                    period: 0.3,
                )
            ],
    

    The spawnable_type property is the type of spawnable in the pool. The weight property is how likely the Spawnable should spawn relative to other Spawnables. The period property is how long the spawner will wait before spawning something else.

    Similarly, the InvasionFormation phase takes in an InvasionFormationPool parameter and spawns a vector of Spawnables with positions from that pool at random. Below is an example of an InvasionFormationPool called Level1Easy defined in spawner.ron.

    Level1Easy: [
                (
                    formation_spawnables: [
                        (
                            spawnable_type: Mob(Enemy(Drone)),
                            position: [150, 310],
                        ),
                        (
                            spawnable_type: Mob(Enemy(Drone)),
                            position: [180, 300],
                        ),
                        (
                            spawnable_type: Mob(Enemy(Drone)),
                            position: [210, 310],
                        ),
                        (
                            spawnable_type: Mob(Enemy(Pawn)),
                            position: [100, 390],
                        ),
                        (
                            spawnable_type: Mob(Enemy(Pawn)),
                            position: [260, 390],
                        ),
                    ],
                    weight: 1.5,
                    period: 10.0,
                ),
                (
                    formation_spawnables: [
                        (
                            spawnable_type: Mob(Enemy(Pawn)),
                            position: [110, 390],
                        ),
                        (
                            spawnable_type: Mob(Enemy(Drone)),
                            position: [150, 370],
                        ),
                        (
                            spawnable_type: Mob(Enemy(MissileLauncher)),
                            position: [180, 300],
                        ),
                        (
                            spawnable_type: Mob(Enemy(Drone)),
                            position: [210, 370],
                        ),
                        (
                            spawnable_type: Mob(Enemy(Pawn)),
                            position: [250, 390],
                        ),
                    ],
                    weight: 0.8,
                    period: 12.0,
                ),
                (
                    formation_spawnables: [
                        (
                            spawnable_type: Mob(Enemy(StraferRight)),
                            position: [180, 300],
                        ),
                        (
                            spawnable_type: Mob(Enemy(StraferLeft)),
                            position: [180, 320],
                        ),
                        (
                            spawnable_type: Mob(Enemy(StraferRight)),
                            position: [170, 340],
                        ),
                        (
                            spawnable_type: Mob(Enemy(StraferLeft)),
                            position: [190, 360],
                        ),
                        (
                            spawnable_type: Mob(Enemy(StraferRight)),
                            position: [160, 380],
                        ),
                        (
                            spawnable_type: Mob(Enemy(StraferLeft)),
                            position: [200, 400],
                        ),
                    ],
                    weight: 1.0,
                    period: 8.0,
                )
            ],  
    

    The formation_spawnables property is a vector of spawnable_types paired with an x y coordinate position. When a formation is spawned, each spawnable in this vector is spawned at the same time at its position, creating a formation. Formations also have a weight and period that works the same as in the InvasionRandomPool.

    The release makes adding a formation by far the most straightforward contribution a contributor can make to the game.

    Change List

    • New InvasionFormationPhase
    • InvasionRandomPhase updated to use periods and weights
    • Minor refactors of the PhaseManager
    • Add spawner pools defined in spawner.ron
    • Strafer enemy divided into variants: StraferLeft and StraferRight
    • Add parent SpawnableType for enemies and allies called Mob
    • Data ron files now included in the binary
    • Config files now generate at runtime
    Source code(tar.gz)
    Source code(zip)
    theta-wave-macosx.zip(16.65 MB)
    theta-wave-win.zip(15.40 MB)
  • v0.1.4(Mar 16, 2021)

    This is the first release since @tigleym joined the project! Together, we have been working hard to refactor the codebase to be more conforming to ECS, and more accessible to new contributors. You can learn more about the revival of this project from our RustFest Global talk. Along the way, we have also added some more fun features! Here is a list:

    Items

    • Blaster Size Enhancer
    • Frequency Augmentor

    Consumables

    • Armor

    Enemies

    • Missile
    • Missile Launcher

    Misc

    • Generalized store to sell any kind of spawnable entity
    • Giblets!
    • Enemy thruster animations
    • Blast hit animations
    • Cursed scrolling background
    • Barriers at the arena borders
    • New sound effects
    • Started writing a game/contribution guide

    Controls for playing the game are here.

    Source code(tar.gz)
    Source code(zip)
    theta-wave-macos.zip(16.90 MB)
    theta-wave-win.zip(15.39 MB)
  • v0.1.3(Sep 25, 2019)

    • More items (view readme for full list of item effects)

      • quadrupedal tentaclover
      • defense satellite
      • double barrel
      • yithian plague
      • spice
    • Items are now purchased from store

      • store restocks with 3 items every 10 seconds (I intend to increase this in the future to about 60 seconds)
      • items can be purchased by using the 1,2, and 3 keys corresponding to the top. middle, and bottom slots respectively
      • when purchased the item is removed from the item pool and spawned at the top of the arena at the same x coordinate as the player
      • skipped items will have their weight of appearing again halved
    • Sound effects added

    • 3D background with GLTF sun and rotating earth

    • Sprites separated into different sprite sheets by category

    Source code(tar.gz)
    Source code(zip)
    space_shooter-linux.zip(30.58 MB)
    space_shooter-windows.zip(27.93 MB)
  • v0.1.2(Aug 28, 2019)

  • v0.1.1(Jun 12, 2019)

  • v0.1.0(Jun 10, 2019)

Owner
Theta Wave
Theta Wave is an opensource Rust game. Theta Wave strives to be an entry point for new Rust game developers to make their first contributions.
Theta Wave
Fish Game for Macroquad is an online multiplayer game, created as a demonstration of Nakama, an open-source scalable game server, using Rust-lang and the Macroquad game engine.

Fish Game for Macroquad is an online multiplayer game, created as a demonstration of Nakama, an open-source scalable game server, using Rust-lang and the Macroquad game engine.

Heroic Labs 130 Dec 29, 2022
The video game for Fonts of Power. A tabletop roleplaying game made in Rust with Bevy!

The code and rules for Fonts of Power, a tactical TTRPG / video game about exploring magical places. You can follow its development in our Discord ser

null 25 Dec 23, 2022
A block game made in Rust and SFML

septadrop A block game made in Rust and SFML. For packaging instructions, see the build folder. Game Controls ??/?? arrow keys: horizontal movement ??

Elnu 1 Dec 19, 2022
Red Light, Green Light is a traditional Korean children's game, popularised by the Squid Game TV series.

Red Light, Green Light Red Light, Green Light is a traditional Korean children's game, popularised by the Squid Game TV series. This project is the di

Cedric Chee 1 Jan 10, 2022
A game inspired by the classic atari game: demon attack

rusty_demon_attack A game inspired by the classic atari game: demon attack You can play the game in the web!

null 58 Jan 4, 2023
Pong-like videogame made with Rust and Bevy

Rust pong Pong-like videogame made with Rust and Bevy Features Correct Physics AI Score Wasm TO DO Score Wasm Multiplayer How to run For the desktop v

Hector Pulido 6 Aug 22, 2022
Data-oriented and data-driven game engine written in Rust

What is Amethyst? Amethyst is a data-driven and data-oriented game engine aiming to be fast and as configurable as possible. Principles These principl

Amethyst Engine 7.9k Dec 31, 2022
Minesweeper game developed with Rust, WebAssembly (Wasm), and Canvas

?? click here to play the game ?? Minesweeper game Revealing all the cells without hitting the mines is the task. Each number in the cell denotes how

Karthik Nedunchezhiyan 23 Dec 28, 2022
Extensible open world rogue like game with pixel art. Players can explore the wilderness and ruins.

Rusted Ruins Extensible open world rogue like game with pixel art. Players can explore the wilderness and ruins. This game is written in Rust. Screens

T. Okubo 427 Dec 13, 2022
A minesweeper game with a terminal and graphical interface

Mine A minesweeper game with a terminal and graphical interface created by Koen Westendorp. Installation Go ahead and try out for yourself! :) git clo

Koen Westendorp 3 Dec 22, 2022
Planetoid is a toy project to demonstrate and learn several technologies. The goal is to create a little multiplayer asteriod game clone.

Planetoid is a toy project to demonstrate and learn several technologies. The goal is to create a little multiplayer asteriod game clone.

René Ribaud 8 Aug 23, 2022
Mk48.io is an online multiplayer naval combat game, in which you take command of a ship and sail your way to victory

Mk48.io Game Mk48.io is an online multiplayer naval combat game, in which you take command of a ship and sail your way to victory. Watch out for torpe

Softbear Studios 160 Jan 2, 2023
A roguelike game in Rust

A fantasy deathcrawl in Rust Work in progress. To run, with Rust compiler and Cargo package manager installed: cargo run --release When building on W

Risto Saarelma 347 Nov 21, 2022
😠⚔️😈 A minimalistic 2D turn-based tactical game in Rust

Zemeroth is a turn-based hexagonal tactical game written in Rust. Support: patreon.com/ozkriff News: @ozkriff on twitter | ozkriff.games | facebook |

Andrey Lesnikóv 1.3k Jan 5, 2023
⬡ Zone of Control is a hexagonal turn-based strategy game written in Rust. [DISCONTINUED]

Zone of Control The project is discontinued Sorry, friends. ZoC is discontinued. See https://ozkriff.github.io/2017-08-17--devlog.html Downloads Preco

Andrey Lesnikóv 354 Nov 14, 2022
This is a simple implementation of the classic snake game in rust

My snake game Looks like this. This is with Roboto Mono Nerd Font. If you use a different font it may look different or distorted. Install rust In ord

Konstantinos Kyriakou 16 Apr 4, 2021
The classic tetris game written in Rust using ncurses

tetris.rs This is the classic tetris game I wrote to have a bit of fun with Rust. Installation and playing cargo install --

null 71 Jul 25, 2022
A refreshingly simple data-driven game engine built in Rust

What is Bevy? Bevy is a refreshingly simple data-driven game engine built in Rust. It is free and open-source forever! WARNING Bevy is still in the ve

Bevy Engine 21.1k Jan 3, 2023
Rust library to create a Good Game Easily

ggez What is this? ggez is a Rust library to create a Good Game Easily. The current version is 0.6.0-rc0. This is a RELEASE CANDIDATE version, which m

null 3.6k Jan 4, 2023