Bomber och granater
Det känns lite orättvist att vår stackars cirkel inte kan försvara sig mot de läskiga fyrkanterna. Därför är det dags att implementera skott som cirkeln kan skjuta ner fyrkanterna med.
Implementering
Känner sig träffade
För att hålla reda på vilka fyrkanter som har blivit träffade av kulor så
lägger vi till ett nytt fält collided
av typen bool
i structen Shape
.
struct Shape {
size: f32,
speed: f32,
x: f32,
y: f32,
collided: bool,
}
Vektor för kulor
Vi måste ha en ny vektor som håller reda på alla kulor som har skjutits. Vi
kallar den bullets
och skapar den efter vektorn med squares
. Här anger vi
vilken typ vektorn ska innehålla eftersom Rust-kompilatorn måste veta vilken
typ det är innan vi har tilldelat den något värde. Vi använder structen
Shape
även för kulorna för enkelhetens skull.
let mut bullets: Vec<Shape> = vec![];
Skjut kulor
Efter cirkeln har förflyttats så lägger vi till en kontroll om spelaren har
tryckt på mellanslag, och lägger till en kula i vektorn med kulor. Kulans x
-
och y
-koordinater sätts till samma som cirkeln, och hastigheten till dubbla
cirkelns hastighet.
if is_key_pressed(KeyCode::Space) {
bullets.push(Shape {
x: circle.x,
y: circle.y,
speed: circle.speed * 2.0,
size: 5.0,
collided: false,
});
}
Notera att vi använder funktionen is_key_pressed()
som bara är sann under
den första bildrutan som tangenten trycks ned.
Eftersom vi har lagt till ett fält på structen Shape
måste vi lägga till den
när vi skapar en fyrkant.
squares.push(Shape {
size,
speed: rand::gen_range(50.0, 150.0),
x: rand::gen_range(size / 2.0, screen_width() - size / 2.0),
y: -size,
collided: false,
});
Flytta kulor
För att kulorna inte ska bli stillastående minor så måste vi loopa över alla kulor och flytta dom i Y-led. Lägg till följande kod efter förflyttningen av fyrkanterna.
for square in &mut squares {
square.y += square.speed * delta_time;
}
for bullet in &mut bullets {
bullet.y -= bullet.speed * delta_time;
}
Ta bort kulor och fyrkanter
Även kulorna behöver tas bort om de hamnar utanför skärmen.
bullets.retain(|bullet| bullet.y > 0.0 - bullet.size / 2.0);
Nu är det dags att ta bort alla fyrkanter och kulor som har kolliderat med
något. Det gör vi enkelt med retain
-metoden och behåller alla som inte har
collided
satt till true
. Vi gör detta på båda vektorerna för squares
och
bullets
.
squares.retain(|square| !square.collided);
bullets.retain(|bullet| !bullet.collided);
Kollidering
Efter vi har kollat om cirkeln har kolliderat med en fyrkant lägger vi till en
kontroll om någon fyrkant blir träffad av en kula. Både kulan och fyrkanten
uppdateras och fältet collided
sätts till true
så att vi kan ta bort dem
längre ned i koden.
for square in squares.iter_mut() {
for bullet in bullets.iter_mut() {
if bullet.collides_with(square) {
bullet.collided = true;
square.collided = true;
}
}
}
Rensa kulor
Om det har blivit game over måste vi även rensa vektorn bullets
så att
kulorna försvinner när ett nytt spel påbörjas.
if gameover && is_key_pressed(KeyCode::Space) {
squares.clear();
bullets.clear();
circle.x = screen_width() / 2.0;
circle.y = screen_height() / 2.0;
gameover = false;
}
Rita ut kulor
Innan vi ritar ut cirkeln så ritar vi ut alla kulor, så att de ritas ut under övriga former.
for bullet in &bullets {
draw_circle(bullet.x, bullet.y, bullet.size / 2.0, RED);
}
Det finns även en funktion som heter
draw_circle_lines()
som används för att rita ut en cirkel som inte är ifylld.
Det var allt för att kunna skjuta sönder fyrkanter.
För att öka svårighetsgraden går det att lägga till en begränsning så att det
måste gå en viss tid mellan varje skott. Använd funktionen
get_time()
för att spara undan när varje skott skjuts och jämför aktuella tiden med detta
värde.
Quiz
Testa dina nya kunskaper genom att svara på följande quiz innan du går vidare.