Compare commits
No commits in common. "0eb55dbe58a1fac7e35fab0cc6f6869bf959fa3e" and "91c082def31b67ebb536c7afdd7f9df0b8ed2cfd" have entirely different histories.
0eb55dbe58
...
91c082def3
11 changed files with 52 additions and 154 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 180 B |
Binary file not shown.
|
Before Width: | Height: | Size: 204 B |
Binary file not shown.
|
Before Width: | Height: | Size: 193 B |
Binary file not shown.
|
Before Width: | Height: | Size: 181 B |
|
|
@ -1,67 +0,0 @@
|
||||||
use bevy::prelude::*;
|
|
||||||
// Source : https://bevy.org/examples/2d-rendering/sprite-sheet/
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
App::new()
|
|
||||||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) // prevents blurry sprites
|
|
||||||
.add_systems(Startup, setup)
|
|
||||||
.add_systems(Update, animate_sprite)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component, Default)]
|
|
||||||
pub struct AnimationIndices {
|
|
||||||
pub first: usize,
|
|
||||||
pub last: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AnimationIndices {
|
|
||||||
pub fn change(&mut self, first: usize, second: usize) {
|
|
||||||
self.first = first;
|
|
||||||
self.last = second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component, Deref, DerefMut)]
|
|
||||||
pub struct AnimationTimer(pub Timer);
|
|
||||||
|
|
||||||
pub fn animate_sprite(time: Res<Time>, mut query: Query<(&AnimationIndices, &mut AnimationTimer, &mut Sprite)>) {
|
|
||||||
for (indices, mut timer, mut sprite) in &mut query {
|
|
||||||
timer.tick(time.delta());
|
|
||||||
|
|
||||||
if timer.just_finished()
|
|
||||||
&& let Some(atlas) = &mut sprite.texture_atlas
|
|
||||||
{
|
|
||||||
atlas.index = if atlas.index >= indices.last || atlas.index < indices.first {
|
|
||||||
indices.first
|
|
||||||
} else {
|
|
||||||
atlas.index + 1
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn setup(
|
|
||||||
mut commands: Commands,
|
|
||||||
asset_server: Res<AssetServer>,
|
|
||||||
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
|
|
||||||
) {
|
|
||||||
let texture = asset_server.load("textures/rpg/chars/gabe/gabe-idle-run.png");
|
|
||||||
let layout = TextureAtlasLayout::from_grid(UVec2::splat(24), 7, 1, None, None);
|
|
||||||
let texture_atlas_layout = texture_atlas_layouts.add(layout);
|
|
||||||
// Use only the subset of sprites in the sheet that make up the run animation
|
|
||||||
let animation_indices = AnimationIndices { first: 1, last: 6 };
|
|
||||||
|
|
||||||
commands.spawn(Camera2d);
|
|
||||||
|
|
||||||
commands.spawn((
|
|
||||||
Sprite::from_atlas_image(
|
|
||||||
texture,
|
|
||||||
TextureAtlas { layout: texture_atlas_layout, index: animation_indices.first },
|
|
||||||
),
|
|
||||||
Transform::from_scale(Vec3::splat(6.0)),
|
|
||||||
animation_indices,
|
|
||||||
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
7
src/box_collider.rs
Normal file
7
src/box_collider.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
use bevy::{prelude::*, render::renderer};
|
||||||
|
|
||||||
|
#[derive(Component, Default)]
|
||||||
|
#[require(Transform)]
|
||||||
|
pub struct BoxCollider {
|
||||||
|
pub dimensions: Vec2,
|
||||||
|
}
|
||||||
|
|
@ -1,16 +1,13 @@
|
||||||
use std::f32::consts::TAU;
|
|
||||||
|
|
||||||
use crate::globals::MAX_MAP_WIDTH;
|
use crate::globals::MAX_MAP_WIDTH;
|
||||||
use crate::physics_body::PhysicsBody;
|
use crate::physics_body::PhysicsBody;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use rand::Rng;
|
|
||||||
|
|
||||||
const CELL_SIZE: usize = 8;
|
const CELL_SIZE: usize = 32;
|
||||||
const MAX_MAP_SIZE: usize = MAX_MAP_WIDTH * 2;
|
const MAX_MAP_SIZE: usize = MAX_MAP_WIDTH * 2;
|
||||||
const ARRAY_WIDTH: usize = MAX_MAP_SIZE / CELL_SIZE;
|
const ARRAY_WIDTH: usize = MAX_MAP_SIZE / CELL_SIZE;
|
||||||
const GRID_ARRAY_SIZE: usize = ARRAY_WIDTH * ARRAY_WIDTH;
|
const GRID_ARRAY_SIZE: usize = ARRAY_WIDTH * ARRAY_WIDTH;
|
||||||
|
|
||||||
const DENSITY_FORCE_SCALE: f32 = 6000.0;
|
const DENSITY_FORCE_SCALE: f32 = 100.0;
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct DensityGrid {
|
pub struct DensityGrid {
|
||||||
|
|
@ -37,16 +34,12 @@ fn get_index_from_uvec2(grid_cell: UVec2) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component, Default)]
|
#[derive(Component, Default)]
|
||||||
pub struct DensityObject {
|
pub struct DensityObject {}
|
||||||
random_offset: Vec2,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_density_object(mut density_grid: ResMut<DensityGrid>, mut query: Query<(&Transform, &mut DensityObject)>) {
|
pub fn init_density_object(mut density_grid: ResMut<DensityGrid>, mut query: Query<&Transform>) {
|
||||||
let mut rng = rand::rng();
|
for transform in &mut query {
|
||||||
for (transform, mut density_obj) in &mut query {
|
|
||||||
let grid_cell = pos_to_grid_cell(transform.translation.xy());
|
let grid_cell = pos_to_grid_cell(transform.translation.xy());
|
||||||
// println!("grid cell {:?}", grid_cell);
|
// println!("grid cell {:?}", grid_cell);
|
||||||
density_obj.random_offset = Vec2::from_angle(rng.random_range(0.0..TAU)) * 0.2;
|
|
||||||
let index = get_index_from_uvec2(grid_cell);
|
let index = get_index_from_uvec2(grid_cell);
|
||||||
density_grid.grid[index] += 1;
|
density_grid.grid[index] += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -64,9 +57,9 @@ pub fn density_grid_update(mut density_grid: ResMut<DensityGrid>, query: Query<&
|
||||||
|
|
||||||
pub fn density_grid_force(
|
pub fn density_grid_force(
|
||||||
density_grid: Res<DensityGrid>,
|
density_grid: Res<DensityGrid>,
|
||||||
mut query: Query<(&mut PhysicsBody, &Transform, &DensityObject)>,
|
mut query: Query<(&mut PhysicsBody, &Transform), With<DensityObject>>,
|
||||||
) {
|
) {
|
||||||
for (mut physics_body, transform, density_obj) in &mut query {
|
for (mut physics_body, transform) in &mut query {
|
||||||
let grid_cell = pos_to_grid_cell(transform.translation.xy());
|
let grid_cell = pos_to_grid_cell(transform.translation.xy());
|
||||||
let mut density_gradient = Vec2::ZERO;
|
let mut density_gradient = Vec2::ZERO;
|
||||||
|
|
||||||
|
|
@ -82,7 +75,6 @@ pub fn density_grid_force(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// println!("density : {:?}", density_gradient);
|
// println!("density : {:?}", density_gradient);
|
||||||
density_gradient += density_obj.random_offset; // To not have a "grid" thingy
|
|
||||||
physics_body.force -= density_gradient * DENSITY_FORCE_SCALE;
|
physics_body.force -= density_gradient * DENSITY_FORCE_SCALE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
65
src/kirby.rs
65
src/kirby.rs
|
|
@ -1,40 +1,25 @@
|
||||||
use crate::animation::{AnimationIndices, AnimationTimer};
|
|
||||||
use crate::physics_body::PhysicsBody;
|
use crate::physics_body::PhysicsBody;
|
||||||
use crate::sphere_collider::SphereCollider;
|
use crate::sphere_collider::SphereCollider;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
#[require(Sprite, PhysicsBody, SphereCollider, AnimationIndices)]
|
#[require(Sprite, PhysicsBody, SphereCollider)]
|
||||||
pub struct Kirby {
|
pub struct Kirby {
|
||||||
speed_force: f32,
|
speed_force: f32,
|
||||||
sucking: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kirby_spawn(
|
pub fn kirby_spawn(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
mut commands: Commands,
|
let sprite = Sprite::from_image(asset_server.load("sprites/kirby.png"));
|
||||||
asset_server: Res<AssetServer>,
|
|
||||||
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
|
|
||||||
) {
|
|
||||||
let texture: Handle<Image> = asset_server.load("sprites/Sprite_kirby-Sheet.png");
|
|
||||||
let body = PhysicsBody { mass: 10.0, force: Vec2::ZERO, velocity: Vec2::ZERO, drag: 0.05 };
|
let body = PhysicsBody { mass: 10.0, force: Vec2::ZERO, velocity: Vec2::ZERO, drag: 0.05 };
|
||||||
let layout = TextureAtlasLayout::from_grid(UVec2::splat(32), 3, 3, None, None);
|
let transform = Transform::from_xyz(0.0, 0.0, 0.0).with_scale(Vec3::ONE * 0.25);
|
||||||
let texture_atlas_layout = texture_atlas_layouts.add(layout);
|
commands.spawn((Kirby { speed_force: 10000.0 }, transform, sprite, body));
|
||||||
let animation_indices = AnimationIndices { first: 3, last: 5 }; // idle
|
|
||||||
|
|
||||||
commands.spawn((
|
|
||||||
Kirby { speed_force: 10000.0, sucking: false },
|
|
||||||
Sprite::from_atlas_image(
|
|
||||||
texture,
|
|
||||||
TextureAtlas { layout: texture_atlas_layout, index: animation_indices.first },
|
|
||||||
),
|
|
||||||
Transform::from_scale(Vec3::splat(3.0)),
|
|
||||||
animation_indices,
|
|
||||||
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
|
|
||||||
body,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_dir(keys: Res<ButtonInput<KeyCode>>) -> Vec2 {
|
pub fn get_dir(keys: Res<ButtonInput<KeyCode>>) -> Vec2 {
|
||||||
|
if keys.pressed(KeyCode::Space) {
|
||||||
|
println!("SUCKING");
|
||||||
|
}
|
||||||
|
|
||||||
let mut dir = Vec2::ZERO;
|
let mut dir = Vec2::ZERO;
|
||||||
|
|
||||||
if keys.pressed(KeyCode::KeyW) {
|
if keys.pressed(KeyCode::KeyW) {
|
||||||
|
|
@ -53,35 +38,13 @@ pub fn get_dir(keys: Res<ButtonInput<KeyCode>>) -> Vec2 {
|
||||||
dir.normalize_or_zero()
|
dir.normalize_or_zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kirby_actions(
|
pub fn kirby_player_move(keys: Res<ButtonInput<KeyCode>>, mut query: Query<(&mut PhysicsBody, &Kirby), With<Kirby>>) {
|
||||||
keys: Res<ButtonInput<KeyCode>>,
|
if keys.pressed(KeyCode::Space) {
|
||||||
mut query: Query<(&mut PhysicsBody, &mut Kirby, &mut AnimationIndices, &mut Transform, &mut Sprite), With<Kirby>>,
|
println!("SUCKING");
|
||||||
) {
|
}
|
||||||
let space_just_pressed = keys.just_pressed(KeyCode::Space);
|
|
||||||
let space_just_released = keys.just_released(KeyCode::Space);
|
|
||||||
let dir = get_dir(keys);
|
let dir = get_dir(keys);
|
||||||
for (mut body, mut kirby, mut anim_indices, mut transform, mut sprite) in &mut query {
|
for (mut body, kirby) in &mut query {
|
||||||
if space_just_released {
|
|
||||||
kirby.sucking = false
|
|
||||||
};
|
|
||||||
|
|
||||||
if space_just_pressed {
|
|
||||||
kirby.sucking = true;
|
|
||||||
anim_indices.change(0, 2);
|
|
||||||
};
|
|
||||||
|
|
||||||
if kirby.sucking {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
if dir.x != 0.0 {
|
|
||||||
sprite.flip_x = dir.x < 0.0;
|
|
||||||
}
|
|
||||||
body.force += dir * kirby.speed_force;
|
body.force += dir * kirby.speed_force;
|
||||||
if dir == Vec2::ZERO {
|
|
||||||
anim_indices.change(3, 5);
|
|
||||||
} else {
|
|
||||||
anim_indices.change(6, 8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,36 @@
|
||||||
use crate::density_grid::DensityObject;
|
use crate::density_grid::DensityObject;
|
||||||
use crate::kirby::Kirby;
|
use crate::kirby::Kirby;
|
||||||
use crate::physics_body::PhysicsBody;
|
use crate::physics_body::PhysicsBody;
|
||||||
|
use crate::sphere_collider::SphereCollider;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::f32::consts::TAU;
|
use std::f32::consts::TAU;
|
||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
#[require(Sprite, PhysicsBody, DensityObject)]
|
#[require(Sprite, PhysicsBody, SphereCollider, DensityObject)]
|
||||||
pub struct Bubble {
|
pub struct Lana {
|
||||||
move_force: f32,
|
move_force: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bubble_spawn(mut commands: Commands, asset_server: Res<AssetServer>) {
|
pub fn lana_spawn(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
let texture: Handle<Image> = asset_server.load("sprites/bubble.png");
|
let texture: Handle<Image> = asset_server.load("sprites/lana.png");
|
||||||
let mut rng = rand::rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
for _ in 0..1000 {
|
for _ in 0..1_000 {
|
||||||
let angle = rng.random_range(0.0..TAU);
|
let angle = rng.random_range(0.0..TAU);
|
||||||
let pos = Vec2::from_angle(angle) * 500.0;
|
let pos = Vec2::from_angle(angle) * 500.0;
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Bubble { move_force: 3000.0 },
|
Lana { move_force: 3000.0 },
|
||||||
Sprite { image: texture.clone(), ..default() },
|
Sprite { image: texture.clone(), ..default() },
|
||||||
Transform::from_translation(pos.extend(0.0)).with_scale(Vec3::splat(1.0)),
|
Transform::from_translation(pos.extend(0.0)).with_scale(Vec3::splat(0.02)),
|
||||||
PhysicsBody { mass: 10.0, force: Vec2::ZERO, velocity: Vec2::ZERO, drag: 0.05 },
|
PhysicsBody { mass: 10.0, force: Vec2::ZERO, velocity: Vec2::ZERO, drag: 0.05 },
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bubble_move(
|
pub fn lana_move(
|
||||||
mut lana_query: Query<(&mut PhysicsBody, &Transform, &Bubble), With<Bubble>>,
|
mut lana_query: Query<(&mut PhysicsBody, &Transform, &Lana), With<Lana>>,
|
||||||
kirby_query: Query<(&Transform, &Kirby), With<Kirby>>,
|
kirby_query: Query<(&Transform, &Kirby), With<Kirby>>,
|
||||||
) {
|
) {
|
||||||
for (mut lana_body, lana_transform, lana) in &mut lana_query {
|
for (mut lana_body, lana_transform, lana) in &mut lana_query {
|
||||||
|
|
@ -49,3 +49,9 @@ pub fn bubble_move(
|
||||||
lana_body.force += dir * lana.move_force;
|
lana_body.force += dir * lana.move_force;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
#[require(Sprite, Transform)]
|
||||||
|
pub struct KirbySuction {
|
||||||
|
box_size: Vec2,
|
||||||
|
}
|
||||||
19
src/main.rs
19
src/main.rs
|
|
@ -1,40 +1,37 @@
|
||||||
use animation::animate_sprite;
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bubble::bubble_move;
|
|
||||||
use bubble::bubble_spawn;
|
|
||||||
use camera::spawn_camera;
|
use camera::spawn_camera;
|
||||||
use density_grid::DensityGrid;
|
use density_grid::DensityGrid;
|
||||||
use density_grid::density_grid_force;
|
use density_grid::density_grid_force;
|
||||||
use density_grid::density_grid_update;
|
use density_grid::density_grid_update;
|
||||||
use density_grid::init_density_object;
|
use density_grid::init_density_object;
|
||||||
use kirby::kirby_actions;
|
use kirby::kirby_player_move;
|
||||||
use kirby::kirby_spawn;
|
use kirby::kirby_spawn;
|
||||||
|
use lana::lana_move;
|
||||||
|
use lana::lana_spawn;
|
||||||
use map::MapBounds;
|
use map::MapBounds;
|
||||||
use physics_body::integrate;
|
use physics_body::integrate;
|
||||||
|
|
||||||
mod animation;
|
|
||||||
mod bubble;
|
|
||||||
mod camera;
|
mod camera;
|
||||||
mod density_grid;
|
mod density_grid;
|
||||||
mod globals;
|
mod globals;
|
||||||
mod kirby;
|
mod kirby;
|
||||||
|
mod lana;
|
||||||
mod map;
|
mod map;
|
||||||
mod physics_body;
|
mod physics_body;
|
||||||
mod sphere_collider;
|
mod sphere_collider;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
.add_plugins(DefaultPlugins)
|
||||||
.insert_resource(MapBounds { min: Vec2::ONE * -600.0, max: Vec2::ONE * 600.0 })
|
.insert_resource(MapBounds { min: Vec2::ONE * -600.0, max: Vec2::ONE * 600.0 })
|
||||||
.insert_resource(DensityGrid::new())
|
.insert_resource(DensityGrid::new())
|
||||||
.add_systems(Startup, spawn_camera)
|
.add_systems(Startup, spawn_camera)
|
||||||
.add_systems(Startup, kirby_spawn)
|
.add_systems(Startup, kirby_spawn)
|
||||||
.add_systems(Startup, bubble_spawn)
|
.add_systems(Startup, lana_spawn)
|
||||||
.add_systems(PostStartup, init_density_object)
|
.add_systems(PostStartup, init_density_object)
|
||||||
.add_systems(Update, animate_sprite)
|
|
||||||
.add_systems(FixedUpdate, (density_grid_update, density_grid_force).chain())
|
.add_systems(FixedUpdate, (density_grid_update, density_grid_force).chain())
|
||||||
.add_systems(FixedUpdate, kirby_actions)
|
.add_systems(FixedUpdate, kirby_player_move)
|
||||||
.add_systems(FixedUpdate, bubble_move)
|
.add_systems(FixedUpdate, lana_move)
|
||||||
.add_systems(FixedPostUpdate, integrate)
|
.add_systems(FixedPostUpdate, integrate)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue