aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--light-client/src/game.rs27
-rw-r--r--light-client/src/main.rs6
-rw-r--r--light-client/src/render/mod.rs (renamed from light-client/src/sprite_renderer.rs)100
-rw-r--r--light-client/src/render/sprite.rs63
-rw-r--r--light-client/src/tilemap.rs28
5 files changed, 118 insertions, 106 deletions
diff --git a/light-client/src/game.rs b/light-client/src/game.rs
index b6bacf74..ac5c3571 100644
--- a/light-client/src/game.rs
+++ b/light-client/src/game.rs
@@ -16,7 +16,7 @@
*/
use crate::{
- sprite_renderer::{SpriteRect, SpriteRenderer},
+ render::{sprite::Sprite, MiscTextures, SpriteRenderer},
tilemap::Tilemap,
};
use hurrycurry_protocol::{
@@ -27,7 +27,7 @@ use hurrycurry_protocol::{
use log::{info, warn};
use sdl2::{
keyboard::{KeyboardState, Scancode},
- rect::{FRect, Rect},
+ rect::Rect,
};
use std::collections::{HashMap, HashSet, VecDeque};
@@ -39,7 +39,8 @@ pub struct Game {
players: HashMap<PlayerID, Player>,
my_id: PlayerID,
- item_sprites: Vec<SpriteRect>,
+ misc_textures: MiscTextures,
+ item_sprites: Vec<Sprite>,
movement_send_cooldown: f32,
}
@@ -59,7 +60,7 @@ pub struct Item {
}
impl Game {
- pub fn new() -> Self {
+ pub fn new(renderer: &SpriteRenderer) -> Self {
Self {
tiles: HashMap::new(),
players: HashMap::new(),
@@ -68,6 +69,7 @@ impl Game {
data: ClientGamedata::default(),
collision_map: HashSet::new(),
movement_send_cooldown: 0.,
+ misc_textures: MiscTextures::init(renderer),
item_sprites: Vec::new(),
}
}
@@ -81,12 +83,14 @@ impl Game {
.item_names
.iter()
.map(|name| {
- SpriteRect::new(
+ Sprite::new(
renderer
.metadata()
.get(&format!("{name}:a"))
.copied()
.unwrap_or(Rect::new(0, 0, 32, 24)),
+ Vec2::ZERO,
+ 0.1,
)
})
.collect();
@@ -236,14 +240,7 @@ impl Game {
self.tilemap.draw(ctx);
for p in self.players.values() {
- let src = ctx.misc_textures().player;
- let dst = FRect::new(
- p.movement.position.x - src.width() as f32 / 32. / 2.,
- p.movement.position.y + 0.3 - src.height() as f32 / 24.,
- src.width() as f32 / 32.,
- src.height() as f32 / 24.,
- );
- ctx.draw(dst.y + dst.h + 1., src, dst);
+ ctx.draw_world(self.misc_textures.player.at(p.movement.position));
if let Some(item) = &p.item {
item.draw(ctx, &self.item_sprites)
}
@@ -257,7 +254,7 @@ impl Game {
}
impl Item {
- pub fn draw(&self, ctx: &mut SpriteRenderer, item_sprites: &[SpriteRect]) {
- item_sprites[self.kind.0].draw_at(ctx, self.position)
+ pub fn draw(&self, ctx: &mut SpriteRenderer, item_sprites: &[Sprite]) {
+ ctx.draw_world(item_sprites[self.kind.0].at(self.position))
}
}
diff --git a/light-client/src/main.rs b/light-client/src/main.rs
index b00ba734..278229d2 100644
--- a/light-client/src/main.rs
+++ b/light-client/src/main.rs
@@ -17,17 +17,17 @@
*/
use game::Game;
use network::Network;
+use render::SpriteRenderer;
use sdl2::{
event::Event,
keyboard::{KeyboardState, Keycode},
pixels::Color,
};
-use sprite_renderer::SpriteRenderer;
use std::time::{Duration, Instant};
pub mod game;
pub mod network;
-pub mod sprite_renderer;
+pub mod render;
pub mod tilemap;
fn main() {
@@ -52,8 +52,8 @@ fn main() {
let texture_creator = canvas.texture_creator();
let mut net = Network::connect("ws://127.0.0.1/").unwrap();
- let mut game = Game::new();
let mut renderer = SpriteRenderer::init(&texture_creator);
+ let mut game = Game::new(&renderer);
net.queue_out.push_back(hurrycurry_protocol::PacketS::Join {
name: "light".to_string(),
diff --git a/light-client/src/sprite_renderer.rs b/light-client/src/render/mod.rs
index aadbfbe3..fbf3d7a5 100644
--- a/light-client/src/sprite_renderer.rs
+++ b/light-client/src/render/mod.rs
@@ -15,6 +15,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+pub mod sprite;
+
use hurrycurry_protocol::glam::Vec2;
use sdl2::{
pixels::PixelFormatEnum,
@@ -22,11 +24,11 @@ use sdl2::{
render::{BlendMode, Canvas, Texture, TextureAccess, TextureCreator},
video::{Window, WindowContext},
};
+use sprite::{Sprite, SpriteDraw};
use std::collections::HashMap;
pub struct SpriteRenderer<'a> {
metadata: HashMap<String, Rect>,
- misc_textures: MiscTextures,
texture: Texture<'a>,
@@ -36,25 +38,9 @@ pub struct SpriteRenderer<'a> {
sprites: Vec<SpriteDraw>,
}
-pub struct MiscTextures {
- pub player: Rect,
-}
-
-pub struct SpriteDraw {
- z_order: i32,
- src: Rect,
- dst: FRect,
-}
-
-pub struct SpriteRect {
- z_offset: f32,
- src: Rect,
- relative_dst: FRect,
-}
-
impl<'a> SpriteRenderer<'a> {
pub fn init(texture_creator: &'a TextureCreator<WindowContext>) -> Self {
- let palette = include_str!("../assets/palette.csv")
+ let palette = include_str!("../../assets/palette.csv")
.split('\n')
.filter(|l| !l.is_empty())
.map(|s| {
@@ -73,7 +59,7 @@ impl<'a> SpriteRenderer<'a> {
let mut texels = vec![255; 1024 * 1024 * 4];
- for (y, line) in include_str!("../assets/atlas.ta").lines().enumerate() {
+ for (y, line) in include_str!("../../assets/atlas.ta").lines().enumerate() {
if line.is_empty() {
continue;
}
@@ -98,7 +84,7 @@ impl<'a> SpriteRenderer<'a> {
texture.update(None, &texels, 1024 * 4).unwrap();
texture.set_blend_mode(BlendMode::Blend);
- let metadata = include_str!("../assets/atlas.meta.csv")
+ let metadata = include_str!("../../assets/atlas.meta.csv")
.lines()
.filter(|l| !l.is_empty())
.map(|l| {
@@ -113,9 +99,6 @@ impl<'a> SpriteRenderer<'a> {
.collect::<HashMap<_, _>>();
Self {
- misc_textures: MiscTextures {
- player: *metadata.get("player+a").unwrap(),
- },
texture,
metadata,
sprites: vec![],
@@ -128,20 +111,24 @@ impl<'a> SpriteRenderer<'a> {
pub fn metadata(&self) -> &HashMap<String, Rect> {
&self.metadata
}
- #[inline]
- pub fn misc_textures(&self) -> &MiscTextures {
- &self.misc_textures
+
+ pub fn set_modulation(&mut self, r: u8, g: u8, b: u8, a: u8) {
+ self.texture.set_alpha_mod(a);
+ self.texture.set_color_mod(r, g, b);
+ }
+ pub fn reset_modulation(&mut self) {
+ self.set_modulation(255, 255, 255, 255)
}
- pub fn draw(&mut self, z_order: f32, src: Rect, dst: FRect) {
+ pub fn draw_world(&mut self, sprite: SpriteDraw) {
self.sprites.push(SpriteDraw {
- z_order: (z_order * 24.) as i32,
- src,
+ z_order: sprite.z_order,
+ src: sprite.src,
dst: FRect::new(
- ((dst.x + self.view_offset.x) * 32.).round() * self.view_scale.x,
- ((dst.y + self.view_offset.y) * 24.).round() * self.view_scale.y,
- (dst.w * 32.).round() * self.view_scale.x,
- (dst.h * 24.).round() * self.view_scale.y,
+ ((sprite.dst.x + self.view_offset.x) * 32.).round() * self.view_scale.x,
+ ((sprite.dst.y + self.view_offset.y) * 24.).round() * self.view_scale.y,
+ (sprite.dst.w * 32.).round() * self.view_scale.x,
+ (sprite.dst.h * 24.).round() * self.view_scale.y,
),
})
}
@@ -154,47 +141,18 @@ impl<'a> SpriteRenderer<'a> {
}
}
-impl Ord for SpriteDraw {
- fn cmp(&self, other: &Self) -> std::cmp::Ordering {
- self.z_order.cmp(&other.z_order)
- }
-}
-impl PartialOrd for SpriteDraw {
- fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
- Some(self.cmp(&other))
- }
-}
-impl Eq for SpriteDraw {}
-impl PartialEq for SpriteDraw {
- fn eq(&self, other: &Self) -> bool {
- self.z_order == other.z_order && self.src == other.src && self.dst == other.dst
- }
+pub struct MiscTextures {
+ pub player: Sprite,
}
-impl SpriteRect {
- pub fn draw_at(&self, ctx: &mut SpriteRenderer, pos: Vec2) {
- ctx.draw(
- self.z_offset + pos.y + 5.,
- self.src,
- FRect::new(
- self.relative_dst.x + pos.x,
- self.relative_dst.y + pos.y,
- self.relative_dst.w,
- self.relative_dst.h,
+impl MiscTextures {
+ pub fn init(renderer: &SpriteRenderer) -> Self {
+ MiscTextures {
+ player: Sprite::new(
+ *renderer.metadata().get("player+a").unwrap(),
+ Vec2::Y * 0.3,
+ 0.,
),
- )
- }
- pub fn new(src: Rect) -> Self {
- let relative_dst = FRect::new(
- 0.0 - src.width() as f32 / 32. / 2.,
- 0.3 - src.height() as f32 / 24.,
- src.width() as f32 / 32.,
- src.height() as f32 / 24.,
- );
- Self {
- z_offset: -relative_dst.h,
- relative_dst,
- src,
}
}
}
diff --git a/light-client/src/render/sprite.rs b/light-client/src/render/sprite.rs
new file mode 100644
index 00000000..c19f8392
--- /dev/null
+++ b/light-client/src/render/sprite.rs
@@ -0,0 +1,63 @@
+use hurrycurry_protocol::glam::Vec2;
+use sdl2::rect::{FRect, Rect};
+
+pub struct Sprite {
+ z_offset: f32,
+ src: Rect,
+ relative_dst: FRect,
+}
+
+impl Sprite {
+ pub fn new(src: Rect, anchor: Vec2, elevation: f32) -> Self {
+ let relative_dst = FRect::new(
+ anchor.x - (src.w as f32) / 32. / 2.,
+ anchor.y - (src.h as f32) / 24.,
+ (src.w as f32) / 32.,
+ (src.h as f32) / 24.,
+ );
+ Self {
+ z_offset: elevation,
+ src,
+ relative_dst,
+ }
+ }
+ pub fn new_tile(src: Rect) -> Self {
+ Self::new(src, Vec2::new(0.5, 1.0), 0.)
+ }
+ pub fn at(&self, pos: Vec2) -> SpriteDraw {
+ SpriteDraw {
+ z_order: ((self.z_offset + pos.y) * 24.) as i32,
+ src: self.src,
+ dst: FRect::new(
+ self.relative_dst.x + pos.x,
+ self.relative_dst.y + pos.y,
+ self.relative_dst.w,
+ self.relative_dst.h,
+ ),
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct SpriteDraw {
+ pub z_order: i32,
+ pub src: Rect,
+ pub dst: FRect,
+}
+
+impl Ord for SpriteDraw {
+ fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+ self.z_order.cmp(&other.z_order)
+ }
+}
+impl PartialOrd for SpriteDraw {
+ fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+ Some(self.cmp(&other))
+ }
+}
+impl Eq for SpriteDraw {}
+impl PartialEq for SpriteDraw {
+ fn eq(&self, other: &Self) -> bool {
+ self.z_order == other.z_order && self.src == other.src && self.dst == other.dst
+ }
+}
diff --git a/light-client/src/tilemap.rs b/light-client/src/tilemap.rs
index e84db8b1..e7341efa 100644
--- a/light-client/src/tilemap.rs
+++ b/light-client/src/tilemap.rs
@@ -15,15 +15,19 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-use crate::sprite_renderer::SpriteRenderer;
use hurrycurry_protocol::{glam::IVec2, TileIndex};
-use sdl2::rect::{FRect, Rect};
+use sdl2::rect::Rect;
use std::collections::HashMap;
+use crate::render::{
+ sprite::{Sprite, SpriteDraw},
+ SpriteRenderer,
+};
+
#[derive(Default)]
pub struct Tilemap {
tile_srcs: Vec<[Rect; 16]>,
- tiles: HashMap<IVec2, (Rect, FRect)>,
+ tiles: HashMap<IVec2, SpriteDraw>,
}
impl Tilemap {
@@ -72,23 +76,13 @@ impl Tilemap {
idx |= 0b0010 * (Some(tile) == neighbors[3]) as usize;
let src = self.tile_srcs[tile.0][idx];
- self.tiles.insert(
- pos,
- (
- src,
- FRect::new(
- pos.x as f32,
- pos.y as f32 + 1. - src.height() as f32 / 24.,
- src.width() as f32 / 32.,
- src.height() as f32 / 24.,
- ),
- ),
- );
+ self.tiles
+ .insert(pos, Sprite::new_tile(src).at(pos.as_vec2()));
}
pub fn draw(&self, ctx: &mut SpriteRenderer) {
- for &(src, dst) in self.tiles.values() {
- ctx.draw(dst.y + dst.h, src, dst);
+ for &sprite in self.tiles.values() {
+ ctx.draw_world(sprite);
}
}
}