use nightshade_api::prelude::*;
struct Game {
player: Entity,
hud: Entity,
banner: Entity,
rings: Vec<Entity>,
popups: Vec<(Entity, f32)>,
won: bool,
}
fn main() {
run(
|world| {
set_background(world, Background::Sunset);
set_bloom(world, true);
let floor = spawn_floor(world, 25.0);
set_texture(world, floor, "checkerboard");
set_texture_tiling(world, floor, 6.0);
let mut rings = Vec::new();
for index in 0..12 {
let angle = index as f32 / 12.0 * std::f32::consts::TAU;
let radius = 6.0 + (index % 3) as f32 * 4.0;
let ring = spawn_object(
world,
Object {
shape: Shape::Torus,
position: vec3(angle.cos() * radius, 0.8, angle.sin() * radius),
scale: vec3(0.5, 0.5, 0.5),
color: GOLD,
..Object::default()
},
);
set_emissive(world, ring, [1.0, 0.7, 0.1], 6.0);
rings.push(ring);
}
let player = first_person(world, vec3(0.0, 1.2, 18.0));
let hud = spawn_text(world, "rings left: 12", ScreenAnchor::TopLeft);
set_text_color(world, hud, GOLD);
set_text_size(world, hud, 30.0);
let banner = spawn_text(world, "", ScreenAnchor::Center);
set_text_color(world, banner, GREEN);
set_text_size(world, banner, 64.0);
Game {
player,
hud,
banner,
rings,
popups: Vec::new(),
won: false,
}
},
|world, game| {
let here = position(world, game.player);
let step = delta_time(world);
let popups = &mut game.popups;
game.rings.retain(|&ring| {
rotate(world, ring, Vec3::y(), step * 2.0);
let spot = position(world, ring);
let offset = spot - here;
if vec3(offset.x, 0.0, offset.z).magnitude() > 1.6 {
return true;
}
emit_burst(world, spot, GOLD, 60);
shake_camera(world, 0.05, 0.15);
let popup = spawn_label(world, "+1 RING", spot + vec3(0.0, 1.0, 0.0));
set_text_color(world, popup, GOLD);
set_text_size(world, popup, 30.0);
popups.push((popup, 0.0));
despawn(world, ring);
false
});
game.popups.retain_mut(|(label, age)| {
*age += step;
if *age > 1.4 {
despawn(world, *label);
return false;
}
let at = position(world, *label);
set_position(world, *label, vec3(at.x, at.y + step * 1.3, at.z));
let fade = 1.0 - *age / 1.4;
set_text_color(world, *label, [GOLD[0], GOLD[1], GOLD[2], fade]);
true
});
set_text(
world,
game.hud,
&format!("rings left: {}", game.rings.len()),
);
if game.rings.is_empty() && !game.won {
game.won = true;
set_text(world, game.banner, "YOU WIN");
}
},
)
.unwrap();
}