Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Part 2 #2

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/bones.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 modified assets/enemy.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 modified assets/player.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
1 change: 1 addition & 0 deletions maps/map2

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions maps/map3

Large diffs are not rendered by default.

136 changes: 136 additions & 0 deletions src/bullet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
use crate::health_system::{DeathEvent, HealthData, ReadDeaths, TakeDamageEvent};
use crate::move_system::{
CollisionEvent, MoveObjectType, MoveSystemObjectWithVelocity, VelocityVector,
};
use crate::player::Speed;
use crate::{AppState, Hitbox};
use bevy::prelude::*;

const BULLET_START_SPEED: f32 = 10.;

pub struct BulletPlugin;

impl Plugin for BulletPlugin {
fn build(&self, app: &mut App) {
app.add_system_set(
SystemSet::on_update(AppState::InGame)
.with_system(despawn_bullets_after_collision.label(ReadDeaths)),
);
}
}

#[derive(Component, Copy, Clone)]
pub struct PlayerBulletMarker;

#[derive(Component, Copy, Clone)]
pub struct EnemyBulletMarker;

#[derive(Component)]
pub struct DirectionVector(pub Vec2);

#[derive(Bundle)]
pub struct PlayerBulletBundle {
marker: PlayerBulletMarker,
speed: Speed,
direction: DirectionVector,
#[bundle]
move_system_bundle: MoveSystemObjectWithVelocity,
health_data: HealthData,
}

impl PlayerBulletBundle {
pub fn new(hitbox: Hitbox, vel: Vec2) -> PlayerBulletBundle {
PlayerBulletBundle {
marker: PlayerBulletMarker,
speed: Speed(BULLET_START_SPEED),
direction: DirectionVector(vel),
move_system_bundle: MoveSystemObjectWithVelocity::new_with_vel_0(
MoveObjectType::PlayerBullet,
hitbox,
),
health_data: HealthData::new_health(1),
}
}
}

#[derive(Bundle)]
pub struct EnemyBulletBundle {
marker: EnemyBulletMarker,
speed: Speed,
direction: DirectionVector,
#[bundle]
move_system_bundle: MoveSystemObjectWithVelocity,
health_data: HealthData,
}

impl EnemyBulletBundle {
pub fn new(hitbox: Hitbox, vel: Vec2) -> EnemyBulletBundle {
EnemyBulletBundle {
marker: EnemyBulletMarker,
speed: Speed(BULLET_START_SPEED),
direction: DirectionVector(vel),
move_system_bundle: MoveSystemObjectWithVelocity::new_with_vel_0(
MoveObjectType::EnemyBullet,
hitbox,
),
health_data: HealthData::new_health(1),
}
}
}

pub fn spawn_bullets<B>(
commands: &mut Commands,
bullet_bundle: B,
sprite_bundle: SpriteBundle,
timer: &mut ResMut<Timer>,
) where
B: Bundle,
{
if timer.finished() {
commands
.spawn_bundle(bullet_bundle)
.insert_bundle(sprite_bundle);
timer.reset();
}
}

pub fn bullet_movement(
mut query: Query<
(&DirectionVector, &mut VelocityVector, &Speed),
Or<(With<EnemyBulletMarker>, With<PlayerBulletMarker>)>,
>,
) {
for (direction, mut vel, &Speed(speed)) in query.iter_mut() {
let new_vel = direction.0 * speed;
vel.0 += new_vel;
}
}

pub fn on_collision_bullet(
mut collision_reader: EventReader<CollisionEvent>,
query_bullet: Query<Entity, Or<(With<EnemyBulletMarker>, With<PlayerBulletMarker>)>>,
mut damage_writer: EventWriter<TakeDamageEvent>,
) {
for collision in collision_reader.iter() {
let bullet = query_bullet.get(collision.object_id);
if let Ok(bullet_entity) = bullet {
// commands.entity(bullet_entity).despawn();
damage_writer.send(TakeDamageEvent {
id: bullet_entity,
amount: 1,
});
}
}
}

pub fn despawn_bullets_after_collision(
mut commands: Commands,
mut death_reader: EventReader<DeathEvent>,
bullets: Query<Entity, Or<(With<EnemyBulletMarker>, With<PlayerBulletMarker>)>>,
) {
for death in death_reader.iter() {
if let Ok(bullet) = bullets.get(death.id) {
commands.entity(bullet).despawn();
}
}
}
17 changes: 9 additions & 8 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
use bevy::prelude::*;
use serde::{Deserialize, Serialize};

/// Position of an entity.
///
/// Maintenance note:
/// Might be replaced by Bevy's Vec2 or Vec3.
/// The 3-dimensional type would probably be better
/// since we *would* like to have entities
/// displayed properly, i.e. a player *on* a floor tile, etc.
/// no matter what the order of the rendered entities is.
// Position of an entity.
#[derive(Component, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct Position(pub f32, pub f32);

// Type of the entity.
#[derive(Clone, Copy, PartialEq)]
pub enum EntityType {
Wall,
Floor,
Player,
Enemy,
Bones,
}

// Information about given texture.
struct TextureInfo {
path: &'static str,
owner_type: EntityType,
Expand All @@ -42,13 +38,18 @@ const TEXTURES: &[TextureInfo] = &[
path: "player.png",
owner_type: EntityType::Player,
},
TextureInfo {
path: "bones.png",
owner_type: EntityType::Bones,
},
];

pub struct TextureWrapper {
pub texture: Handle<Image>,
pub owner_type: EntityType,
}

// Loads textures.
pub fn load_textures(mut commands: Commands, asset_server: Res<AssetServer>) {
let load_texture = |path: &str, owner_type: EntityType| {
let texture = asset_server.load(path);
Expand Down
Loading