Commit 7bc08475 authored by Mathieu Nivoliez's avatar Mathieu Nivoliez

Implement up to the chapter "Entities and Components" of the rogue like

guide in rust.

For now, everything is inside the main file, I would like to split it in
the near future as the file get larger.

Next task, independantly of the guide, is to add CI to the project and
even CD to it.
parent 588b9521
This diff is collapsed.
......@@ -7,3 +7,6 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rltk = "0.5.17"
specs = "0.15.1"
specs-derive = "0.4.0"
# Rusty Roguelike
Little Rogue Like made in Rust using the [guide](http://bfnightly.bracketproductions.com/rustbook/chapter_0.html).
## Lecture
- [Introduction](http://bfnightly.bracketproductions.com/rustbook/chapter_0.html)
- [Section 1](http://bfnightly.bracketproductions.com/rustbook/chapter_1.html)
- [Entities and component](http://bfnightly.bracketproductions.com/rustbook/chapter_2.html)
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
void main()
{
vec3 col = texture(screenTexture, TexCoords).rgb;
FragColor = vec4(col, 1.0);
}
\ No newline at end of file
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 TexCoords;
void main()
{
TexCoords = aTexCoords;
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
}
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCoord;
in vec3 ourBackground;
// texture sampler
uniform sampler2D texture1;
void main()
{
vec4 original = texture(texture1, TexCoord);
if (original.r < 0.1f || original.g < 0.1f || original.b < 0.1f) discard;
vec4 fg = original * vec4(ourColor, 1.f);
FragColor = fg;
}
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec3 bColor;
layout (location = 3) in vec2 aTexCoord;
out vec3 ourColor;
out vec3 ourBackground;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
ourBackground = bColor;
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
\ No newline at end of file
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCoord;
in vec3 ourBackground;
// texture sampler
uniform sampler2D texture1;
void main()
{
vec4 original = texture(texture1, TexCoord);
vec4 fg = original.r > 0.1f || original.g > 0.1f || original.b > 0.1f ? original * vec4(ourColor, 1.f) : vec4(ourBackground, 1.f);
FragColor = fg;
}
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec3 bColor;
layout (location = 3) in vec2 aTexCoord;
out vec3 ourColor;
out vec3 ourBackground;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
ourBackground = bColor;
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
\ No newline at end of file
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
uniform vec3 screenSize;
uniform bool screenBurn;
void main()
{
vec3 col = texture(screenTexture, TexCoords).rgb;
float scanLine = mod(gl_FragCoord.y, 2.0) * 0.25;
vec3 scanColor = col.rgb - scanLine;
if (col.r < 0.1f && col.g < 0.1f && col.b < 0.1f) {
if (screenBurn) {
float dist = (1.0 - distance(vec2(gl_FragCoord.x / screenSize.x, gl_FragCoord.y / screenSize.y), vec2(0.5,0.5))) * 0.2;
FragColor = vec4(0.0, dist, dist, 1.0);
} else {
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
} else {
FragColor = vec4(scanColor, 1.0);
}
}
\ No newline at end of file
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 TexCoords;
void main()
{
TexCoords = aTexCoords;
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
}
// Only useful if compile to wasm
rltk::add_wasm_support!();
use rltk::{Console, GameState, Rltk, VirtualKeyCode, RGB};
use specs::prelude::*;
use std::cmp::{max, min};
#[macro_use]
extern crate specs_derive;
// Component
#[derive(Component)]
struct Position {
x: i32,
y: i32,
}
#[derive(Component)]
struct Renderable {
glyph: u8,
fg: RGB,
bg: RGB,
}
#[derive(Component)]
struct LeftMover;
#[derive(Component, Debug)]
struct Player;
// Systems
struct LeftWalker;
impl<'a> System<'a> for LeftWalker {
type SystemData = (ReadStorage<'a, LeftMover>, WriteStorage<'a, Position>);
fn run(&mut self, (lefty, mut pos): Self::SystemData) {
for (_lefty, pos) in (&lefty, &mut pos).join() {
pos.x -= 1;
if pos.x < 0 {
pos.x = 79;
}
}
}
}
// Functions
fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
let mut positions = ecs.write_storage::<Position>();
let mut players = ecs.write_storage::<Player>();
for (_player, pos) in (&mut players, &mut positions).join() {
pos.x = min(79, max(0, pos.x + delta_x));
pos.y = min(49, max(0, pos.y + delta_y));
}
}
fn player_input(gs: &mut State, ctx: &mut Rltk) {
// Player movement
match ctx.key {
None => {} // Nothing happened
Some(key) => match key {
VirtualKeyCode::Left => try_move_player(-1, 0, &mut gs.ecs),
VirtualKeyCode::Right => try_move_player(1, 0, &mut gs.ecs),
VirtualKeyCode::Up => try_move_player(0, -1, &mut gs.ecs),
VirtualKeyCode::Down => try_move_player(0, 1, &mut gs.ecs),
_ => {}
},
}
}
// Main State
struct State {
ecs: World,
}
impl State {
fn run_systems(&mut self) {
let mut lw = LeftWalker;
lw.run_now(&self.ecs);
self.ecs.maintain();
}
}
impl GameState for State {
fn tick(&mut self, ctx: &mut Rltk) {
ctx.cls();
self.run_systems();
player_input(self, ctx);
let positions = self.ecs.read_storage::<Position>();
let renderables = self.ecs.read_storage::<Renderable>();
for (pos, render) in (&positions, &renderables).join() {
ctx.set(pos.x, pos.y, render.fg, render.bg, render.glyph);
}
}
}
// Entry point
fn main() {
println!("Hello, world!");
// Init renderer
let context = Rltk::init_simple8x8(80, 50, "Hello Rust World", "resources");
// Init global state with an ecs world
let mut gs = State { ecs: World::new() };
// Register components to the world
gs.ecs.register::<Position>();
gs.ecs.register::<Renderable>();
gs.ecs.register::<LeftMover>();
gs.ecs.register::<Player>();
// Create an entity
gs.ecs
.create_entity()
.with(Position { x: 40, y: 25 })
.with(Renderable {
glyph: rltk::to_cp437('@'),
fg: RGB::named(rltk::YELLOW),
bg: RGB::named(rltk::BLACK),
})
.with(Player)
.build();
for i in 0..10 {
gs.ecs
.create_entity()
.with(Position { x: i * 7, y: 20 })
.with(Renderable {
glyph: rltk::to_cp437('☺'),
fg: RGB::named(rltk::RED),
bg: RGB::named(rltk::BLACK),
})
.with(LeftMover)
.build();
}
// Run the game
rltk::main_loop(context, gs);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment