Compare commits
No commits in common. "master" and "skunk2d" have entirely different histories.
File diff suppressed because it is too large
Load Diff
|
@ -6,4 +6,5 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
skunk2d = {path = "../skunk2d"}
|
||||
rand = "0.8.5"
|
Binary file not shown.
After Width: | Height: | Size: 1001 B |
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 910 B |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1 @@
|
|||
ŚŠŚüţü¤˘¤”–”DBD¬®¬”’”|~|\Z\śžś´˛´ŚŽŚ¤¦¤
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "nightly"
|
|
@ -0,0 +1,42 @@
|
|||
use std::time::{Duration, Instant};
|
||||
use skunk2d::Vec2;
|
||||
|
||||
pub struct Interpolator {
|
||||
start: Instant,
|
||||
end: Instant,
|
||||
length: Duration
|
||||
}
|
||||
|
||||
impl Interpolator {
|
||||
pub fn new(start: Instant, length: Duration) -> Self {
|
||||
Interpolator {
|
||||
start,
|
||||
end: start + length,
|
||||
length
|
||||
}
|
||||
}
|
||||
|
||||
//interpolator that will always return 1.0f64
|
||||
pub fn fake() -> Self {
|
||||
//ugly <_<
|
||||
let meh = Instant::now() - Duration::from_secs(100);
|
||||
Interpolator::new(meh, Duration::from_secs(1))
|
||||
}
|
||||
|
||||
pub fn get(&self, pos: Instant) -> f64 {
|
||||
(pos - self.start).div_duration_f64(self.length).max(0f64).min(1f64)
|
||||
}
|
||||
|
||||
pub fn apply_vec2(&self, pos: Instant, v1: Vec2<i32>, v2: Vec2<i32>) -> Vec2<i32> {
|
||||
let p = self.get(pos);
|
||||
let delta = v2 - v1;
|
||||
if delta.x.abs() > 100 || delta.y.abs() > 100 {
|
||||
v2
|
||||
} else {
|
||||
Vec2 {
|
||||
x: (v1.x as f64 + delta.x as f64 * p).round() as i32,
|
||||
y: (v1.y as f64 + delta.y as f64 * p).round() as i32
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
90
src/main.rs
90
src/main.rs
|
@ -1,3 +1,89 @@
|
|||
fn main() {
|
||||
println!("Hello World nyaa");
|
||||
#![feature(div_duration)]
|
||||
|
||||
mod unit_kind;
|
||||
mod unit;
|
||||
mod interpolator;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::time::{Duration, Instant};
|
||||
use rand::Rng;
|
||||
use skunk2d::{Direction, Event, HexMap, Image, run, Tileset, Vec2, WindowState};
|
||||
use crate::unit::Unit;
|
||||
use crate::unit_kind::UnitKind;
|
||||
|
||||
//todo: keep unit_map position and unit's position in sync... how?
|
||||
|
||||
struct Game {
|
||||
map: HexMap,
|
||||
unit_map: Vec<Option<Rc<RefCell<Unit>>>>,
|
||||
unit: Rc<RefCell<Unit>>,
|
||||
last_tick: Instant,
|
||||
tick_duration: Duration,
|
||||
current_tick: i32,
|
||||
}
|
||||
|
||||
fn setup_palette(ws: &mut WindowState) {
|
||||
ws.set_palette(0, 0xc0, 0xf0, 0xd0);
|
||||
ws.set_palette(2, 0x10, 0x30, 0x20);
|
||||
ws.set_palette(1, 0xb0, 0xe0, 0xc0);
|
||||
ws.set_palette(3, 0xa0, 0xd0, 0xb0);
|
||||
|
||||
ws.set_palette(255, 0xff, 0xff, 0xff);
|
||||
ws.set_palette(254, 0x00, 0x00, 0x00);
|
||||
ws.set_palette(253, 0x80, 0x80, 0x80);
|
||||
|
||||
}
|
||||
|
||||
impl Game {
|
||||
pub fn tick(&mut self, window_state: &mut WindowState) {
|
||||
window_state.log(format!("tick: {}", self.current_tick).as_str());
|
||||
|
||||
let mut unit = self.unit.borrow_mut();
|
||||
unit.cool();
|
||||
unit.move_unit(rand::thread_rng().gen(), &self.map);
|
||||
//unit.set_pos(Vec2{x: 5, y: self.current_tick % self.map.size().y});
|
||||
}
|
||||
}
|
||||
|
||||
impl skunk2d::Game for Game {
|
||||
fn new(window_state: &mut WindowState) -> Self {
|
||||
setup_palette(window_state);
|
||||
window_state.scramble_palette();
|
||||
let tick_duration = Duration::from_secs(1) / 10;
|
||||
let tileset = Tileset::load("assets/hex3.gif", Vec2{x: 1, y: 1});
|
||||
let kind = UnitKind::new("tank", 4, tick_duration);
|
||||
let map = HexMap::new(Vec2{x: 26, y: 22}, tileset, Vec2{ x: 72, y: 24 });
|
||||
let idx_size = map.idx_size();
|
||||
Game {
|
||||
map,
|
||||
unit_map: vec![None; idx_size],
|
||||
unit: kind.spawn(Vec2{x: 5, y: 5}),
|
||||
last_tick: Instant::now(),
|
||||
tick_duration,
|
||||
current_tick: 0
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, window_state: &mut WindowState) {
|
||||
if Instant::now() - self.last_tick >= self.tick_duration {
|
||||
self.tick(window_state);
|
||||
self.last_tick += self.tick_duration;
|
||||
self.current_tick += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn on_event(&mut self, window_state: &mut WindowState, event: Event) {
|
||||
}
|
||||
|
||||
fn draw(&self, target: &mut Image) {
|
||||
let now = Instant::now();
|
||||
target.clear();
|
||||
target.draw_hexmap(Vec2::zero(), &self.map);
|
||||
self.unit.borrow().draw(target, &self.map, now);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
run::<Game>(1920, 1080, 60);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
use std::rc::Rc;
|
||||
use std::time::Instant;
|
||||
use skunk2d::{HexMap, Image, Vec2, Direction};
|
||||
use crate::interpolator::Interpolator;
|
||||
use crate::unit_kind::UnitKind;
|
||||
|
||||
pub struct Unit {
|
||||
pub kind: Rc<UnitKind>,
|
||||
pub pos: Vec2<i32>,
|
||||
pub interpolator: Interpolator,
|
||||
pub old_pos: Vec2<i32>,
|
||||
pub cooldown: i32
|
||||
}
|
||||
|
||||
impl Unit {
|
||||
pub fn cool(&mut self) {
|
||||
self.cooldown = (self.cooldown - 1).max(0)
|
||||
}
|
||||
|
||||
pub fn draw(&self, target: &mut Image, map: &HexMap, time: Instant) {
|
||||
let old_pos = map.coord_to_pixel(self.old_pos);
|
||||
let new_pos = map.coord_to_pixel(self.pos);
|
||||
let pos = self.interpolator.apply_vec2(time, old_pos, new_pos);
|
||||
//todo: don't hardcode offset :P
|
||||
target.draw_image( pos + Vec2{x: 0, y: -24}, &self.kind.sprite);
|
||||
}
|
||||
|
||||
pub fn move_unit(&mut self, dir: Direction, map: &HexMap) {
|
||||
if self.cooldown == 0 {
|
||||
let new_pos = HexMap::get_neighbour(self.pos, dir);
|
||||
if map.is_valid_coord(new_pos) {
|
||||
self.set_pos(new_pos);
|
||||
self.cooldown = self.kind.speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_pos(&mut self, pos: Vec2<i32>) {
|
||||
self.interpolator = Interpolator::new(Instant::now(), self.kind.movement_duration);
|
||||
self.old_pos = self.pos;
|
||||
self.pos = pos;
|
||||
}
|
||||
|
||||
pub fn add_pos(&mut self, pos: Vec2<i32>) {
|
||||
self.set_pos(self.pos + pos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
use std::cell::RefCell;
|
||||
use std::ops::Mul;
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
use skunk2d::{Image, Vec2};
|
||||
use crate::interpolator::Interpolator;
|
||||
use crate::unit::Unit;
|
||||
|
||||
pub struct UnitKind {
|
||||
pub sprite: Rc<Image>,
|
||||
pub name: String,
|
||||
pub speed: i32,
|
||||
pub movement_duration: Duration
|
||||
}
|
||||
|
||||
impl UnitKind {
|
||||
pub fn new(name: &str, speed: i32, tick_duration: Duration) -> Rc<Self> {
|
||||
UnitKind {
|
||||
sprite: Image::load(format!("assets/units/{}.gif", name).as_str()),
|
||||
name: name.into(),
|
||||
speed,
|
||||
movement_duration: tick_duration.mul(speed as u32)
|
||||
}.into()
|
||||
}
|
||||
|
||||
pub fn spawn(self: Rc<Self>, pos: Vec2<i32>) -> Rc<RefCell<Unit>> {
|
||||
RefCell::new(Unit {
|
||||
kind: self,
|
||||
pos,
|
||||
interpolator: Interpolator::fake(),
|
||||
old_pos: pos,
|
||||
cooldown: 0
|
||||
}).into()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue