9de2383712
* Move all examples to individual crates * CI: Add libsdl2 * Use Ubuntu bionic for updated libsdl; 2.0.8 * Clippy * libudev-dev is a dependency of libsdl2-dev * Clippy * Remove unnecessary dev-dependency * `winit` is actually used in unit tests * Fix a typo * Move `simple-invaders` crate
107 lines
3.4 KiB
Rust
107 lines
3.4 KiB
Rust
use crate::collision::{BulletDetail, Collision, LaserDetail};
|
|
use crate::geo::Point;
|
|
use crate::sprites::{rect, Drawable};
|
|
use crate::{Bullet, Invaders, Laser, Player, Shield, GRID};
|
|
|
|
// Colors
|
|
const RED: [u8; 4] = [255, 0, 0, 255];
|
|
const GREEN: [u8; 4] = [0, 255, 0, 255];
|
|
const BLUE: [u8; 4] = [0, 0, 255, 255];
|
|
const YELLOW: [u8; 4] = [255, 255, 0, 255];
|
|
|
|
/// Draw bounding boxes for the invader fleet and each invader.
|
|
pub(crate) fn draw_invaders(screen: &mut [u8], invaders: &Invaders, collision: &Collision) {
|
|
// Draw invaders bounding box
|
|
{
|
|
let (top, right, bottom, left) = invaders.get_bounds();
|
|
let p1 = Point::new(left, top);
|
|
let p2 = Point::new(right, bottom);
|
|
|
|
rect(screen, &p1, &p2, BLUE);
|
|
}
|
|
|
|
// Draw bounding boxes for each invader
|
|
for (y, row) in invaders.grid.iter().enumerate() {
|
|
for (x, col) in row.iter().enumerate() {
|
|
let detail = BulletDetail::Invader(x, y);
|
|
if let Some(invader) = col {
|
|
let p1 = invader.pos;
|
|
let p2 = p1 + Point::new(invader.sprite.width(), invader.sprite.height());
|
|
|
|
// Select color based on proximity to bullet
|
|
let color = if collision.bullet_details.contains(&detail) {
|
|
YELLOW
|
|
} else {
|
|
GREEN
|
|
};
|
|
|
|
rect(screen, &p1, &p2, color);
|
|
} else if collision.bullet_details.contains(&detail) {
|
|
let x = x - invaders.bounds.left_col;
|
|
let y = y - invaders.bounds.top_row;
|
|
let p1 = invaders.bounds.pos + Point::new(x, y) * GRID;
|
|
let p2 = p1 + GRID;
|
|
|
|
rect(screen, &p1, &p2, RED);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Draw bounding box for bullet.
|
|
pub(crate) fn draw_bullet(screen: &mut [u8], bullet: Option<&Bullet>) {
|
|
if let Some(bullet) = bullet {
|
|
let p1 = bullet.pos;
|
|
let p2 = p1 + Point::new(bullet.sprite.width(), bullet.sprite.height());
|
|
|
|
rect(screen, &p1, &p2, GREEN);
|
|
}
|
|
}
|
|
|
|
/// Draw bounding box for lasers.
|
|
pub(crate) fn draw_lasers(screen: &mut [u8], lasers: &[Laser]) {
|
|
for laser in lasers {
|
|
let p1 = laser.pos;
|
|
let p2 = p1 + Point::new(laser.sprite.width(), laser.sprite.height());
|
|
|
|
rect(screen, &p1, &p2, GREEN);
|
|
}
|
|
}
|
|
|
|
/// Draw bounding box for player.
|
|
pub(crate) fn draw_player(screen: &mut [u8], player: &Player, collision: &Collision) {
|
|
let p1 = player.pos;
|
|
let p2 = p1 + Point::new(player.sprite.width(), player.sprite.height());
|
|
|
|
// Select color based on collisions
|
|
let detail = LaserDetail::Player;
|
|
let color = if collision.laser_details.contains(&detail) {
|
|
RED
|
|
} else {
|
|
GREEN
|
|
};
|
|
|
|
rect(screen, &p1, &p2, color);
|
|
}
|
|
|
|
/// Draw bounding boxes for shields.
|
|
pub(crate) fn draw_shields(screen: &mut [u8], shields: &[Shield], collision: &Collision) {
|
|
for (i, shield) in shields.iter().enumerate() {
|
|
let p1 = shield.pos;
|
|
let p2 = p1 + Point::new(shield.sprite.width(), shield.sprite.height());
|
|
|
|
// Select color based on collisions
|
|
let laser_detail = LaserDetail::Shield(i);
|
|
let bullet_detail = BulletDetail::Shield(i);
|
|
let color = if collision.laser_details.contains(&laser_detail)
|
|
|| collision.bullet_details.contains(&bullet_detail)
|
|
{
|
|
RED
|
|
} else {
|
|
GREEN
|
|
};
|
|
|
|
rect(screen, &p1, &p2, color);
|
|
}
|
|
}
|