Fullscreen and jumping and stuff
This commit is contained in:
parent
d171be23d9
commit
7f2694ab24
14 changed files with 347 additions and 35 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,3 +5,5 @@ Cargo.lock
|
||||||
|
|
||||||
*.dll
|
*.dll
|
||||||
|
|
||||||
|
djam_4.*
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,6 @@ version = "0.1.0"
|
||||||
authors = ["Gnarwhal <git.aspect893@passmail.net>"]
|
authors = ["Gnarwhal <git.aspect893@passmail.net>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
amethyst_window = "0.5.0"
|
|
||||||
winit = "0.22.2"
|
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1"
|
version = "1"
|
||||||
features = ["derive"]
|
features = ["derive"]
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
ShortHop: [
|
ShortHop: [
|
||||||
|
[ScanCode(57)],
|
||||||
[Controller(0, X)],
|
[Controller(0, X)],
|
||||||
[Controller(1, X)],
|
[Controller(1, X)],
|
||||||
[Controller(2, X)],
|
[Controller(2, X)],
|
||||||
|
@ -22,7 +23,6 @@
|
||||||
],
|
],
|
||||||
FullHop: [
|
FullHop: [
|
||||||
[ScanCode(17)],
|
[ScanCode(17)],
|
||||||
[ScanCode(57)],
|
|
||||||
[Controller(0, A)],
|
[Controller(0, A)],
|
||||||
[Controller(1, A)],
|
[Controller(1, A)],
|
||||||
[Controller(2, A)],
|
[Controller(2, A)],
|
||||||
|
@ -31,4 +31,4 @@
|
||||||
[Controller(5, A)],
|
[Controller(5, A)],
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
BIN
resources/sprites.png
Normal file
BIN
resources/sprites.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 206 B |
12
resources/sprites.ron
Normal file
12
resources/sprites.ron
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
List((
|
||||||
|
texture_width: 16,
|
||||||
|
texture_height: 16,
|
||||||
|
sprites: [
|
||||||
|
(
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
))
|
|
@ -25,7 +25,12 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
player::Player
|
physics::Gravity,
|
||||||
|
physics::Dynamic,
|
||||||
|
physics::Static,
|
||||||
|
|
||||||
|
player::Player,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod player;
|
pub mod physics;
|
||||||
|
pub mod player;
|
||||||
|
|
62
src/components/physics.rs
Normal file
62
src/components/physics.rs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Gnarwhal
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files(the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
use amethyst::{
|
||||||
|
core::math::Vector2,
|
||||||
|
ecs::prelude::{Component, DenseVecStorage}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Gravity;
|
||||||
|
|
||||||
|
impl Component for Gravity {
|
||||||
|
type Storage = DenseVecStorage<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Dynamic {
|
||||||
|
pub velocity: Vector2<f32>,
|
||||||
|
pub grounded: bool,
|
||||||
|
pub friction_coefficient: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Dynamic {
|
||||||
|
fn default() -> Self {
|
||||||
|
Dynamic {
|
||||||
|
velocity: Vector2::new(0.0, 0.0),
|
||||||
|
grounded: false,
|
||||||
|
friction_coefficient: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for Dynamic {
|
||||||
|
type Storage = DenseVecStorage<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Static;
|
||||||
|
|
||||||
|
impl Component for Static {
|
||||||
|
type Storage = DenseVecStorage<Self>;
|
||||||
|
}
|
|
@ -24,18 +24,32 @@
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
use core::default::Default;
|
||||||
use amethyst::{
|
use amethyst::{
|
||||||
ecs::prelude::{Component, DenseVecStorage},
|
ecs::prelude::{Component, DenseVecStorage},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
pub id: u32,
|
pub jump_ready: bool,
|
||||||
|
pub jump_count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Player {
|
impl Player {
|
||||||
pub fn new(id: u32) -> Player {
|
pub fn reset_jumps(&mut self, jump_count: usize) {
|
||||||
|
self.jump_ready = true;
|
||||||
|
self.jump_count = jump_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn trigger_jump(&mut self) {
|
||||||
|
self.jump_ready = false;
|
||||||
|
self.jump_count -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Default for Player {
|
||||||
|
fn default() -> Player {
|
||||||
return Player{
|
return Player{
|
||||||
id
|
jump_ready: true,
|
||||||
|
jump_count: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -38,8 +38,9 @@ use amethyst::{
|
||||||
plugins::{RenderFlat2D, RenderToWindow},
|
plugins::{RenderFlat2D, RenderToWindow},
|
||||||
},
|
},
|
||||||
utils::application_root_dir,
|
utils::application_root_dir,
|
||||||
|
window::{DisplayConfig, MonitorIdent},
|
||||||
|
winit::EventsLoop,
|
||||||
};
|
};
|
||||||
use amethyst_window::{DisplayConfig, Icon};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
fn main() -> amethyst::Result<()> {
|
fn main() -> amethyst::Result<()> {
|
||||||
|
@ -51,8 +52,14 @@ fn main() -> amethyst::Result<()> {
|
||||||
let display_config_path = resources_dir.join("display_config.ron");
|
let display_config_path = resources_dir.join("display_config.ron");
|
||||||
let binding_path = resources_dir.join("bindings.ron");
|
let binding_path = resources_dir.join("bindings.ron");
|
||||||
|
|
||||||
|
let events_loop = EventsLoop::new();
|
||||||
|
|
||||||
|
let monitor = MonitorIdent::from_primary(&events_loop);
|
||||||
|
|
||||||
let mut display_config = DisplayConfig::load(display_config_path)?;
|
let mut display_config = DisplayConfig::load(display_config_path)?;
|
||||||
display_config.icon = Some(PathBuf::from("resources/icon.png"));
|
display_config.icon = Some(PathBuf::from("resources/icon.png"));
|
||||||
|
display_config.dimensions = Some(monitor.monitor_id(&events_loop).get_dimensions().into());
|
||||||
|
display_config.fullscreen = Some(monitor);
|
||||||
|
|
||||||
let input_bundle = InputBundle::<systems::PlayerBindings>::new()
|
let input_bundle = InputBundle::<systems::PlayerBindings>::new()
|
||||||
.with_bindings_from_file(binding_path)?;
|
.with_bindings_from_file(binding_path)?;
|
||||||
|
@ -68,7 +75,9 @@ fn main() -> amethyst::Result<()> {
|
||||||
)
|
)
|
||||||
.with_plugin(RenderFlat2D::default())
|
.with_plugin(RenderFlat2D::default())
|
||||||
)?
|
)?
|
||||||
.with(systems::PlayerSystem, "player_system", &["input_system"]);
|
.with(systems::ForceSystem, "force_system", &[])
|
||||||
|
.with(systems::PlayerSystem, "player_system", &["force_system", "input_system"])
|
||||||
|
.with(systems::CollisionSystem, "physics_system", &["player_system"]);
|
||||||
|
|
||||||
let mut game = Application::new(resources_dir, states::LevelState, game_data)?;
|
let mut game = Application::new(resources_dir, states::LevelState, game_data)?;
|
||||||
game.run();
|
game.run();
|
||||||
|
|
|
@ -27,18 +27,21 @@
|
||||||
use amethyst::{
|
use amethyst::{
|
||||||
assets::{AssetStorage, Loader, Handle},
|
assets::{AssetStorage, Loader, Handle},
|
||||||
core::transform::Transform,
|
core::transform::Transform,
|
||||||
ecs::prelude::{Component, DenseVecStorage},
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
renderer::{Camera, ImageFormat, SpriteRender, SpriteSheet, SpriteSheetFormat, Texture}
|
renderer::{Camera, ImageFormat, SpriteRender, SpriteSheet, SpriteSheetFormat, Texture}
|
||||||
};
|
};
|
||||||
|
use crate::components::Dynamic;
|
||||||
|
use crate::components::Gravity;
|
||||||
use crate::components::Player;
|
use crate::components::Player;
|
||||||
|
|
||||||
pub const CAMERA_WIDTH: f32 = 1920.0;
|
pub const CAMERA_WIDTH: f32 = 384.0;
|
||||||
pub const CAMERA_HEIGHT: f32 = 1080.0;
|
pub const CAMERA_HEIGHT: f32 = 216.0;
|
||||||
|
|
||||||
|
pub const BLOCK_SIZE: f32 = 16.0;
|
||||||
|
|
||||||
fn initialize_camera(world: &mut World) {
|
fn initialize_camera(world: &mut World) {
|
||||||
let mut transform = Transform::default();
|
let mut transform = Transform::default();
|
||||||
transform.set_translation_xyz(CAMERA_WIDTH * 0.5, CAMERA_HEIGHT * 0.5, 1.0);
|
transform.set_translation_xyz(0.0, 0.0, 1.0);
|
||||||
|
|
||||||
world
|
world
|
||||||
.create_entity()
|
.create_entity()
|
||||||
|
@ -47,21 +50,57 @@ fn initialize_camera(world: &mut World) {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_player(world: &mut World) {
|
fn initialize_player(world: &mut World, sprite_sheet_handle: Handle<SpriteSheet>) {
|
||||||
|
let sprite_render = SpriteRender{
|
||||||
|
sprite_sheet: sprite_sheet_handle,
|
||||||
|
sprite_number: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut transform = Transform::default();
|
||||||
|
transform.set_translation_xyz(0.0, 48.0, 0.0);
|
||||||
|
|
||||||
world
|
world
|
||||||
.create_entity()
|
.create_entity()
|
||||||
.with(Player::new(0))
|
.with(sprite_render)
|
||||||
|
.with(Player::default())
|
||||||
.with(Transform::default())
|
.with(Transform::default())
|
||||||
|
.with(Dynamic::default())
|
||||||
|
.with(Gravity)
|
||||||
|
.with(transform)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_sprite_sheet(world: &mut World) -> Handle<SpriteSheet> {
|
||||||
|
let texture_handle = {
|
||||||
|
let loader = world.read_resource::<Loader>();
|
||||||
|
let texture_storage = world.read_resource::<AssetStorage<Texture>>();
|
||||||
|
loader.load(
|
||||||
|
"sprites.png",
|
||||||
|
ImageFormat::default(),
|
||||||
|
(),
|
||||||
|
&texture_storage,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let loader = world.read_resource::<Loader>();
|
||||||
|
let sprite_sheet_store = world.read_resource::<AssetStorage<SpriteSheet>>();
|
||||||
|
loader.load(
|
||||||
|
"sprites.ron",
|
||||||
|
SpriteSheetFormat(texture_handle),
|
||||||
|
(),
|
||||||
|
&sprite_sheet_store,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub struct LevelState;
|
pub struct LevelState;
|
||||||
|
|
||||||
impl SimpleState for LevelState {
|
impl SimpleState for LevelState {
|
||||||
fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) {
|
fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) {
|
||||||
let world = data.world;
|
let world = data.world;
|
||||||
|
|
||||||
|
let sprite_sheet_handle = load_sprite_sheet(world);
|
||||||
|
|
||||||
initialize_camera(world);
|
initialize_camera(world);
|
||||||
initialize_player(world);
|
initialize_player(world, sprite_sheet_handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,4 +28,4 @@ pub use self::{
|
||||||
level::LevelState
|
level::LevelState
|
||||||
};
|
};
|
||||||
|
|
||||||
mod level;
|
pub mod level;
|
|
@ -25,8 +25,12 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
|
physics::ForceSystem,
|
||||||
|
physics::CollisionSystem,
|
||||||
|
|
||||||
player::PlayerSystem,
|
player::PlayerSystem,
|
||||||
player::PlayerBindings,
|
player::PlayerBindings,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod player;
|
pub mod physics;
|
||||||
|
pub mod player;
|
104
src/systems/physics.rs
Normal file
104
src/systems/physics.rs
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Gnarwhal
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files(the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
use amethyst::{
|
||||||
|
core::timing::Time,
|
||||||
|
core::{Transform},
|
||||||
|
derive::SystemDesc,
|
||||||
|
ecs::{Join, Read, ReadStorage, System, SystemData, WriteStorage},
|
||||||
|
};
|
||||||
|
use crate::components::Dynamic;
|
||||||
|
use crate::components::Static;
|
||||||
|
use crate::components::Gravity;
|
||||||
|
use crate::systems::player::FULL_HOP_TIME;
|
||||||
|
use crate::systems::player::FULL_HOP_HEIGHT;
|
||||||
|
use crate::systems::player::MAX_GROUND_SPEED;
|
||||||
|
use crate::systems::player::MAX_AERIAL_SPEED;
|
||||||
|
use crate::states::level::CAMERA_HEIGHT;
|
||||||
|
|
||||||
|
pub const FRICTION: f32 = MAX_GROUND_SPEED / 0.25;
|
||||||
|
pub const AIR_RESISTANCE: f32 = MAX_AERIAL_SPEED / 1.0;
|
||||||
|
|
||||||
|
pub const GRAVITY: f32 = -2.0 * FULL_HOP_HEIGHT / (FULL_HOP_TIME * FULL_HOP_TIME);
|
||||||
|
|
||||||
|
#[derive(SystemDesc)]
|
||||||
|
pub struct ForceSystem;
|
||||||
|
|
||||||
|
fn apply_resistance(velocity: f32, resistance: f32) -> f32 {
|
||||||
|
if velocity < 0.0 {
|
||||||
|
(velocity + resistance).min(0.0)
|
||||||
|
} else if velocity > 0.0 {
|
||||||
|
(velocity - resistance).max(0.0)
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s> System<'s> for ForceSystem {
|
||||||
|
type SystemData = (
|
||||||
|
WriteStorage<'s, Dynamic>,
|
||||||
|
ReadStorage<'s, Gravity>,
|
||||||
|
Read<'s, Time>,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn run(&mut self, (mut dynamics, gravities, delta_time): Self::SystemData) {
|
||||||
|
for dynamic in (&mut dynamics).join() {
|
||||||
|
let velocity = &mut dynamic.velocity;
|
||||||
|
velocity.x = apply_resistance(velocity.x, match dynamic.grounded { true => FRICTION, false => AIR_RESISTANCE, } * dynamic.friction_coefficient * delta_time.delta_seconds());
|
||||||
|
}
|
||||||
|
for (dynamic, _) in (&mut dynamics, &gravities).join() {
|
||||||
|
dynamic.velocity.y += GRAVITY * delta_time.delta_seconds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SystemDesc)]
|
||||||
|
pub struct CollisionSystem;
|
||||||
|
|
||||||
|
impl<'s> System<'s> for CollisionSystem {
|
||||||
|
type SystemData = (
|
||||||
|
WriteStorage<'s, Transform>,
|
||||||
|
WriteStorage<'s, Dynamic>,
|
||||||
|
ReadStorage<'s, Static>,
|
||||||
|
Read<'s, Time>,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn run(&mut self, (mut transforms, mut dynamics, statics, delta_time): Self::SystemData) {
|
||||||
|
for (transform, dynamic) in (&mut transforms, &mut dynamics).join() {
|
||||||
|
let translation = transform.translation_mut();
|
||||||
|
translation.x += dynamic.velocity.x * delta_time.delta_seconds();
|
||||||
|
translation.y += dynamic.velocity.y * delta_time.delta_seconds();
|
||||||
|
const FLOOR: f32 = -CAMERA_HEIGHT / 2.0 + 8.0;
|
||||||
|
if translation.y < FLOOR {
|
||||||
|
translation.y = FLOOR;
|
||||||
|
dynamic.velocity.y = 0.0;
|
||||||
|
dynamic.grounded = true;
|
||||||
|
} else {
|
||||||
|
dynamic.grounded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,13 +27,16 @@
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
|
||||||
use amethyst::{
|
use amethyst::{
|
||||||
core::{Transform, SystemDesc},
|
core::timing::Time,
|
||||||
derive::SystemDesc,
|
derive::SystemDesc,
|
||||||
ecs::{Join, Read, ReadStorage, System, SystemData, World, WriteStorage},
|
ecs::{Join, Read, System, SystemData, WriteStorage},
|
||||||
input::{InputHandler, BindingTypes, Bindings},
|
input::{InputHandler, BindingTypes},
|
||||||
};
|
};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
use crate::components::Dynamic;
|
||||||
use crate::components::Player;
|
use crate::components::Player;
|
||||||
|
use crate::systems::physics::GRAVITY;
|
||||||
|
use crate::states::level::BLOCK_SIZE;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum MovementBindings {
|
pub enum MovementBindings {
|
||||||
|
@ -58,7 +61,6 @@ impl Display for ActionBindings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PlayerBindings;
|
pub struct PlayerBindings;
|
||||||
|
|
||||||
|
@ -67,31 +69,94 @@ impl BindingTypes for PlayerBindings {
|
||||||
type Action = ActionBindings;
|
type Action = ActionBindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const FULL_HOP_TIME: f32 = 0.35;
|
||||||
|
pub const SHORT_HOP_HEIGHT: f32 = 1.5 * BLOCK_SIZE;
|
||||||
|
pub const FULL_HOP_HEIGHT: f32 = 3.25 * BLOCK_SIZE;
|
||||||
|
pub const AERIAL_HOP_HEIGHT: f32 = 2.25 * BLOCK_SIZE;
|
||||||
|
const JUMP_COUNT: usize = 2;
|
||||||
|
|
||||||
|
pub const MAX_GROUND_SPEED: f32 = 10.0 * BLOCK_SIZE;
|
||||||
|
const GROUND_ACCELERATION: f32 = (MAX_GROUND_SPEED * 2.0) / 0.1;
|
||||||
|
|
||||||
|
pub const MAX_AERIAL_SPEED: f32 = 12.0 * BLOCK_SIZE;
|
||||||
|
const AERIAL_ACCELERATION: f32 = (MAX_AERIAL_SPEED * 2.0) / 0.5;
|
||||||
|
const AERIAL_JUMP_HORZ_BOOST: f32 = AERIAL_ACCELERATION * 0.3;
|
||||||
|
|
||||||
#[derive(SystemDesc)]
|
#[derive(SystemDesc)]
|
||||||
pub struct PlayerSystem;
|
pub struct PlayerSystem;
|
||||||
|
|
||||||
impl <'s> System<'s> for PlayerSystem {
|
impl <'s> System<'s> for PlayerSystem {
|
||||||
type SystemData = (
|
type SystemData = (
|
||||||
WriteStorage<'s, Transform>,
|
WriteStorage<'s, Dynamic>,
|
||||||
ReadStorage<'s, Player>,
|
WriteStorage<'s, Player>,
|
||||||
Read<'s, InputHandler<PlayerBindings>>,
|
Read<'s, InputHandler<PlayerBindings>>,
|
||||||
|
Read<'s, Time>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, (mut transforms, players, input): Self::SystemData) {
|
fn run(&mut self, (mut dynamics, mut players, input, delta_time): Self::SystemData) {
|
||||||
for (transform, _) in (&mut transforms, &players).join() {
|
for (dynamic, player) in (&mut dynamics, &mut players).join() {
|
||||||
|
let velocity = &mut dynamic.velocity;
|
||||||
let mut movement = 0.0f32;
|
let mut movement = 0.0f32;
|
||||||
for input_id in -1..6 {
|
for input_id in -1..6 {
|
||||||
movement += input
|
movement += input
|
||||||
.axis_value(&MovementBindings::Horizontal(input_id))
|
.axis_value(&MovementBindings::Horizontal(input_id))
|
||||||
.unwrap_or(0.0);
|
.unwrap_or(0.0);
|
||||||
|
|
||||||
|
}
|
||||||
|
movement.max(-1.0).min(1.0);
|
||||||
|
if movement != 0.0 {
|
||||||
|
dynamic.friction_coefficient = 0.0;
|
||||||
|
} else {
|
||||||
|
dynamic.friction_coefficient = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if movement != 0.0 {
|
//////// OLD DEBUGGING STUFF - MAY BE USEFUL LATER ////////
|
||||||
println!("Movement: {}", movement);
|
/*print!("Codes: ");
|
||||||
|
for code in input.scan_codes_that_are_down() {
|
||||||
|
print!("{}, ", code);
|
||||||
}
|
}
|
||||||
if input.action_is_down(&ActionBindings::FullHop).unwrap_or(false) {
|
println!();*/
|
||||||
println!("Yump yump!");
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if dynamic.grounded {
|
||||||
|
player.reset_jumps(JUMP_COUNT);
|
||||||
|
|
||||||
|
if (movement < 0.0 && velocity.x > -MAX_GROUND_SPEED)
|
||||||
|
|| (movement > 0.0 && velocity.x < MAX_GROUND_SPEED) {
|
||||||
|
velocity.x += movement * GROUND_ACCELERATION * delta_time.delta_seconds();
|
||||||
|
velocity.x = velocity.x.max(-MAX_GROUND_SPEED).min(MAX_GROUND_SPEED);
|
||||||
|
}
|
||||||
|
|
||||||
|
let SHORT_HOP_SPEED: f32 = (-2.0 * SHORT_HOP_HEIGHT * GRAVITY).sqrt();
|
||||||
|
let FULL_HOP_SPEED: f32 = (-2.0 * FULL_HOP_HEIGHT * GRAVITY).sqrt();
|
||||||
|
if player.jump_ready {
|
||||||
|
if input.action_is_down(&ActionBindings::ShortHop).unwrap_or(false) {
|
||||||
|
velocity.y = SHORT_HOP_SPEED;
|
||||||
|
player.trigger_jump();
|
||||||
|
} else if input.action_is_down(&ActionBindings::FullHop).unwrap_or(false) {
|
||||||
|
velocity.y = FULL_HOP_SPEED;
|
||||||
|
player.trigger_jump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
velocity.x = velocity.x.max(-MAX_GROUND_SPEED).min(MAX_GROUND_SPEED);
|
||||||
|
} else {
|
||||||
|
let AERIAL_HOP_SPEED: f32 = (-2.0 * AERIAL_HOP_HEIGHT * GRAVITY).sqrt();
|
||||||
|
if player.jump_ready
|
||||||
|
&& player.jump_count > 0
|
||||||
|
&& (input.action_is_down(&ActionBindings::ShortHop).unwrap_or(false)
|
||||||
|
|| input.action_is_down(&ActionBindings::FullHop ).unwrap_or(false)) {
|
||||||
|
velocity.y = AERIAL_HOP_SPEED;
|
||||||
|
player.trigger_jump();
|
||||||
|
velocity.x += movement * AERIAL_JUMP_HORZ_BOOST;
|
||||||
|
} else {
|
||||||
|
if !(input.action_is_down(&ActionBindings::ShortHop).unwrap_or(false)
|
||||||
|
|| input.action_is_down(&ActionBindings::FullHop ).unwrap_or(false)) {
|
||||||
|
player.jump_ready = true;
|
||||||
|
}
|
||||||
|
velocity.x += movement * AERIAL_ACCELERATION * delta_time.delta_seconds();
|
||||||
|
}
|
||||||
|
velocity.x = velocity.x.max(-MAX_AERIAL_SPEED).min(MAX_AERIAL_SPEED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue