summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs307
1 files changed, 298 insertions, 9 deletions
diff --git a/src/main.rs b/src/main.rs
index a1fee19..c69d791 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,12 +1,301 @@
-use ggez::event::{self};
-use ggez::{ContextBuilder, GameResult};
+use bevy::math::Vec3;
+use bevy::prelude::*;
+use gems::cell::{self, Cell, Occupant};
+use gems::constants;
+use rand::{thread_rng, Rng};
+use std::time::Duration;
-use gems::game::Game;
+fn star_spawning(mut commands: Commands, time: Res<Time>, mut q: Query<&mut Timer>) {
+ for mut timer in q.iter_mut() {
+ if !timer.repeating() {
+ timer.tick(time.delta());
+ if timer.just_finished() {
+ timer.set_duration(Duration::new(thread_rng().gen_range(2..5), 0));
+ timer.reset();
+ commands
+ .spawn_bundle(SpriteSheetBundle {
+ sprite: TextureAtlasSprite::new(constants::TILESHEET_STAR1),
+ transform: Transform {
+ translation: Vec3::new(
+ thread_rng().gen_range(-300..300) as f32,
+ thread_rng().gen_range(-200..300) as f32,
+ 0.0,
+ ),
+ scale: Vec3::splat(thread_rng().gen_range(1..3) as f32),
+ ..Default::default()
+ },
+ ..Default::default()
+ })
+ .insert(Timer::from_seconds(0.25, true));
+ }
+ }
+ }
+}
+
+pub fn setup(
+ mut commands: Commands,
+ asset_server: Res<AssetServer>,
+ mut materials: ResMut<Assets<ColorMaterial>>,
+ mut texture_atlases: ResMut<Assets<TextureAtlas>>,
+) {
+ let background = asset_server.load("background.png");
+ let tileset = asset_server.load("tileset.png");
+ let title = asset_server.load("title.png");
+
+ let atlas = TextureAtlas::from_grid(
+ tileset,
+ Vec2::new(constants::TILE_SIZE, constants::TILE_SIZE),
+ 5,
+ 5,
+ );
+ let atlas_handle = texture_atlases.add(atlas);
+
+ commands.spawn_bundle(OrthographicCameraBundle::new_2d());
+ commands.spawn_bundle(SpriteBundle {
+ material: materials.add(background.into()),
+ transform: Transform {
+ translation: Vec3::new(50.0, 0.0, 0.0),
+ scale: Vec3::splat(constants::TILE_SCALE),
+ ..Default::default()
+ },
+ ..Default::default()
+ });
+ commands.spawn_bundle(SpriteBundle {
+ material: materials.add(title.into()),
+ transform: Transform {
+ translation: Vec3::new(240.0, 200.0, 0.0),
+ scale: Vec3::splat(2.0),
+ ..Default::default()
+ },
+ ..Default::default()
+ });
+ commands.spawn_bundle(SpriteSheetBundle {
+ sprite: TextureAtlasSprite::new(constants::TILESHEET_COSMONAUT1),
+ texture_atlas: atlas_handle.clone(),
+ transform: Transform {
+ translation: Vec3::new(225.0, -200.0, 0.0),
+ scale: Vec3::splat(constants::TILE_SCALE),
+ ..Default::default()
+ },
+ ..Default::default()
+ });
+ commands.spawn_bundle((Timer::from_seconds(1.0, false),));
+ commands.spawn_bundle(SpriteSheetBundle {
+ sprite: TextureAtlasSprite::new(constants::TILESHEET_COSMONAUT2),
+ texture_atlas: atlas_handle.clone(),
+ transform: Transform {
+ translation: Vec3::new(
+ 225.0,
+ -200.0 + (-constants::TILE_SIZE) * constants::TILE_SCALE,
+ 0.0,
+ ),
+ scale: Vec3::splat(constants::TILE_SCALE),
+ ..Default::default()
+ },
+ ..Default::default()
+ });
+
+ for i in 0..constants::GRID_SIZE {
+ for j in 0..constants::GRID_SIZE {
+ commands
+ .spawn_bundle(SpriteSheetBundle {
+ texture_atlas: atlas_handle.clone(),
+ visible: Visible {
+ is_visible: false,
+ is_transparent: true,
+ },
+ transform: Transform {
+ translation: Vec3::new(
+ ((i as f32) * constants::TILE_SIZE * constants::TILE_SCALE) - 330.0,
+ ((j as f32) * constants::TILE_SIZE * constants::TILE_SCALE) - 160.0,
+ 1.0,
+ ),
+ scale: Vec3::splat(constants::TILE_SCALE),
+ ..Default::default()
+ },
+ ..Default::default()
+ })
+ .insert(Cell::new(i, j));
+ }
+ }
+}
+
+fn animation(
+ mut commands: Commands,
+ time: Res<Time>,
+ mut q: Query<(
+ Entity,
+ Option<&mut Cell>,
+ &mut Timer,
+ &mut TextureAtlasSprite,
+ &mut Visible,
+ )>,
+) {
+ for (entity, cell, mut timer, mut sprite, mut visible) in q.iter_mut() {
+ timer.tick(time.delta());
+ if timer.finished() {
+ let index = match sprite.index {
+ constants::TILESHEET_EXPLOSION1 => Some(constants::TILESHEET_EXPLOSION2),
+ constants::TILESHEET_EXPLOSION2 => Some(constants::TILESHEET_EXPLOSION3),
+ constants::TILESHEET_EXPLOSION3 => Some(constants::TILESHEET_EXPLOSION4),
+ constants::TILESHEET_EXPLOSION4 => Some(constants::TILESHEET_EXPLOSION5),
+
+ constants::TILESHEET_VISOR1 => Some(constants::TILESHEET_VISOR2),
+ constants::TILESHEET_VISOR2 => Some(constants::TILESHEET_VISOR3),
+ constants::TILESHEET_VISOR3 => Some(constants::TILESHEET_VISOR4),
+
+ constants::TILESHEET_STAR1 => Some(constants::TILESHEET_STAR2),
+ constants::TILESHEET_STAR2 => Some(constants::TILESHEET_STAR3),
+
+ _ => None,
+ };
+
+ if let Some(index) = index {
+ sprite.index = index;
+ } else if let Some(mut cell) = cell {
+ cell.set_occupant(Occupant::None, &mut sprite, &mut visible);
+ commands.entity(entity).remove::<Timer>();
+ } else {
+ commands.entity(entity).despawn();
+ }
+ }
+ }
+}
+
+fn cosmonaut_detect(
+ mut commands: Commands,
+ windows: Res<Windows>,
+ mut q: Query<(&Transform, &TextureAtlasSprite)>,
+) {
+ if let Some(mut cursor_position) = windows
+ .get_primary()
+ .and_then(|window| window.cursor_position())
+ {
+ cursor_position.x -=
+ (constants::WINDOW_WIDTH / 2.0) - constants::TILE_SIZE * constants::TILE_SCALE * 0.5;
+ cursor_position.y -=
+ (constants::WINDOW_HEIGHT / 2.0) - constants::TILE_SIZE * constants::TILE_SCALE * 0.5;
+ for (transform, sprite) in q.iter_mut() {
+ if transform.translation.x < cursor_position.x
+ && transform.translation.x + constants::TILE_SIZE * constants::TILE_SCALE
+ > cursor_position.x
+ && transform.translation.y < cursor_position.y
+ && transform.translation.y + constants::TILE_SIZE * constants::TILE_SCALE
+ > cursor_position.y
+ && sprite.index == constants::TILESHEET_COSMONAUT1
+ {
+ commands
+ .spawn_bundle(SpriteSheetBundle {
+ sprite: TextureAtlasSprite::new(constants::TILESHEET_VISOR1),
+ transform: *transform,
+ ..Default::default()
+ })
+ .insert(Timer::from_seconds(0.1, true));
+ }
+ }
+ }
+}
+
+fn mouse(
+ windows: Res<Windows>,
+ mut q: Query<(&mut Cell, &mut Transform, &mut TextureAtlasSprite)>,
+ mouse_button_input: Res<Input<MouseButton>>,
+) {
+ if let Some(mut cursor_position) = windows
+ .get_primary()
+ .and_then(|window| window.cursor_position())
+ {
+ cursor_position.x -=
+ (constants::WINDOW_WIDTH / 2.0) - constants::TILE_SIZE * constants::TILE_SCALE * 0.5;
+ cursor_position.y -=
+ (constants::WINDOW_HEIGHT / 2.0) - constants::TILE_SIZE * constants::TILE_SCALE * 0.5;
+
+ for (cell, _, mut sprite) in q.iter_mut() {
+ if cell.selected {
+ sprite.color.set_a(0.2);
+ } else if cell.hovered {
+ sprite.color.set_a(0.5);
+ } else {
+ sprite.color.set_a(1.0);
+ }
+ }
+
+ for (mut cell, transform, _) in q.iter_mut() {
+ if transform.translation.x < cursor_position.x
+ && transform.translation.x + constants::TILE_SIZE * constants::TILE_SCALE
+ > cursor_position.x
+ && transform.translation.y < cursor_position.y
+ && transform.translation.y + constants::TILE_SIZE * constants::TILE_SCALE
+ > cursor_position.y
+ {
+ cell.hovered = true;
+ if mouse_button_input.just_pressed(MouseButton::Left) {
+ cell.selected = true;
+ }
+ } else {
+ cell.hovered = false;
+ }
+ }
+
+ if mouse_button_input.just_released(MouseButton::Left) {
+ let mut cells: Vec<Cell> = Vec::new();
+ for (cell, _, _) in q.iter_mut() {
+ cells.push(*cell);
+ }
+ if let Some(mut selected) = cells.clone().iter_mut().find(|c| c.selected) {
+ if let Some(mut hovered) = cells.iter_mut().find(|c| c.hovered) {
+ if (selected.x == hovered.x + 1 && selected.y == hovered.y)
+ || (selected.x == hovered.x.overflowing_sub(1).0 && selected.y == hovered.y)
+ || (selected.y == hovered.y + 1 && selected.x == hovered.x)
+ || (selected.y == hovered.y.overflowing_sub(1).0 && selected.x == hovered.x)
+ {
+ let tmp = selected.occupant;
+ selected.occupant = hovered.occupant;
+ hovered.occupant = tmp;
+ for (mut cell, _, mut sprite) in q.iter_mut() {
+ if cell.x == selected.x && cell.y == selected.y {
+ cell.occupant = selected.occupant;
+ sprite.index = cell.occupant.to_index();
+ } else if cell.x == hovered.x && cell.y == hovered.y {
+ cell.occupant = hovered.occupant;
+ sprite.index = cell.occupant.to_index();
+ }
+ }
+ }
+ }
+ }
+ for (mut cell, _, _) in q.iter_mut() {
+ cell.selected = false;
+ }
+ }
+ }
+}
+
+pub struct GemsPlugin;
+impl Plugin for GemsPlugin {
+ fn build(&self, app: &mut AppBuilder) {
+ app.add_startup_system(setup.system());
+ app.add_system(cell::insert.system());
+ app.add_system(cell::falling.system());
+ app.add_system(cell::check.system());
+ app.add_system(cell::start_explosion.system());
+ app.add_system(mouse.system());
+ app.add_system(cosmonaut_detect.system());
+ app.add_system(animation.system());
+ app.add_system(star_spawning.system());
+ }
+}
-pub fn main() -> GameResult {
- let (ref mut context, ref mut event_loop) = ContextBuilder::new("gems", "jw&tb")
- .add_resource_path("./resources")
- .build()?;
- let game = &mut Game::new(context)?;
- event::run(context, event_loop, game)
+pub fn main() {
+ App::build()
+ .insert_resource(WindowDescriptor {
+ title: "gems".to_string(),
+ width: constants::WINDOW_WIDTH,
+ height: constants::WINDOW_HEIGHT,
+ resizable: false,
+ ..Default::default()
+ })
+ .add_plugins(DefaultPlugins)
+ .add_plugin(GemsPlugin)
+ .run();
}