interpolator
This commit is contained in:
parent
74fa53a30a
commit
c64d698e04
Binary file not shown.
After Width: | Height: | Size: 1.4 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
src/main.rs
20
src/main.rs
|
@ -1,5 +1,8 @@
|
||||||
|
#![feature(div_duration)]
|
||||||
|
|
||||||
mod unit_kind;
|
mod unit_kind;
|
||||||
mod unit;
|
mod unit;
|
||||||
|
mod interpolator;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -32,20 +35,22 @@ impl Game {
|
||||||
pub fn tick(&mut self, window_state: &mut WindowState) {
|
pub fn tick(&mut self, window_state: &mut WindowState) {
|
||||||
window_state.log(format!("tick: {}", self.current_tick).as_str());
|
window_state.log(format!("tick: {}", self.current_tick).as_str());
|
||||||
|
|
||||||
self.unit.borrow_mut().pos.y = self.current_tick % self.map.size().y;
|
self.unit.borrow_mut().set_pos(Vec2{x: 5, y: self.current_tick % self.map.size().y});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl skunk2d::Game for Game {
|
impl skunk2d::Game for Game {
|
||||||
fn new(window_state: &mut WindowState) -> Self {
|
fn new(window_state: &mut WindowState) -> Self {
|
||||||
setup_palette(window_state);
|
setup_palette(window_state);
|
||||||
let tileset = Tileset::load("assets/hex2.gif", Vec2{x: 2, y: 1});
|
window_state.scramble_palette();
|
||||||
let kind = UnitKind::new("bob");
|
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", 1, tick_duration);
|
||||||
Game {
|
Game {
|
||||||
map: HexMap::new(Vec2{x: 11, y: 11}, tileset, Vec2{ x: 23, y: 13 }),
|
map: HexMap::new(Vec2{x: 26, y: 22}, tileset, Vec2{ x: 72, y: 24 }),
|
||||||
unit: kind.spawn(Vec2{x: 5, y: 5}),
|
unit: kind.spawn(Vec2{x: 5, y: 5}),
|
||||||
last_tick: Instant::now(),
|
last_tick: Instant::now(),
|
||||||
tick_duration: Duration::from_secs(1) / 10,
|
tick_duration,
|
||||||
current_tick: 0
|
current_tick: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,12 +67,13 @@ impl skunk2d::Game for Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, target: &mut Image) {
|
fn draw(&self, target: &mut Image) {
|
||||||
|
let now = Instant::now();
|
||||||
target.clear();
|
target.clear();
|
||||||
target.draw_hexmap(Vec2::zero(), &self.map);
|
target.draw_hexmap(Vec2::zero(), &self.map);
|
||||||
self.unit.borrow().draw(target, &self.map);
|
self.unit.borrow().draw(target, &self.map, now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
run::<Game>(640, 360);
|
run::<Game>(1920, 1080);
|
||||||
}
|
}
|
||||||
|
|
24
src/unit.rs
24
src/unit.rs
|
@ -1,14 +1,32 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::time::Instant;
|
||||||
use skunk2d::{HexMap, Image, Vec2};
|
use skunk2d::{HexMap, Image, Vec2};
|
||||||
|
use crate::interpolator::Interpolator;
|
||||||
use crate::unit_kind::UnitKind;
|
use crate::unit_kind::UnitKind;
|
||||||
|
|
||||||
pub struct Unit {
|
pub struct Unit {
|
||||||
pub kind: Rc<UnitKind>,
|
pub kind: Rc<UnitKind>,
|
||||||
pub pos: Vec2<i32>
|
pub pos: Vec2<i32>,
|
||||||
|
pub interpolator: Interpolator,
|
||||||
|
pub old_pos: Vec2<i32>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Unit {
|
impl Unit {
|
||||||
pub fn draw(&self, target: &mut Image, map: &HexMap) {
|
pub fn draw(&self, target: &mut Image, map: &HexMap, time: Instant) {
|
||||||
target.draw_image( map.coord_to_pixel(self.pos), &self.kind.sprite);
|
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 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,25 +1,34 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::ops::Mul;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::time::Duration;
|
||||||
use skunk2d::{Image, Vec2};
|
use skunk2d::{Image, Vec2};
|
||||||
|
use crate::interpolator::Interpolator;
|
||||||
use crate::unit::Unit;
|
use crate::unit::Unit;
|
||||||
|
|
||||||
pub struct UnitKind {
|
pub struct UnitKind {
|
||||||
pub sprite: Rc<Image>,
|
pub sprite: Rc<Image>,
|
||||||
pub name: String
|
pub name: String,
|
||||||
|
pub speed: i32,
|
||||||
|
pub movement_duration: Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnitKind {
|
impl UnitKind {
|
||||||
pub fn new(name: &str) -> Rc<Self> {
|
pub fn new(name: &str, speed: i32, tick_duration: Duration) -> Rc<Self> {
|
||||||
UnitKind {
|
UnitKind {
|
||||||
sprite: Image::load(format!("assets/units/{}.gif", name).as_str()),
|
sprite: Image::load(format!("assets/units/{}.gif", name).as_str()),
|
||||||
name: name.into()
|
name: name.into(),
|
||||||
|
speed,
|
||||||
|
movement_duration: tick_duration.mul(speed as u32)
|
||||||
}.into()
|
}.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn(self: Rc<Self>, pos: Vec2<i32>) -> Rc<RefCell<Unit>> {
|
pub fn spawn(self: Rc<Self>, pos: Vec2<i32>) -> Rc<RefCell<Unit>> {
|
||||||
RefCell::new(Unit {
|
RefCell::new(Unit {
|
||||||
kind: self,
|
kind: self,
|
||||||
pos
|
pos,
|
||||||
|
interpolator: Interpolator::fake(),
|
||||||
|
old_pos: pos
|
||||||
}).into()
|
}).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue