Fallande fyrkanter
För att det ska hända lite mer i vårt spel är det dags att skapa lite action. Eftersom hjälten i vårt spel är en modig cirkel så får våra motståndare bli kantiga fyrkanter som faller ner från toppen av fönstret.
Implementering
Struct för former
För att hålla reda på vår cirkel och alla fyrkanter så skapar vi en struct som
vi kan ge namnet Shape
som innehåller storlek, hastighet samt x och
y-koordinater.
struct Shape {
size: f32,
speed: f32,
x: f32,
y: f32,
}
Initiera slumpgenerator
Vi kommer använda oss av en slumpgenerator för att avgöra när nya fyrkanter
ska komma in på skärmen. Därför behöver vi seeda slumpgeneratorn så att det
inte blir samma slumptal varje gång. Detta görs i början av main
-funktionen
med metoden rand::srand()
som vi skickar in nuvarande tid till som seed.
rand::srand(miniquad::date::now() as u64);
Vi använder oss av metoden miniquad::date::now()
från det underliggande
grafikramverket Miniquad
för att få den aktuella tiden.
Vektor med fyrkanter
I början av main
-funktionen skapar vi en vektor squares
som kommer
innehålla alla fyrkanter som ska visas på skärmen. Den nya variabeln circle
får representera vår hjälte, den fantastiska cirkeln. Hastigheten använder
konstanten MOVEMENT_SPEED
och x
och y
-fälten sätts till mitten av
skärmen.
let mut squares = vec![];
let mut circle = Shape {
size: 32.0,
speed: MOVEMENT_SPEED,
x: screen_width() / 2.0,
y: screen_height() / 2.0,
};
Börja med att ändra programmet så att circle
används i stället för variablerna
x
, och y
och bekräfta att allt fungerar som förut innan du börjar skapa
fiendefyrkanter.
Rust-kompilatorn kan ge varningen “type annotations needed” på raden där vektorn skapas. Detta kommer försvinna när vi lägger till en fyrkant i vektorn i avsnittet nedan.
Skapa nya fyrkanter
Nu är det dags att starta invasionen av fyrkanter. Här delar vi som tidigare upp förflyttningen och utritningen av fyrkanterna. Det gör att förflyttningen inte behöver vara beroende av uppdateringsfrekvensen av skärmen, och vi kan se till att alla förändringar har skett innan vi börjar rita upp något på skärmen.
Först använder vi oss av funktionen rand::gen_range()
för att avgöra om vi ska
lägga till en ny fyrkant. Den tar två argument, ett lägsta värde och ett
högsta värde, och returnerar sedan ett slumpat tal mellan dom två värdena. Om
värdet är tillräckligt högt så skapar vi en ny Shape och lägger till i vektorn
squares
. För att få lite variation använder vi även rand::gen_range()
för
att få olika storlek, hastighet och startposition på alla fyrkanter.
if rand::gen_range(0, 99) >= 95 {
let size = rand::gen_range(16.0, 64.0);
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,
});
}
Rektanglar ritas ut med början från övre vänstra hörnet. Därför subtraherar vi halva fyrkantens storlek när vi räknar ut X-positionen. Y-positionen börjar på negativt av fyrkantens storlek, så att den börjar helt utanför skärmen.
Uppdatera fyrkanters position
Nu kan vi gå igenom hela vektorn med en for-loop och uppdatera y-positionen
med hjälp av fyrkantens hastighet och variabeln delta_time
. Detta gör att
fyrkanterna kommer åka neråt över skärmen.
for square in &mut squares {
square.y += square.speed * delta_time;
}
Rensa bort fyrkanter som inte syns
Därefter måste vi rensa upp alla fyrkanter som har hamnat utanför skärmen då
det är onödigt att rita ut saker som inte syns. Vi använder oss av metoden
retain()
på vektorn som tar en funktion som avgör om elementen ska behållas.
Vi kollar att fyrkantens y-värde fortfarande är mindre än höjden på fönstret
plus storleken på fyrkanten.
squares.retain(|square| square.y < screen_height() + square.size);
Rita ut fyrkanterna
Till sist lägger vi till en for-loop som går igenom vektorn squares
och
använder funktionen draw_rectangle()
för att rita ut en rektangel på den
uppdaterade positionen och med rätt storlek. Eftersom rektanglar ritas ut med
x och y från hörnet längst upp till vänster och våra koordinater utgår från
center av fyrkanten så använder vi lite matematik för att räkna ut var dom ska
placeras. Storleken används två gånger, en gång för fyrkantens bredd och en
gång för fyrkantens höjd. Vi sätter färgen till GREEN
så att alla fyrkanter
blir gröna.
Det finns även funktionen
draw_rectangle_ex()
som tar structen
DrawTextureParams
istället för en färg. Med den kan man förutom färg även sätta rotation
och offset
på rektangeln.
for square in &squares {
draw_rectangle(
square.x - square.size / 2.0,
square.y - square.size / 2.0,
square.size,
square.size,
GREEN,
);
}
Försök att ge olika färger till fyrkanterna genom att använda metoden
choose()
på vektorer från Macroquads
ChooseRandom trait
som returnerar ett slumpmässigt valt element från vektorn.
Quiz
Testa dina nya kunskaper genom att svara på följande quiz innan du går vidare.