Skip to content

Commit

Permalink
Move scale and angle to Entity; refactor draw interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jjyr committed Aug 28, 2024
1 parent a9d362d commit 87a5a4d
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 93 deletions.
8 changes: 3 additions & 5 deletions examples/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,7 @@ impl EntityType for Brick {
let size = BRICK_SIZE * scale;
let center_pos = self.dead_pos + BRICK_SIZE * 0.5;
ent.pos = center_pos - size * 0.5;
ent.size = size;

anim.sheet.scale = Vec2::splat(scale);
ent.scale = Vec2::splat(scale);
anim.sheet.color = color;
}
}
Expand Down Expand Up @@ -377,11 +375,11 @@ impl Scene for Demo {
fn draw(&mut self, eng: &mut Engine) {
eng.scene_base_draw();
if let Some(text) = self.score_text.as_ref() {
eng.draw_image(text, Vec2::new(0.0, 0.0));
eng.draw_image(text, Vec2::new(0.0, 0.0), None, None);
}
if let Some(text) = self.fps_text.as_ref() {
let x = eng.view_size().x - text.size().x as f32;
eng.draw_image(text, Vec2::new(x, 0.0));
eng.draw_image(text, Vec2::new(x, 0.0), None, None);
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ impl Animation {
pub fn new(sheet: Sprite) -> Self {
Self { sheet }
}
pub(crate) fn draw(&mut self, render: &mut Render, pos: Vec2) {
render.draw_image(&self.sheet, pos)
pub(crate) fn draw(
&mut self,
render: &mut Render,
pos: Vec2,
scale: Option<Vec2>,
angle: Option<f32>,
) {
render.draw_image(&self.sheet, pos, scale, angle)
}
}
7 changes: 4 additions & 3 deletions src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,10 @@ impl Camera {
) {
if let Some(follow) = follow {
let follow = follow.borrow();
let follow_size = follow.scaled_size();
let size = Vec2::new(
follow.size.x.min(self.deadzone.x),
follow.size.y.min(self.deadzone.y),
follow_size.x.min(self.deadzone.x),
follow_size.y.min(self.deadzone.y),
);
if follow.pos.x < self.deadzone_pos.x {
self.deadzone_pos.x = follow.pos.x;
Expand All @@ -92,7 +93,7 @@ impl Camera {
}

if self.snap_to_platform && follow.on_ground {
self.deadzone_pos.y = follow.pos.y + follow.size.y - self.deadzone.y;
self.deadzone_pos.y = follow.pos.y + follow_size.y - self.deadzone.y;
}

let deadzone_target = self.deadzone_pos + self.deadzone * 0.5;
Expand Down
19 changes: 14 additions & 5 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,14 @@ impl Engine {
}

/// Draw image
pub fn draw_image(&mut self, image: &Sprite, pos: Vec2) {
self.render.draw_image(image, pos);
pub fn draw_image(
&mut self,
image: &Sprite,
pos: Vec2,
scale: Option<Vec2>,
angle: Option<f32>,
) {
self.render.draw_image(image, pos, scale, angle);
}

/// Draw image as tile
Expand All @@ -226,11 +232,14 @@ impl Engine {
tile: u16,
tile_size: Vec2,
dst_pos: Vec2,
scale: Option<Vec2>,
angle: Option<f32>,
flip_x: bool,
flip_y: bool,
) {
self.render
.draw_tile(image, tile, tile_size, dst_pos, flip_x, flip_y);
self.render.draw_tile(
image, tile, tile_size, dst_pos, scale, angle, flip_x, flip_y,
);
}

/// Sweep axis
Expand Down Expand Up @@ -410,7 +419,7 @@ impl Engine {
if res {
let max_pos = {
let ent1 = ent1.borrow();
sweep_axis.get(ent1.pos) + sweep_axis.get(ent1.size)
sweep_axis.get(ent1.pos) + sweep_axis.get(ent1.scaled_size())
};
for j in (i + 1)..self.world.entities.len() {
let ent1 = self.world.entities[i].clone();
Expand Down
39 changes: 28 additions & 11 deletions src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ pub struct Entity {
pub group: EntityGroup,
pub check_against: EntityGroup,
pub pos: Vec2,
pub scale: Vec2,
pub angle: f32,
pub size: Vec2,
pub vel: Vec2,
pub accel: Vec2,
Expand Down Expand Up @@ -173,14 +175,22 @@ impl Entity {
min_slide_normal: 1.0, // cosf(to_radians(0))
anim: None,
instance,
scale: Vec2::splat(1.0),
angle: 0.0,
}
}

pub(crate) fn is_touching(&self, other: &Entity) -> bool {
!(self.pos.x >= other.pos.x + other.size.x
|| self.pos.x + self.size.x <= other.pos.x
|| self.pos.y >= other.pos.y + other.size.y
|| self.pos.y + self.size.y <= other.pos.y)
let self_size = self.scaled_size();
let other_size = other.scaled_size();
!(self.pos.x >= other.pos.x + other_size.x
|| self.pos.x + self_size.x <= other.pos.x
|| self.pos.y >= other.pos.y + other_size.y
|| self.pos.y + self_size.y <= other.pos.y)
}

pub fn scaled_size(&self) -> Vec2 {
self.size * self.scale
}
}

Expand Down Expand Up @@ -220,7 +230,12 @@ pub trait EntityType: DynClone {
// Draw entity anim
fn draw(&self, eng: &mut Engine, ent: &mut Entity, viewport: Vec2) {
if let Some(anim) = ent.anim.as_mut() {
anim.draw(&mut eng.render, (ent.pos - viewport) - ent.offset);
anim.draw(
&mut eng.render,
(ent.pos - viewport) - ent.offset,
Some(ent.scale),
Some(ent.angle),
);
}
}

Expand Down Expand Up @@ -343,15 +358,17 @@ impl World {

/// Resolve entity collision
pub(crate) fn resolve_collision(eng: &mut Engine, a: &mut Entity, b: &mut Entity) {
let a_size = a.scaled_size();
let b_size = b.scaled_size();
let overlap_x: f32 = if a.pos.x < b.pos.x {
a.pos.x + a.size.x - b.pos.x
a.pos.x + a_size.x - b.pos.x
} else {
b.pos.x + b.size.x - a.pos.x
b.pos.x + b_size.x - a.pos.x
};
let overlap_y: f32 = if a.pos.y < b.pos.y {
a.pos.y + a.size.y - b.pos.y
a.pos.y + a_size.y - b.pos.y
} else {
b.pos.y + b.size.y - a.pos.y
b.pos.y + b_size.y - a.pos.y
};

let a_move;
Expand Down Expand Up @@ -465,7 +482,7 @@ pub(crate) fn entities_separate_on_y_axis(
pub(crate) fn entity_move(eng: &mut Engine, ent: &mut Entity, vstep: Vec2) {
if ent.physics.contains(EntityPhysics::WORLD) && eng.collision_map.is_some() {
let map = eng.collision_map.as_ref().unwrap();
let t = trace(map, ent.pos, vstep, ent.size);
let t = trace(map, ent.pos, vstep, ent.scaled_size());
handle_trace_result(eng, ent, &t);
// The previous trace was stopped short and we still have some velocity
// left? Do a second trace with the new velocity. this allows us
Expand All @@ -478,7 +495,7 @@ pub(crate) fn entity_move(eng: &mut Engine, ent: &mut Entity, vstep: Vec2) {
let remaining = 1. - t.length;
let vstep2 = rotated_normal * (vel_along_normal * remaining);
let map = eng.collision_map.as_ref().unwrap();
let t2 = trace(map, ent.pos, vstep2, ent.size);
let t2 = trace(map, ent.pos, vstep2, ent.scaled_size());
handle_trace_result(eng, ent, &t2);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ fn map_draw_tile(render: &mut Render, map: &Map, tile: &Tile, pos: Vec2) {
tile.tile_id,
Vec2::splat(map.tile_size),
pos,
None,
None,
tile.flip_x,
tile.flip_y,
);
Expand Down
11 changes: 5 additions & 6 deletions src/platform/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use anyhow::Result;
use glam::{UVec2, Vec2};
use glam::UVec2;

use crate::{
color::Color,
engine::Engine,
handle::{Handle, HandleId},
types::Rect,
};

#[cfg(not(target_arch = "wasm32"))]
Expand All @@ -22,11 +23,9 @@ pub trait Platform {
&mut self,
texture: &Handle,
color: Color,
pos: Vec2,
size: Vec2,
uv_offset: Vec2,
uv_size: Option<Vec2>,
angle: f32,
src: Option<Rect>,
dst: Rect,
angle: Option<f32>,
flip_x: bool,
flip_y: bool,
);
Expand Down
50 changes: 27 additions & 23 deletions src/platform/sdl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::{
engine::Engine,
handle::{Handle, HandleId},
input::{KeyCode, KeyState},
types::Rect,
};

use super::Platform;
Expand Down Expand Up @@ -53,6 +54,18 @@ impl ScreenBuffer {
}
}

impl From<Rect> for sdl2::rect::Rect {
fn from(value: Rect) -> Self {
let size = value.max - value.min;
sdl2::rect::Rect::new(
value.min.x.floor() as i32,
value.min.y.floor() as i32,
size.x.floor() as u32,
size.y.floor() as u32,
)
}
}

pub struct SDLPlatform {
screen_buffer: ScreenBuffer,
textures: HashMap<u64, Texture>,
Expand Down Expand Up @@ -88,41 +101,32 @@ impl Platform for SDLPlatform {
&mut self,
handle: &Handle,
color: Color,
pos: Vec2,
size: Vec2,
uv_offset: Vec2,
uv_size: Option<Vec2>,
angle: f32,
src: Option<Rect>,
dst: Rect,
angle: Option<f32>,
flip_x: bool,
flip_y: bool,
) {
let Some(texture) = self.textures.get_mut(&handle.id()) else {
log::debug!("Failed to get texture {}", handle.id());
return;
};
let uv_size = uv_size.unwrap_or_else(|| {
let q = texture.query();
Vec2::new(q.width as f32, q.height as f32)
});

let src = sdl2::rect::Rect::new(
uv_offset.x.floor() as i32,
uv_offset.y.floor() as i32,
uv_size.x.floor() as u32,
uv_size.y.floor() as u32,
);
let dst = sdl2::rect::Rect::new(
pos.x.floor() as i32,
pos.y.floor() as i32,
size.x.floor() as u32,
size.y.floor() as u32,
);

let src: Option<sdl2::rect::Rect> = src.map(Into::into);
let dst: sdl2::rect::Rect = dst.into();
texture.set_color_mod(color.r, color.g, color.b);

self.screen_buffer
.canvas
.copy_ex(texture, src, dst, angle.into(), None, flip_x, flip_y)
.copy_ex(
texture,
src,
dst,
angle.unwrap_or_default().into(),
None,
flip_x,
flip_y,
)
.unwrap();
}

Expand Down
37 changes: 28 additions & 9 deletions src/platform/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::{
engine::Engine,
handle::{Handle, HandleId},
input::{KeyCode, KeyState},
types::Rect,
};

use super::Platform;
Expand Down Expand Up @@ -149,13 +150,11 @@ impl Platform for WebPlatform {

fn draw(
&mut self,
texture: &crate::handle::Handle,
color: crate::prelude::Color,
pos: glam::Vec2,
size: glam::Vec2,
uv_offset: glam::Vec2,
uv_size: Option<glam::Vec2>,
_angle: f32,
texture: &Handle,
color: Color,
src: Option<Rect>,
dst: Rect,
angle: Option<f32>,
flip_x: bool,
flip_y: bool,
) {
Expand All @@ -164,8 +163,16 @@ impl Platform for WebPlatform {
return;
};
let canvas = texture.tint_color(color, &self.document);
let uv_size =
uv_size.unwrap_or_else(|| Vec2::new(canvas.width() as f32, canvas.height() as f32));
let uv_size = match src.as_ref() {
Some(src) => src.max - src.min,
None => Vec2::new(canvas.width() as f32, canvas.height() as f32),
};

let uv_offset = src.map(|src| src.min).unwrap_or_else(|| Vec2::ZERO);

let pos = dst.min;
let size = dst.max - dst.min;

let mut dx = pos.x;
let mut dy = pos.y;
// flip
Expand All @@ -187,8 +194,20 @@ impl Platform for WebPlatform {
if flip_y { -1.0 } else { 1.0 },
)
.unwrap();

let dw = (size.x as f64 * self.device_pixel_ratio).floor();
let dh = (size.y as f64 * self.device_pixel_ratio).floor();

// rotate by center with angle degree in counter clock-wise
if let Some(angle) = angle {
let dw_hf = (dw * 0.5).floor();
let dh_hf = (dh * 0.5).floor();
// move to center
self.buf.translate(dw_hf, dh_hf).unwrap();
// rotate counter clockwise
self.buf.rotate((-angle as f64).to_radians()).unwrap();
self.buf.translate(-dw_hf, -dh_hf).unwrap();
}
self.buf
.draw_image_with_html_canvas_element_and_sw_and_sh_and_dx_and_dy_and_dw_and_dh(
&canvas,
Expand Down
Loading

0 comments on commit 87a5a4d

Please sign in to comment.