chore: squash commits

This commit is contained in:
Muhammad Nauman Raza 2024-04-12 11:05:08 +01:00
parent 7d6044c9cf
commit 61cf4b9f74
Signed by: devraza
GPG key ID: 91EAD6081011574B
10 changed files with 910 additions and 472 deletions

1153
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -2,6 +2,9 @@
name = "ambition" name = "ambition"
version = "0.4.0" version = "0.4.0"
edition = "2021" edition = "2021"
authors = ["Muhammad Nauman Raza <devraza.hazard643@slmail.me>"]
description = "A fast-paced 2D MMORPG."
readme = "README.md"
# Squeeze out more performance for `release` builds - very slow compile times # Squeeze out more performance for `release` builds - very slow compile times
[profile.release] [profile.release]
@ -15,7 +18,7 @@ opt-level = 1
opt-level = 3 opt-level = 3
[dependencies] [dependencies]
bevy = { version = "0.13.0" } bevy = { version = "0.13.2", features = ["wayland"] }
bevy_egui = "0.25.0" bevy_egui = "0.27.1"
bevy_hanabi = "0.10.0" bevy_hanabi = "0.11.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"

View file

@ -1,7 +1,7 @@
*Go forth and realise your...* *Go forth and realise your...*
# Ambition # Ambition
A fast-paced, textual 2D multiplayer role-playing game written in Rust. A fast-paced 2D multiplayer role-playing game written in Rust.
## Credits ## Credits
- [Muhammad Nauman Raza](https://github.com/devraza) - Project manager/founder, producer, and programmer - [Muhammad Nauman Raza](https://github.com/devraza) - Project manager/founder, producer, and programmer

View file

@ -21,11 +21,11 @@
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1710868679, "lastModified": 1713543440,
"narHash": "sha256-V1o2bCZdeYKP/0zgVp4EN0KUjMItAMk6J7SvCXUI5IU=", "narHash": "sha256-lnzZQYG0+EXl/6NkGpyIz+FEOc/DSEG57AP1VsdeNrM=",
"owner": "guibou", "owner": "guibou",
"repo": "nixGL", "repo": "nixGL",
"rev": "d709a8abcde5b01db76ca794280745a43c8662be", "rev": "310f8e49a149e4c9ea52f1adf70cdc768ec53f8a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -51,11 +51,11 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1711163522, "lastModified": 1716509168,
"narHash": "sha256-YN/Ciidm+A0fmJPWlHBGvVkcarYWSC+s3NTPk/P+q3c=", "narHash": "sha256-4zSIhSRRIoEBwjbPm3YiGtbd8HDWzFxJjw5DYSDy1n8=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "44d0940ea560dee511026a53f0e2e2cde489b4d4", "rev": "bfb7a882678e518398ce9a31a881538679f6f092",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -1,5 +1,5 @@
{ {
description = "Rust development environment for Ambition using fenix"; description = "Rust development environment for Ambition";
inputs = { inputs = {
utils.url = "github:numtide/flake-utils"; utils.url = "github:numtide/flake-utils";
@ -41,16 +41,14 @@
pkgs.udev pkgs.udev
pkgs.alsa-lib pkgs.alsa-lib
pkgs.libxkbcommon pkgs.libxkbcommon
pkgs.wayland
]}"''; ]}"'';
buildInputs = with pkgs; [ buildInputs = with pkgs; [
xorg.libX11 xorg.libXcursor xorg.libXi xorg.libXrandr # To use the x11 feature xorg.libX11 xorg.libXcursor xorg.libXi xorg.libXrandr # To use the x11 feature
libxkbcommon # To use the wayland feature libxkbcommon wayland # To use the wayland feature
udev alsa-lib vulkan-loader udev alsa-lib vulkan-loader
pkgs.nixgl.nixVulkanIntel
mold pkgs.nixgl.nixVulkanIntel mold clang pkg-config tokei
clang
pkg-config
tokei
]; ];
}; };
} }

View file

@ -4,4 +4,4 @@ timestamp := `date +"%Y-%m-%d\ %H:%M"`
# Backup assets # Backup assets
backup: backup:
ouch compress assets/player assets/logo assets/attacks ~/NAS/Documents/Ambition/{{timestamp}}.tar.gz ouch compress assets/player assets/logo assets/attacks ~/NAS/Documents/Ambition/Assets/{{timestamp}}.tar.gz

62
src/enemy.rs Normal file
View file

