Skip to content

Commit 2894f92

Browse files
committed
feat(perfs): Pre compute collision to improve performance, fixed wrong sound effect for the air
1 parent 3fdc3a7 commit 2894f92

File tree

8 files changed

+79
-31
lines changed

8 files changed

+79
-31
lines changed

.github/workflows/on_release.yml

+6-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
matrix:
1212
config:
13-
- { os: ubuntu-18.04, name: starlight-1961-linux, archive: starlight-1961_linux.zip, bin: starlight-1961, ui: vulkan }
13+
- { os: ubuntu-18.04, name: starlight-1961-linux, archive: starlight-1961_linux.tar.gz, bin: starlight-1961, ui: vulkan }
1414
- { os: macos-latest, name: starlight-1961-macos, archive: starlight-1961_macOs.zip,bin: starlight-1961, ui: metal }
1515
- { os: windows-latest, name: starlight-1961-windows, archive: starlight-1961_windows.zip,bin: starlight-1961.exe, ui: vulkan }
1616
steps:
@@ -33,9 +33,12 @@ jobs:
3333
run: |
3434
move target/release/${{matrix.config.bin}} ${{matrix.config.name}}/${{matrix.config.bin}}
3535
move assets ${{matrix.config.name}}/assets
36-
- name: Zip files (Linux & Mac)
37-
if: matrix.config.os != 'windows-latest'
36+
- name: Zip files Mac
37+
if: matrix.config.os == 'macos-latest'
3838
run: 7z a -t7z ${{matrix.config.archive}} ${{matrix.config.name}}
39+
- name: Zip files Linux
40+
if: matrix.config.os == 'ubuntu-18.04'
41+
run: tar -zcvf ${{matrix.config.archive}} ${{matrix.config.name}}
3942
- name: Zip files (Windows)
4043
if: matrix.config.os == 'windows-latest'
4144
run: 7z a -t7z ${{matrix.config.archive}} ${{matrix.config.name}}

assets/sprites/main.png

-92 Bytes
Loading

src/entities/collision.rs

+43-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
use crate::utils::Point2D;
1+
use crate::utils::{Point2D, min_of_f32_vec, max_of_f32_vec};
22
use amethyst::core::ecs::{Component, DenseVecStorage};
33
use geo::{Polygon, LineString};
44
use geo::intersects::Intersects;
5+
use std::cmp::Ordering;
56

67
pub struct ButtonPlatform;
78

@@ -29,23 +30,42 @@ impl Component for Transparent {
2930

3031
#[derive(Debug)]
3132
pub struct Colliders {
33+
pub min_x: f32,
34+
pub min_y: f32,
35+
pub max_x: f32,
36+
pub max_y: f32,
3237
colliders: Vec<Collider>,
33-
polygons: Vec<Polygon<f32>>
38+
polygons: Vec<Polygon<f32>>,
3439
}
3540

3641
impl Colliders {
3742
pub fn from_vec(colliders: Vec<Collider>) -> Colliders {
38-
Colliders { polygons: colliders.iter().map(|collider| collider.to_polygon()).collect(), colliders }
39-
}
40-
pub fn from_points(a: Point2D, b: Point2D, c: Point2D ,d: Point2D ) -> Colliders {
41-
Colliders { polygons: vec![
42-
Polygon::new(
43-
LineString::from(
44-
vec![(a.x, a.y), (b.x, b.y), (c.x, c.y), (d.x, d.y), (a.x, a.y)]
45-
),
46-
vec![],
43+
let (min_x, min_y, max_x, max_y) = {
44+
(
45+
colliders.iter().map(|col| min_of_f32_vec([col.a.x, col.b.x, col.c.x, col.d.x])).min_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)).unwrap(),
46+
colliders.iter().map(|col| min_of_f32_vec([col.a.y, col.b.y, col.c.y, col.d.y])).min_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)).unwrap(),
47+
colliders.iter().map(|col| max_of_f32_vec([col.a.x, col.b.x, col.c.x, col.d.x])).max_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)).unwrap(),
48+
colliders.iter().map(|col| max_of_f32_vec([col.a.y, col.b.y, col.c.y, col.d.y])).max_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)).unwrap()
4749
)
48-
], colliders: Vec::new() }
50+
};
51+
Colliders { polygons: colliders.iter().map(|collider| collider.to_polygon()).collect(), colliders, min_x, min_y, max_x, max_y }
52+
}
53+
pub fn from_points(a: Point2D, b: Point2D, c: Point2D, d: Point2D) -> Colliders {
54+
Colliders {
55+
polygons: vec![
56+
Polygon::new(
57+
LineString::from(
58+
vec![(a.x, a.y), (b.x, b.y), (c.x, c.y), (d.x, d.y), (a.x, a.y)]
59+
),
60+
vec![],
61+
)
62+
],
63+
colliders: Vec::new(),
64+
min_x: min_of_f32_vec([a.x, b.x, c.x, d.x]),
65+
min_y: min_of_f32_vec([a.y, b.y, c.y, d.y]),
66+
max_x: max_of_f32_vec([a.x, b.x, c.x, d.x]),
67+
max_y: max_of_f32_vec([a.y, b.y, c.y, d.y]),
68+
}
4969
}
5070

