Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move scale and angle to Entity; refactor draw interface #3

Merged
merged 1 commit into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading