Skip to content

Commit 5cabc06

Browse files
committed
content: Add projectile exhibit.
This exercises a complete set of `Move` behaviors used to create a long-distance moving object.
1 parent f078f3f commit 5cabc06

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

all-is-cubes-content/src/blocks.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub enum DemoBlocks {
5555
Clock,
5656
BecomeBlinker(bool),
5757
Explosion(i8),
58+
Projectile,
5859
}
5960
impl BlockModule for DemoBlocks {
6061
fn namespace() -> &'static str {
@@ -492,6 +493,30 @@ pub async fn install_demo_blocks(
492493
})?
493494
.build_txn(txn)
494495
}
496+
497+
Projectile => Block::builder()
498+
.display_name("Projectile")
499+
.voxels_fn(resolution, |cube| {
500+
let [r, _] = square_radius(resolution, cube);
501+
if r * 4 < resolution_g {
502+
&lamppost_metal
503+
} else {
504+
&AIR
505+
}
506+
})?
507+
.animation_hint(AnimationHint::replacement(block::AnimationChange::Shape))
508+
.tick_action(TickAction {
509+
operation: Operation::Alt(
510+
[
511+
Operation::StartMove(block::Move::new(Face6::PY, 0, 32)),
512+
// if we can't move, vanish
513+
Operation::Become(AIR),
514+
]
515+
.into(),
516+
),
517+
schedule: time::Schedule::EVERY_TICK,
518+
})
519+
.build_txn(txn),
495520
})
496521
})
497522
.await?

all-is-cubes-content/src/city/exhibits.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use all_is_cubes::inv;
2929
use all_is_cubes::linking::{BlockProvider, InGenError};
3030
use all_is_cubes::listen::ListenableSource;
3131
use all_is_cubes::math::{
32-
rgb_const, rgba_const, Cube, Face6, FaceMap, FreeCoordinate, GridAab, GridCoordinate,
32+
notnan, rgb_const, rgba_const, Cube, Face6, FaceMap, FreeCoordinate, GridAab, GridCoordinate,
3333
GridPoint, GridRotation, GridSize, GridVector, Gridgid, NotNan, Rgb, Rgba,
3434
};
3535
use all_is_cubes::op::Operation;
@@ -55,6 +55,7 @@ pub(crate) static DEMO_CITY_EXHIBITS: &[Exhibit] = &[
5555
TRANSPARENCY_SMALL,
5656
COLLISION,
5757
RESOLUTIONS,
58+
PROJECTILE,
5859
ANIMATION,
5960
MAKE_SOME_BLOCKS,
6061
DASHED_BOXES,
@@ -866,6 +867,48 @@ fn MOVED_BLOCKS(_: Context<'_>) {
866867
Ok((space, txn))
867868
}
868869

870+
#[macro_rules_attribute::apply(exhibit!)]
871+
#[exhibit(
872+
name: "Projectile",
873+
subtitle: "click me to launch",
874+
placement: Placement::Surface,
875+
)]
876+
fn PROJECTILE(ctx: Context<'_>) {
877+
let demo_blocks = BlockProvider::<DemoBlocks>::using(ctx.universe)?;
878+
let txn = ExhibitTransaction::default();
879+
880+
let projectile = &demo_blocks[DemoBlocks::Projectile];
881+
882+
let moving_in = projectile
883+
.clone()
884+
.with_modifier(Move::new(Face6::NY, 256, -32));
885+
886+
// TODO: make the launcher block visibly contain and launch the projectile.
887+
// This will require getting `Move` tick actions to cooperate with `Composite`.
888+
let launcher = Block::builder()
889+
.display_name(literal!("Launcher"))
890+
.color(Rgb::UNIFORM_LUMINANCE_RED.with_alpha(notnan!(1.0)))
891+
.animation_hint(block::AnimationHint::replacement(
892+
block::AnimationChange::Shape,
893+
))
894+
.activation_action(Operation::Neighbors(
895+
[
896+
// TODO: Instead of `DestroyTo`, we should have an operation that only
897+
// succeeds if there is room to enter empty space here (if the destination
898+
// is AIR, for now).
899+
(Cube::new(0, 1, 0), Operation::DestroyTo(moving_in)),
900+
]
901+
.into(),
902+
))
903+
.build();
904+
905+
let space = Space::builder(GridAab::ORIGIN_CUBE)
906+
.filled_with(launcher)
907+
.build();
908+
909+
Ok((space, txn))
910+
}
911+
869912
#[macro_rules_attribute::apply(exhibit!)]
870913
#[exhibit(
871914
name: "Operation::Become",

0 commit comments

Comments
 (0)