5171
pub fn polygons(&self) -> &Vec<Polygon<f32>> {
@@ -63,10 +83,10 @@ impl Component for Colliders {
6383

6484
#[derive(Debug)]
6585
pub struct Collider {
66-
a: Point2D,
67-
b: Point2D,
68-
c: Point2D,
69-
d: Point2D,
86+
pub a: Point2D,
87+
pub b: Point2D,
88+
pub c: Point2D,
89+
pub d: Point2D,
7090
}
7191

7292
impl Collider {
@@ -97,7 +117,6 @@ impl Collider {
97117
}
98118

99119
pub fn are_colliding(ship_polygon: &Vec<Polygon<f32>>, struct_polygons: &Vec<Polygon<f32>>) -> bool {
100-
101120
for polygon in ship_polygon.iter() {
102121
for struct_polygon in struct_polygons.iter() {
103122
if polygon.intersects(struct_polygon) {
@@ -106,4 +125,11 @@ pub fn are_colliding(ship_polygon: &Vec<Polygon<f32>>, struct_polygons: &Vec<Pol
106125
}
107126
}
108127
false
128+
}
129+
130+
pub fn compute_is_eligible_for_collision(col1: &Colliders, col2: &Colliders) -> bool {
131+
!(col1.min_x < col2.min_x && col1.max_x < col2.min_x && col1.min_x < col2.max_x && col1.max_x < col2.max_x)
132+
&& !(col1.min_x > col2.min_x && col1.max_x > col2.min_x && col1.min_x > col2.max_x && col1.max_x > col2.max_x)
133+
&& !(col1.min_y < col2.min_y && col1.max_y < col2.min_y && col1.min_y < col2.max_y && col1.max_y < col2.max_y)
134+
&& !(col1.min_y > col2.min_y && col1.max_y > col2.min_y && col1.min_y > col2.max_y && col1.max_y > col2.max_y)
109135
}

src/resources/main_resource.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,13 @@ impl MainResource {
127127
}
128128

129129
pub fn get_colliders_polygons_for_collision(&self, x: f32, y:f32) -> Vec<Polygon<f32>> {
130+
self.get_colliders_for_collision(x, y).to_owned_polygons()
131+
}
132+
133+
pub fn get_colliders_for_collision(&self, x: f32, y:f32) -> Colliders {
130134
let main_collider = Collider::new(Point2D{x: x+2., y: y-2.}, 28., -28.);
131135
let colliders = Colliders::from_vec(vec![main_collider]);
132-
colliders.to_owned_polygons()
136+
colliders
133137
}
134138

135139
pub fn get_colliders_polygons_for_landing(&self, x: f32, y:f32) -> Vec<Polygon<f32>> {

src/systems/bullet_system.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use amethyst::core::ecs::{System, ReadStorage, WriteStorage, Join, Read, Entitie
22
use crate::entities::canons::{Bullet, Canon, CanonKind, canon_kind_to_bullet_speed, canon_kind_to_bullet_life_duration};
33
use amethyst::core::{Transform, Time};
44
use crate::utils::Direction;
5-
use crate::entities::collision::{Colliders, are_colliding};
5+
use crate::entities::collision::{Colliders, are_colliding, compute_is_eligible_for_collision};
66
use geo::Polygon;
77
use crate::utils::sprites::sprite_to_entities::init_bullet_collider;
88
use crate::resources::main_resource::MainResource;
@@ -48,7 +48,7 @@ impl<'s> System<'s> for BulletSystem {
4848
for (_ship, transform) in (&ships, &transforms).join() {
4949
ship_polygon = main_resource.get_colliders_polygons_for_collision(transform.translation().x, transform.translation().y);
5050
}
51-
let mut bullet_vec: Vec<(u32, Vec<Polygon<f32>>)> = Vec::new();
51+
let mut bullet_vec: Vec<(u32, Colliders)> = Vec::new();
5252
for (bullet, transform, entity) in (&mut bullets, &mut transforms, &entities).join() {
5353
let colliders = init_bullet_collider(&bullet.kind, transform.translation().x, transform.translation().y);
5454
match bullet.kind {
@@ -77,7 +77,7 @@ impl<'s> System<'s> for BulletSystem {
7777
}
7878
}
7979
}else{
80-
bullet_vec.push((entity.id(), colliders.polygons().clone()));
80+
bullet_vec.push((entity.id(), colliders));
8181
}
8282
let bullet_speed = canon_kind_to_bullet_speed(&bullet.kind);
8383
match bullet.direction {
@@ -91,9 +91,13 @@ impl<'s> System<'s> for BulletSystem {
9191
if bullet.life_duration <= 0. { let _res = entities.delete(entity); }
9292
}
9393

94-
let joined: Vec<_> = (&colliders, !&bullets, !&canons).join().flat_map(|(a,b,c)| a.to_owned_polygons()).collect();
95-
for (id, polygons) in bullet_vec.iter(){
96-
if are_colliding(&polygons, &joined) {
94+
let joined: Vec<_> = (&colliders, !&bullets, !&canons)
95+
.join()
96+
.filter(|(a, b, c)| {
97+
return bullet_vec.iter().any(|(id, collider)| compute_is_eligible_for_collision(*a, &collider));
98+
}).flat_map(|(a,b,c)| a.to_owned_polygons()).collect();
99+
for (id, col) in bullet_vec.iter(){
100+
if are_colliding(&col.to_owned_polygons(), &joined) {
97101
let e = entities.entity(*id);
98102
let _res = entities.delete(e);
99103
}

src/systems/collision_system.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use amethyst::core::ecs::{System, ReadStorage, Write, Join};
2-
use crate::entities::collision::{Colliders, LandingPlatform, are_colliding};
2+
use crate::entities::collision::{Colliders, LandingPlatform, are_colliding, compute_is_eligible_for_collision};
33
use crate::entities::ship::ShipParent;
44
use amethyst::core::Transform;
55
use crate::resources::main_resource::MainResource;
@@ -23,10 +23,11 @@ impl<'s> System<'s> for CollisionSystem {
2323

2424
fn run(&mut self, (colliders, landing_plateforms,plasma_doors, bonus, ships, transforms, mut ship_resource, bullets): Self::SystemData) {
2525
for (_ship, transform) in (&ships, &transforms).join() {
26-
let ship_polygon = ship_resource.get_colliders_polygons_for_collision(transform.translation().x, transform.translation().y);
26+
let ship_collider = ship_resource.get_colliders_for_collision(transform.translation().x, transform.translation().y);
27+
let ship_polygon = ship_collider.to_owned_polygons();
2728
for (collider, _, _, _, _) in (&colliders, !&landing_plateforms, !&bullets, !&plasma_doors, !&bonus).join() {
2829
let struct_polygons = collider.polygons();
29-
if !ship_resource.is_exploding && are_colliding(&ship_polygon, struct_polygons) {
30+
if !ship_resource.is_exploding && compute_is_eligible_for_collision(&collider, &ship_collider) && are_colliding(&ship_polygon, struct_polygons) {
3031
ship_resource.ship_life -= ship_resource.ship_life;
3132
}
3233
}

src/utils/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,14 @@ pub enum Direction {
1515

1616
pub fn distance_between_two_points(xa: f32, ya:f32, xb:f32, yb:f32) -> f32 {
1717
((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb)).sqrt()
18+
}
19+
20+
pub fn min_of_f32_vec(mut list: [f32; 4]) -> f32 {
21+
list.sort_by(|a, b| a.partial_cmp(b).unwrap());
22+
list[0]
23+
}
24+
25+
pub fn max_of_f32_vec(mut list: [f32; 4]) -> f32 {
26+
list.sort_by(|a, b| b.partial_cmp(a).unwrap());
27+
list[0]
1828
}

src/utils/sound.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub fn play_bonus(sounds: &Sounds, storage: &AssetStorage<Source>, output: Optio
9898

9999
pub fn play_air(sounds: &Sounds, storage: &AssetStorage<Source>, output: Option<&Output>) {
100100
if let Some(ref output) = output.as_ref() {
101-
if let Some(sound) = storage.get(&sounds.bonus) {
101+
if let Some(sound) = storage.get(&sounds.air) {
102102
output.play_once(sound, 1.0);
103103
}
104104
}

0 commit comments

Comments
 (0)