Resumed to project. INIT

This commit is contained in:
2026-06-17 08:23:13 +02:00
commit fd02ed6d8b
51 changed files with 5067 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
mod pixelhelper;
use crate::assets::Image;
use crate::input::{GameAction, InputState};
use crate::net::{EntityInfo, NetClient, NetEvent};
use shared::{chunk_id, player_action};
pub enum GameSignal {
Quit,
}
pub struct Game {
#[allow(dead_code)]
tileset: Vec<[u8; 64]>,
entity_tileset: Vec<[u8; 64]>,
net: NetClient,
player_entity_id: u32,
player_pos: (i32, i32),
entities: Vec<EntityInfo>,
}
impl Game {
pub fn start() -> Self {
let image = Image::from_tga("assets/tilesets/overworld.tga");
let tileset = image.to_tileset();
let entity_tileset = Image::from_tga("assets/tilesets/entities.tga").to_tileset();
let server_addr = "127.0.0.1:7777".parse().unwrap();
Game {
tileset,
entity_tileset,
net: NetClient::new(server_addr),
player_entity_id: 0,
player_pos: (16, 16),
entities: Vec::new(),
}
}
pub fn update(&mut self, render_frame: &mut [u8], _dt: usize, input: &InputState)
-> Option<GameSignal>
{
if input.button_held(GameAction::Up) { self.net.send_action(player_action::NORTH); }
if input.button_held(GameAction::Down) { self.net.send_action(player_action::SOUTH); }
if input.button_held(GameAction::Left) { self.net.send_action(player_action::WEST); }
if input.button_held(GameAction::Right) { self.net.send_action(player_action::EAST); }
if input.button_pressed(GameAction::Confirm) {
self.net.send_ping();
println!("ping sent");
}
for event in self.net.poll() {
match event {
NetEvent::Pong { rtt_ms } => println!("pong! rtt = {rtt_ms} ms"),
NetEvent::State { tick, player_entity_id } => {
println!("state tick={tick} player_entity_id={player_entity_id}");
self.player_entity_id = player_entity_id;
}
NetEvent::Chunk { chunk_id } => println!("chunk cached id={chunk_id}"),
NetEvent::Entity { entities } => {
self.player_pos = entities.iter()
.find(|e| e.id == self.player_entity_id)
.map(|e| (e.pos_x as i32, e.pos_y as i32))
.unwrap_or(self.player_pos);
self.entities = entities;
}
NetEvent::Disconnected => println!("disconnected from server"),
}
}
if input.button_pressed(GameAction::Cancel) {
println!("Goodbye!");
return Some(GameSignal::Quit);
}
self.render_viewport(render_frame);
None
}
fn render_viewport(&self, frame: &mut [u8]) {
const WALL: u8 = 0x00;
const W: usize = 320;
frame.fill(0);
let ox = self.player_pos.0 - 15;
let oy = self.player_pos.1 - 15;
for vy in 0..30i32 {
for vx in 0..30i32 {
let wx = ox + vx;
let wy = oy + vy;
let cid = chunk_id(wx.div_euclid(32) as i16, wy.div_euclid(32) as i16);
let tile_idx = wy.rem_euclid(32) as usize * 32 + wx.rem_euclid(32) as usize;
let tile_id = self.net.chunk_cache.get(&cid)
.map(|c| c.tiles[tile_idx])
.unwrap_or(0);
let px = vx * 8;
let py = vy * 8;
if let Some(tile) = self.tileset.get(tile_id as usize) {
pixelhelper::blit_tile(frame, W, px, py, tile);
} else {
for dy in 0..8 {
for dx in 0..8 {
pixelhelper::set_pixel(frame, W, px + dx, py + dy, WALL);
}
}
}
}
}
// Entity pass
let ox = self.player_pos.0 - 15;
let oy = self.player_pos.1 - 15;
for e in &self.entities {
let vx = e.pos_x as i32 - ox;
let vy = e.pos_y as i32 - oy;
if vx < 0 || vx >= 30 || vy < 0 || vy >= 30 { continue; }
if let Some(tile) = self.entity_tileset.get(e.type_id as usize) {
pixelhelper::blit_tile(frame, W, vx * 8, vy * 8, tile);
}
}
}
}