Skip to content

Commit

Permalink
Shooting, better camera
Browse files Browse the repository at this point in the history
  • Loading branch information
Linus-Mussmaecher committed Apr 11, 2024
1 parent ede5336 commit 4335c5b
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 42 deletions.
Binary file modified assets/ship.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/ship_power.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
137 changes: 95 additions & 42 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ fn main() -> Result<()> {

struct OrbitsInstance {
objects: Vec<SpaceObject>,
scale: f32,
ship_image: graphics::Image,
ship_power_image: graphics::Image,
sun_image: graphics::Image,
}

impl OrbitsInstance {
const GRAVITY: f32 = 1.0;
const ROT_ACCELERATION: f32 = 0.1;
const LIN_ACCELARATION: f32 = 0.02;
const GRAVITY: f32 = 0.1;
const ROT_ACCELERATION: f32 = 0.05;
const LIN_ACCELARATION: f32 = 0.001;
}

impl Game for OrbitsInstance {
Expand All @@ -31,52 +35,99 @@ impl Game for OrbitsInstance {
coffee::load::Join::join((
graphics::Image::load("./assets/sun.png"),
graphics::Image::load("./assets/ship.png"),
graphics::Image::load("./assets/ship_power.png"),
))
.map(|(sun, ship)| OrbitsInstance {
.map(|(sun, ship, ship_power)| OrbitsInstance {
objects: vec![
// Ship
SpaceObject {
position: Point::from([256.0, 0.0]),
velocity: Vector::from([0.0, 2.0]),
velocity: Vector::from([0.0, 0.6]),
angle: 0.0,
mass: 1.0,
sprite: ship,
sprite: ship.clone(),
size: 16.0,
ship: Some(ShipInfo {
shot_cd: 0.0,
fuel: 1.0,
keymap: [
keyboard::KeyCode::W,
keyboard::KeyCode::A,
keyboard::KeyCode::D,
keyboard::KeyCode::S,
],
}),
},
// Sun
SpaceObject {
position: Point::from([0.0, 0.0]),
velocity: Vector::zeros(),
angle: 0.0,
mass: 1024.0,
sprite: sun,
sprite: sun.clone(),
size: 96.0,
ship: None,
},
],
scale: 1.0,
ship_image: ship,
ship_power_image: ship_power,
sun_image: sun,
})
}

fn interact(&mut self, input: &mut Self::Input, window: &mut Window) {
// Screen interaction
if input.is_key_pressed(keyboard::KeyCode::F11) {
if input.was_key_released(keyboard::KeyCode::F11) {
window.toggle_fullscreen();
}

if let Some(ship) = self.objects.first_mut() {
// Accelerate when W is pressed
if input.is_key_pressed(keyboard::KeyCode::W) {
ship.velocity += nalgebra::Rotation2::new(ship.angle)
.transform_vector(&Vector::x())
* Self::LIN_ACCELARATION;
}
// Turn with A/D
if input.is_key_pressed(keyboard::KeyCode::A) {
ship.angle += Self::ROT_ACCELERATION;
}
if input.is_key_pressed(keyboard::KeyCode::D) {
ship.angle -= Self::ROT_ACCELERATION;
let mut shots = Vec::new();

for possible_ship in self.objects.iter_mut() {
if possible_ship.ship.is_some() {
let ship = possible_ship;
let ship_info = ship.ship.as_mut().unwrap();
// Accelerate when W is pressed
if input.is_key_pressed(ship_info.keymap[0]) {
ship.velocity += nalgebra::Rotation2::new(ship.angle)
.transform_vector(&Vector::x())
* Self::LIN_ACCELARATION;
ship.sprite = self.ship_power_image.clone();
} else {
ship.sprite = self.ship_image.clone();
}
// Turn with A/D
if input.is_key_pressed(ship_info.keymap[1]) {
ship.angle += Self::ROT_ACCELERATION;
}
if input.is_key_pressed(ship_info.keymap[2]) {
ship.angle -= Self::ROT_ACCELERATION;
}
// Shoot with S
if ship_info.shot_cd <= 0.0 {
if input.is_key_pressed(ship_info.keymap[3]) {
shots.push(SpaceObject {
position: ship.position + 5.0 * ship.velocity,
velocity: ship.velocity
+ nalgebra::Rotation2::new(ship.angle)
.transform_vector(&Vector::x())
* 0.8,
angle: ship.angle,
mass: 0.01,
size: 4.0,
sprite: self.sun_image.clone(),
ship: None,
});
ship_info.shot_cd = 1.0;
}
} else {
ship_info.shot_cd = (ship_info.shot_cd - 0.01).max(0.0);
}
}
}

self.objects.extend(shots);
}

fn update(&mut self, _window: &Window) {
Expand Down Expand Up @@ -104,40 +155,30 @@ impl Game for OrbitsInstance {
object.velocity += accleration / object.mass;
object.position += object.velocity;
}

self.objects
.retain(|object| (object.position.to_homogeneous().xy()).norm() <= 1000.)
}

fn draw(&mut self, frame: &mut Frame, _timer: &Timer) {
// Clear the current frame
frame.clear(graphics::Color::BLACK);

// Get weighted average position
let mut total_mass = 0.0;
let mut center = Vector::zeros();

for object in self.objects.iter() {
center -= object.mass * object.position.to_homogeneous().xy();
total_mass += object.mass;
}

center /= total_mass;

center += Vector::from([frame.width() / 2., frame.height() / 2.]);

let mut min_scale: f32 = 1.0;

let (w, h) = (frame.width(), frame.height());

for object in self.objects.iter() {
let w_scale = (object.position.x - center.x).abs() / w * 5.0;
let h_scale = (object.position.y - center.y).abs() / h * 5.0;

dbg!(w_scale);
dbg!(h_scale);
dbg!(min_scale);
for object in self.objects.iter().filter(|obj| obj.ship.is_some()) {
let w_scale = object.position.x.abs() / w * 2.2;
let h_scale = object.position.y.abs() / h * 2.2;

min_scale = min_scale.max(w_scale).max(h_scale);
}

if min_scale > self.scale || min_scale < self.scale / 2. {
self.scale = min_scale;
}

let mut target = frame.as_target();

for object in self.objects.iter() {
Expand All @@ -147,7 +188,11 @@ impl Game for OrbitsInstance {
..Default::default()
},
&mut target
.transform(graphics::Transformation::translate(center))
.transform(graphics::Transformation::translate(Vector::from([
w / 2.,
h / 2.,
])))
.transform(graphics::Transformation::scale(1. / self.scale))
.transform(graphics::Transformation::translate(
object.position.to_homogeneous().xy(),
))
Expand All @@ -169,4 +214,12 @@ struct SpaceObject {
mass: f32,
size: f32,
sprite: graphics::Image,
ship: Option<ShipInfo>,
}

#[derive(Debug, Clone)]
struct ShipInfo {
shot_cd: f32,
fuel: f32,
keymap: [keyboard::KeyCode; 4],
}

0 comments on commit 4335c5b

Please sign in to comment.