Skip to content

Commit

Permalink
feat: tilemap layers 🥐
Browse files Browse the repository at this point in the history
  • Loading branch information
eerii committed Dec 10, 2023
1 parent ca53563 commit aebe0e3
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 146 deletions.
Binary file modified assets/sprites/river_stix.aseprite
Binary file not shown.
Binary file modified assets/sprites/river_stix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
104 changes: 70 additions & 34 deletions src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ use rand::Rng;

use crate::{
tilemap::{
play_to_real_size, EndTile, LevelSize, PathTile, StartTile, TilesAvailable, MAP_SIZE,
play_to_real_size, EndTile, ForegroundTile, LevelSize, PathTile, StartTile, TilemapLayer,
TilesAvailable, MAP_SIZE,
},
GameState,
};

//0, 1, 2, 3, 4, 5, 130, 160, 250, 300, 400, 500, 700, 900, 1200, 1500, 2000, 2500, 3500,
const START_SCORES: [u32; 22] = [
const START_SCORES: [u32; 20] = [
0, 5, 30, 50, 70, 100, 130, 160, 250, 300, 400, 500, 700, 900, 1200, 1500, 2000, 2500, 3500,
5000, 7000, 8500,
5000,
];

const END_SCORES: [u32; 5] = [0, 60, 350, 3000, 9000];
const END_SCORES: [u32; 4] = [0, 60, 350, 3000];

pub struct CharonPlugin;

Expand Down Expand Up @@ -87,9 +88,10 @@ fn spawn_start_end(
score: Res<GameScore>,
mut level_size: ResMut<LevelSize>,
mut available: ResMut<TilesAvailable>,
tilemap: Query<&TileStorage>,
tilemap: Query<(&TilemapLayer, &TileStorage)>,
starts: Query<&TilePos, With<StartTile>>,
ends: Query<&TilePos, With<EndTile>>,
mut visible: Query<&mut TileVisible>,
mut cam: Query<&mut GameCam>,
mut start_spawned: Local<usize>,
mut end_spawned: Local<usize>,
Expand All @@ -98,13 +100,13 @@ fn spawn_start_end(
let next_start = if *start_spawned < START_SCORES.len() {
START_SCORES[*start_spawned]
} else {
(*start_spawned + 1 - START_SCORES.len()) as u32 * 10000
5000 + (*start_spawned + 1 - START_SCORES.len()) as u32 * 1000
};

let next_end = if *end_spawned < END_SCORES.len() {
END_SCORES[*end_spawned]
} else {
(*end_spawned + 1 - END_SCORES.len()) as u32 * 25000
(*end_spawned + 1 - END_SCORES.len()) as u32 * 10000
};

let mut is_start = false;
Expand Down Expand Up @@ -134,38 +136,72 @@ fn spawn_start_end(
}
let (offset, size) = play_to_real_size(&level_size);

if let Ok(storage) = tilemap.get_single() {
if is_start {
let pos = if *start_spawned <= 1 {
Some(TilePos {
x: offset.x + 1,
y: offset.y + size.y / 2,
})
let mut spawn_fun = |is_start: bool| {
// Get spawn position
let spawn_pos = {
if is_start {
if *start_spawned <= 1 {
Some(TilePos {
x: offset.x + 1,
y: offset.y + size.y / 2,
})
} else {
get_spawn_pos(&offset, &size, &starts, &ends)
}
} else {
get_spawn_pos(&offset, &size, &starts, &ends)
};
if let Some(pos) = pos {
cmd.entity(storage.get(&pos).unwrap())
.insert((StartTile::default(), PathTile::default()));
available.0 += 3;
if *end_spawned <= 1 {
Some(TilePos {
x: offset.x + size.x - 2,
y: offset.y + size.y / 2,
})
} else {
get_spawn_pos(&offset, &size, &starts, &ends)
}
}
}
};

if is_end {
let pos = if *end_spawned <= 1 {
Some(TilePos {
x: offset.x + size.x - 2,
y: offset.y + size.y / 2,
})
} else {
get_spawn_pos(&offset, &size, &starts, &ends)
};
if let Some(pos) = pos {
cmd.entity(storage.get(&pos).unwrap())
.insert((EndTile, PathTile::default()));
available.0 += 5;
if let Some(pos) = spawn_pos {
for (layer, storage) in tilemap.iter() {
match layer {
// Insert the logical tile in the river
TilemapLayer::RiverStix => {
if let Some(entity) = storage.get(&pos) {
if is_start {
cmd.entity(entity)
.insert((StartTile::default(), PathTile::default()));
} else {
cmd.entity(entity).insert((EndTile, PathTile::default()));
}
if let Ok(mut visible) = visible.get_mut(entity) {
visible.0 = true;
}
}
}
// Add the graphics element to the foreground
TilemapLayer::Foreground => {
if let Some(entity) = storage.get(&pos) {
cmd.entity(entity).insert(if is_start {
ForegroundTile::Start
} else {
ForegroundTile::End
});
if let Ok(mut visible) = visible.get_mut(entity) {
visible.0 = true;
}
}
}
_ => continue,
}
}
available.0 += if is_start { 2 } else { 4 };
}
};

if is_start {
spawn_fun(true);
}
if is_end {
spawn_fun(false);
}
}

Expand Down
115 changes: 84 additions & 31 deletions src/spirits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ use rand::Rng;
use crate::{
game::GameScore,
load::{GameAssets, SpiritAssets},
tilemap::{get_neighbours, pos_to_tile, tile_to_pos, EndTile, PathTile, StartTile},
tilemap::{
get_neighbours, pos_to_tile, tile_to_pos, EndTile, PathTile, StartTile, TilemapLayer,
},
GameState,
};

const SPIRIT_SPEED: f32 = 200.;
const SPIRIT_SIZE: f32 = 32.;
const MAX_SPIRITS_IN_TILE: u32 = 3;

pub const INITIAL_SPAWN_TIME: f32 = 1.0;
const LOSE_COUNT: f32 = 40.;
pub const INITIAL_SPAWN_TIME: f32 = 1.2;
const LOSE_COUNT: f32 = 30.;

const FUN_A: f32 = 10.;

Expand All @@ -28,18 +30,36 @@ pub struct SpiritPlugin;

impl Plugin for SpiritPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
Update,
(
spawn_spirit,
check_lose_count,
next_tile_spirit,
spirit_collision,
move_spirit,
integrate,
app.insert_resource(EndTimer::default())
.add_systems(
Update,
(
spawn_spirit,
check_lose_count,
next_tile_spirit,
spirit_collision,
move_spirit,
integrate,
)
.run_if(in_state(GameState::Play)),
)
.run_if(in_state(GameState::Play)),
);
.add_systems(
PostUpdate,
clear_end_count.run_if(in_state(GameState::Play)),
);
}
}

// ·········
// Resources
// ·········

#[derive(Resource)]
pub struct EndTimer(Timer);

impl Default for EndTimer {
fn default() -> Self {
Self(Timer::from_seconds(0.3, TimerMode::Repeating))
}
}

Expand Down Expand Up @@ -84,12 +104,17 @@ fn spawn_spirit(
time: Res<Time>,
spirit_assets: Res<SpiritAssets>,
mut start: Query<(&TilePos, &mut StartTile, &mut PathTile)>,
tilemap: Query<(&TilemapGridSize, &TilemapType, &Transform)>,
tilemap: Query<(&TilemapLayer, &TilemapGridSize, &TilemapType, &Transform)>,
) {
for (start_pos, mut start_tile, mut start_path) in start.iter_mut() {
if start_tile.spawn_timer.tick(time.delta()).just_finished() {
if let Ok((grid_size, map_type, trans)) = tilemap.get_single() {
start_tile.lose_counter += 1.;
start_tile.lose_counter += 1.;

for (layer, grid_size, map_type, trans) in tilemap.iter() {
match layer {
TilemapLayer::RiverStix => {}
_ => continue,
}

// Don't spawn entities if the path is not complete
if !start_tile.completed_once {
Expand All @@ -100,7 +125,7 @@ fn spawn_spirit(
let pos = tile_to_pos(start_pos, grid_size, map_type, trans);

// If there is already another entity there, don't spawn
if start_path.count >= 1 {
if start_path.count >= 2 {
continue;
}
start_path.count += 1;
Expand All @@ -110,7 +135,7 @@ fn spawn_spirit(
SpriteSheetBundle {
sprite: TextureAtlasSprite::new(0),
texture_atlas: spirit_assets.stix.clone(),
transform: Transform::from_translation(pos.extend(1.)),
transform: Transform::from_translation(pos.extend(5.)),
..default()
},
Spirit::new(*start_pos, pos),
Expand All @@ -119,7 +144,7 @@ fn spawn_spirit(

// Reduce timer 0.01 seconds until it is 0.5
let duration = start_tile.spawn_timer.duration().as_millis();
if duration > 600 {
if duration > 500 {
start_tile
.spawn_timer
.set_duration(Duration::from_millis((duration - 5) as u64));
Expand All @@ -135,14 +160,19 @@ fn check_lose_count(
assets: Res<GameAssets>,
mut start: Query<(&TilePos, &mut StartTile)>,
mut text: Query<&mut Text, With<LoseText>>,
tilemap: Query<(&TilemapGridSize, &TilemapType, &Transform)>,
tilemap: Query<(&TilemapLayer, &TilemapGridSize, &TilemapType, &Transform)>,
) {
for (pos, mut start) in start.iter_mut() {
if start.lose_counter > 10. {
if start.lose_counter > 1. {
let lose_text = start.lose_text;

if lose_text.is_none() {
if let Ok((grid_size, map_type, trans)) = tilemap.get_single() {
for (layer, grid_size, map_type, trans) in tilemap.iter() {
match layer {
TilemapLayer::RiverStix => {}
_ => continue,
}

let pos = tile_to_pos(pos, grid_size, map_type, trans);
start.lose_text = Some(
cmd.spawn((
Expand All @@ -167,7 +197,7 @@ fn check_lose_count(
};

if let Ok(mut text) = text.get_mut(lose_text.unwrap()) {
let remainder = 16. - ((start.lose_counter - 10.) / 2.).min(15.);
let remainder = (LOSE_COUNT - start.lose_counter) / 2. + 1.;
text.sections[0].value = if remainder <= 2. {
"!!!".to_string()
} else if remainder > 15. {
Expand All @@ -185,13 +215,13 @@ fn check_lose_count(

fn next_tile_spirit(
mut cmd: Commands,
mut score: ResMut<GameScore>,
mut spirit: Query<(Entity, &Transform, &mut Spirit)>,
mut paths: Query<(&TilePos, &mut PathTile)>,
start: Query<Entity, With<StartTile>>,
end: Query<Entity, With<EndTile>>,
tilemap: Query<
(
&TilemapLayer,
&TilemapSize,
&TilemapGridSize,
&TilemapType,
Expand All @@ -201,7 +231,11 @@ fn next_tile_spirit(
Without<Spirit>,
>,
) {
if let Ok((map_size, grid_size, map_type, storage, map_trans)) = tilemap.get_single() {
for (layer, map_size, grid_size, map_type, storage, map_trans) in tilemap.iter() {
match layer {
TilemapLayer::RiverStix => {}
_ => continue,
}
for (spirit_entity, trans, mut spirit) in spirit.iter_mut() {
if let Some(tile_pos) = pos_to_tile(
&trans.translation.xy(),
Expand All @@ -214,6 +248,7 @@ fn next_tile_spirit(
continue;
}

// TODO: Move this so it updates for other spirits
// Update counts
if let Some(entity) = storage.get(&tile_pos) {
if let Ok((_, mut path)) = paths.get_mut(entity) {
Expand All @@ -234,11 +269,6 @@ fn next_tile_spirit(
// If the spirit is on the end tile, despawn
if let Some(entity) = storage.get(&tile_pos) {
if end.get(entity).is_ok() {
cmd.get_entity(spirit_entity).unwrap().despawn_recursive();
score.score += 1;
if let Ok((_, mut path)) = paths.get_mut(entity) {
path.count = 0;
}
continue;
}
if let Some(end) = spirit.selected_end {
Expand Down Expand Up @@ -361,6 +391,29 @@ fn next_tile_spirit(
}
}

fn clear_end_count(
mut cmd: Commands,
time: Res<Time>,
mut score: ResMut<GameScore>,
mut end: Query<(&mut PathTile, &TilePos), With<EndTile>>,
spirits: Query<(Entity, &Spirit)>,
mut timer: ResMut<EndTimer>,
) {
if !timer.0.tick(time.delta()).just_finished() {
return;
}
for (mut end, end_pos) in end.iter_mut() {
for (entity, spirit) in spirits.iter() {
if spirit.curr_tile == *end_pos {
cmd.get_entity(entity).unwrap().despawn_recursive();
end.count -= 1;
score.score += 1;
break;
}
}
}
}

fn move_spirit(mut spirits: Query<(&mut Spirit, &Transform)>) {
for (mut spirit, trans) in spirits.iter_mut() {
// Move towards next tile
Expand Down
Loading

0 comments on commit aebe0e3

Please sign in to comment.