Compare commits
18 Commits
305f8740ab
...
main
Author | SHA1 | Date | |
---|---|---|---|
ed0fb59cae | |||
321557f47f | |||
f4388e1626 | |||
d54148e5db | |||
accda086f4 | |||
b562abe976 | |||
22ed2261f3 | |||
d4175e0710 | |||
e04e620930 | |||
f12412ff14 | |||
c87b0bf5d5 | |||
1702da5d16 | |||
d38e41de29 | |||
d31c73b005 | |||
a83a8ce528 | |||
e683e5c490 | |||
31e82e73ba | |||
7e49baf599 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
8
.idea/.gitignore
generated
vendored
8
.idea/.gitignore
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# Editor-based HTTP Client requests
|
|
||||||
/httpRequests/
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
6
.idea/GitLink.xml
generated
6
.idea/GitLink.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="uk.co.ben_gibson.git.link.SettingsState">
|
|
||||||
<option name="host" value="e0f86390-1091-4871-8aeb-f534fbc99cf0" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
6
.idea/compilerexplorer.settings.xml
generated
6
.idea/compilerexplorer.settings.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerExplorerSettingsProvider">
|
|
||||||
<option name="highlightColorRGB" value="-16711681" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
7
.idea/discord.xml
generated
7
.idea/discord.xml
generated
@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="DiscordProjectSettings">
|
|
||||||
<option name="show" value="PROJECT_FILES" />
|
|
||||||
<option name="description" value="" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
15
.idea/git_toolbox_prj.xml
generated
15
.idea/git_toolbox_prj.xml
generated
@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="GitToolBoxProjectSettings">
|
|
||||||
<option name="commitMessageIssueKeyValidationOverride">
|
|
||||||
<BoolValueOverride>
|
|
||||||
<option name="enabled" value="true" />
|
|
||||||
</BoolValueOverride>
|
|
||||||
</option>
|
|
||||||
<option name="commitMessageValidationEnabledOverride">
|
|
||||||
<BoolValueOverride>
|
|
||||||
<option name="enabled" value="true" />
|
|
||||||
</BoolValueOverride>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/monstrous.iml" filepath="$PROJECT_DIR$/.idea/monstrous.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
11
.idea/monstrous.iml
generated
11
.idea/monstrous.iml
generated
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="CPP_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
6
.vscode/extensions.json
vendored
Normal file
6
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"vadimcn.vscode-lldb",
|
||||||
|
"rust-lang.rust-analyzer"
|
||||||
|
]
|
||||||
|
}
|
45
.vscode/launch.json
vendored
Normal file
45
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug executable 'monstrous'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--bin=monstrous",
|
||||||
|
"--package=monstrous"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "monstrous",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug unit tests in executable 'monstrous'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--no-run",
|
||||||
|
"--bin=monstrous",
|
||||||
|
"--package=monstrous"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "monstrous",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
1249
Cargo.lock
generated
1249
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
14
Cargo.toml
@ -2,10 +2,18 @@
|
|||||||
name = "monstrous"
|
name = "monstrous"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "AGPL-3.0+"
|
license = "AGPL-3.0-or-later"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = "0.7.0"
|
bevy = "0.9"
|
||||||
bevy_ecs_tilemap = "0.6.0"
|
bevy_ecs_tilemap = "0.9"
|
||||||
|
rand = "0.8.5"
|
||||||
|
ron = "0.8.0"
|
||||||
|
serde = { version = "1.0.143", features = ["derive"] }
|
||||||
|
|
||||||
|
# Enable max optimizations for dependencies, but not for our code:
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = 3
|
||||||
|
|
||||||
|
32
README.md
Normal file
32
README.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Monstrous
|
||||||
|
|
||||||
|
A game of survival, community, and unspeakable horror. Maybe. One day. Hopefully.
|
||||||
|
|
||||||
|
## How to build?
|
||||||
|
|
||||||
|
Having Rust installed, clone the repository and do:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ cargo run
|
||||||
|
```
|
||||||
|
|
||||||
|
...that's it. Right now it won't do much.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Monstrous, a game of survival, community and unspeakable horror.
|
||||||
|
|
||||||
|
Copyright (C) 2022 Sandra Modzelewska
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
BIN
assets/pawn.aseprite
Normal file
BIN
assets/pawn.aseprite
Normal file
Binary file not shown.
BIN
assets/pawn.png
Normal file
BIN
assets/pawn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 442 B |
23
assets/surfaces.ron
Normal file
23
assets/surfaces.ron
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[
|
||||||
|
SurfaceDef {
|
||||||
|
label: "Mud",
|
||||||
|
name: "mud",
|
||||||
|
description: "Soil saturated with water.",
|
||||||
|
texture_index: 13,
|
||||||
|
support: 20.0,
|
||||||
|
},
|
||||||
|
SurfaceDef {
|
||||||
|
label: "Grass",
|
||||||
|
name: "grass",
|
||||||
|
description: "Green. Try to touch it.",
|
||||||
|
texture_index: 14,
|
||||||
|
support: 40.0,
|
||||||
|
},
|
||||||
|
SurfaceDef {
|
||||||
|
label: "Sand",
|
||||||
|
name: "sand",
|
||||||
|
description: "Gets everywhere, ruins vanilla sex fantasies.",
|
||||||
|
texture_index: 15,
|
||||||
|
support: 20.0,
|
||||||
|
},
|
||||||
|
]
|
BIN
assets/tileset.aseprite
Normal file
BIN
assets/tileset.aseprite
Normal file
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 130 B After Width: | Height: | Size: 2.1 KiB |
@ -1 +0,0 @@
|
|||||||
pub mod texture;
|
|
@ -1,20 +0,0 @@
|
|||||||
use bevy::{prelude::*, render::render_resource::TextureUsages};
|
|
||||||
|
|
||||||
pub fn set_texture_filters_to_nearest(
|
|
||||||
mut texture_events: EventReader<AssetEvent<Image>>,
|
|
||||||
mut textures: ResMut<Assets<Image>>,
|
|
||||||
) {
|
|
||||||
// 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.texture_descriptor.usage = TextureUsages::TEXTURE_BINDING
|
|
||||||
| TextureUsages::COPY_SRC
|
|
||||||
| TextureUsages::COPY_DST;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
96
src/main.rs
96
src/main.rs
@ -1,50 +1,80 @@
|
|||||||
use bevy::prelude::*;
|
// Copyright 2022 ModZero.
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
use bevy::{
|
||||||
|
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
|
||||||
|
input::mouse::MouseMotion,
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
use bevy_ecs_tilemap::prelude::*;
|
use bevy_ecs_tilemap::prelude::*;
|
||||||
|
|
||||||
mod helpers;
|
use pawns::{make_pawn, pawn_control, pawn_motion, pawn_transform};
|
||||||
|
use terrain::make_ground_layer;
|
||||||
|
|
||||||
fn startup(mut commands: Commands, asset_server: Res<AssetServer>, mut map_query: MapQuery) {
|
mod pawns;
|
||||||
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
|
mod terrain;
|
||||||
|
|
||||||
let texture_handle = asset_server.load("tileset.png");
|
fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
|
commands.spawn(Camera2dBundle::default());
|
||||||
|
|
||||||
let map_entity = commands.spawn().id();
|
let tileset_texture_handle = asset_server.load("tileset.png");
|
||||||
let mut map = Map::new(0u16, map_entity);
|
let pawn_texture_handle: Handle<Image> = asset_server.load("pawn.png");
|
||||||
|
|
||||||
let (mut layer_builder, layer_entity) = LayerBuilder::<TileBundle>::new(
|
let tilemap_size = TilemapSize { x: 320, y: 320 };
|
||||||
|
let tile_size = TilemapTileSize { x: 32.0, y: 32.0 };
|
||||||
|
|
||||||
|
let tilemap_entity = make_ground_layer(
|
||||||
&mut commands,
|
&mut commands,
|
||||||
LayerSettings::new(
|
tilemap_size,
|
||||||
MapSize(3, 3),
|
tileset_texture_handle,
|
||||||
ChunkSize(8, 8),
|
tile_size,
|
||||||
TileSize(8.0, 8.0),
|
|
||||||
TextureSize(24.0, 24.0)
|
|
||||||
),
|
|
||||||
0u16,
|
|
||||||
0u16
|
|
||||||
);
|
);
|
||||||
layer_builder.set_all(TileBundle::default());
|
make_pawn(
|
||||||
|
&mut commands,
|
||||||
|
tilemap_entity,
|
||||||
|
pawn_texture_handle,
|
||||||
|
&tile_size,
|
||||||
|
&tilemap_size,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
map_query.build_layer(&mut commands, layer_builder, texture_handle);
|
fn mouse_motion(
|
||||||
map.add_layer(&mut commands, 0u16, layer_entity);
|
mut motion_evr: EventReader<MouseMotion>,
|
||||||
|
buttons: Res<Input<MouseButton>>,
|
||||||
commands
|
mut query: Query<(&mut Transform, &mut OrthographicProjection), With<Camera>>,
|
||||||
.entity(map_entity)
|
) {
|
||||||
.insert(map)
|
for ev in motion_evr.iter() {
|
||||||
.insert(Transform::from_xyz(-128.0, -128.0, 0.0))
|
if buttons.pressed(MouseButton::Middle) {
|
||||||
.insert(GlobalTransform::default());
|
for (mut transform, mut _ortho) in query.iter_mut() {
|
||||||
|
let direction = Vec3::new(ev.delta.x, ev.delta.y * -1.0, 0.0);
|
||||||
|
transform.translation += direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.insert_resource(WindowDescriptor {
|
.add_plugins(
|
||||||
width: 1270.0,
|
DefaultPlugins
|
||||||
height: 720.0,
|
.set(WindowPlugin {
|
||||||
title: String::from("Monstrous"),
|
window: WindowDescriptor {
|
||||||
..Default::default()
|
width: 1270.0,
|
||||||
})
|
height: 720.0,
|
||||||
.add_plugins(DefaultPlugins)
|
title: String::from("Monstrous"),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..default()
|
||||||
|
})
|
||||||
|
.set(ImagePlugin::default_nearest()),
|
||||||
|
)
|
||||||
|
.add_plugin(LogDiagnosticsPlugin::default())
|
||||||
|
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
||||||
.add_plugin(TilemapPlugin)
|
.add_plugin(TilemapPlugin)
|
||||||
.add_startup_system(startup)
|
.add_startup_system(startup)
|
||||||
.add_system(helpers::texture::set_texture_filters_to_nearest)
|
.add_system(mouse_motion)
|
||||||
|
.add_system(pawn_control)
|
||||||
|
.add_system(pawn_motion)
|
||||||
|
.add_system(pawn_transform)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
161
src/pawns.rs
Normal file
161
src/pawns.rs
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
use bevy::{
|
||||||
|
input::{mouse::MouseButtonInput, ButtonState},
|
||||||
|
math::Vec4Swizzles,
|
||||||
|
prelude::*,
|
||||||
|
render::camera::RenderTarget,
|
||||||
|
};
|
||||||
|
use bevy_ecs_tilemap::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct PlayerCharacter {}
|
||||||
|
|
||||||
|
#[derive(Component, Default, Clone, Copy, Debug)]
|
||||||
|
pub struct PawnPos {
|
||||||
|
pub x: u32,
|
||||||
|
pub y: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Default, Clone, Copy, Debug)]
|
||||||
|
pub struct PawnDest {
|
||||||
|
pub x: u32,
|
||||||
|
pub y: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Default, Clone, Copy, Debug)]
|
||||||
|
pub struct PawnNextTile {
|
||||||
|
pub x: u32,
|
||||||
|
pub y: u32,
|
||||||
|
pub progress: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Bundle, Default)]
|
||||||
|
struct PawnBundle {
|
||||||
|
position: PawnPos,
|
||||||
|
sprite: Sprite,
|
||||||
|
transform: Transform,
|
||||||
|
global_transform: GlobalTransform,
|
||||||
|
texture: Handle<Image>,
|
||||||
|
visibility: Visibility,
|
||||||
|
computed_visibility: ComputedVisibility,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_pawn(
|
||||||
|
commands: &mut Commands,
|
||||||
|
tilemap_entity: Entity,
|
||||||
|
texture_handle: Handle<Image>,
|
||||||
|
tile_size: &TilemapTileSize,
|
||||||
|
map_size: &TilemapSize,
|
||||||
|
) {
|
||||||
|
let pos = PawnPos {
|
||||||
|
x: map_size.x / 2,
|
||||||
|
y: map_size.y / 2,
|
||||||
|
};
|
||||||
|
commands
|
||||||
|
.spawn(PawnBundle {
|
||||||
|
position: pos,
|
||||||
|
transform: Transform::from_xyz(
|
||||||
|
(pos.x as f32) * tile_size.x,
|
||||||
|
(pos.y as f32) * tile_size.y,
|
||||||
|
1.0,
|
||||||
|
),
|
||||||
|
texture: texture_handle,
|
||||||
|
visibility: Visibility { is_visible: true },
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.insert(PlayerCharacter {})
|
||||||
|
.set_parent(tilemap_entity);
|
||||||
|
info!("Pawn at {:?}", pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pawn_control(
|
||||||
|
mut commands: Commands,
|
||||||
|
wnds: Res<Windows>,
|
||||||
|
query: Query<Entity, With<PlayerCharacter>>,
|
||||||
|
mut buttons_evr: EventReader<MouseButtonInput>,
|
||||||
|
camera_q: Query<(&GlobalTransform, &Camera)>,
|
||||||
|
tilemap_q: Query<(&TilemapSize, &TilemapGridSize, &TilemapType, &Transform)>,
|
||||||
|
) {
|
||||||
|
for ev in buttons_evr.iter() {
|
||||||
|
if (ev.button == MouseButton::Right) && (ev.state == ButtonState::Released) {
|
||||||
|
let (cam_gt, cam) = camera_q.single();
|
||||||
|
let wnd = if let RenderTarget::Window(id) = cam.target {
|
||||||
|
wnds.get(id).unwrap()
|
||||||
|
} else {
|
||||||
|
wnds.get_primary().unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(screen_pos) = wnd.cursor_position() {
|
||||||
|
query.for_each(|entity| {
|
||||||
|
if let Some(world_ray) = cam.viewport_to_world(cam_gt, screen_pos) {
|
||||||
|
let (map_size, map_grid_size, map_type, map_t) = tilemap_q.single();
|
||||||
|
|
||||||
|
let tilemap_pos = (map_t.compute_matrix().inverse()
|
||||||
|
* Vec4::from((world_ray.origin, 1.0)))
|
||||||
|
.xy();
|
||||||
|
if let Some(tile_pos) =
|
||||||
|
TilePos::from_world_pos(&tilemap_pos, map_size, map_grid_size, map_type)
|
||||||
|
{
|
||||||
|
commands
|
||||||
|
.entity(entity)
|
||||||
|
.insert(PawnDest {
|
||||||
|
x: tile_pos.x,
|
||||||
|
y: tile_pos.y,
|
||||||
|
})
|
||||||
|
.remove::<PawnNextTile>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PawnsToPath = (Without<PawnNextTile>, With<PawnDest>);
|
||||||
|
|
||||||
|
pub fn pawn_motion(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut pawn_q: Query<(Entity, &PawnPos, &PawnDest), PawnsToPath>,
|
||||||
|
) {
|
||||||
|
pawn_q.for_each_mut(|(entity, pos, dest)| {
|
||||||
|
if pos.x == dest.x && pos.y == dest.y {
|
||||||
|
commands.entity(entity).remove::<PawnDest>();
|
||||||
|
} else {
|
||||||
|
let next_tile = { TilePos::new(dest.x, dest.y) };
|
||||||
|
commands.entity(entity).insert(PawnNextTile {
|
||||||
|
x: next_tile.x,
|
||||||
|
y: next_tile.y,
|
||||||
|
progress: 0.0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pawn_transform(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut pawn_q: Query<(Entity, &mut PawnPos, &mut Transform, &mut PawnNextTile)>,
|
||||||
|
tilemap_q: Query<&TilemapTileSize>,
|
||||||
|
time: Res<Time>,
|
||||||
|
) {
|
||||||
|
let map_tile_size = tilemap_q.single();
|
||||||
|
pawn_q.for_each_mut(|(entity, mut pos, mut transform, mut next_tile)| {
|
||||||
|
let distance = Vec2::from((pos.x as f32, pos.y as f32))
|
||||||
|
.distance(Vec2::from((next_tile.x as f32, next_tile.y as f32)));
|
||||||
|
let velocity = 1.0;
|
||||||
|
let new_progress = next_tile.progress + velocity * time.delta_seconds();
|
||||||
|
if new_progress >= distance {
|
||||||
|
pos.x = next_tile.x;
|
||||||
|
pos.y = next_tile.y;
|
||||||
|
transform.translation.x = (pos.x as f32) * map_tile_size.x;
|
||||||
|
transform.translation.y = (pos.y as f32) * map_tile_size.y;
|
||||||
|
commands.entity(entity).remove::<PawnNextTile>();
|
||||||
|
} else {
|
||||||
|
next_tile.progress = new_progress;
|
||||||
|
transform.translation.x = (pos.x as f32
|
||||||
|
+ (next_tile.x as f32 - pos.x as f32) * (next_tile.progress / distance))
|
||||||
|
* map_tile_size.x;
|
||||||
|
transform.translation.y = (pos.y as f32
|
||||||
|
+ (next_tile.y as f32 - pos.y as f32) * (next_tile.progress / distance))
|
||||||
|
* map_tile_size.y;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
96
src/terrain.rs
Normal file
96
src/terrain.rs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// Copyright 2022 ModZero.
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_ecs_tilemap::prelude::*;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct SurfaceDef<'a> {
|
||||||
|
pub label: &'a str,
|
||||||
|
pub name: &'a str,
|
||||||
|
pub description: &'a str,
|
||||||
|
pub texture_index: u32,
|
||||||
|
pub support: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Clone)]
|
||||||
|
struct TileTerrain {
|
||||||
|
terrain_id: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TileTerrain {
|
||||||
|
fn def(&self) -> &SurfaceDef {
|
||||||
|
&TERRAINS[self.terrain_id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TERRAINS: [SurfaceDef; 3] = [
|
||||||
|
SurfaceDef {
|
||||||
|
label: "Mud",
|
||||||
|
name: "mud",
|
||||||
|
description: "Soil saturated with water.",
|
||||||
|
texture_index: 13,
|
||||||
|
support: 20.0,
|
||||||
|
},
|
||||||
|
SurfaceDef {
|
||||||
|
label: "Grass",
|
||||||
|
name: "grass",
|
||||||
|
description: "Green. Try to touch it.",
|
||||||
|
texture_index: 14,
|
||||||
|
support: 40.0,
|
||||||
|
},
|
||||||
|
SurfaceDef {
|
||||||
|
label: "Sand",
|
||||||
|
name: "sand",
|
||||||
|
description: "Gets everywhere, ruins vanilla sex fantasies.",
|
||||||
|
texture_index: 15,
|
||||||
|
support: 20.0,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
pub fn make_ground_layer(
|
||||||
|
commands: &mut Commands,
|
||||||
|
tilemap_size: TilemapSize,
|
||||||
|
texture_handle: Handle<Image>,
|
||||||
|
tile_size: TilemapTileSize,
|
||||||
|
) -> Entity {
|
||||||
|
let mut tile_storage = TileStorage::empty(tilemap_size);
|
||||||
|
let tilemap_entity = commands.spawn_empty().id();
|
||||||
|
|
||||||
|
for x in 0..tilemap_size.x {
|
||||||
|
for y in 0..tilemap_size.y {
|
||||||
|
let tile_pos = TilePos { x, y };
|
||||||
|
|
||||||
|
let tile_terrain = TileTerrain { terrain_id: 1 };
|
||||||
|
let tile_entity = commands
|
||||||
|
.spawn((
|
||||||
|
tile_terrain.clone(),
|
||||||
|
TileBundle {
|
||||||
|
position: tile_pos,
|
||||||
|
tilemap_id: TilemapId(tilemap_entity),
|
||||||
|
texture_index: TileTextureIndex(tile_terrain.def().texture_index),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.id();
|
||||||
|
tile_storage.set(&tile_pos, tile_entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let grid_size = tile_size.into();
|
||||||
|
let map_type = TilemapType::default();
|
||||||
|
|
||||||
|
commands.entity(tilemap_entity).insert(TilemapBundle {
|
||||||
|
grid_size,
|
||||||
|
map_type,
|
||||||
|
size: tilemap_size,
|
||||||
|
storage: tile_storage.clone(),
|
||||||
|
texture: TilemapTexture::Single(texture_handle),
|
||||||
|
tile_size,
|
||||||
|
transform: get_tilemap_center_transform(&tilemap_size, &grid_size, &map_type, 0.0),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
tilemap_entity
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user