haw-gj13-game/src/game/scene.rs

218 lines
7 KiB
Rust
Raw Normal View History

2024-11-23 18:10:33 +01:00
use std::collections::HashMap;
2024-11-23 17:09:42 +01:00
use std::fs;
2024-11-23 18:10:33 +01:00
use bevy::sprite::MaterialMesh2dBundle;
2024-11-23 16:24:16 +01:00
use bevy::{core_pipeline::smaa::SmaaSpecializedRenderPipelines, prelude::*};
2024-11-23 16:13:54 +01:00
use bevy::{prelude::*, scene::ScenePlugin};
2024-11-23 19:21:51 +01:00
// use bevy_editor_pls::EditorPlugin;
2024-11-23 18:10:33 +01:00
use bevy_rapier2d::prelude::{Collider, *};
use readformat::{readf, readf1};
2024-11-22 22:39:00 +01:00
2024-11-23 18:10:33 +01:00
use crate::game::WORLD_DEPTH;
2024-11-24 05:48:56 +01:00
use crate::parallax::{parallax, Parallax};
2024-11-23 01:40:50 +01:00
use crate::AppState;
2024-11-23 18:33:27 +01:00
use super::player::PlayerSpawnOneshot;
2024-11-23 18:42:52 +01:00
use super::{PLAYER_DEPTH, PLAYER_SIZE_FRACTION};
2024-11-23 18:33:27 +01:00
2024-11-23 18:10:33 +01:00
#[derive(Component)]
struct Block;
2024-11-23 18:42:52 +01:00
#[derive(Resource, Default, Clone, Copy)]
2024-11-23 18:33:27 +01:00
pub struct PlayerCoords {
2024-11-23 21:42:35 +01:00
pub x: f32,
pub y: f32,
pub block_size: f32,
2024-11-23 18:22:41 +01:00
}
2024-11-23 19:00:54 +01:00
impl PlayerCoords {
pub fn get_collider(&self) -> Collider {
2024-11-23 20:19:49 +01:00
let size = 0.5;
2024-11-23 19:00:54 +01:00
2024-11-23 22:55:19 +01:00
Collider::round_cuboid(size, size, 2.0)
2024-11-23 21:02:15 +01:00
// Collider::cuboid(size, size)
2024-11-23 19:00:54 +01:00
}
}
2024-11-23 18:48:35 +01:00
impl From<PlayerCoords> for Transform {
fn from(val: PlayerCoords) -> Self {
let PlayerCoords { x, y, block_size } = val;
2024-11-23 18:42:52 +01:00
Transform {
translation: Vec3 {
x,
y,
z: PLAYER_DEPTH,
},
2024-11-23 18:48:35 +01:00
scale: Vec3::splat(val.block_size * PLAYER_SIZE_FRACTION),
2024-11-23 18:42:52 +01:00
..Default::default()
}
}
}
2024-11-22 22:39:00 +01:00
pub(super) fn scene_plugin(app: &mut App) {
2024-11-23 19:21:51 +01:00
// app.add_plugins(EditorPlugin::default());
2024-11-23 17:09:42 +01:00
// app.add_systems(, )
app.add_systems(Startup, (import_text_world,));
}
2024-11-23 23:53:13 +01:00
#[derive(Default, Resource)]
2024-11-23 17:15:27 +01:00
pub struct WorldInfo {
2024-11-23 23:53:13 +01:00
pub block_size: f32,
pub blocks: Vec<(String, String)>,
pub spawnpoints: Vec<(usize, usize)>,
2024-11-23 17:15:27 +01:00
}
2024-11-23 18:10:33 +01:00
pub(super) fn import_text_world(
mut commands: Commands,
assets: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
2024-11-23 18:33:27 +01:00
mut player_spawn_oneshot: Res<PlayerSpawnOneshot>,
2024-11-23 18:10:33 +01:00
) {
2024-11-23 17:15:27 +01:00
let world_string = fs::read_to_string("assets/world.txt").expect("need a world to load");
2024-11-23 22:55:19 +01:00
let [info_string, links_string, world_string] =
&readf("header\n{}\nlinks\n{}\nblocks\n{}", &world_string)
.expect("world does not have sections")[..]
2024-11-23 17:15:27 +01:00
else {
2024-11-23 18:10:33 +01:00
unreachable!()
2024-11-23 17:15:27 +01:00
};
2024-11-23 18:10:33 +01:00
let mut wi = WorldInfo::default();
2024-11-24 05:48:56 +01:00
let mut parallax_info = Parallax::default();
2024-11-23 17:15:27 +01:00
for line in info_string.lines() {
2024-11-23 18:10:33 +01:00
let [name, val] = &readf(" {} = {}", line).expect("invalid line in info section")[..]
else {
unreachable!()
};
match name.as_str() {
"block-size" => wi.block_size = val.parse().unwrap(),
2024-11-24 05:48:56 +01:00
"parallax.offset" => parallax_info.offset = val.parse().unwrap(),
"parallax.size" => {
parallax_info.size = {
let x = readf("{}x{}", val).unwrap();
Vec2::new(x[0].parse().unwrap(), x[1].parse().unwrap())
}
}
"parallax.tiles" => parallax_info.tiles = val.parse().unwrap(),
"parallax.tex" => parallax_info.tex = val.clone(),
"parallax.factor" => parallax_info.factor = val.parse().unwrap(),
"parallax.factor.y" => parallax_info.y_factor = val.parse().unwrap(),
"parallax.depth" => parallax_info.depth = val.parse().unwrap(),
"parallax.enable" => {
if val == "true" {
parallax(
&mut commands,
&mut materials,
&mut meshes,
&assets,
parallax_info.clone(),
)
}
}
2024-11-23 18:10:33 +01:00
x if x.starts_with(".") => {
let x = readf1(".{}", x).unwrap();
wi.blocks.push((x, val.to_owned()));
}
x => panic!("invalid setting {x}"),
}
}
for (current_y, line) in world_string.lines().rev().enumerate() {
let mut i = 0;
// try to match every defined block
'a: while i < line.len() {
if line[i..].starts_with(" ") {
i += 1;
continue;
}
for possible_block in wi.blocks.iter() {
if line[i..].starts_with(possible_block.0.as_str()) {
let len = possible_block.0.len();
let (tex, collider) = if let Some(s) = possible_block.1.strip_prefix("_") {
(s.to_owned(), false)
} else {
(possible_block.1.to_owned(), true)
};
2024-11-23 22:55:19 +01:00
let (tex, fixed) = if let Some(s) = tex.strip_prefix("~") {
(s.to_owned(), false)
} else {
(tex, true)
};
2024-11-23 18:10:33 +01:00
let x = i as f32 * wi.block_size;
let y = current_y as f32 * wi.block_size;
2024-11-23 18:22:41 +01:00
if tex == "[player]" {
2024-11-23 18:33:27 +01:00
commands.insert_resource(PlayerCoords {
2024-11-23 18:22:41 +01:00
x,
y,
block_size: wi.block_size,
2024-11-23 18:33:27 +01:00
});
commands.run_system(player_spawn_oneshot.0);
2024-11-23 23:53:13 +01:00
} else if tex == "[spawn]" {
wi.spawnpoints.push((i, current_y));
2024-11-23 18:22:41 +01:00
} else {
spawn_block(
&mut commands,
&mut meshes,
&mut materials,
&assets,
tex,
(x, y, len, wi.block_size),
2024-11-23 22:55:19 +01:00
(collider, fixed),
2024-11-23 18:22:41 +01:00
);
2024-11-23 18:10:33 +01:00
}
println!("spawned {possible_block:?} at {x}, {y}");
i += len;
continue 'a;
}
}
panic!("unknown block in at {i},{current_y}");
}
2024-11-23 17:15:27 +01:00
}
2024-11-24 02:05:26 +01:00
wi.spawnpoints.sort_by(|a, b| a.0.cmp(&b.0));
println!("{:?}", wi.spawnpoints);
2024-11-23 23:53:13 +01:00
commands.insert_resource(wi);
2024-11-22 22:39:00 +01:00
}
2024-11-23 18:22:41 +01:00
fn spawn_block(
commands: &mut Commands,
meshes: &mut ResMut<Assets<Mesh>>,
materials: &mut ResMut<Assets<ColorMaterial>>,
assets: &Res<AssetServer>,
tex: String,
(x, y, len, block_size): (f32, f32, usize, f32),
2024-11-23 22:55:19 +01:00
(collider, fixed): (bool, bool),
2024-11-23 18:22:41 +01:00
) {
let mut command = commands.spawn((
Block,
MaterialMesh2dBundle {
mesh: meshes
.add(Rectangle::new(block_size * len as f32, block_size))
.into(),
material: materials.add(assets.load(tex)),
transform: Transform::from_xyz(x, y, WORLD_DEPTH),
..Default::default()
},
));
if collider {
command.insert((
2024-11-23 22:55:19 +01:00
if fixed {
RigidBody::Fixed
} else {
RigidBody::Dynamic
},
if fixed {
2024-11-24 02:05:26 +01:00
Collider::cuboid(block_size / 2.1 * len as f32, block_size / 2.1)
2024-11-23 22:55:19 +01:00
} else {
2024-11-23 23:53:13 +01:00
Collider::ball(block_size / 2.)
2024-11-23 22:55:19 +01:00
},
AdditionalMassProperties::Mass(1.0),
2024-11-23 18:22:41 +01:00
Velocity::default(),
));
}
}