Skip to content

Commit

Permalink
feat: Remove Scenes struct, fix imports and refactor some parts
Browse files Browse the repository at this point in the history
  • Loading branch information
sp-luciano-chinke committed Jun 28, 2021
1 parent 7cd0638 commit 9164831
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 137 deletions.
3 changes: 1 addition & 2 deletions src/invaders.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::frame::{Drawable, Frame};
use crate::{NUM_COLS, NUM_ROWS};
use rusty_time::timer::Timer;
use std::cmp::max;
use std::time::Duration;
use std::{cmp::max, time::Duration};

pub struct Invader {
pub x: usize,
Expand Down
7 changes: 0 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,3 @@ pub mod shot;

pub const NUM_ROWS: usize = 20;
pub const NUM_COLS: usize = 40;

#[derive(PartialEq, Copy, Clone)]
pub enum Scenes {
Menu,
Game,
End,
}
130 changes: 75 additions & 55 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
use crossterm::cursor::{Hide, Show};
use crossterm::terminal::{EnterAlternateScreen, LeaveAlternateScreen};
use crossterm::{terminal, ExecutableCommand};
use invaders::frame::{new_frame, Drawable, Frame};
use invaders::invaders::Invaders;
use invaders::menu::Menu;
use invaders::player::Player;
use invaders::score::Score;
use invaders::Scenes;
use invaders::{frame, render};
use crossterm::{
cursor::{Hide, Show},
event::{self, Event, KeyCode},
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
ExecutableCommand,
};
use rusty_audio::Audio;
use std::error::Error;
use std::sync::mpsc;
use std::sync::mpsc::Receiver;
use std::time::{Duration, Instant};
use std::{io, thread};
use std::{
error::Error,
sync::mpsc::{self, Receiver},
time::{Duration, Instant},
{io, thread},
};

use invaders::{
frame::{self, new_frame, Drawable, Frame},
invaders::Invaders,
menu::Menu,
player::Player,
render,
score::Score,
};

fn render_screen(render_rx: Receiver<Frame>) {
let mut last_frame = frame::new_frame();
Expand All @@ -29,10 +35,15 @@ fn render_screen(render_rx: Receiver<Frame>) {
}
}

fn reset_game(in_menu: &mut bool, player: &mut Player, invaders: &mut Invaders) {
*in_menu = true;
*player = Player::new();
*invaders = Invaders::new();
}

fn main() -> Result<(), Box<dyn Error>> {
let mut audio = Audio::new();
let audios = ["explode", "lose", "move", "pew", "startup", "win"];
for item in audios.iter() {
for item in &["explode", "lose", "move", "pew", "startup", "win"] {
audio.add(item, &format!("{}.wav", item));
}
audio.play("startup");
Expand All @@ -55,46 +66,54 @@ fn main() -> Result<(), Box<dyn Error>> {
let mut invaders = Invaders::new();
let mut score = Score::new();
let mut menu = Menu::new();
let mut scene = Scenes::Menu;

fn reset_game(scene: &mut Scenes, player: &mut Player, invaders: &mut Invaders) {
*scene = Scenes::Menu;
*player = Player::new();
*invaders = Invaders::new();
}
let mut in_menu = true;

fn draw(drawables: Vec<&dyn Drawable>, frame: &mut Frame) {
for drawable in drawables {
drawable.draw(frame);
}
}

while scene != Scenes::End {
'gameloop: loop {
// Per-frame init
let delta = instant.elapsed();
instant = Instant::now();
let mut curr_frame = new_frame();

if scene == Scenes::Menu {
// How can I improve this? (used to avoid problems with references)
if menu.selected == Scenes::Game {
scene = Scenes::Game;
menu.reset_selected();
} else if menu.selected == Scenes::End {
scene = Scenes::End;
menu.reset_selected();
if in_menu {
// Input handlers for the menu
while event::poll(Duration::default())? {
if let Event::Key(key_event) = event::read()? {
match key_event.code {
KeyCode::Up => menu.change_option(true),
KeyCode::Down => menu.change_option(false),
KeyCode::Char(' ') | KeyCode::Enter => {
if menu.selection == 0 {
in_menu = false;
} else {
break 'gameloop;
}
}
_ => {}
}
}
}
// Input
menu.set_handlers()?;
// Draw & render
draw(vec![&menu], &mut curr_frame);
} else if scene == Scenes::Game {
// How can I improve this? (used to avoid problems with references)
if player.scene == Scenes::Menu {
reset_game(&mut scene, &mut player, &mut invaders);
menu.draw(&mut curr_frame);
} else {
// Input handlers for the game
while event::poll(Duration::default())? {
if let Event::Key(key_event) = event::read()? {
match key_event.code {
KeyCode::Left => player.move_left(),
KeyCode::Right => player.move_right(),
KeyCode::Char(' ') | KeyCode::Enter => {
if player.shoot() {
audio.play("pew");
}
}
KeyCode::Esc | KeyCode::Char('q') => {
audio.play("lose");
in_menu = true;
reset_game(&mut in_menu, &mut player, &mut invaders);
}
_ => {}
}
}
}
// Input
player.set_handlers(&mut audio)?;

// Updates
player.update(delta);
Expand All @@ -107,22 +126,23 @@ fn main() -> Result<(), Box<dyn Error>> {
score.add_points(hits);
}
// Draw & render
draw(vec![&player, &invaders, &score], &mut curr_frame);
player.draw(&mut curr_frame);
invaders.draw(&mut curr_frame);
score.draw(&mut curr_frame);
}

let _ = render_tx.send(curr_frame);
thread::sleep(Duration::from_millis(1));

// Final checks if we are in game
if scene == Scenes::Game {
if !in_menu {
// Win or lose?
if invaders.all_killed() {
audio.play("win");
reset_game(&mut scene, &mut player, &mut invaders);
}
if invaders.reached_bottom() {
reset_game(&mut in_menu, &mut player, &mut invaders);
} else if invaders.reached_bottom() {
audio.play("lose");
reset_game(&mut scene, &mut player, &mut invaders);
reset_game(&mut in_menu, &mut player, &mut invaders);
}
}
}
Expand Down
38 changes: 2 additions & 36 deletions src/menu.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,25 @@
use crate::frame::{Drawable, Frame};
use crate::Scenes;
use crossterm::event;
use crossterm::event::{Event, KeyCode};
use std::error::Error;
use std::time::Duration;

pub struct Menu {
options: Vec<String>,
pub options: Vec<String>,
pub selection: usize,
pub selected: Scenes,
}

impl Menu {
pub fn new() -> Self {
Self {
options: vec![String::from("New game"), String::from("Exit")],
selection: 0,
selected: Scenes::Menu,
}
}

pub fn reset_selected(&mut self) {
self.selected = Scenes::Menu;
}

pub fn change_option(&mut self, upwards: bool) {
if upwards && self.selection > 0 {
self.selection -= 1;
} else if !upwards && self.selection <= self.options.len() - 1 {
} else if !upwards && self.selection < self.options.len() - 1 {
self.selection += 1;
}
}

pub fn select_option(&mut self) {
if self.selection == 0 {
self.selected = Scenes::Game;
} else {
self.selected = Scenes::End;
}
}

pub fn set_handlers(&mut self) -> Result<(), Box<dyn Error>> {
// Input
while event::poll(Duration::default())? {
if let Event::Key(key_event) = event::read()? {
match key_event.code {
KeyCode::Up => self.change_option(true),
KeyCode::Down => self.change_option(false),
KeyCode::Char(' ') | KeyCode::Enter => self.select_option(),
_ => {}
}
}
}
Ok(())
}
}

// Reuse Frame grid to print the menu options
Expand Down
39 changes: 6 additions & 33 deletions src/player.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
use crate::frame::{Drawable, Frame};
use crate::invaders::Invaders;
use crate::shot::Shot;
use crate::Scenes;
use crate::{NUM_COLS, NUM_ROWS};
use crossterm::event;
use crossterm::event::{Event, KeyCode};
use rusty_audio::Audio;
use std::error::Error;
use crate::{
frame::{Drawable, Frame},
invaders::Invaders,
shot::Shot,
{NUM_COLS, NUM_ROWS},
};
use std::time::Duration;

pub struct Player {
x: usize,
y: usize,
shots: Vec<Shot>,
pub scene: Scenes,
}

impl Player {
Expand All @@ -22,7 +18,6 @@ impl Player {
x: NUM_COLS / 2,
y: NUM_ROWS - 1,
shots: Vec::new(),
scene: Scenes::Game,
}
}
pub fn move_left(&mut self) {
Expand Down Expand Up @@ -62,28 +57,6 @@ impl Player {
}
hit_something
}
pub fn set_handlers(&mut self, audio: &mut Audio) -> Result<(), Box<dyn Error>> {
// Inputs
while event::poll(Duration::default())? {
if let Event::Key(key_event) = event::read()? {
match key_event.code {
KeyCode::Left => self.move_left(),
KeyCode::Right => self.move_right(),
KeyCode::Char(' ') | KeyCode::Enter => {
if self.shoot() {
audio.play("pew");
}
}
KeyCode::Esc | KeyCode::Char('q') => {
audio.play("lose");
self.scene = Scenes::Menu;
}
_ => {}
}
}
}
Ok(())
}
}

impl Drawable for Player {
Expand Down
10 changes: 6 additions & 4 deletions src/render.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::frame::Frame;
use crossterm::cursor::MoveTo;
use crossterm::style::{Color, SetBackgroundColor, SetForegroundColor};
use crossterm::terminal::{Clear, ClearType};
use crossterm::QueueableCommand;
use crossterm::{
cursor::MoveTo,
style::{Color, SetBackgroundColor, SetForegroundColor},
terminal::{Clear, ClearType},
QueueableCommand,
};
use std::io::{Stdout, Write};

pub fn render(stdout: &mut Stdout, last_frame: &Frame, curr_frame: &Frame, force: bool) {
Expand Down

0 comments on commit 9164831

Please sign in to comment.