Skip to content

Commit

Permalink
refactor(deps): update chuot to 0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
tversteeg committed Nov 24, 2024
1 parent 7fb9adc commit 45a79f0
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 93 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ categories = ["games"]

[dependencies]
log = "0.4"
chuot = "0.2"
chuot = "0.3"
glamour = "0.15"
puffin = "0.19"
glamour = "0.11"
nanoserde = "0.1"

[workspace]
Expand Down
2 changes: 1 addition & 1 deletion assets/projectile/spear-1.ron
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(offset: Middle)
(pivot_x: Center, pivot_y: Center)
26 changes: 0 additions & 26 deletions src/camera.rs

This file was deleted.

20 changes: 20 additions & 0 deletions src/color.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use chuot::RGBA8;

/// Different colors.
///
/// Based on DB32 scale.
Expand Down Expand Up @@ -77,10 +79,28 @@ impl Color {
Self::DarkForestGreen => 0xff_8a_6f_30,
}
}

/// Convert to RGBA8.
pub const fn as_rgba8(self) -> RGBA8 {
let rgba = self.as_u32();

RGBA8::new(
((rgba >> 16) & 0xFF) as u8,
((rgba >> 8) & 0xFF) as u8,
(rgba & 0xFF) as u8,
((rgba >> 24) & 0xFF) as u8,
)
}
}

impl From<Color> for u32 {
fn from(value: Color) -> Self {
value.as_u32()
}
}

impl From<Color> for RGBA8 {
fn from(value: Color) -> Self {
value.as_rgba8()
}
}
66 changes: 33 additions & 33 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
mod camera;
mod color;
mod projectile;
mod settings;
mod terrain;
mod unit;
mod utils;

use camera::Camera;
use chuot::{context::KeyCode, Config, Context, Game};
use chuot::{Config, Context, Game, KeyCode};
use color::Color;
use glamour::Vector2;
use projectile::Projectile;
Expand All @@ -27,8 +25,6 @@ pub enum GameState {
Play {
/// First level ground.
terrain: Terrain,
/// Camera position.
camera: Camera,
/// Timer for when a unit should spawn.
unit_spawner: Timer,
/// Timer for when an enemy unit should spawn.
Expand All @@ -37,6 +33,8 @@ pub enum GameState {
units: Vec<Unit>,
/// Projectiles flying around.
projectiles: Vec<Projectile>,
/// Camera position.
camera_x: f32,
},
}

Expand All @@ -53,47 +51,50 @@ impl Game for GameState {

match self {
GameState::Load {} => {
let camera_x = WIDTH / 2.0;
let terrain = Terrain::new("level.grass-1", ctx.clone());

// Initialize camera
ctx.main_camera()
.follow((camera_x, -HEIGHT / 2.0 + terrain.size.height));

// Load the initial state the first frame
*self = GameState::Play {
terrain: Terrain::new("level.grass-1", ctx.clone()),
camera: Camera::default(),
unit_spawner: Timer::new(settings.unit_spawn_interval),
enemy_unit_spawner: Timer::new(settings.enemy_unit_spawn_interval),
units: Vec::new(),
projectiles: Vec::new(),
terrain,
camera_x,
};
}
GameState::Play {
camera,
terrain,
unit_spawner,
enemy_unit_spawner,
units,
projectiles,
camera_x,
} => {
// Handle mouse events
if let Some((mouse_x, _mouse_y)) = ctx.mouse() {
if let Some(mouse_x) = ctx.mouse_x() {
if mouse_x <= settings.pan_edge_offset {
// Pan to the left
camera.pan(
-settings.pan_speed * dt,
0.0,
0.0,
terrain.size.width - WIDTH,
);
} else if mouse_x >= 320.0 - settings.pan_edge_offset {
*camera_x -= settings.pan_speed * dt;
*camera_x = camera_x.max(WIDTH / 2.0);

ctx.main_camera().follow_x(*camera_x);
} else if mouse_x >= ctx.width() - settings.pan_edge_offset {
// Pan to the right
camera.pan(
settings.pan_speed * dt,
0.0,
0.0,
terrain.size.width - WIDTH,
);
*camera_x += settings.pan_speed * dt;
*camera_x = camera_x.min(terrain.size.width - WIDTH / 2.0);

ctx.main_camera().follow_x(*camera_x);
}
}

// Draw the terrain
terrain.draw(ctx.clone(), *camera);
terrain.draw(ctx.clone());

// Update all projectiles
projectiles.retain_mut(|projectile| !projectile.update(terrain, dt, &settings));
Expand All @@ -109,15 +110,15 @@ impl Game for GameState {
if unit_spawner.update(dt) {
// Spawn a unit at the upper edge of the terrain image
units.push(Unit::new(
Vector2::new(10.0, terrain.y),
Vector2::new(10.0, 0.0),
UnitType::PlayerSpear,
ctx.clone(),
));
}
if enemy_unit_spawner.update(dt) {
// Spawn a unit at the upper edge of the terrain image
units.push(Unit::new(
(terrain.size.width - 10.0, terrain.y).into(),
(terrain.size.width - 10.0, 0.0).into(),
UnitType::EnemySpear,
ctx.clone(),
));
Expand All @@ -129,32 +130,31 @@ impl Game for GameState {
fn render(&mut self, ctx: Context) {
// Draw a basic FPS counter
let fps = ctx.frames_per_second();
ctx.text("font.torus-sans", &format!("{fps:.1}")).draw();
ctx.text("font.torus-sans", &format!("{fps:.1}"))
.use_ui_camera()
.draw();

match self {
GameState::Load {} => {
ctx.text("font.torus-sans", "Loading game")
.translate((20.0, 20.0))
.draw();
ctx.text("font.torus-sans", "Loading game").draw();
}
GameState::Play {
camera,
terrain,
units,
projectiles,
..
} => {
// Draw the terrain
terrain.draw(ctx.clone(), *camera);
terrain.draw(ctx.clone());

// Draw all units
units.iter().for_each(|unit| {
unit.render(*camera, ctx.clone());
unit.render(ctx.clone());
});

// Draw all projectiles
projectiles.iter().for_each(|projectile| {
projectile.render(*camera, ctx.clone());
projectile.render(ctx.clone());
});
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/projectile.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use chuot::Context;
use glamour::Vector2;

use crate::{camera::Camera, settings::Settings, terrain::Terrain};
use crate::{settings::Settings, terrain::Terrain};

/// Spear asset path.
const ASSET_PATH: &str = "projectile.spear-1";
Expand Down Expand Up @@ -33,12 +33,12 @@ impl Projectile {
}

/// Draw the projectile.
pub fn render(&self, camera: Camera, ctx: Context) {
pub fn render(&self, ctx: Context) {
puffin::profile_function!();
let rotation = self.vel.y.atan2(self.vel.x);

ctx.sprite(ASSET_PATH)
.translate(self.pos + camera.into())
.translate(self.pos)
.rotate(rotation)
.draw();
}
Expand Down
2 changes: 1 addition & 1 deletion src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use chuot::{
use nanoserde::DeRon;

/// Game settings loaded from a file so it's easier to change them with hot-reloading.
#[derive(DeRon)]
#[derive(Debug, DeRon)]
pub struct Settings {
/// Distance from the edge at which the camera will pan.
pub pan_edge_offset: f32,
Expand Down
29 changes: 6 additions & 23 deletions src/terrain.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use chuot::Context;
use glamour::{Size2, Vector2};

use crate::{camera::Camera, HEIGHT};

/// How many pixels to skip before taking a height sample.
const HEIGHT_VALUE_INTERVAL: usize = 3;

Expand All @@ -14,8 +12,6 @@ pub struct Terrain {
pub size: Size2,
/// Height values for each couple of pixels.
heights: Vec<f32>,
/// Where to draw the terrain.
pub y: f32,
}

impl Terrain {
Expand All @@ -33,13 +29,7 @@ impl Terrain {
let first_height = pixels
.iter()
.enumerate()
.find_map(|(idx, pixel)| {
if pixel & 0xFF000000 != 0 {
Some(idx)
} else {
None
}
})
.find_map(|(idx, pixel)| if pixel.a != 0 { Some(idx) } else { None })
.expect("Image is fully transparent")
/ width;

Expand All @@ -52,7 +42,7 @@ impl Terrain {
for y in first_height..height {
let idx = y * width + x;
// We only care about transparency
if pixels[idx] & 0xFF000000 != 0 {
if pixels[idx].a != 0 {
return y as f32;
}
}
Expand All @@ -63,28 +53,21 @@ impl Terrain {

let level = level.to_owned();

let y = HEIGHT - size.height;

Self {
heights,
level,
size,
y,
}
}

pub fn draw(&mut self, ctx: Context, camera: Camera) {
let camera_offset: Vector2 = camera.into();

pub fn draw(&mut self, ctx: Context) {
// Draw the level at the bottom of the screen
ctx.sprite(&self.level)
.translate(camera_offset + Vector2::new(0.0, self.y))
.draw();
ctx.sprite(&self.level).draw();
}

/// Whether a point collides with the terrain
pub fn point_collides(&self, point: Vector2) -> bool {
if point.x < 0.0 || point.y < self.y {
if point.x < 0.0 || point.y < 0.0 {
return false;
}

Expand All @@ -94,6 +77,6 @@ impl Terrain {
// If it's out of bounds there's no collision, otherwise check if the point is inside the terrain
self.heights
.get(index)
.is_some_and(|height| point.y >= height + self.y)
.is_some_and(|height| point.y >= *height)
}
}
9 changes: 5 additions & 4 deletions src/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use glamour::{Size2, Vector2};
use nanoserde::DeRon;

use crate::{
camera::Camera,
projectile::Projectile,
terrain::Terrain,
utils::{random::RandomRange, timer::Timer},
Expand Down Expand Up @@ -116,7 +115,7 @@ impl Unit {
self.hide_hands_delay = hide_hands_delay;

Some(Projectile::new(
self.pos + projectile_spawn_offset.into(),
self.pos + Vector2::from_tuple(projectile_spawn_offset),
Vector2::new(velocity, -velocity),
))
} else {
Expand All @@ -137,20 +136,22 @@ impl Unit {
}

/// Draw the unit.
pub fn render(&self, camera: Camera, ctx: Context) {
pub fn render(&self, ctx: Context) {
puffin::profile_scope!("Unit render");

let settings = self.settings(ctx.clone());

let draw_pos = self.pos - self.ground_collision_point() + camera.into();
let draw_pos = self.pos - self.ground_collision_point();

ctx.sprite(self.r#type.asset_path())
.translate(draw_pos)
.use_main_camera()
.draw();

ctx.text("font.debug", &format!("{}", self.health))
.translate(draw_pos)
.translate(settings.healthbar_offset)
.use_main_camera()
.draw();

if let Some(hands_asset_path) = &settings.hands_asset_path {
Expand Down

0 comments on commit 45a79f0

Please sign in to comment.