Select Git revision
main.rs 8.24 KiB
#![allow(unused)]
use bevy::{
core::FixedTimestep,
prelude::*,
render::{camera::Camera, texture::FilterMode},
};
use bevy_ecs_tilemap::{prelude::*, MapQuery};
use std::f32::consts::PI;
const PLAYER_SHEET: &str = "character_zombie_sheet.png";
fn main() {
env_logger::Builder::from_default_env()
.filter_level(log::LevelFilter::Info)
.init();
App::build()
.insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
.insert_resource(WindowDescriptor {
title: "My Little Zombie".to_string(),
width: 1920.,
height: 1080.,
vsync: true,
cursor_visible: false,
// resizable: false,
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_plugin(TilemapPlugin)
.add_plugin(TiledMapPlugin)
.add_startup_system(setup.system())
.add_system_set(
SystemSet::new()
.with_run_criteria(FixedTimestep::step(1.0 / 60.0))
.with_system(player_movement.system())
.with_system(camera.system())
.with_system(parallax.system()),
)
.add_system(set_texture_filters_to_nearest.system())
.run();
}
fn set_texture_filters_to_nearest(
mut texture_events: EventReader<AssetEvent<Texture>>,
mut textures: ResMut<Assets<Texture>>,
) {
// quick and dirty, run this for all textures anytime a texture is created.
for event in texture_events.iter() {
match event {
AssetEvent::Created { handle } => {
if let Some(mut texture) = textures.get_mut(handle) {
texture.sampler.min_filter = FilterMode::Nearest;
}
}
_ => (),
}
}
}
fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut materials: ResMut<Assets<ColorMaterial>>,
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
mut windows: ResMut<Windows>,
) {
let mut window = windows.get_primary_mut().unwrap();
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
let bottom = -window.height() / 2.0;
// load the tile map
let handle: Handle<TiledMap> = asset_server.load("tmap.tmx");
let map_entity = commands.spawn().id();
commands.entity(map_entity).insert_bundle(TiledMapBundle {
tiled_map: handle,
map: Map::new(0u16, map_entity),
transform: Transform {
translation: Vec3::new(0., bottom, 1.0),
scale: Vec3::new(4.0, 4.0, 1.0),
..Default::default()
},
..Default::default()
});
let texture_handle = asset_server.load(PLAYER_SHEET);
let texture_atlas = TextureAtlas::from_grid(texture_handle, Vec2::new(96.0, 128.0), 9, 5);
let atlas_handle = texture_atlases.add(texture_atlas);
commands
.spawn_bundle(SpriteSheetBundle {
texture_atlas: atlas_handle,
transform: Transform {
translation: Vec3::new(0., bottom / 2.0, 10.0),
scale: Vec3::new(1., 1., 1.0),
..Default::default()
},
..Default::default()
})
.insert(Player {
y: bottom / 2.,
..Player::default()
});
}
#[derive(Copy, Clone)]
enum Direction {
Right,
Left,
Idle,
}
pub struct Player {
direction: Direction,
jump: bool,
index: u32,
y: f32,
}
impl Default for Player {
fn default() -> Self {
Player {
direction: Direction::Idle,
jump: false,
index: 3,
y: 0.,
}
}
}
// run each frame (60Hz)
fn player_movement(
mut query: Query<(&mut Player, &mut Transform, &mut TextureAtlasSprite)>,
keyboard_input: Res<Input<KeyCode>>,
) {
if let Ok((mut player, mut transform, mut sprite)) = query.single_mut() {
let (index, state, dir) = if player.jump {
// already in jump
let mut index = player.index + 1;
match index {
4 => {
sprite.index = 7;
}
8 => {
sprite.index = 8;
}
60 => {
sprite.index = 3;
}
_ => {}
};
if index == 64 {
index = 0;
player.jump = false
};
if index > 8 && index < (60) {
transform.translation.y =
player.y + (((index - 8) as f32) * PI / (60.0 - 8.0)).sin() * 200.0;
} else {
transform.translation.y = player.y
}
(index, player.direction, 0.)
} else if keyboard_input.pressed(KeyCode::Space) {
// start jump
player.jump = true;
sprite.index = 3;
let index = 0;
(index, player.direction, 0.)
} else if keyboard_input.pressed(KeyCode::Right) {
sprite.flip_x = false;
match player.direction {
// already walking
Direction::Right => {
let index = (player.index + 1) % 32;
sprite.index = (4 * 9) + index / 4;
(index, Direction::Right, 2.)
}
// starting walking
_ => {
let index = 3 * 4;
sprite.index = (4 * 9) + index / 4;
(index, Direction::Right, 2.)
}
}
} else if keyboard_input.pressed(KeyCode::Left) {
sprite.flip_x = true;
match player.direction {
// already walking
Direction::Left => {
let index = (player.index + 1) % 32;
sprite.index = (4 * 9) + index / 4;
(index, Direction::Left, -2.)
}
// starting walking
_ => {
let index = 3 * 4;
sprite.index = (4 * 9) + index / 4;
(index, Direction::Left, -2.)
}
}
} else {
match player.direction {
// already idle
Direction::Idle => {
let index = (player.index + 1) % 256;
sprite.index = if index > 224 { 0 } else { 9 * 1 + 6 };
(index, Direction::Idle, 0.)
}
// start idle
_ => {
player.index = 0;
sprite.index = 0;
(0, Direction::Idle, 0.)
}
}
};
player.direction = state;
player.index = index;
transform.translation.x += dir;
}
}
// A simple camera system for moving and zooming the camera.
pub fn camera(
time: Res<Time>,
keyboard_input: Res<Input<KeyCode>>,
mut query: Query<&mut Transform, With<Camera>>,
) {
// println!("camera");
for mut transform in query.iter_mut() {
// print!("-");
let mut direction = Vec3::ZERO;
let scale = transform.scale.x;
if keyboard_input.pressed(KeyCode::A) {
direction -= Vec3::new(1.0, 0.0, 0.0);
}
if keyboard_input.pressed(KeyCode::D) {
direction += Vec3::new(1.0, 0.0, 0.0);
}
if keyboard_input.pressed(KeyCode::W) {
direction += Vec3::new(0.0, 1.0, 0.0);
}
if keyboard_input.pressed(KeyCode::S) {
direction -= Vec3::new(0.0, 1.0, 0.0);
}
if keyboard_input.pressed(KeyCode::Z) {
let scale = scale + 0.1;
transform.scale = Vec3::splat(scale);
}
if keyboard_input.pressed(KeyCode::X) {
let scale = scale - 0.1;
transform.scale = Vec3::splat(scale);
}
if transform.scale.x < 1.0 {
transform.scale = Vec3::splat(1.0)
}
transform.translation += time.delta_seconds() * direction * 500.;
}
}
// parallaxing
pub fn parallax(mut query: Query<(&mut Transform, &Layer)>) {
println!("parallax");
for (mut _transform, layer) in query.iter_mut() {
print!(
"layer_id {:?}, map_id {:?}",
layer.settings.layer_id, layer.settings.map_id
);
}
}