summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/shaders/enemy_material.wgsl15
-rw-r--r--design.md47
-rw-r--r--plan.md39
-rw-r--r--src/main.rs46
4 files changed, 135 insertions, 12 deletions
diff --git a/assets/shaders/enemy_material.wgsl b/assets/shaders/enemy_material.wgsl
new file mode 100644
index 0000000..4b20d19
--- /dev/null
+++ b/assets/shaders/enemy_material.wgsl
@@ -0,0 +1,15 @@
+struct EnemyMaterial {
+ color: vec4<f32>,
+};
+
+@group(1) @binding(0)
+var<uniform> material: EnemyMaterial;
+
+struct FragmentInput {
+ #import bevy_pbr::mesh_vertex_output
+}
+
+@fragment
+fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
+ return material.color * vec4<f32>(in.world_normal, 1.0);
+}
diff --git a/design.md b/design.md
index 21b7136..fad240f 100644
--- a/design.md
+++ b/design.md
@@ -1,12 +1,47 @@
-terrorhedron
-+ conway polyhedral notation
-+ editable voxel map
-+ deterministic multiplayer
+# terrorhedron, but
+- conway polyhedral notation leading to different enemy/turret design and balance
+- editable voxel map
+- deterministic multiplayer
-enemies are shapes:
-[ ] generate a table with all shapes generated from T (tetrahedron)
+## enemies are shapes:
+- [x] generate a table with all shapes generated from T (tetrahedron)
with at most 5 operators
between s (snub), k (kis), a (ambo), d (dual)
in canonical form.
provide the vertex number, time needed
to see if it's viable to generate them on the fly.
+
+-> it's not viable to generate on the fly any shape using the topological operators.
+they act only on the topology, which leaves some degrees of freedom.
+
+- [x] evaluate pregenerated options
+ - use the 5 platonic, 13 archimedean and their dual the 13 catalans -> 31 shapes.
+ - precalc all variations of "skad" up to depth n=3: 84, n=4: 340, n=5: 1364.
+
+-> i'll stick to the 31 for now
+
+## reference of the 31=(13+13+5) shapes.
+T, kT, dkT,
+aT, kaT, dkaT, aaT, daaT, kdaaT, dkdaaT, aaaT, daaaT, daT, kdaT, dkdaT, saT, dsaT
+sT, ksT, dksT, asT, dasT, kdasT, dkdasT, aasT, daasT, dsT, kdsT, dkdsT, ssT, dssT
+
+### properties of all available shapes up to depth n
+contain duplicates, dddT = ddT = dT = T or saT = sdaT
+contain canonicalization artifacts
+
+- [ ] shape shader
+ - used to indicate both the topology and a variant
+ - used only to indicate the topology
+
+shader variants: striped, dotted, translucient, negative, burning, wireframe
+
+## enemies
+### operator effects
+
+they stack multiplicativly.
+
+- T: no effect
+- k: +20% speed
+- a: +3 life, 2x damage
+- d: -2 life, duplicates on death (only when losing the d)
+- s: multiplies life by 3, speed -20%
diff --git a/plan.md b/plan.md
new file mode 100644
index 0000000..792f340
--- /dev/null
+++ b/plan.md
@@ -0,0 +1,39 @@
+# plan
+list of tasks to get to the prototype.
+
+## camera
+the camera should be first person flying and transition to orbital on click seamlessly.
+it must support being focused on a point (turret, attach, enemy).
+
+## level geometry
+voxels
+- occlusions (normal blocks + decorative)
+- attachment points
+- path(s)
+decorative blocks and lights.
+
+## level editor
+ui for action/block selection.
+actions:
+- edit level geometry
+- edit path
+- edit attachments
+- edit lights
+- edit waves
+
+## enemy shader
+default
+hit effect
+
+## path line shader
+
+## multiplayer
+
+## turrets
+### placement
+### upgrade
+### shooting
+
+## wave spawning
+
+## waves balance
diff --git a/src/main.rs b/src/main.rs
index 24b706f..9e43468 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,7 +2,11 @@ use std::collections::HashMap;
use itertools::Itertools;
-use bevy::prelude::*;
+use bevy::{
+ prelude::*,
+ reflect::TypeUuid,
+ render::render_resource::{AsBindGroup, ShaderRef},
+};
use polyhedron_ops as p_ops;
use smooth_bevy_cameras::{
controllers::orbit::{OrbitCameraBundle, OrbitCameraController, OrbitCameraPlugin},
@@ -17,6 +21,7 @@ fn main() {
.add_plugin(OrbitCameraPlugin::default())
.add_startup_system(setup)
.add_system(bevy::window::close_on_esc)
+ .add_plugin(MaterialPlugin::<EnemyMaterial>::default())
.run();
}
@@ -30,7 +35,6 @@ impl ShapeMap {
let mut sm = ShapeMap {
shapes: HashMap::new(),
};
-
for var in (1..=depth as usize).flat_map(|n| {
std::iter::repeat(ops.chars())
.take(n)
@@ -50,18 +54,22 @@ impl ShapeMap {
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
- mut materials: ResMut<Assets<StandardMaterial>>,
+ mut base_materials: ResMut<Assets<StandardMaterial>>,
+ mut enemy_materials: ResMut<Assets<EnemyMaterial>>,
) {
let depth = 1;
- let sm = ShapeMap::new("T", "asdk", depth);
+ let sm = ShapeMap::new("T", "skad", depth);
let mut x = 0;
let mut y = 0;
for (_, s) in sm.shapes.iter() {
let pos = Vec3::new(0.0, x as f32 * 2.0, y as f32 * 2.0);
- commands.spawn(PbrBundle {
+ commands.spawn(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(s.clone())),
- material: materials.add(Color::rgb(0.4, 0.35, 0.3).into()),
+ material: enemy_materials.add(EnemyMaterial {
+ color: Color::rgba(1.0, 1.0, 1.0, 1.0),
+ alpha_mode: AlphaMode::Opaque,
+ }),
transform: Transform::from_translation(pos),
..default()
});
@@ -72,6 +80,14 @@ fn setup(
}
}
+ // reference cube
+ commands.spawn(MaterialMeshBundle {
+ mesh: meshes.add(Mesh::from(shape::Cube::default())),
+ material: base_materials.add(Color::BLUE.into()),
+ transform: Transform::from_translation(Vec3::new(-2.0, 0.0, 0.0)),
+ ..default()
+ });
+
commands
// light
.spawn(DirectionalLightBundle {
@@ -93,3 +109,21 @@ fn setup(
Vec3::new(0., -1., 0.),
));
}
+
+impl Material for EnemyMaterial {
+ fn fragment_shader() -> ShaderRef {
+ "shaders/enemy_material.wgsl".into()
+ }
+
+ fn alpha_mode(&self) -> AlphaMode {
+ self.alpha_mode
+ }
+}
+
+#[derive(AsBindGroup, TypeUuid, Debug, Clone)]
+#[uuid = "f690fdae-d598-45ab-8225-97e2a3f056e0"]
+pub struct EnemyMaterial {
+ #[uniform(0)]
+ color: Color,
+ alpha_mode: AlphaMode,
+}