Skip to content

Commit

Permalink
Merge pull request #27 from thombruce/feat/stars
Browse files Browse the repository at this point in the history
feat/stars
  • Loading branch information
thombruce authored Oct 4, 2023
2 parents 14cb07e + 4af11b8 commit 327c27d
Show file tree
Hide file tree
Showing 14 changed files with 268 additions and 25 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Animated star and planet exported as spritesheets from Deep-Fold's Pixel Planet Generator
- Basic orbital system moving planet in circlular orbit around star
- Pausable GameTime resource and tick system to prevent dynamic systems jumping forwards after unpause
- Attribution for Deep-Fold in Credits for Pixel Planets
- WorldInspectorPlugin from bevy-inspector-egui for development/debugging

### Changed

- Adjusted scale of ship smaller by default
- Moved background handling to plugin
- Adjusted movement scale of background for parallax effect
- Moved assets to reusable resources plugin in assets.rs
- Moved controls to table in README

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ Built on [Rust](https://www.rust-lang.org/) with [Bevy](https://bevyengine.org/)

From [Kenney.nl](https://www.kenney.nl/), [CC0](https://creativecommons.org/publicdomain/zero/1.0/)

- [Pixel Planet Generator](https://deep-fold.itch.io/pixel-planet-generator) by [Deep-Fold](https://deep-fold.itch.io/)

From [itch.io](https://itch.io/)

### Music

- [Lightspeed](https://freemusicarchive.org/music/beat-mekanik/single/lightspeed/) by [Beat Mekanik](https://freemusicarchive.org/music/beat-mekanik/)
Expand Down
3 changes: 3 additions & 0 deletions assets/space/celestials/planet-pixelplanet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/space/celestials/star-pixelplanet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 23 additions & 1 deletion src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use bevy::prelude::*;
#[derive(Debug, Resource)]
pub struct SpriteAssets {
pub player_ship: Handle<Image>,
pub star: Handle<TextureAtlas>,
pub planet: Handle<TextureAtlas>,
pub background: Handle<Image>,
}
#[derive(Debug, Resource)]
Expand Down Expand Up @@ -30,9 +32,29 @@ impl Plugin for AssetsPlugin {
// See: asset_server.free_unused_assets()
// We can then remove the use of PreStartup above, which
// doesn't feel idiomatic.
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
) {
commands.insert_resource(SpriteAssets {
player_ship: asset_server.load("space/ships/playerShip2_blue.png"),
star: texture_atlases.add(TextureAtlas::from_grid(
asset_server.load("space/celestials/star-pixelplanet.png"),
Vec2::new(500.0, 500.0),
25,
5,
None,
None,
)),
planet: texture_atlases.add(TextureAtlas::from_grid(
asset_server.load("space/celestials/planet-pixelplanet.png"),
Vec2::new(125.0, 125.0),
25,
5,
None,
None,
)),
background: asset_server.load("space/backgrounds/custom.png"),
});
commands.insert_resource(AudioAssets {
Expand Down
34 changes: 34 additions & 0 deletions src/background.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use bevy::{prelude::*, render::view::NoFrustumCulling};
use bevy_tiling_background::{
BackgroundImageBundle, BackgroundMaterial, SetImageRepeatingExt, TilingBackgroundPlugin,
};

use crate::assets::SpriteAssets;

pub struct BackgroundPlugin;
impl Plugin for BackgroundPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(TilingBackgroundPlugin::<BackgroundMaterial>::default());

app.add_systems(Startup, setup);
}
}

/// The setup function
fn setup(
mut commands: Commands,
sprites: Res<SpriteAssets>,
mut materials: ResMut<Assets<BackgroundMaterial>>,
) {
let image = sprites.background.clone();
// Queue a command to set the image to be repeating once the image is loaded.
commands.set_image_repeating(image.clone());

commands.spawn((
BackgroundImageBundle::from_image(image, materials.as_mut())
.at_z_layer(-0.1)
.with_movement_scale(0.1),
NoFrustumCulling,
Name::new("Background"),
));
}
15 changes: 15 additions & 0 deletions src/credits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,21 @@ fn setup(mut commands: Commands, ui: Res<UiAssets>) {
),
..default()
},));
parent.spawn((TextBundle {
style: Style {
margin: UiRect::top(Val::Px(25.)),
..default()
},
text: Text::from_section(
"Pixel Planets by Deep-Fold",
TextStyle {
font: ui.font.clone(),
font_size: 20.0,
color: Color::rgb_u8(0xCC, 0xCC, 0xCC),
},
),
..default()
},));
parent.spawn((TextBundle {
style: Style {
margin: UiRect::top(Val::Px(50.)),
Expand Down
18 changes: 18 additions & 0 deletions src/game_time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use bevy::{prelude::*, time::Stopwatch};

use crate::state::AppState;

#[derive(Resource, Deref)]
pub struct GameTime(Stopwatch);

pub struct GameTimePlugin;
impl Plugin for GameTimePlugin {
fn build(&self, app: &mut App) {
app.insert_resource(GameTime(Stopwatch::new()))
.add_systems(Update, tick_game_time.run_if(in_state(AppState::Active)));
}
}

fn tick_game_time(time: Res<Time>, mut game_time: ResMut<GameTime>) {
game_time.0.tick(time.delta());
}
46 changes: 22 additions & 24 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
use bevy::{audio::PlaybackMode, prelude::*, render::view::NoFrustumCulling};
use bevy::{audio::PlaybackMode, prelude::*};
use bevy_inspector_egui::quick::WorldInspectorPlugin;
use bevy_rapier2d::prelude::*;
use bevy_tiling_background::{
BackgroundImageBundle, BackgroundMaterial, SetImageRepeatingExt, TilingBackgroundPlugin,
};
use leafwing_input_manager::prelude::*;

mod assets;
mod background;
mod camera;
mod credits;
mod effects;
mod game_time;
mod hud;
mod menu;
mod orbit;
mod pause;
mod planet;
mod planetary_system;
mod ship;
mod star;
mod state;

use crate::{
assets::{AssetsPlugin, AudioAssets, SpriteAssets},
assets::{AssetsPlugin, AudioAssets},
background::BackgroundPlugin,
camera::CameraPlugin,
credits::CreditsPlugin,
effects::EffectsPlugin,
game_time::GameTimePlugin,
hud::HudPlugin,
menu::{MenuAction, MenuPlugin},
pause::PausePlugin,
planetary_system::PlanetarySystemPlugin,
ship::ShipPlugin,
state::{AppState, ForState, StatePlugin},
};
Expand All @@ -34,17 +40,20 @@ fn main() {
app.add_state::<AppState>();

app.add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
title: String::from("Verse"),
DefaultPlugins
.set(WindowPlugin {
primary_window: Some(Window {
title: String::from("Verse"),
..default()
}),
..default()
}),
..default()
}),
})
.set(ImagePlugin::default_nearest()),
GameTimePlugin,
AssetsPlugin,
RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(1.0),
InputManagerPlugin::<MenuAction>::default(),
TilingBackgroundPlugin::<BackgroundMaterial>::default(),
BackgroundPlugin,
CameraPlugin,
StatePlugin,
HudPlugin,
Expand All @@ -53,6 +62,7 @@ fn main() {
CreditsPlugin,
EffectsPlugin,
PausePlugin,
PlanetarySystemPlugin,
));

#[cfg(debug_assertions)]
Expand All @@ -71,23 +81,11 @@ fn main() {
/// The setup function
fn setup(
mut commands: Commands,
sprites: Res<SpriteAssets>,
audios: Res<AudioAssets>,
mut rapier_configuration: ResMut<RapierConfiguration>,
mut materials: ResMut<Assets<BackgroundMaterial>>,
) {
rapier_configuration.gravity = Vec2::ZERO;

let image = sprites.background.clone();
// Queue a command to set the image to be repeating once the image is loaded.
commands.set_image_repeating(image.clone());

commands.spawn((
BackgroundImageBundle::from_image(image, materials.as_mut()).at_z_layer(-0.1),
NoFrustumCulling,
Name::new("Background"),
));

// TODO: Moved here from menu to prevent reloading every time the credits are toggled.
// In reality, we do want this to be respawned when the menu is re-entered,
// just not if the previous state was also a menu state (e.g. Credits).
Expand Down
30 changes: 30 additions & 0 deletions src/orbit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use bevy::prelude::*;

use crate::game_time::GameTime;

const ORBITAL_PERIOD_SCALING_FACTOR: f32 = 1.0;

#[derive(Component, Clone, Debug)]
pub struct Orbit {
pub semi_major_axis: f32,
// pub eccentricity: f32,
// pub argument_of_periapsis: f32,
// pub initial_mean_anomaly: f32,
}

/// Really basic circular motion around (0., 0.) or parent entity
pub fn orbital_positioning_system(
game_time: Res<GameTime>,
mut orbits: Query<(&Orbit, &mut Transform)>,
) {
for (orbit, mut transform) in orbits.iter_mut() {
transform.translation.x = (game_time.elapsed_secs() / orbit.semi_major_axis.sqrt()
* ORBITAL_PERIOD_SCALING_FACTOR)
.cos()
* orbit.semi_major_axis;
transform.translation.y = (game_time.elapsed_secs() / orbit.semi_major_axis.sqrt()
* ORBITAL_PERIOD_SCALING_FACTOR)
.sin()
* orbit.semi_major_axis;
}
}
4 changes: 4 additions & 0 deletions src/planet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use bevy::prelude::*;

#[derive(Component, Clone, Debug)]
pub struct Planet {}
96 changes: 96 additions & 0 deletions src/planetary_system.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use bevy::prelude::*;

use crate::{
assets::SpriteAssets,
orbit::{orbital_positioning_system, Orbit},
planet::Planet,
star::Star,
state::AppState,
};

pub struct PlanetarySystemPlugin;
impl Plugin for PlanetarySystemPlugin {
fn build(&self, app: &mut App) {
app.add_systems(OnEnter(AppState::GameCreate), setup);
app.add_systems(
Update,
(animate_sprite, orbital_positioning_system).run_if(in_state(AppState::Active)),
);
}
}

#[derive(Component)]
struct AnimationIndices {
first: usize,
last: usize,
}

#[derive(Component, Deref, DerefMut)]
struct AnimationTimer(Timer);

fn animate_sprite(
time: Res<Time>,
mut query: Query<(
&AnimationIndices,
&mut AnimationTimer,
&mut TextureAtlasSprite,
)>,
) {
for (indices, mut timer, mut sprite) in &mut query {
timer.tick(time.delta());
if timer.just_finished() {
sprite.index = if sprite.index == indices.last {
indices.first
} else {
sprite.index + 1
};
}
}
}

fn setup(mut commands: Commands, sprites: Res<SpriteAssets>) {
// Star
let star_animation_indices = AnimationIndices {
first: 0,
last: 124,
};

// Planet
let planet_animation_indices = AnimationIndices {
first: 0,
last: 124,
};

commands
.spawn((
SpriteSheetBundle {
texture_atlas: sprites.star.clone(),
sprite: TextureAtlasSprite::new(star_animation_indices.first),
transform: Transform::from_scale(Vec3::splat(2.0)),
..default()
},
star_animation_indices,
// TODO: .1 is too fast, .2 is too choppy; needs more animation frames.
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
Star {},
Name::new("Star"),
))
.with_children(|parent| {
parent.spawn((
SpriteSheetBundle {
texture_atlas: sprites.planet.clone(),
sprite: TextureAtlasSprite::new(planet_animation_indices.first),
transform: Transform::from_scale(Vec3::splat(2.0 / 2.0)), // Divide by parent scale?
..default()
},
planet_animation_indices,
// TODO: .1 is too fast, .2 is too choppy; needs more animation frames.
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
Planet {},
Orbit {
semi_major_axis: 500.0 / 2.0, // Divide by parent scale?
},
Name::new("Planet"),
));
});
}
5 changes: 5 additions & 0 deletions src/ship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ fn setup(mut commands: Commands, sprites: Res<SpriteAssets>) {
},
SpriteBundle {
texture: sprites.player_ship.clone(),
transform: Transform {
translation: Vec3::new(0., 0., 100.0),
scale: Vec3::splat(0.5),
..default()
},
..default()
},
RigidBody::Dynamic,
Expand Down
Loading

0 comments on commit 327c27d

Please sign in to comment.