progress
This commit is contained in:
parent
c0ce496ce0
commit
e9c8cdbf48
8 changed files with 340 additions and 37 deletions
|
@ -11,7 +11,8 @@ const vec4 top = vec4(0.5, 0.5, 0.5, 1.0);
|
||||||
const vec4 bot = vec4(0.4, 0.4, 0.4, 1.0);
|
const vec4 bot = vec4(0.4, 0.4, 0.4, 1.0);
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
outcolor = 0.2 * (bot * (1 - pos.y) + top * (1 - pos.x)) + 0.2;
|
outcolor = vec4(0.2 * (0.4 * (1 - pos.y) + 0.5 * (1 - pos.x)) + 0.2);
|
||||||
|
outcolor.w = 1.0;
|
||||||
// if ((pos.x > -threshold && pos.x < threshold)
|
// if ((pos.x > -threshold && pos.x < threshold)
|
||||||
// || (pos.y > -threshold && pos.y < threshold)
|
// || (pos.y > -threshold && pos.y < threshold)
|
||||||
// || (pos.x > 1.0-threshold && pos.x < 1.0+threshold)
|
// || (pos.x > 1.0-threshold && pos.x < 1.0+threshold)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct PlayerData {
|
pub struct PlayerData {
|
||||||
pub position: [u32; 2],
|
pub position: [i32; 2],
|
||||||
pub color: [u32; 3],
|
pub color: [u32; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@ pub struct PlayerData {
|
||||||
pub struct BlockData {
|
pub struct BlockData {
|
||||||
pub movable: bool,
|
pub movable: bool,
|
||||||
pub orientation: u32,
|
pub orientation: u32,
|
||||||
pub position: [u32; 2],
|
pub position: [i32; 2],
|
||||||
pub color: [u32; 3],
|
pub color: [u32; 3],
|
||||||
pub segments: Vec<[u32; 4]>,
|
pub segments: Vec<[i32; 4]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
|
47
src/enums.rs
47
src/enums.rs
|
@ -1,11 +1,13 @@
|
||||||
#[derive(Copy, Clone)]
|
use std::ops::Add;
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Hash, PartialOrd, Copy, Clone)]
|
||||||
pub enum Board {
|
pub enum Board {
|
||||||
Left = 0,
|
Left = 0,
|
||||||
Right = 1,
|
Right = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u32> for Board {
|
impl From<i32> for Board {
|
||||||
fn from(n: u32) -> Self {
|
fn from(n: i32) -> Self {
|
||||||
match n {
|
match n {
|
||||||
0 => Board::Left,
|
0 => Board::Left,
|
||||||
1 => Board::Right,
|
1 => Board::Right,
|
||||||
|
@ -40,7 +42,27 @@ pub enum PushDir {
|
||||||
Right,
|
Right,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
impl PushDir {
|
||||||
|
pub fn as_pair(&self) -> (i32, i32) {
|
||||||
|
match self {
|
||||||
|
PushDir::Up => (0, -1),
|
||||||
|
PushDir::Down => (0, 1),
|
||||||
|
PushDir::Left => (-1, 0),
|
||||||
|
PushDir::Right => (1, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<PushDir> for (i32, i32, Board) {
|
||||||
|
type Output = (i32, i32, Board);
|
||||||
|
|
||||||
|
fn add(self, rhs: PushDir) -> Self::Output {
|
||||||
|
let offset = rhs.as_pair();
|
||||||
|
(self.0 + offset.0, self.1 + offset.1, self.2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialOrd, PartialEq)]
|
||||||
pub enum Shape {
|
pub enum Shape {
|
||||||
Full = 0,
|
Full = 0,
|
||||||
TopRight = 1,
|
TopRight = 1,
|
||||||
|
@ -49,8 +71,8 @@ pub enum Shape {
|
||||||
BottomRight = 4,
|
BottomRight = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u32> for Shape {
|
impl From<i32> for Shape {
|
||||||
fn from(n: u32) -> Self {
|
fn from(n: i32) -> Self {
|
||||||
match n {
|
match n {
|
||||||
0 => Shape::Full,
|
0 => Shape::Full,
|
||||||
1 => Shape::TopRight,
|
1 => Shape::TopRight,
|
||||||
|
@ -61,3 +83,16 @@ impl From<u32> for Shape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Shape {
|
||||||
|
pub fn is_opposite(&self, other: &Shape) -> bool {
|
||||||
|
use Shape::*;
|
||||||
|
match (self, other) {
|
||||||
|
(TopRight, BottomLeft)
|
||||||
|
| (BottomLeft, TopRight)
|
||||||
|
| (TopLeft, BottomRight)
|
||||||
|
| (BottomRight, TopLeft) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
58
src/game.rs
58
src/game.rs
|
@ -1,7 +1,10 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use glium::glutin::{ElementState, Event, VirtualKeyCode, WindowEvent};
|
||||||
use glium::{Display, Frame};
|
use glium::{Display, Frame};
|
||||||
|
|
||||||
|
use crate::enums::PushDir;
|
||||||
use crate::level::Level;
|
use crate::level::Level;
|
||||||
use crate::renderer::Renderer;
|
use crate::renderer::Renderer;
|
||||||
use crate::resources::Resources;
|
use crate::resources::Resources;
|
||||||
|
@ -20,6 +23,7 @@ pub struct Game<'a> {
|
||||||
pub display: &'a Display,
|
pub display: &'a Display,
|
||||||
levels: Vec<Level>,
|
levels: Vec<Level>,
|
||||||
current_level: usize,
|
current_level: usize,
|
||||||
|
keymap: HashMap<VirtualKeyCode, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Game<'a> {
|
impl<'a> Game<'a> {
|
||||||
|
@ -41,6 +45,26 @@ impl<'a> Game<'a> {
|
||||||
display,
|
display,
|
||||||
levels,
|
levels,
|
||||||
current_level: 0,
|
current_level: 0,
|
||||||
|
keymap: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_event(&mut self, event: Event) {
|
||||||
|
match event {
|
||||||
|
Event::WindowEvent { event, .. } => match event {
|
||||||
|
WindowEvent::Resized(size) => self.resources.window_dimensions = size.into(),
|
||||||
|
WindowEvent::KeyboardInput { input, .. } => {
|
||||||
|
if let Some(code) = &input.virtual_keycode {
|
||||||
|
if let ElementState::Pressed = &input.state {
|
||||||
|
self.keymap.insert(*code, true);
|
||||||
|
} else {
|
||||||
|
self.keymap.insert(*code, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +76,39 @@ impl<'a> Game<'a> {
|
||||||
self.levels.iter().nth(self.current_level).unwrap()
|
self.levels.iter().nth(self.current_level).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, delta: Duration) {}
|
pub fn get_current_level_mut(&mut self) -> &mut Level {
|
||||||
|
self.levels.iter_mut().nth(self.current_level).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_pressed(&self, code: &VirtualKeyCode) -> bool {
|
||||||
|
if let Some(true) = self.keymap.get(code) {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self, delta: Duration) {
|
||||||
|
macro_rules! shit {
|
||||||
|
($key:expr, $player:expr, $movement:expr) => {
|
||||||
|
if self.is_pressed(&$key) {
|
||||||
|
let mut level = self.get_current_level_mut();
|
||||||
|
level.handle_movement($player, $movement);
|
||||||
|
self.keymap.insert($key, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
shit!(VirtualKeyCode::W, true, PushDir::Up);
|
||||||
|
shit!(VirtualKeyCode::A, true, PushDir::Left);
|
||||||
|
shit!(VirtualKeyCode::S, true, PushDir::Down);
|
||||||
|
shit!(VirtualKeyCode::D, true, PushDir::Right);
|
||||||
|
|
||||||
|
shit!(VirtualKeyCode::I, false, PushDir::Up);
|
||||||
|
shit!(VirtualKeyCode::J, false, PushDir::Left);
|
||||||
|
shit!(VirtualKeyCode::K, false, PushDir::Down);
|
||||||
|
shit!(VirtualKeyCode::L, false, PushDir::Right);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render(&self, renderer: &mut Renderer) {
|
pub fn render(&self, renderer: &mut Renderer) {
|
||||||
let level = self.get_current_level();
|
let level = self.get_current_level();
|
||||||
|
|
223
src/level.rs
223
src/level.rs
|
@ -1,26 +1,35 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
use crate::data::LevelData;
|
use crate::data::LevelData;
|
||||||
use crate::enums::{Board, Orientation, Shape};
|
use crate::enums::{Board, Orientation, PushDir, Shape};
|
||||||
use crate::renderer::Renderer;
|
use crate::renderer::Renderer;
|
||||||
use crate::{GAME_HEIGHT, GAME_WIDTH};
|
|
||||||
|
|
||||||
pub struct Level {
|
pub struct Level {
|
||||||
dimensions: (u32, u32),
|
dimensions: (u32, u32),
|
||||||
move_stack: VecDeque<()>,
|
move_stack: VecDeque<()>,
|
||||||
|
cell_map: CellMap,
|
||||||
blocks: Vec<Block>,
|
blocks: Vec<Block>,
|
||||||
|
player1: Player,
|
||||||
|
player2: Player,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
position: (u32, u32),
|
movable: bool,
|
||||||
|
position: (i32, i32),
|
||||||
color: (f32, f32, f32),
|
color: (f32, f32, f32),
|
||||||
orientation: Orientation,
|
orientation: Orientation,
|
||||||
segments: Vec<Segment>,
|
segments: Vec<Segment>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialOrd, PartialEq)]
|
||||||
|
pub struct Segment(i32, i32, Shape, Board);
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Segment(u32, u32, Shape, Board);
|
pub struct Player {
|
||||||
|
pub position: [i32; 2],
|
||||||
|
pub color: [u32; 3],
|
||||||
|
}
|
||||||
|
|
||||||
impl Level {
|
impl Level {
|
||||||
pub fn from_json(data: impl AsRef<str>) -> Level {
|
pub fn from_json(data: impl AsRef<str>) -> Level {
|
||||||
|
@ -31,6 +40,7 @@ impl Level {
|
||||||
.blocks
|
.blocks
|
||||||
.iter()
|
.iter()
|
||||||
.map(|block| {
|
.map(|block| {
|
||||||
|
let movable = block.movable;
|
||||||
let position = (block.position[0], block.position[1]);
|
let position = (block.position[0], block.position[1]);
|
||||||
let segments = block
|
let segments = block
|
||||||
.segments
|
.segments
|
||||||
|
@ -46,6 +56,7 @@ impl Level {
|
||||||
block.color[2] as f32 / 256.0,
|
block.color[2] as f32 / 256.0,
|
||||||
);
|
);
|
||||||
Block {
|
Block {
|
||||||
|
movable,
|
||||||
position,
|
position,
|
||||||
color,
|
color,
|
||||||
segments,
|
segments,
|
||||||
|
@ -54,40 +65,138 @@ impl Level {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let player1 = Player {
|
||||||
|
position: data.player1.position,
|
||||||
|
color: data.player1.color,
|
||||||
|
};
|
||||||
|
let player2 = Player {
|
||||||
|
position: data.player2.position,
|
||||||
|
color: data.player2.color,
|
||||||
|
};
|
||||||
|
|
||||||
Level {
|
Level {
|
||||||
dimensions: (data.dimensions[0], data.dimensions[1]),
|
dimensions: (data.dimensions[0], data.dimensions[1]),
|
||||||
move_stack: VecDeque::new(),
|
move_stack: VecDeque::new(),
|
||||||
|
cell_map: CellMap::new(),
|
||||||
blocks,
|
blocks,
|
||||||
|
player1,
|
||||||
|
player2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// player1: true -> player1, false -> player2
|
||||||
|
// TODO: don't use a boolean here
|
||||||
|
pub fn handle_movement(&mut self, player1: bool, direction: PushDir) -> bool {
|
||||||
|
let mut player = if player1 {
|
||||||
|
&self.player1
|
||||||
|
} else {
|
||||||
|
&self.player2
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: check out of bounds
|
||||||
|
let movement = direction.as_pair();
|
||||||
|
let x = player.position[0] + movement.0;
|
||||||
|
let y = player.position[1] + movement.1;
|
||||||
|
|
||||||
|
let result = self.can_move(player1, direction).clone();
|
||||||
|
let mut player = if player1 {
|
||||||
|
&mut self.player1
|
||||||
|
} else {
|
||||||
|
&mut self.player2
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(_) = result {
|
||||||
|
player.position[0] = x;
|
||||||
|
player.position[1] = y;
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: don't use a boolean here
|
||||||
|
pub fn can_move(&self, player1: bool, direction: PushDir) -> Option<()> {
|
||||||
|
// an absolute segment (as opposed to relative to a block)
|
||||||
|
#[derive(Copy, Clone, PartialOrd, PartialEq)]
|
||||||
|
struct ASegment(i32, i32, Shape, Board);
|
||||||
|
|
||||||
|
fn can_push(src: Segment, dst: Segment) -> bool {
|
||||||
|
if src.3 != dst.3 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
let player = if player1 {
|
||||||
|
(
|
||||||
|
self.player1.position[0],
|
||||||
|
self.player1.position[1],
|
||||||
|
Board::Left,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
self.player2.position[0],
|
||||||
|
self.player2.position[1],
|
||||||
|
Board::Right,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// check to make sure that the player isn't trying to go out of bounds
|
||||||
|
let target = player + direction;
|
||||||
|
if target.0 < 0
|
||||||
|
|| target.0 >= self.dimensions.0 as i32
|
||||||
|
|| target.1 < 0
|
||||||
|
|| target.1 >= self.dimensions.1 as i32
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we're sharing a triangle cell
|
||||||
|
if let CellContents::Double(a, b) = self.cell_map.get(player) {}
|
||||||
|
|
||||||
|
// 08/06 pickup
|
||||||
|
// need to determine whether or not segment should hold a reference back to block or not?
|
||||||
|
// either way, segment in the cellmap should hold block information
|
||||||
|
// maybe cellmap should just carry a block index? seems hacky
|
||||||
|
// using refs to manage the whole thing is messy and probably doesn't work
|
||||||
|
// ???
|
||||||
|
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render(&self, renderer: &mut Renderer) {
|
pub fn render(&self, renderer: &mut Renderer) {
|
||||||
let playfield_ratio = (2 * self.dimensions.0 + 6) as f64 / (self.dimensions.1 + 4) as f64;
|
// board positioning calculations
|
||||||
let screen_ratio = GAME_WIDTH as f64 / GAME_HEIGHT as f64;
|
let playfield_ratio = (2 * self.dimensions.0 + 6) as f32 / (self.dimensions.1 + 4) as f32;
|
||||||
|
let screen_ratio = renderer.window.0 / renderer.window.1;
|
||||||
|
|
||||||
|
let cols = self.dimensions.0 as i32;
|
||||||
|
let rows = self.dimensions.1 as i32;
|
||||||
|
|
||||||
let (scale, xoff, yoff) = if playfield_ratio > screen_ratio {
|
let (scale, xoff, yoff) = if playfield_ratio > screen_ratio {
|
||||||
let scale = GAME_WIDTH / (2 * self.dimensions.0 + 6);
|
let scale = renderer.window.0 as i32 / (2 * cols + 6);
|
||||||
let yoff = GAME_HEIGHT / 2 - (self.dimensions.1 + 4) * scale / 2;
|
let yoff = renderer.window.1 as i32 / 2 - (rows + 4) * scale / 2;
|
||||||
(scale, 0, yoff)
|
(scale, 0, yoff)
|
||||||
} else {
|
} else {
|
||||||
let scale = GAME_HEIGHT / (self.dimensions.1 + 4);
|
let scale = renderer.window.1 as i32 / (rows + 4);
|
||||||
let xoff = GAME_WIDTH / 2 - (2 * self.dimensions.0 + 6) * scale / 2;
|
let xoff = renderer.window.0 as i32 / 2 - (2 * cols + 6) * scale / 2;
|
||||||
(scale, xoff, 0)
|
(scale, xoff, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.render_boards(renderer, scale, (xoff, yoff));
|
self.render_boards(renderer, scale, (xoff, yoff));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_boards(&self, renderer: &mut Renderer, scale: u32, offset: (u32, u32)) {
|
fn render_boards(&self, renderer: &mut Renderer, scale: i32, offset: (i32, i32)) {
|
||||||
let left_off = (offset.0 + 2 * scale, offset.1 + 2 * scale);
|
let left_off = (offset.0 + 2 * scale, offset.1 + 2 * scale);
|
||||||
let right_off = (
|
let right_off = (
|
||||||
offset.0 + (4 + self.dimensions.0) * scale,
|
offset.0 + (4 + self.dimensions.0 as i32) * scale,
|
||||||
offset.1 + 2 * scale,
|
offset.1 + 2 * scale,
|
||||||
);
|
);
|
||||||
|
|
||||||
// render the grid
|
// render the grid
|
||||||
for x in 0..self.dimensions.0 {
|
// TODO: do this in one single pass instead of once for each cell
|
||||||
for y in 0..self.dimensions.1 {
|
for x in 0..self.dimensions.0 as i32 {
|
||||||
|
for y in 0..self.dimensions.1 as i32 {
|
||||||
renderer.render_cell((left_off.0 + x * scale, left_off.1 + y * scale), scale);
|
renderer.render_cell((left_off.0 + x * scale, left_off.1 + y * scale), scale);
|
||||||
renderer.render_cell((right_off.0 + x * scale, right_off.1 + y * scale), scale);
|
renderer.render_cell((right_off.0 + x * scale, right_off.1 + y * scale), scale);
|
||||||
}
|
}
|
||||||
|
@ -105,5 +214,89 @@ impl Level {
|
||||||
renderer.render_segment(location, scale, block.color, block.orientation, segment.2);
|
renderer.render_segment(location, scale, block.color, block.orientation, segment.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// render player
|
||||||
|
self.render_player(renderer, &self.player1, scale, left_off);
|
||||||
|
self.render_player(renderer, &self.player2, scale, right_off);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_player(
|
||||||
|
&self,
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
player: &Player,
|
||||||
|
scale: i32,
|
||||||
|
offset: (i32, i32),
|
||||||
|
) {
|
||||||
|
let location = (
|
||||||
|
offset.0 + player.position[0] * scale + 4,
|
||||||
|
offset.1 + player.position[1] * scale + 4,
|
||||||
|
);
|
||||||
|
renderer.render_segment(
|
||||||
|
location,
|
||||||
|
(scale - 8),
|
||||||
|
(
|
||||||
|
player.color[0] as f32,
|
||||||
|
player.color[1] as f32,
|
||||||
|
player.color[2] as f32,
|
||||||
|
),
|
||||||
|
Orientation::Both,
|
||||||
|
Shape::Full,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CellMap(HashMap<(i32, i32, Board), CellContents>);
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
enum CellContents {
|
||||||
|
Empty,
|
||||||
|
Player,
|
||||||
|
Single(Segment),
|
||||||
|
|
||||||
|
// invariant: .0 < .1
|
||||||
|
Double(Segment, Segment),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CellMap {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
CellMap(HashMap::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, loc: (i32, i32, Board)) -> CellContents {
|
||||||
|
self.0
|
||||||
|
.get(&loc)
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(|| CellContents::Empty)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self, loc: (i32, i32, Board)) {
|
||||||
|
self.0.remove(&loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, loc: (i32, i32, Board), segment: &Segment) -> bool {
|
||||||
|
let contents = self.get(loc).clone();
|
||||||
|
match contents {
|
||||||
|
CellContents::Empty => {
|
||||||
|
// just add it like normal
|
||||||
|
self.0.insert(loc, CellContents::Single(*segment));
|
||||||
|
true
|
||||||
|
}
|
||||||
|
CellContents::Single(existing) => {
|
||||||
|
if existing.2.is_opposite(&segment.2) {
|
||||||
|
self.0.insert(
|
||||||
|
loc,
|
||||||
|
if *segment < existing {
|
||||||
|
CellContents::Double(*segment, existing)
|
||||||
|
} else {
|
||||||
|
CellContents::Double(existing, *segment)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CellContents::Player | CellContents::Double(_, _) => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ fn main() {
|
||||||
println!("size: {:?}", window.get_inner_size());
|
println!("size: {:?}", window.get_inner_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
let game = Game::new(&display);
|
let mut game = Game::new(&display);
|
||||||
|
|
||||||
let mut closed = false;
|
let mut closed = false;
|
||||||
let mut prev = Instant::now();
|
let mut prev = Instant::now();
|
||||||
|
@ -54,9 +54,11 @@ fn main() {
|
||||||
event: WindowEvent::CloseRequested,
|
event: WindowEvent::CloseRequested,
|
||||||
..
|
..
|
||||||
} => closed = true,
|
} => closed = true,
|
||||||
_ => (),
|
_ => game.handle_event(event),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
game.update(delta);
|
||||||
|
|
||||||
let mut target = display.draw();
|
let mut target = display.draw();
|
||||||
target.clear(None, Some((0.0, 0.0, 0.0, 1.0)), true, None, None);
|
target.clear(None, Some((0.0, 0.0, 0.0, 1.0)), true, None, None);
|
||||||
let mut renderer = game.create_renderer(&mut target);
|
let mut renderer = game.create_renderer(&mut target);
|
||||||
|
|
|
@ -5,9 +5,9 @@ use nalgebra::{Matrix4, Vector4};
|
||||||
|
|
||||||
use crate::enums::{Orientation, Shape};
|
use crate::enums::{Orientation, Shape};
|
||||||
use crate::game::Game;
|
use crate::game::Game;
|
||||||
use crate::{GAME_HEIGHT, GAME_WIDTH};
|
|
||||||
|
|
||||||
pub struct Renderer<'a, 'b> {
|
pub struct Renderer<'a, 'b> {
|
||||||
|
pub window: (f32, f32),
|
||||||
target: &'a mut Frame,
|
target: &'a mut Frame,
|
||||||
display: &'b Display,
|
display: &'b Display,
|
||||||
cell_program: &'b Program,
|
cell_program: &'b Program,
|
||||||
|
@ -18,6 +18,10 @@ pub struct Renderer<'a, 'b> {
|
||||||
impl<'a, 'b> Renderer<'a, 'b> {
|
impl<'a, 'b> Renderer<'a, 'b> {
|
||||||
pub fn new(game: &'b Game, target: &'a mut Frame) -> Self {
|
pub fn new(game: &'b Game, target: &'a mut Frame) -> Self {
|
||||||
Renderer {
|
Renderer {
|
||||||
|
window: (
|
||||||
|
game.resources.window_dimensions.0 as f32,
|
||||||
|
game.resources.window_dimensions.1 as f32,
|
||||||
|
),
|
||||||
target,
|
target,
|
||||||
display: &game.display,
|
display: &game.display,
|
||||||
cell_program: game.resources.get_shader("cell").unwrap(),
|
cell_program: game.resources.get_shader("cell").unwrap(),
|
||||||
|
@ -26,7 +30,7 @@ impl<'a, 'b> Renderer<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_cell(&mut self, location: (u32, u32), scale: u32) {
|
pub fn render_cell(&mut self, location: (i32, i32), scale: i32) {
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
point: [f32; 2],
|
point: [f32; 2],
|
||||||
|
@ -43,8 +47,14 @@ impl<'a, 'b> Renderer<'a, 'b> {
|
||||||
vertices.push(Vertex { point: [1.0, 0.0] });
|
vertices.push(Vertex { point: [1.0, 0.0] });
|
||||||
let vertex_buffer = VertexBuffer::new(self.display, &vertices).unwrap();
|
let vertex_buffer = VertexBuffer::new(self.display, &vertices).unwrap();
|
||||||
|
|
||||||
let projection =
|
let projection = glm::ortho::<f32>(
|
||||||
glm::ortho::<f32>(0.0, GAME_WIDTH as f32, GAME_HEIGHT as f32, 0.0, -1.0, 1.0);
|
0.0,
|
||||||
|
self.window.0 as f32,
|
||||||
|
self.window.1 as f32,
|
||||||
|
0.0,
|
||||||
|
-1.0,
|
||||||
|
1.0,
|
||||||
|
);
|
||||||
let mut matrix = Matrix4::<f32>::identity();
|
let mut matrix = Matrix4::<f32>::identity();
|
||||||
matrix = matrix.append_nonuniform_scaling(&[scale as f32, scale as f32, 1.0].into());
|
matrix = matrix.append_nonuniform_scaling(&[scale as f32, scale as f32, 1.0].into());
|
||||||
matrix = matrix.append_translation(&[location.0 as f32, location.1 as f32, 0.0].into());
|
matrix = matrix.append_translation(&[location.0 as f32, location.1 as f32, 0.0].into());
|
||||||
|
@ -73,8 +83,8 @@ impl<'a, 'b> Renderer<'a, 'b> {
|
||||||
|
|
||||||
pub fn render_segment(
|
pub fn render_segment(
|
||||||
&mut self,
|
&mut self,
|
||||||
location: (u32, u32),
|
location: (i32, i32),
|
||||||
scale: u32,
|
scale: i32,
|
||||||
color: (f32, f32, f32),
|
color: (f32, f32, f32),
|
||||||
orientation: Orientation,
|
orientation: Orientation,
|
||||||
shape: Shape,
|
shape: Shape,
|
||||||
|
@ -175,8 +185,14 @@ impl<'a, 'b> Renderer<'a, 'b> {
|
||||||
let vertex_buffer = VertexBuffer::new(self.display, &vertices).unwrap();
|
let vertex_buffer = VertexBuffer::new(self.display, &vertices).unwrap();
|
||||||
let tint = Vector4::from([color.0, color.1, color.2, 1.0f32]);
|
let tint = Vector4::from([color.0, color.1, color.2, 1.0f32]);
|
||||||
|
|
||||||
let projection =
|
let projection = glm::ortho::<f32>(
|
||||||
glm::ortho::<f32>(0.0, GAME_WIDTH as f32, GAME_HEIGHT as f32, 0.0, -1.0, 1.0);
|
0.0,
|
||||||
|
self.window.0 as f32,
|
||||||
|
self.window.1 as f32,
|
||||||
|
0.0,
|
||||||
|
-1.0,
|
||||||
|
1.0,
|
||||||
|
);
|
||||||
let mut matrix = Matrix4::<f32>::identity();
|
let mut matrix = Matrix4::<f32>::identity();
|
||||||
matrix = matrix.append_nonuniform_scaling(&[scale as f32, scale as f32, 1.0].into());
|
matrix = matrix.append_nonuniform_scaling(&[scale as f32, scale as f32, 1.0].into());
|
||||||
matrix = matrix.append_translation(&[location.0 as f32, location.1 as f32, 0.0].into());
|
matrix = matrix.append_translation(&[location.0 as f32, location.1 as f32, 0.0].into());
|
||||||
|
|
Loading…
Reference in a new issue