Skip to content
Snippets Groups Projects
Commit d3653bb7 authored by radow's avatar radow
Browse files

initial commit

parent ae569c24
Branches
No related tags found
No related merge requests found
/target
{
"CurrentProjectSetting": null
}
\ No newline at end of file
{
"ExpandedNodes": [
""
],
"SelectedNode": "\\.gitignore",
"PreviewInSolutionExplorer": false
}
\ No newline at end of file
File added
File added
Cargo.lock 0 → 100644
This diff is collapsed.
[package]
name = "rusttest"
version = "0.1.0"
authors = ["radow <masteroftheriddles@googlemail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tetra = "0.6"
rand = "0.5.0"
SDL2.dll 0 → 100644
File added
SDL2.lib 0 → 100644
File added
resources/player.png

1.74 KiB

resources/spike.png

1.72 KiB

resources/tile.png

1.57 KiB

use std::collections::HashMap;
use tetra::graphics::{self, Color, DrawParams, Texture};
use tetra::input::{self, Key};
use tetra::math::Vec2;
use tetra::{Context, ContextBuilder, State};
use rand::{thread_rng, Rng};
//constants
const WINDOW_WIDTH: f32 = 1280.0;
const WINDOW_HEIGHT: f32 = 720.0;
const BOARD_WIDTH: usize = 39;
const BOARD_HEIGHT: usize = 22;
fn main() -> tetra::Result {
ContextBuilder::new("rusttest", WINDOW_WIDTH as i32, WINDOW_HEIGHT as i32)
.quit_on_escape(true)
.build()?
.run(GameState::new)
}
struct GameState {
player: Entity,
foes: Foes,
tile: Texture,
world: World,
}
impl GameState {
fn new(ctx: &mut Context) -> tetra::Result<GameState> {
//load graphics
let player_texture = Texture::new(ctx, "./resources/player.png")?;
let tile_texture = Texture::new(ctx, "./resources/tile.png")?;
//set initial position
let player_position = Vec2::new(5,7);
Ok(GameState {
player: Entity::new_pos(player_texture, player_position, 1),
foes: Foes::generate(6, Texture::new(ctx, "./resources/spike.png")?),
tile: tile_texture,
world: World::new(),
})
}
}
impl State for GameState {
// draw call
fn draw(&mut self, ctx: &mut Context) -> tetra::Result {
graphics::clear(ctx, Color::rgb(0.220, 0.220, 0.220));
for x in 0..BOARD_WIDTH{
for y in 0..BOARD_HEIGHT{
let tile = self.world.tiles[x][y] as WorldTile;
let mut c = Color::BLACK;
if tile.passable {
c = Color::WHITE;
}
self.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: c,
})
}
}
self.player.draw(ctx);
let ids: Vec<&u32> = self.foes.list.keys().collect();
for id in &ids{
self.foes.list[id].draw(ctx);
}
Ok(())
}
//game loop
fn update(&mut self, ctx: &mut Context) -> tetra::Result {
let mut tick = false;
//input
if input::is_key_pressed(ctx, Key::A) {
if self.world.is_passable(Vec2::new(self.player.position.x-1,self.player.position.y)) {
if self.world.is_occupied_by(Vec2::new(self.player.position.x-1,self.player.position.y))>1 {
//collision
}
else {
self.player.position.x -= 1;
}
}
self.player.transform.scale.x = -1.0;
tick = true;
}
if input::is_key_pressed(ctx, Key::D) {
if self.world.is_passable(Vec2::new(self.player.position.x+1,self.player.position.y)) {
self.player.position.x += 1;
tick = true;
}
self.player.transform.scale.x = 1.0;
}
if input::is_key_pressed(ctx, Key::W) {
if self.world.is_passable(Vec2::new(self.player.position.x,self.player.position.y-1)) {
self.player.position.y -= 1;
tick = true;
}
}
if input::is_key_pressed(ctx, Key::S) {
if self.world.is_passable(Vec2::new(self.player.position.x,self.player.position.y+1)) {
self.player.position.y += 1;
tick = true;
}
}
if input::is_key_pressed(ctx, Key::Space) {
tick = true;
}
// logic
if tick{
let ids: Vec<&u32> = self.foes.list.keys().collect();
for id in &ids{
// tried To move the logic into the entity, but run into reference ownership issues
//self.foes.list[id].update(self);
let mut newpos = self.foes.list[id].position;
let mut rng = thread_rng();
let n:u8 = rng.gen_range(0, 4);
match n{
0 => newpos.x += 1,
1 => newpos.x -= 1,
2 => newpos.y += 1,
3 => newpos.y -= 1,
_ => newpos.y -= 0, //impossible to reach, can we avoid this somehow?
}
if self.world.is_passable(newpos){
// ownership issues
//self.foes.list[id].position = newpos;
}
}
}
Ok(())
}
}
struct Entity {
texture: Texture,
transform: DrawParams,
position: Vec2<u32>,
id: u32,
}
impl Entity {
fn new_pos(texture: Texture, initial_position: Vec2<u32>, id: u32) -> Entity{
Entity::with_darwparams(texture, DrawParams{
position: Vec2::new(16.0+(initial_position.x as f32) * 33.0, 16.0+(initial_position.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,
}, initial_position,
id)
}
fn with_darwparams(texture: Texture, transform: DrawParams, position: Vec2<u32>, id: u32) -> Entity{
Entity{
texture,
transform,
position,
id,
}
}
fn get_drawparams(&self) -> DrawParams{
let mut dp = self.transform.clone();
dp.position= Vec2::new(16.0+(self.position.x as f32) * 33.0, 16.0+(self.position.y as f32) * 33.0);
dp
}
fn update(&self, gs: &GameState ){
// let mut newpos = self.position;
// let mut rng = thread_rng();
// let n:u8 = rng.gen_range(0, 4);
// match n{
// 0 => newpos.x += 1,
// 1 => newpos.x -= 1,
// 2 => newpos.y += 1,
// 3 => newpos.y -= 1,
// _ => newpos.y -= 0, //impossible to reach, can we avoid this somehow?
// }
// if gs.world.is_passable(newpos){
// self.position = newpos;
// }
}
fn draw(&self, ctx: &mut Context){
self.texture.draw(ctx, self.get_drawparams());
}
}
#[derive(Copy, Clone)]
struct WorldTile{
passable: bool,
occupant: u32,
}
struct World{
tiles: [[WorldTile; BOARD_HEIGHT]; BOARD_WIDTH],
}
impl World{
fn new() -> World{
let mut new_world: [[WorldTile; BOARD_HEIGHT]; BOARD_WIDTH] = [[WorldTile{passable: false, occupant:0}; BOARD_HEIGHT];BOARD_WIDTH];
for x in 0..BOARD_WIDTH{
for y in 0..BOARD_HEIGHT{
if x==0||x==BOARD_WIDTH-1||y==0||y==BOARD_HEIGHT-1 {
new_world[x][y].passable = false;
}
else{
let mut rng = thread_rng();
let n:u8 = rng.gen_range(0, 10);
if n<2{
new_world[x][y].passable = false;
}
else {new_world[x][y].passable = true;}
}
}
}
World{tiles: new_world}
}
fn is_passable(&self, pos:Vec2<u32>) -> bool{
let tile = self.tiles[pos.x as usize][pos.y as usize] as WorldTile;
tile.passable
}
fn is_occupied_by(&self, pos:Vec2<u32>) -> u32{
let tile = self.tiles[pos.x as usize][pos.y as usize] as WorldTile;
tile.occupant
}
}
struct Foes{
list: HashMap<u32, Entity>
}
impl Foes{
fn generate(n:u32, texture:Texture) -> Foes{
let mut entities = HashMap::new();
for i in 2..n{
// initial foe position to be calculated here
entities.insert(i, Entity::new_pos(texture.clone(),Vec2::new(i,i), i));
}
Foes{list:entities}
}
}
\ 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