@ -0,0 +1,62 @@
use bevy::prelude::*;
use std::f32::consts::PI;
use crate::player::*;
// Define the enemy component
#[derive(Component)]
pub struct Enemy {
pub name: String,
pub movement_speed: f32,
/*
pub rotation_speed: f32,
pub health: f32,
pub health_max: f32,
pub stamina: f32,
pub stamina_max: f32,
pub mana: f32,
pub mana_max: f32,
*/
}
// Define the enemy movement system
#[allow(clippy::type_complexity)]
pub fn enemy_movement(
time: Res<Time>,
mut set: ParamSet<(
Query<&Transform, With<Player>>,
Query<&mut Transform, With<Enemy>>,
)>,
mut enemy_query: Query<&Enemy>,
) {
let enemy = enemy_query.single_mut();
// Bring the player translation into scope
let mut player_translation = Vec3::ZERO;
for player_transform in set.p0().iter_mut() {
player_translation = player_transform.translation;
}
// Get the enemy's movement distance (based on movement speed)
let movement_distance = enemy.movement_speed * time.delta_seconds();
for mut enemy_transform in set.p1().iter_mut() {
// Calculate the angle from the enemy to the player's position
let difference = player_translation - enemy_transform.translation;
let angle = difference.y.atan2(difference.x) - PI / 2.; // Subtract PI/2. to orient the enemy correctly
// Return a Quat for the enemy's movement direction based on the angle
let movement_direction = Quat::from_axis_angle(Vec3::new(0., 0., 1.), angle);
// Update the rotation and translation of the enemy
enemy_transform.rotation = movement_direction;
enemy_transform.translation += movement_direction * Vec3::Y * movement_distance;
}
}
pub fn change_enemy_color(mut query: Query<&mut Sprite, With<Enemy>>) {
for mut sprite in query.iter_mut() {
sprite.color = Color::rgb(0.5, 1.0, 0.5);
}
}

View file

@ -13,12 +13,14 @@ mod player;
use crate::player::*; use crate::player::*;
mod ui; mod ui;
use crate::ui::*; use crate::ui::*;
mod enemy;
use crate::enemy::*;
// Version information // Version information
const VERSION: &str = env!("CARGO_PKG_VERSION"); const VERSION: &str = env!("CARGO_PKG_VERSION");
const PKGNAME: &str = env!("CARGO_PKG_NAME"); const PKGNAME: &str = env!("CARGO_PKG_NAME");
// Create a map of the Hypernova colorscheme // Create a map of the kagayaki colorscheme
lazy_static! { lazy_static! {
static ref KAGAYAKI: HashMap<&'static str, (u8, u8, u8)> = vec![ static ref KAGAYAKI: HashMap<&'static str, (u8, u8, u8)> = vec![
("BLACK", (13, 13, 15)), ("BLACK", (13, 13, 15)),
@ -59,7 +61,15 @@ fn main() {
.add_systems(Startup, (setup, setup_ui)) .add_systems(Startup, (setup, setup_ui))
.add_systems( .add_systems(
Update, Update,
(render_ui, movement, camera_follow, player_regen, attack), (
render_ui,
player_movement,
player_regen,
player_attack,
attack_movement,
enemy_movement,
change_enemy_color,
),
) )
.run(); .run();
} }
@ -97,4 +107,29 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
mana: 100., mana: 100.,
mana_max: 100., mana_max: 100.,
}); });
// Spawn an enemy
commands
.spawn(SpriteBundle {
texture: asset_server.load("player/player-4x.png"),
transform: Transform {
scale: Vec3::splat(0.2),
..default()
},
..default()
})
.insert(Enemy {
name: "Goblin".to_string(),
movement_speed: 256.,
/*
rotation_speed: f32::to_radians(360.),
health: 10.,
health_max: 10.,
stamina: 10.,
stamina_max: 10.,
mana: 100.,
mana_max: 100.,
*/
});
} }

View file

@ -22,10 +22,11 @@ pub struct Attack {
} }
// Define the player movement system // Define the player movement system
pub fn movement( pub fn player_movement(
time: Res<Time>, time: Res<Time>,
keys: Res<ButtonInput<KeyCode>>, keys: Res<ButtonInput<KeyCode>>,
mut player_query: Query<(&mut Player, &mut Transform), With<Player>>, mut player_query: Query<(&mut Player, &mut Transform), With<Player>>,
camera_query: Query<&mut Transform, (Without<Player>, With<Camera>)>,
) { ) {
let (mut player, mut transform) = player_query.single_mut(); let (mut player, mut transform) = player_query.single_mut();
@ -66,62 +67,63 @@ pub fn movement(
// Update the player translation with the translation // Update the player translation with the translation
transform.translation += movement_direction * movement_distance; transform.translation += movement_direction * movement_distance;
camera_follow(
camera_query,
transform.translation.x,
transform.translation.y,
)
} }
pub fn attack( #[allow(clippy::type_complexity)]
pub fn player_attack(
keys: Res<ButtonInput<KeyCode>>, keys: Res<ButtonInput<KeyCode>>,
mut set: ParamSet<( mut player_query: Query<(&Transform, &mut Player), With<Player>>,
Query<&mut Transform, With<Attack>>,
Query<&Transform, With<Player>>,
)>,
mut player_query: Query<&mut Player>,
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
) { ) {
let mut player = player_query.single_mut(); let (transform, mut player) = player_query.single_mut();
let attack_position = transform.translation + (transform.rotation * Vec3::Y * 100.);
for player_transform in set.p1().iter_mut() { if keys.just_pressed(KeyCode::Enter) {
let attack_position = commands
player_transform.translation + ((player_transform.rotation * Vec3::Y) * 100.); .spawn(SpriteBundle {
texture: asset_server.load("attacks/stone_cannon.png"),
transform: Transform {
scale: Vec3::splat(0.3),
translation: attack_position,
rotation: transform.rotation,
},
..default()
})
.insert(Attack {
velocity: 20.,
damage: 20.,
});
if keys.just_pressed(KeyCode::Enter) { player.mana -= 1.;
commands
.spawn(SpriteBundle {
texture: asset_server.load("attacks/stone_cannon.png"),
transform: Transform {
scale: Vec3::splat(0.3),
translation: attack_position,
rotation: player_transform.rotation,
},
..default()
})
.insert(Attack {
velocity: 10.,
damage: 20.,
});
player.mana -= 1.;
}
} }
}
for mut attack_transform in set.p0().iter_mut() { pub fn attack_movement(mut attack_query: Query<(&mut Transform, Option<&Attack>), With<Attack>>) {
let direction = attack_transform.rotation * Vec3::Y; for (mut transform, attack) in attack_query.iter_mut() {
attack_transform.translation += direction * 20.; if let Some(attack) = attack {
let direction = transform.rotation * Vec3::Y;
transform.translation += direction * attack.velocity;
}
} }
} }
// Function to make the camera follow the plaeyr // Function to make the camera follow the plaeyr
pub fn camera_follow( fn camera_follow(
mut player: Query<(&Player, &mut Transform)>, mut camera_query: Query<&mut Transform, (Without<Player>, With<Camera>)>,
mut cameras: Query<&mut Transform, (With<Camera>, Without<Player>)>, player_x: f32,
player_y: f32,
) { ) {
let (_, transform) = player.single_mut(); let mut camera_transform = camera_query.single_mut();
let pos = transform.translation;
for mut camera_transform in &mut cameras { camera_transform.translation.x = player_x;
camera_transform.translation.x = pos.x; camera_transform.translation.y = player_y;
camera_transform.translation.y = pos.y;
}
} }
pub fn player_regen(mut player_query: Query<&mut Player, With<Player>>, time: Res<Time>) { pub fn player_regen(mut player_query: Query<&mut Player, With<Player>>, time: Res<Time>) {

View file

@ -105,7 +105,7 @@ pub fn render_ui(
egui::CentralPanel::default() egui::CentralPanel::default()
.frame(egui::containers::Frame { .frame(egui::containers::Frame {
fill: egui::Color32::TRANSPARENT, fill: egui::Color32::TRANSPARENT,
inner_margin: egui::style::Margin::same(10.), inner_margin: crate::ui::egui::Margin::same(10.),
..default() ..default()
}) })
.show(ctx, |ui| { .show(ctx, |ui| {
@ -116,8 +116,9 @@ pub fn render_ui(
egui::Grid::new("Stats") egui::Grid::new("Stats")
.spacing(egui::Vec2::new(20., 10.)) .spacing(egui::Vec2::new(20., 10.))
.show(ui, |ui| { .show(ui, |ui| {
let health_bar = egui::widgets::ProgressBar::new(player.health) let health_bar =
.desired_width(window_width / 10.); egui::widgets::ProgressBar::new(player.health / player.health_max)
.desired_width(window_width / 10.);
let mut stamina_bar = let mut stamina_bar =
egui::widgets::ProgressBar::new(player.stamina / player.stamina_max) egui::widgets::ProgressBar::new(player.stamina / player.stamina_max)
.desired_width(window_width / 10.); .desired_width(window_width / 10.);