Making a HUD work

Efter att vår Alfa-presentation fick kompletteringar att göra så har jag suttit och jobbat med dessa. Det vi fick komplettering på var att man ska kunna döda fienden som fanns och att ha en fungerande HUD.

Det jag satt med mest var vår Heads Up Display, aka HUD, som spelaren ser när han eller hon spelar spelet. Den kan representera hur mycket skada spelaren tål eller hur mycket skott kvar spelaren har att skjuta. Just vår HUD, för tillfället, visar bara hur mycket skada spelaren kan ta samt hur mycket den har tagit med hjälp av en mätare. Saker som ska tillkomma är en sköld, så spelaren kan ta extra mycket skada, den genereras dessutom när spelaren inte tagit skada på ett tag, samt en räknare för hur mycket skott som spelaren har kvar på sitt andra vapen. Men som sagt så har jag hittills bara lagt till en livmätare.

Det första jag behövde tänka på var hur jag skulle få mätaren att kunna röra på sig. Min tanke var att skapa en grön rektangel bakom den genomskinliga tuben som Peter har ritat. Så jag skapade en klass till HUDen och började med att lägga in bilden på den och rektangeln som skulle föreställa livet. Sedan kollade jag så jag blev nöjd med hur den såg ut i spelet. Det lätta med detta är att det handlar om väldigt lite kod att skriva, allt som görs som sagt är att lägga in en bild och att skapa en rektangel. Men det första jobbiga jag kom på var hur jag skulle kunna rita ut bilden på spelets view, som är det man ser av spelplanen. Jag började med att rita ut den bara på spelbanan, vilket gjorde att den ritades ut högst upp i vänstra delen av spelplanen, såklart. Så jag ritade ut den på spelarens position och subtraherade hälften av bredden på skärmen och addera med hälften av höjden, eftersom spelaren befinner sig i mitten av skärmen. Detta gjorde att HUD-bilden betedde sig konstigt och rörde sig runt lite grann när man körde med skeppet. Min lösning var att rita ut det på en ny view som läggs ovanpå spelets view, men som också följer efter spelarens rörelser. Detta löste även problemet med att jag ritar ut en svart bild ovanpå hela spelet för att rita ut ljuset som fick HUDen att bli synlig endast när man lös på den.

12655805_1032024530192444_601659818_n

Nu till det verkliga problemet, hur ska jag få rektangeln att bli mindre när spelaren skadas? Jag kollade runt i rektangelklassens egna funktioner och två stycken verkade funka för mig: scale() och setScale(). Jag började med scale som fungerar att den tar in två värden, ett x och ett y värde som sedan multiplicerar värdena med den originella storleken på rektangeln. Det jobbiga med detta, som jag kom på, är att om spelaren tar 10 i skada (spelaren har 100 i liv) så är det 100*0.9, men nästa gång spelaren skadas så är inte 0.9 * 90 = 10 utan 9 etc. Så min lösning blev tillslut att ha ett maxlife och ett currentlife. Maxlife är alltid 100 och currentlife ändras när spelaren tar skada. Jag ändrade också till setScale istället som fungerar så att den tar två värden som scale men den multiplicerar original värdet med det nya värdet. Så ifall rektangeln är 100 i längd och jag använder setScale(2,1) så multipliceras 100 med 2. Jag ändrade också rektangeln till en pixel bred och satte setScale(100, 1). Koden som ändrar storleken på rektangeln:

void HeadsUp::GotHit(float damage)
{
currentlife -= damage;
hSprite.setScale(currentlife, 1);
}

currentlife är likamycket som maxlife vilket är 100. Nu skadas spelaren 10 skada istället så damage blir 10 istället för 0,9. Detta fungerade mycket bra och jag gjorde samma uträkning för att få tillbaka liv men adderar heal istället för att subtrahera damage från currentlife.

Desolate Echo – Game Development Week 4

Förra veckan var inlämning av Gamedesign document som alla jobbade hårt på för att göra klart det som inte var färdigt än. En ändring vi gjorde med projektet var att byta namn från Colossal Core till Desolate Echo. Vi ansåg att Colossal Core inte längre stämde överens med vad vi gjort spelet till. Tidigare hade spelet fokuserat bara på kolossala bossar som man ska slåss mot i kärnan av en planet, vi ändrade båda dessa delar av spelet och samtidigt namnet. Det nya namnet handlar mer om att vara ensam i ett mörkt och trångt utrymme och endast höra ekot av sig själv. Från att handla om att döda kolossala bossar ändrade vi det till att döda en boss per bana och en massa små fiender längs vägen dit. Vi utökade också kartan med en del och har nu mycket mer små gångar och delar att utforska.

I programmeringsväg har jag själv suttit och jobbat med att kanonen på taket av skeppet ska följa musens position, det har gått sådär. Logiken är inte jätte svår, ta positionen på musen relativt till fönstret, ta positionen av skeppet och räkna ut vinkeln emellan dessa. Min första tanke var att använda sin, cos och tan för att få ut vinklarna. Jag ritade upp en fin bild som demonstrerar min tanke:Untitled

Så i klartext för att räkna ut vinkel c behöver man använda väldigt basic gymnasiematte. tan(c) = sidey/sidex, vilket i mitt exempel blir tan(c) = 3/5, tan^-1(3/5) = 80. Jag la till detta i projektet. Musens position updateras rätt relativt till fönstret och kanonen rör sig efter musen. Problemet jag hade först var att jag hade tagit positionen av skeppet på hela kartan, vilket ändras när man flyttar på sig. Så istället för det så hämtade jag hälften av fönstrets x och y värden för att räkna ut avståndet och vinkeln till musen därifrån istället. Jag gick ut på internet för att hitta ett alternativ på hur man kan lösa problemet. Några sa att kanonens sprite måste peka höger för setRotation()’s noll är till höger inte uppåt. Men det löste ju inget såklart. Sedan sa folk att jag skulle använda mig utav

atan2f(rhs.y, rhs.x) * 180.0f / PI

där rhs.y och rhs.x är sidex och sidey på bilden. (* 180 / PI) är för att konvertera från radian till grader. Detta funkade mycket bra och jag kunde gå vidare.

Jag arbetade med projektilerna för skeppet också vilket gick ganska smärtfritt. Jag kopierade lite funktioner från skeppets klass och la till i projektilklassen. Sedan la jag till samma kod för kanonen som fick den att följa musen i klassen och fixade en funktion som gav projektilen en hastighet och en vinkel som räknades ut med samma funktion som innan. Projektilobjektet skapas i turretklassen när spelaren klickar på vänster musknapp och läggs i en lista så spelaren kan skjuta flera gånger.

Jag fick också hjälp av Semih med ljuset som fick det att funka så vi kan visa upp det på alfapresentationen imorgon. Mycket snällt!

Det han gjorde var att skapa ett nytt lager ovanför det befintliga som allt i spelet ritas ut på. Sedan tar han och gör det övre lagret svart och sen laddapointLightTextures en textur in som är en vit-skinande-ljus-liknande bild. Lamptexturen ritas ut med en blending som gör så att det vita i texturen blir genomskinligt. Så skapades ljuset! c924b0fc6ffefb124b7f7393b6455dc5

Game Development Week 3

Förra veckan jobbade jag mycket med kodning i bakgrunden till spelet. Jag jobbade med ScreenManager, HoverCraftTurret, InputManager, LightManager, PlayerShip, de olika menyerna som main menu, pause menu och spelfönstret och jag gjorde en soundmanager.

ScreenManager gick bra att skriva, jag kollade upp en tutorial på github som gick igenom bra hur man gjorde. Det tog ungefär en timme att bli klar med. Sedan gjorde jag även de olika fönsterna som man ser när man startar spelet och när man spelar. Det var från samma tutorial så det tog lika lång tid och lika smärtfritt. När jag var klar med screenmanager och de olika screensen så började jag att arbeta på ljusmotorn, jag kollade runt på internet efter ett bra alternativ av olika ljusmotorer och hittade en som hette Let There Be Light. Jag laddade ner koden för att se om jag skulle kunna skriva den själv men insåg fort att det skulle ta lika lång tid att skriva en ljusmotor som det skulle ta att skriva hela spelet, om inte längre. Jag började försöka implementera denna motor i spelet men märkte att det var ganska krångligt eftersom man behövde ladda ner extra bibliotek till c++ för att det skulle funka. Men jag läste forumtråden och såg att skaparen hade släppt en version 2 som fanns att ladda ner gratis, så jag gjorde det och märkte att denna var lättare att använda och man behövde bara använda SFML och inte glew som behövdes för LTBL 1. Trots att det var lättare att förstå så har jag fortfarande inte fått det att funka än, men jag kämpar för att få det implementerat i spelet.

Jag har också jobbat en del med PlayerShip tillsammans med Alfons som hade uppgiften från början men han behövde lite hjälp med matematiken på hur skeppet ska svänga, så jag hjälpte honom med den uppgiften och det gick bra. Problemet var pga. att man svänger med wasd och skeppet vänder sig mot riktningen man trycker och samtidigt får fart åt det hållet. När t.ex. skeppet pekar åt 90° vilket är knappen D och man vill åka 270° alltså till vänster, vilket är knappen A, så måste man skriva if(playership.getRotation() < 270 && playership.getRotation() >= 90) så ska skeppet rotera 1.8° per frame i klockans riktning. Detta måste man göra för alla riktningar så att man kan vända åt alla håll från alla håll utan att skeppet snurrar åt fel håll. Men matematiken löste sig ganska snabbt när jag hjälpt till och skeppet åkte mycket fint över skärmen.

Det sista jag jobbade med förra veckan var en soundmanager. Den gick väldigt bra utan några fel. Det behövdes inte många rader kod för att det skulle funka. Koden laddar in en plats från datorn i string form och gör en buffer som sedan görs till ett sound som returnas tillbaka till klassen som använder ljudet.49bf3dcc5b66552e3cf0761e189737fe