Added radar frame
parent
aa2a1943b2
commit
a85a0f8188
10
TODO.md
10
TODO.md
|
@ -1,3 +1,13 @@
|
|||
## Specific Jobs
|
||||
- UI: health, shield, fuel, heat, energy bars
|
||||
- UI: text arranger
|
||||
- Sound system
|
||||
- Particles, impact effects
|
||||
- Debris on ship death
|
||||
- Radar: dynamic colors, size, planets and suns
|
||||
|
||||
----------------------------------
|
||||
|
||||
## Game & Story
|
||||
- Landmarks to determine speed?
|
||||
- How to keep player in system bounds, what to do if they fly far away
|
||||
|
|
2
assets
2
assets
|
@ -1 +1 @@
|
|||
Subproject commit 8205d79e8aa9d7e4976fe8a7794e83819ec19688
|
||||
Subproject commit 91377416617d049acec68bb5a17647dcac7acd0e
|
|
@ -24,3 +24,6 @@ path = "ui/radar.png"
|
|||
|
||||
[texture."ui::blip"]
|
||||
path = "ui/blip.png"
|
||||
|
||||
[texture."ui::radarframe"]
|
||||
path = "ui/radarframe.png"
|
||||
|
|
|
@ -356,28 +356,46 @@ impl GPUState {
|
|||
let width = s.dimensions.x;
|
||||
let height = s.dimensions.y;
|
||||
|
||||
// Compute square scale, since we must apply screen aspect ratio
|
||||
// AFTER rotation.
|
||||
let scale = Matrix4::from_nonuniform_scale(
|
||||
width / logical_size.width,
|
||||
width / logical_size.height,
|
||||
height / logical_size.height,
|
||||
1.0,
|
||||
);
|
||||
let rotate = Matrix4::from_angle_z(s.angle);
|
||||
let translate = Matrix4::from_translation(match s.pos {
|
||||
super::AnchoredUiPosition::NorthWest(p) => Vector3 {
|
||||
super::AnchoredUiPosition::NwC(p) => Vector3 {
|
||||
// Note the signs. Positive y points north!
|
||||
x: -1.0 + p.x / (logical_size.width / 2.0),
|
||||
y: 1.0 + p.y / (logical_size.height / 2.0),
|
||||
z: 0.0,
|
||||
},
|
||||
super::AnchoredUiPosition::NwNw(p) => Vector3 {
|
||||
x: -1.0 + (width / 2.0 + p.x) / (logical_size.width / 2.0),
|
||||
y: 1.0 - (height / 2.0 - p.y) / (logical_size.height / 2.0),
|
||||
z: 0.0,
|
||||
},
|
||||
_ => Vector3 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
super::AnchoredUiPosition::NwNe(p) => Vector3 {
|
||||
x: -1.0 - (width / 2.0 - p.x) / (logical_size.width / 2.0),
|
||||
y: 1.0 - (height / 2.0 - p.y) / (logical_size.height / 2.0),
|
||||
z: 0.0,
|
||||
},
|
||||
super::AnchoredUiPosition::NwSw(p) => Vector3 {
|
||||
x: -1.0 + (width / 2.0 + p.x) / (logical_size.width / 2.0),
|
||||
y: 1.0 + (height / 2.0 + p.y) / (logical_size.height / 2.0),
|
||||
z: 0.0,
|
||||
},
|
||||
super::AnchoredUiPosition::NwSe(p) => Vector3 {
|
||||
x: -1.0 - (width / 2.0 - p.x) / (logical_size.width / 2.0),
|
||||
y: 1.0 + (height / 2.0 + p.y) / (logical_size.height / 2.0),
|
||||
z: 0.0,
|
||||
},
|
||||
});
|
||||
let screen_aspect = Matrix4::from_nonuniform_scale(1.0 / self.window_aspect, 1.0, 1.0);
|
||||
|
||||
instances.push(SpriteInstance {
|
||||
transform: (OPENGL_TO_WGPU_MATRIX * translate * rotate * scale).into(),
|
||||
transform: (OPENGL_TO_WGPU_MATRIX * translate * screen_aspect * rotate * scale).into(),
|
||||
texture_index: texture.index,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,13 +8,25 @@ use cgmath::{Deg, Point2, Point3};
|
|||
/// positive X always points right.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AnchoredUiPosition {
|
||||
/// Position of this sprite's center,
|
||||
/// relative to the nw corner of the window.
|
||||
NwC(Point2<f32>),
|
||||
|
||||
/// Position of this sprite's nw corner,
|
||||
/// relative to the nw corner of the window.
|
||||
NorthWest(Point2<f32>),
|
||||
NwNw(Point2<f32>),
|
||||
|
||||
/// Position of this sprite's ne corner,
|
||||
/// relative to the nw corner of the window.
|
||||
NwNe(Point2<f32>),
|
||||
|
||||
/// Position of this sprite's sw corner,
|
||||
/// relative to the sw corner of the window.
|
||||
SouthWest(Point2<f32>),
|
||||
/// relative to the nw corner of the window.
|
||||
NwSw(Point2<f32>),
|
||||
|
||||
/// Position of this sprite's se corner,
|
||||
/// relative to the nw corner of the window.
|
||||
NwSe(Point2<f32>),
|
||||
}
|
||||
|
||||
/// A sprite that represents a ui element
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
use cgmath::{Deg, InnerSpace, Point2};
|
||||
use cgmath::{Deg, InnerSpace, Point2, Vector2};
|
||||
use galactica_content as content;
|
||||
use galactica_render::{AnchoredUiPosition, UiSprite};
|
||||
use galactica_world::{util, ShipPhysicsHandle, World};
|
||||
|
||||
// TODO: camera as one unit
|
||||
pub fn build_radar(
|
||||
ct: &content::Content,
|
||||
player: &ShipPhysicsHandle,
|
||||
physics: &World,
|
||||
ct: &content::Content,
|
||||
camera_zoom: f32,
|
||||
camera_aspect: f32,
|
||||
) -> Vec<UiSprite> {
|
||||
let mut out = Vec::new();
|
||||
|
||||
|
@ -15,7 +18,7 @@ pub fn build_radar(
|
|||
|
||||
out.push(UiSprite {
|
||||
texture: ct.get_texture_handle("ui::radar"),
|
||||
pos: AnchoredUiPosition::NorthWest(Point2 { x: 10.0, y: -10.0 }),
|
||||
pos: AnchoredUiPosition::NwNw(Point2 { x: 10.0, y: -10.0 }),
|
||||
dimensions: Point2 {
|
||||
x: radar_size,
|
||||
y: radar_size,
|
||||
|
@ -23,26 +26,98 @@ pub fn build_radar(
|
|||
angle: Deg(0.0),
|
||||
});
|
||||
|
||||
// Draw viewport frame
|
||||
let d = Vector2 {
|
||||
x: (camera_zoom / 2.0) * camera_aspect,
|
||||
y: camera_zoom / 2.0,
|
||||
};
|
||||
let m = d.magnitude() / radar_range;
|
||||
let d = d / radar_range * (radar_size / 2.0);
|
||||
println!("{:?}", d);
|
||||
if m < 0.8 {
|
||||
let texture = ct.get_texture_handle("ui::radarframe");
|
||||
let dimensions = Point2 {
|
||||
x: texture.aspect,
|
||||
y: 1.0,
|
||||
} * 7.0f32.min((0.8 - m) * 70.0);
|
||||
out.push(UiSprite {
|
||||
texture,
|
||||
pos: AnchoredUiPosition::NwNw(Point2 {
|
||||
x: (radar_size / 2.0 + 10.0) - d.x,
|
||||
y: (radar_size / -2.0 - 10.0) + d.y,
|
||||
}),
|
||||
dimensions,
|
||||
angle: Deg(0.0),
|
||||
});
|
||||
|
||||
out.push(UiSprite {
|
||||
texture,
|
||||
pos: AnchoredUiPosition::NwSw(Point2 {
|
||||
x: (radar_size / 2.0 + 10.0) - d.x,
|
||||
y: (radar_size / -2.0 - 10.0) - d.y,
|
||||
}),
|
||||
dimensions,
|
||||
angle: Deg(90.0),
|
||||
});
|
||||
|
||||
out.push(UiSprite {
|
||||
texture,
|
||||
pos: AnchoredUiPosition::NwSe(Point2 {
|
||||
x: (radar_size / 2.0 + 10.0) + d.x,
|
||||
y: (radar_size / -2.0 - 10.0) - d.y,
|
||||
}),
|
||||
dimensions,
|
||||
angle: Deg(180.0),
|
||||
});
|
||||
|
||||
out.push(UiSprite {
|
||||
texture,
|
||||
pos: AnchoredUiPosition::NwNe(Point2 {
|
||||
x: (radar_size / 2.0 + 10.0) + d.x,
|
||||
y: (radar_size / -2.0 - 10.0) + d.y,
|
||||
}),
|
||||
dimensions,
|
||||
angle: Deg(270.0),
|
||||
});
|
||||
}
|
||||
|
||||
let (_, pr) = physics.get_ship_body(player).unwrap();
|
||||
let pr = util::rigidbody_position(pr);
|
||||
let texture = ct.get_texture_handle("ui::blip");
|
||||
for (s, r) in physics.iter_ship_body() {
|
||||
if s.physics_handle == *player {
|
||||
continue;
|
||||
}
|
||||
let r = util::rigidbody_position(r);
|
||||
let d = r - pr;
|
||||
let p = util::rigidbody_position(r);
|
||||
let d = p - pr;
|
||||
let m = d.magnitude() / radar_range;
|
||||
if m < 0.8 {
|
||||
let angle: Deg<f32> = util::rigidbody_rotation(r)
|
||||
.angle(Vector2 { x: 0.0, y: 1.0 })
|
||||
.into();
|
||||
if s.physics_handle == *player {
|
||||
out.push(UiSprite {
|
||||
texture: ct.get_texture_handle("ui::blip"),
|
||||
pos: AnchoredUiPosition::NorthWest(
|
||||
texture,
|
||||
pos: AnchoredUiPosition::NwC(Point2 {
|
||||
x: radar_size / 2.0 + 10.0,
|
||||
y: radar_size / -2.0 - 10.0,
|
||||
}),
|
||||
dimensions: Point2 {
|
||||
x: texture.aspect,
|
||||
y: 1.0,
|
||||
} * 5.0f32.min((0.8 - m) * 50.0),
|
||||
angle: -angle,
|
||||
});
|
||||
} else if m < 0.8 {
|
||||
out.push(UiSprite {
|
||||
texture,
|
||||
pos: AnchoredUiPosition::NwC(
|
||||
Point2 {
|
||||
x: radar_size / 2.0 + 10.0,
|
||||
y: radar_size / -2.0 - 10.0,
|
||||
} + (d / radar_range * 150.0),
|
||||
} + (d / radar_range * (radar_size / 2.0)),
|
||||
),
|
||||
dimensions: Point2 { x: 1.0, y: 1.0 } * 5.0f32.min((0.8 - m) * 50.0),
|
||||
angle: Deg(0.0),
|
||||
dimensions: Point2 {
|
||||
x: texture.aspect,
|
||||
y: 1.0,
|
||||
} * 5.0f32.min((0.8 - m) * 50.0),
|
||||
angle: -angle,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,4 +8,7 @@ pub struct Camera {
|
|||
/// Camera zoom
|
||||
/// (How many game units tall is the viewport?)
|
||||
pub zoom: f32,
|
||||
|
||||
/// Aspect ratio of viewport (width / height)
|
||||
pub aspect: f32,
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ impl Game {
|
|||
camera: Camera {
|
||||
pos: (0.0, 0.0).into(),
|
||||
zoom: 500.0,
|
||||
aspect: 1.0,
|
||||
},
|
||||
system: object::System::new(&ct, SystemHandle { index: 0 }),
|
||||
|
||||
|
@ -179,6 +180,12 @@ impl Game {
|
|||
}
|
||||
|
||||
pub fn get_ui_sprites(&self) -> Vec<UiSprite> {
|
||||
return ui::build_radar(&self.player, &self.physics, &self.content);
|
||||
return ui::build_radar(
|
||||
&self.content,
|
||||
&self.player,
|
||||
&self.physics,
|
||||
self.camera.zoom,
|
||||
self.camera.aspect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ fn main() -> Result<()> {
|
|||
|
||||
let mut game = game::Game::new(content);
|
||||
gpu.update_starfield_buffer();
|
||||
game.camera.aspect = gpu.window_size.width as f32 / gpu.window_size.height as f32;
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
match event {
|
||||
|
@ -75,9 +76,13 @@ fn main() -> Result<()> {
|
|||
}
|
||||
WindowEvent::Resized(_) => {
|
||||
gpu.resize();
|
||||
game.camera.aspect =
|
||||
gpu.window_size.width as f32 / gpu.window_size.height as f32;
|
||||
}
|
||||
WindowEvent::ScaleFactorChanged { .. } => {
|
||||
gpu.resize();
|
||||
game.camera.aspect =
|
||||
gpu.window_size.width as f32 / gpu.window_size.height as f32;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue