huge refactor
This commit is contained in:
parent
e9c8cdbf48
commit
b0ef20ff8b
11 changed files with 278 additions and 139 deletions
|
@ -17,8 +17,8 @@
|
||||||
"position": [1, 3],
|
"position": [1, 3],
|
||||||
"color": [255, 10, 100],
|
"color": [255, 10, 100],
|
||||||
"segments": [
|
"segments": [
|
||||||
[0, 0, 0, 0],
|
[1, 3, 0, 0],
|
||||||
[1, 0, 4, 0],
|
[2, 3, 4, 0],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -27,8 +27,8 @@
|
||||||
"position": [2, 4],
|
"position": [2, 4],
|
||||||
"color": [105, 210, 50],
|
"color": [105, 210, 50],
|
||||||
"segments": [
|
"segments": [
|
||||||
[0, 0, 2, 0],
|
[2, 4, 2, 0],
|
||||||
[0, 1, 0, 0],
|
[2, 5, 0, 0],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -37,8 +37,8 @@
|
||||||
"position": [0, 4],
|
"position": [0, 4],
|
||||||
"color": [35, 150, 100],
|
"color": [35, 150, 100],
|
||||||
"segments": [
|
"segments": [
|
||||||
[0, 0, 1, 1],
|
[0, 4, 1, 1],
|
||||||
[0, 1, 0, 1],
|
[0, 5, 0, 1],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -47,8 +47,8 @@
|
||||||
"position": [0, 3],
|
"position": [0, 3],
|
||||||
"color": [25, 120, 10],
|
"color": [25, 120, 10],
|
||||||
"segments": [
|
"segments": [
|
||||||
[0, 0, 3, 1],
|
[0, 3, 3, 1],
|
||||||
[1, 0, 0, 1],
|
[1, 3, 0, 1],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
"position": [0, 2],
|
"position": [0, 2],
|
||||||
"color": [15, 15, 15],
|
"color": [15, 15, 15],
|
||||||
"segments": [
|
"segments": [
|
||||||
[0, 0, 0, 0],
|
[0, 2, 0, 0],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
"position": [2, 2],
|
"position": [2, 2],
|
||||||
"color": [15, 15, 15],
|
"color": [15, 15, 15],
|
||||||
"segments": [
|
"segments": [
|
||||||
[0, 0, 0, 1],
|
[2, 2, 0, 1],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
14
src/color.rs
Normal file
14
src/color.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct Color(pub f32, pub f32, pub f32, pub f32);
|
||||||
|
|
||||||
|
impl Color {
|
||||||
|
pub fn from_rgb_u32(r: u32, g: u32, b: u32) -> Self {
|
||||||
|
Color(r as f32 / 256.0, g as f32 / 256.0, b as f32 / 256.0, 1.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(u32, u32, u32)> for Color {
|
||||||
|
fn from(tuple: (u32, u32, u32)) -> Self {
|
||||||
|
Color::from_rgb_u32(tuple.0, tuple.1, tuple.2)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,15 @@
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct PlayerData {
|
pub struct PlayerData {
|
||||||
pub position: [i32; 2],
|
pub position: (i32, i32),
|
||||||
pub color: [u32; 3],
|
pub color: (u32, u32, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct BlockData {
|
pub struct BlockData {
|
||||||
pub movable: bool,
|
pub movable: bool,
|
||||||
pub orientation: u32,
|
pub orientation: u32,
|
||||||
pub position: [i32; 2],
|
pub position: (i32, i32),
|
||||||
pub color: [u32; 3],
|
pub color: (u32, u32, u32),
|
||||||
pub segments: Vec<[i32; 4]>,
|
pub segments: Vec<[i32; 4]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
src/enums.rs
18
src/enums.rs
|
@ -1,6 +1,6 @@
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Hash, PartialOrd, Copy, Clone)]
|
#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Copy, Clone)]
|
||||||
pub enum Board {
|
pub enum Board {
|
||||||
Left = 0,
|
Left = 0,
|
||||||
Right = 1,
|
Right = 1,
|
||||||
|
@ -18,9 +18,10 @@ impl From<i32> for Board {
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum Orientation {
|
pub enum Orientation {
|
||||||
Both = 0,
|
None = 0,
|
||||||
Horizontal = 1,
|
Horizontal = 1,
|
||||||
Vertical = 2,
|
Vertical = 2,
|
||||||
|
Both = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u32> for Orientation {
|
impl From<u32> for Orientation {
|
||||||
|
@ -62,7 +63,7 @@ impl Add<PushDir> for (i32, i32, Board) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialOrd, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
|
||||||
pub enum Shape {
|
pub enum Shape {
|
||||||
Full = 0,
|
Full = 0,
|
||||||
TopRight = 1,
|
TopRight = 1,
|
||||||
|
@ -85,6 +86,17 @@ impl From<i32> for Shape {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shape {
|
impl Shape {
|
||||||
|
pub fn opposite(&self) -> Shape {
|
||||||
|
use Shape::*;
|
||||||
|
match self {
|
||||||
|
TopRight => BottomLeft,
|
||||||
|
BottomLeft => TopRight,
|
||||||
|
TopLeft => BottomRight,
|
||||||
|
BottomRight => TopLeft,
|
||||||
|
Full => Full,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_opposite(&self, other: &Shape) -> bool {
|
pub fn is_opposite(&self, other: &Shape) -> bool {
|
||||||
use Shape::*;
|
use Shape::*;
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
|
|
|
@ -92,7 +92,7 @@ impl<'a> Game<'a> {
|
||||||
macro_rules! shit {
|
macro_rules! shit {
|
||||||
($key:expr, $player:expr, $movement:expr) => {
|
($key:expr, $player:expr, $movement:expr) => {
|
||||||
if self.is_pressed(&$key) {
|
if self.is_pressed(&$key) {
|
||||||
let mut level = self.get_current_level_mut();
|
let level = self.get_current_level_mut();
|
||||||
level.handle_movement($player, $movement);
|
level.handle_movement($player, $movement);
|
||||||
self.keymap.insert($key, false);
|
self.keymap.insert($key, false);
|
||||||
}
|
}
|
||||||
|
|
63
src/level/block.rs
Normal file
63
src/level/block.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
use crate::color::Color;
|
||||||
|
use crate::data::BlockData;
|
||||||
|
use crate::enums::Orientation;
|
||||||
|
use crate::level::Segment;
|
||||||
|
|
||||||
|
pub trait Blockish {
|
||||||
|
fn get_color(&self) -> Color;
|
||||||
|
fn get_orientation(&self) -> Orientation;
|
||||||
|
|
||||||
|
// TODO: don't alloc/clone here?
|
||||||
|
fn get_segments(&self) -> Vec<Segment>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Block {
|
||||||
|
movable: bool,
|
||||||
|
position: (i32, i32),
|
||||||
|
color: Color,
|
||||||
|
orientation: Orientation,
|
||||||
|
segments: Vec<Segment>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Block {
|
||||||
|
pub fn from_data(index: usize, data: &BlockData) -> Self {
|
||||||
|
let movable = data.movable;
|
||||||
|
let position = (data.position.0, data.position.1);
|
||||||
|
let segments = data
|
||||||
|
.segments
|
||||||
|
.iter()
|
||||||
|
.map(|segment| {
|
||||||
|
let seg = Segment {
|
||||||
|
position: (segment[0], segment[1]),
|
||||||
|
shape: segment[2].into(),
|
||||||
|
board: segment[3].into(),
|
||||||
|
};
|
||||||
|
seg
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let orientation = data.orientation.into();
|
||||||
|
let color = Color::from_rgb_u32(data.color.0, data.color.1, data.color.2);
|
||||||
|
Block {
|
||||||
|
movable,
|
||||||
|
position,
|
||||||
|
color,
|
||||||
|
segments,
|
||||||
|
orientation,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Blockish for Block {
|
||||||
|
fn get_color(&self) -> Color {
|
||||||
|
self.color
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_orientation(&self) -> Orientation {
|
||||||
|
self.orientation
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_segments(&self) -> Vec<Segment> {
|
||||||
|
self.segments.clone()
|
||||||
|
}
|
||||||
|
}
|
72
src/level/cell_map.rs
Normal file
72
src/level/cell_map.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::enums::Board;
|
||||||
|
use crate::level::Segment;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CellMap(HashMap<(i32, i32, Board), CellContents>);
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub enum CellContents {
|
||||||
|
Empty,
|
||||||
|
Player,
|
||||||
|
Single((usize, Segment)),
|
||||||
|
|
||||||
|
// invariant: .0 < .1
|
||||||
|
Double((usize, Segment), (usize, 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_player(&mut self, loc: (i32, i32, Board)) -> bool {
|
||||||
|
let contents = self.get(loc).clone();
|
||||||
|
match contents {
|
||||||
|
CellContents::Empty => {
|
||||||
|
self.0.insert(loc, CellContents::Player);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, loc: (i32, i32, Board), index: usize, segment: &Segment) -> bool {
|
||||||
|
let contents = self.get(loc).clone();
|
||||||
|
match contents {
|
||||||
|
CellContents::Empty => {
|
||||||
|
// just add it like normal
|
||||||
|
self.0.insert(loc, CellContents::Single((index, *segment)));
|
||||||
|
true
|
||||||
|
}
|
||||||
|
CellContents::Single((index0, existing)) => {
|
||||||
|
if existing.shape.is_opposite(&segment.shape) {
|
||||||
|
self.0.insert(
|
||||||
|
loc,
|
||||||
|
if *segment < existing {
|
||||||
|
CellContents::Double((index, *segment), (index0, existing))
|
||||||
|
} else {
|
||||||
|
CellContents::Double((index0, existing), (index, *segment))
|
||||||
|
},
|
||||||
|
);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CellContents::Player | CellContents::Double(_, _) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,18 @@
|
||||||
|
mod block;
|
||||||
|
mod cell_map;
|
||||||
|
mod player;
|
||||||
|
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
|
use crate::color::Color;
|
||||||
use crate::data::LevelData;
|
use crate::data::LevelData;
|
||||||
use crate::enums::{Board, Orientation, PushDir, Shape};
|
use crate::enums::{Board, Orientation, PushDir, Shape};
|
||||||
use crate::renderer::Renderer;
|
use crate::renderer::Renderer;
|
||||||
|
|
||||||
|
use self::block::{Block, Blockish};
|
||||||
|
use self::cell_map::{CellContents, CellMap};
|
||||||
|
use self::player::Player;
|
||||||
|
|
||||||
pub struct Level {
|
pub struct Level {
|
||||||
dimensions: (u32, u32),
|
dimensions: (u32, u32),
|
||||||
move_stack: VecDeque<()>,
|
move_stack: VecDeque<()>,
|
||||||
|
@ -13,22 +22,11 @@ pub struct Level {
|
||||||
player2: Player,
|
player2: Player,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
|
||||||
pub struct Block {
|
pub struct Segment {
|
||||||
movable: bool,
|
|
||||||
position: (i32, i32),
|
position: (i32, i32),
|
||||||
color: (f32, f32, f32),
|
shape: Shape,
|
||||||
orientation: Orientation,
|
board: Board,
|
||||||
segments: Vec<Segment>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialOrd, PartialEq)]
|
|
||||||
pub struct Segment(i32, i32, Shape, Board);
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct Player {
|
|
||||||
pub position: [i32; 2],
|
|
||||||
pub color: [u32; 3],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Level {
|
impl Level {
|
||||||
|
@ -36,48 +34,48 @@ impl Level {
|
||||||
let data: LevelData = json5::from_str(data.as_ref()).unwrap();
|
let data: LevelData = json5::from_str(data.as_ref()).unwrap();
|
||||||
println!("{:?}", data);
|
println!("{:?}", data);
|
||||||
|
|
||||||
|
let mut cell_map = CellMap::new();
|
||||||
|
|
||||||
let blocks = data
|
let blocks = data
|
||||||
.blocks
|
.blocks
|
||||||
.iter()
|
.iter()
|
||||||
.map(|block| {
|
.enumerate()
|
||||||
let movable = block.movable;
|
.map(|(i, block)| {
|
||||||
let position = (block.position[0], block.position[1]);
|
let block = Block::from_data(i, block);
|
||||||
let segments = block
|
for segment in block.get_segments() {
|
||||||
.segments
|
cell_map.add(
|
||||||
.iter()
|
(segment.position.0, segment.position.1, segment.board),
|
||||||
.map(|segment| {
|
i,
|
||||||
Segment(segment[0], segment[1], segment[2].into(), segment[3].into())
|
&segment,
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let orientation = block.orientation.into();
|
|
||||||
let color = (
|
|
||||||
block.color[0] as f32 / 256.0,
|
|
||||||
block.color[1] as f32 / 256.0,
|
|
||||||
block.color[2] as f32 / 256.0,
|
|
||||||
);
|
);
|
||||||
Block {
|
|
||||||
movable,
|
|
||||||
position,
|
|
||||||
color,
|
|
||||||
segments,
|
|
||||||
orientation,
|
|
||||||
}
|
}
|
||||||
|
block
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let player1 = Player {
|
let player1 = Player {
|
||||||
position: data.player1.position,
|
position: data.player1.position,
|
||||||
color: data.player1.color,
|
color: data.player1.color.into(),
|
||||||
};
|
};
|
||||||
let player2 = Player {
|
let player2 = Player {
|
||||||
position: data.player2.position,
|
position: data.player2.position,
|
||||||
color: data.player2.color,
|
color: data.player2.color.into(),
|
||||||
};
|
};
|
||||||
|
cell_map.add_player((
|
||||||
|
data.player1.position.0,
|
||||||
|
data.player1.position.1,
|
||||||
|
Board::Left,
|
||||||
|
));
|
||||||
|
cell_map.add_player((
|
||||||
|
data.player2.position.0,
|
||||||
|
data.player2.position.1,
|
||||||
|
Board::Right,
|
||||||
|
));
|
||||||
|
|
||||||
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(),
|
cell_map,
|
||||||
blocks,
|
blocks,
|
||||||
player1,
|
player1,
|
||||||
player2,
|
player2,
|
||||||
|
@ -87,7 +85,7 @@ impl Level {
|
||||||
// player1: true -> player1, false -> player2
|
// player1: true -> player1, false -> player2
|
||||||
// TODO: don't use a boolean here
|
// TODO: don't use a boolean here
|
||||||
pub fn handle_movement(&mut self, player1: bool, direction: PushDir) -> bool {
|
pub fn handle_movement(&mut self, player1: bool, direction: PushDir) -> bool {
|
||||||
let mut player = if player1 {
|
let player = if player1 {
|
||||||
&self.player1
|
&self.player1
|
||||||
} else {
|
} else {
|
||||||
&self.player2
|
&self.player2
|
||||||
|
@ -95,8 +93,8 @@ impl Level {
|
||||||
|
|
||||||
// TODO: check out of bounds
|
// TODO: check out of bounds
|
||||||
let movement = direction.as_pair();
|
let movement = direction.as_pair();
|
||||||
let x = player.position[0] + movement.0;
|
let x = player.position.0 + movement.0;
|
||||||
let y = player.position[1] + movement.1;
|
let y = player.position.1 + movement.1;
|
||||||
|
|
||||||
let result = self.can_move(player1, direction).clone();
|
let result = self.can_move(player1, direction).clone();
|
||||||
let mut player = if player1 {
|
let mut player = if player1 {
|
||||||
|
@ -106,21 +104,25 @@ impl Level {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(_) = result {
|
if let Some(_) = result {
|
||||||
player.position[0] = x;
|
player.position.0 = x;
|
||||||
player.position[1] = y;
|
player.position.1 = y;
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn try_move(&self) {}
|
||||||
|
|
||||||
// TODO: don't use a boolean here
|
// TODO: don't use a boolean here
|
||||||
pub fn can_move(&self, player1: bool, direction: PushDir) -> Option<()> {
|
pub fn can_move(&self, player1: bool, direction: PushDir) -> Option<()> {
|
||||||
// an absolute segment (as opposed to relative to a block)
|
// an absolute segment (as opposed to relative to a block)
|
||||||
#[derive(Copy, Clone, PartialOrd, PartialEq)]
|
#[derive(Copy, Clone, PartialOrd, PartialEq)]
|
||||||
struct ASegment(i32, i32, Shape, Board);
|
struct ASegment(i32, i32, Shape, Board);
|
||||||
|
|
||||||
fn can_push(src: Segment, dst: Segment) -> bool {
|
struct PushMap(CellMap);
|
||||||
|
|
||||||
|
fn can_push_segment(src: ASegment, dst: ASegment) -> bool {
|
||||||
if src.3 != dst.3 {
|
if src.3 != dst.3 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -130,14 +132,14 @@ impl Level {
|
||||||
|
|
||||||
let player = if player1 {
|
let player = if player1 {
|
||||||
(
|
(
|
||||||
self.player1.position[0],
|
self.player1.position.0,
|
||||||
self.player1.position[1],
|
self.player1.position.1,
|
||||||
Board::Left,
|
Board::Left,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
self.player2.position[0],
|
self.player2.position.0,
|
||||||
self.player2.position[1],
|
self.player2.position.1,
|
||||||
Board::Right,
|
Board::Right,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -153,7 +155,9 @@ impl Level {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we're sharing a triangle cell
|
// check if we're sharing a triangle cell
|
||||||
if let CellContents::Double(a, b) = self.cell_map.get(player) {}
|
if let CellContents::Double(a, b) = self.cell_map.get(player) {
|
||||||
|
// get the shape of the other block
|
||||||
|
}
|
||||||
|
|
||||||
// 08/06 pickup
|
// 08/06 pickup
|
||||||
// need to determine whether or not segment should hold a reference back to block or not?
|
// need to determine whether or not segment should hold a reference back to block or not?
|
||||||
|
@ -204,14 +208,22 @@ impl Level {
|
||||||
|
|
||||||
// render blocks
|
// render blocks
|
||||||
for block in self.blocks.iter() {
|
for block in self.blocks.iter() {
|
||||||
for segment in block.segments.iter() {
|
for segment in block.get_segments().iter() {
|
||||||
let offset = match &segment.3 {
|
let offset = match &segment.board {
|
||||||
Board::Left => left_off,
|
Board::Left => left_off,
|
||||||
Board::Right => right_off,
|
Board::Right => right_off,
|
||||||
};
|
};
|
||||||
let coord = (segment.0 + block.position.0, segment.1 + block.position.1);
|
let location = (
|
||||||
let location = (offset.0 + coord.0 * scale, offset.1 + coord.1 * scale);
|
offset.0 + segment.position.0 * scale,
|
||||||
renderer.render_segment(location, scale, block.color, block.orientation, segment.2);
|
offset.1 + segment.position.1 * scale,
|
||||||
|
);
|
||||||
|
renderer.render_segment(
|
||||||
|
location,
|
||||||
|
scale,
|
||||||
|
block.get_color(),
|
||||||
|
block.get_orientation(),
|
||||||
|
segment.shape,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,75 +240,15 @@ impl Level {
|
||||||
offset: (i32, i32),
|
offset: (i32, i32),
|
||||||
) {
|
) {
|
||||||
let location = (
|
let location = (
|
||||||
offset.0 + player.position[0] * scale + 4,
|
offset.0 + player.position.0 * scale + 4,
|
||||||
offset.1 + player.position[1] * scale + 4,
|
offset.1 + player.position.1 * scale + 4,
|
||||||
);
|
);
|
||||||
renderer.render_segment(
|
renderer.render_segment(
|
||||||
location,
|
location,
|
||||||
(scale - 8),
|
(scale - 8),
|
||||||
(
|
player.color,
|
||||||
player.color[0] as f32,
|
|
||||||
player.color[1] as f32,
|
|
||||||
player.color[2] as f32,
|
|
||||||
),
|
|
||||||
Orientation::Both,
|
Orientation::Both,
|
||||||
Shape::Full,
|
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
23
src/level/player.rs
Normal file
23
src/level/player.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
use crate::color::Color;
|
||||||
|
use crate::enums::Orientation;
|
||||||
|
use crate::level::{Blockish, Segment};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Player {
|
||||||
|
pub position: (i32, i32),
|
||||||
|
pub color: Color,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Blockish for Player {
|
||||||
|
fn get_color(&self) -> Color {
|
||||||
|
self.color
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_orientation(&self) -> Orientation {
|
||||||
|
Orientation::None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_segments(&self) -> Vec<Segment> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ extern crate nalgebra_glm as glm;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
mod color;
|
||||||
mod data;
|
mod data;
|
||||||
mod enums;
|
mod enums;
|
||||||
mod game;
|
mod game;
|
||||||
|
|
|
@ -3,6 +3,7 @@ use glium::index::{NoIndices, PrimitiveType};
|
||||||
use glium::{Display, Frame, Program, Surface, Texture2d, VertexBuffer};
|
use glium::{Display, Frame, Program, Surface, Texture2d, VertexBuffer};
|
||||||
use nalgebra::{Matrix4, Vector4};
|
use nalgebra::{Matrix4, Vector4};
|
||||||
|
|
||||||
|
use crate::color::Color;
|
||||||
use crate::enums::{Orientation, Shape};
|
use crate::enums::{Orientation, Shape};
|
||||||
use crate::game::Game;
|
use crate::game::Game;
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ impl<'a, 'b> Renderer<'a, 'b> {
|
||||||
&mut self,
|
&mut self,
|
||||||
location: (i32, i32),
|
location: (i32, i32),
|
||||||
scale: i32,
|
scale: i32,
|
||||||
color: (f32, f32, f32),
|
color: Color,
|
||||||
orientation: Orientation,
|
orientation: Orientation,
|
||||||
shape: Shape,
|
shape: Shape,
|
||||||
) {
|
) {
|
||||||
|
@ -199,6 +200,7 @@ impl<'a, 'b> Renderer<'a, 'b> {
|
||||||
|
|
||||||
let rotate_texture = match orientation {
|
let rotate_texture = match orientation {
|
||||||
Orientation::Both => false,
|
Orientation::Both => false,
|
||||||
|
Orientation::None => false,
|
||||||
Orientation::Vertical => true,
|
Orientation::Vertical => true,
|
||||||
Orientation::Horizontal => false,
|
Orientation::Horizontal => false,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue