Skip to content
Snippets Groups Projects
Commit 647d4594 authored by pumapaul's avatar pumapaul
Browse files

Add modularized structure and run + level initialization

parent 3c21d6d6
Branches
No related tags found
No related merge requests found
.idea
/target
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ab_glyph"
version = "0.2.10"
......
mod run;
mod level;
mod player;
mod enemy;
mod textures;
pub mod config;
mod tile;
use tetra::{Context, State};
use tetra::graphics::{self, Color, DrawParams};
use tetra::input::{self, Key};
use run::Run;
use textures::Textures;
use crate::game_state::tile::Tile;
use tetra::math::Vec2;
pub struct GameState {
current_run: Run,
high_score: usize,
textures: Textures
}
impl GameState {
pub fn new(ctx: &mut Context) -> tetra::Result<GameState> {
let textures = Textures::init(ctx);
if textures.is_ok() {
Ok(GameState {
current_run: Run::new(),
high_score: 0,
textures: textures.unwrap()
})
} else {
Err(textures.err().unwrap())
}
}
}
impl State for GameState {
fn update(&mut self, ctx: &mut Context) -> tetra::Result {
let keys = input::get_keys_pressed(ctx);
for key in keys {
println!("{:?}", key);
}
Ok(())
}
fn draw(&mut self, ctx: &mut Context) -> tetra::Result {
graphics::clear(ctx, Color::rgb(0.220, 0.220, 0.220));
self.draw_board(ctx);
Ok(())
}
}
// DRAWING HELPERS
impl GameState {
fn draw_board(&mut self, ctx: &mut Context) -> tetra::Result {
GameState::draw_boundary(self, ctx);
GameState::draw_tiles(self, ctx);
Ok(())
}
fn draw_boundary(&mut self, ctx: &mut Context) {
let boundary_width = config::BOARD_WIDTH + 2;
let boundary_height = config::BOARD_HEIGHT + 2;
for x in 0..boundary_width {
GameState::draw_tile(self, Color::BLACK, x, 0, ctx);
GameState::draw_tile(self, Color::BLACK, x, boundary_height - 1, ctx);
}
for y in 0..boundary_height {
GameState::draw_tile(self, Color::BLACK, 0, y, ctx);
GameState::draw_tile(self, Color::BLACK, boundary_width - 1, y, ctx);
}
}
fn draw_tiles(&mut self, ctx: &mut Context) {
let board = self.current_run.level.board;
for x in 0..board.len() {
for y in 0..board[x].len() {
let tile = board[x][y];
let draw_x = x + 1;
let draw_y = y + 1;
match tile {
Tile::Empty => GameState::draw_tile(self, Color::WHITE, draw_x, draw_y, ctx),
Tile::Wall => GameState::draw_tile(self, Color::BLACK, draw_x, draw_y, ctx),
Tile::Player => GameState::draw_player(self, draw_x, draw_y, ctx),
Tile::Enemy(_) => GameState::draw_enemy(self, draw_x, draw_y, ctx),
_ => {}
}
}
}
}
fn draw_tile(&mut self, color: Color, x: usize, y: usize, ctx: &mut Context) {
self.textures.tile.draw(ctx, DrawParams {
position: Vec2::new(x as f32 * 33.0, y as f32 * 33.0),
scale: Vec2::new(1.0, 1.0),
origin: Vec2::new(0.0, 0.0),
rotation: 0.0,
color,
})
}
fn draw_player(&mut self, x: usize, y: usize, ctx: &mut Context) {
GameState::draw_tile(self, Color::WHITE, x, y, ctx);
let draw_params = GameState::create_entity_draw_params(x, y);
self.textures.player.draw(ctx, draw_params)
}
fn draw_enemy(&mut self, x: usize, y: usize, ctx: &mut Context) {
GameState::draw_tile(self, Color::WHITE, x, y, ctx);
let draw_params = GameState::create_entity_draw_params(x, y);
self.textures.enemy.draw(ctx, draw_params)
}
fn create_entity_draw_params(x: usize, y: usize) -> DrawParams {
DrawParams {
position: Vec2::new(16.0 + (x as f32) * 33.0, 16.0 + (y as f32) * 33.0),
scale: Vec2::new(1.0, 1.0),
origin: Vec2::new(16.0, 16.0),
rotation: 0.0,
color: Color::WHITE,
}
}
}
\ No newline at end of file
pub const WINDOW_WIDTH: f32 = 1280.0;
pub const WINDOW_HEIGHT: f32 = 720.0;
pub const BOARD_WIDTH: usize = 35;
pub const BOARD_HEIGHT: usize = 19;
pub const PLAYER_STARTING_AP: usize = 1;
pub const PLAYER_STARTING_HP: usize = 10;
pub struct Enemy {
}
impl Enemy {
pub fn new() -> Enemy {
Enemy {}
}
}
\ No newline at end of file
use crate::game_state::config;
use crate::game_state::enemy::Enemy;
use crate::game_state::tile::Tile;
use rand::{thread_rng, Rng};
type Board = [[Tile; config::BOARD_HEIGHT]; config::BOARD_WIDTH];
pub struct Level {
pub board: Board,
enemies: Vec<Enemy>,
turn_count: usize
}
impl Level {
pub fn new(difficulty: usize) -> Level {
let enemies = Level::create_enemies(difficulty);
let board = Level::create_board(enemies.len());
Level {
board,
enemies,
turn_count: 0
}
}
}
// Enemies
impl Level {
fn create_enemies(difficulty: usize) -> Vec<Enemy> {
let enemy_count = Level::calc_enemy_count(difficulty);
let mut result = Vec::new();
for _i in 0..enemy_count {
result.push(Enemy::new());
}
return result
}
fn calc_enemy_count(difficulty: usize) -> usize {
difficulty + 2
}
}
// Board
impl Level {
fn create_board(enemy_count: usize) -> Board {
let board = [[Tile::Empty; config::BOARD_HEIGHT]; config::BOARD_WIDTH];
let with_walls = Level::add_walls(board);
let with_player = Level::add_player(with_walls);
let with_enemies = Level::add_enemies(enemy_count, with_player);
return with_enemies;
}
fn add_walls(board: Board) -> Board {
let mut board = board.clone();
for x in 0..board.len() {
for y in 0..board[x].len() {
let n = thread_rng().gen_range(0, 10);
if n < 2 {
board[x][y] = Tile::Wall;
}
}
}
board
}
fn add_player(board: Board) -> Board {
Level::add_entity(Tile::Player, board)
}
fn add_enemies(enemy_count: usize, board: Board) -> Board {
let mut result = board.clone();
for index in 0..enemy_count - 1 {
result = Level::add_entity(Tile::Enemy(index), result);
}
result
}
fn add_entity(entity: Tile, board: Board) -> Board {
let empty_count = Level::count_empty_tiles(board);
let player_position = thread_rng().gen_range(0, empty_count);
let player_x = player_position / config::BOARD_HEIGHT;
let player_y = player_position % config::BOARD_HEIGHT;
let mut board = board.clone();
board[player_x][player_y] = entity;
board
}
fn count_empty_tiles(board: Board) -> usize {
let mut result = 0;
for x in 0..board.len() {
for y in 0..board[x].len() {
match board[x][y] {
Tile::Empty => result += 1,
_ => {},
}
}
}
result
}
}
\ No newline at end of file
pub struct Player {
current_hp: usize,
max_hp: usize,
attack_power: usize
}
impl Player {
pub fn new(attack_power: usize, hit_points: usize) -> Player {
Player {
current_hp: hit_points,
max_hp: hit_points,
attack_power
}
}
}
\ No newline at end of file
use crate::game_state::player::Player;
use crate::game_state::level::Level;
use crate::game_state::config;
pub struct Run {
turn_count: usize,
level_count: usize,
player: Player,
pub level: Level
}
impl Run {
pub fn new() -> Run {
let hp = config::PLAYER_STARTING_HP;
let ap = config::PLAYER_STARTING_AP;
Run {
turn_count: 0,
level_count: 0,
player: Player::new(ap, hp),
level: Level::new(0)
}
}
}
\ No newline at end of file
use tetra::{Context};
use tetra::graphics::{Texture};
pub struct Textures {
pub tile: Texture,
pub player: Texture,
pub enemy: Texture,
}
impl Textures {
pub fn init(ctx: &mut Context) -> tetra::Result<Textures> {
Ok(Textures {
tile: Texture::new(ctx, "./resources/tile.png")?,
player: Texture::new(ctx, "./resources/player.png")?,
enemy: Texture::new(ctx, "./resources/spike.png")?,
})
}
}
\ No newline at end of file
#[derive(Copy, Clone)]
pub enum Tile {
Enemy(usize),
Exit,
Empty,
Health,
Player,
Wall
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment