Crunch

Oj oj oj! Nu går det undan! Sista veckan är kommen och vi har en del kvar att göra inför morgondagens inlämning. Vi programmerare har nu hållit i vår programmerings redovisning i vår kurs spelprogrammering 2. Här är en lista av vad vi ska göra tills imorgon: En ny valuta för att spelaren ska kunna bygga turrets, fixa alla koordinater för vår nya aspect ratio. Jag teamade upp med Mathias i gruppen för att tillsammans fixa koordinaterna.

Jag kan börja mad att säga att source tree slutade fungera och vi försökte fixa det i flera timmar men vi insåg att det skulle sluka upp hela kvällen så vi bestämde oss för att ”merga” våra koder manuellt. Vi satt alltså med två olika versioner av spelet och kopierade och klistrade in kod samt ändrade flera värden. Vi var tvungna att ändra i stort sätt alla spawn koordinater för fiende 1, för fiende 2 och för bossen. Att göra det var lätt nog. Vi hade redan skrivit upp koordinaterna i kommentar kod för alla våra sektorer så vi behövde bara kopiera de koordinaterna till den nya koden. Koordinaterna för avataren, turrets, turretslots, raketspawn och hud element hade redan blivit implementerade så i den änden var vi redan klara. Mathias hade också gjort en tutorial för spelet som fortfarande hade de gamla koordinaterna för vår gamla aspect ratio så den var vi tvungna att ändra de koordinaterna för vår nya aspect ratio. Tutorialen består av en sf::Rectangleshape som agerar som fönstret för texten, en sf::Text som innehåller instruktionerna för spelaren och en till sf::Rectangleshape som har en till sf::Text i sig som agerar som ”fortsätt knappen”. Alla dessa objekt hade koordinater som behövde ändras, och inte bara för en sektor utan två sektorer. Så vi reworkade alla objekt med en origin i mitten av alla objekt respektive så att det skulle vara lättare att göra koordinaterna mjuk kodade. Sedan gjorde vi alla koordinaterna till mitten av den viewen som det ska ritas ut i med en simpel getCenter() / 2 för både x och y koordinaterna. Knapp textens koordinater gick lätt att centrera i knapp rektangeln genom att göra det till samma position som kanppen eftersom att båda objektens origins sitter precis i mitten av objekten.

Vi skulle självklart tänkt på att göra om vårt aspect ratio tidigare än efter betan men naiva som vi var trodde vi att det skulle gått bra med den gamla och jätte konstiga aspect ration som vi för någon anledning gjorde i början. Om vi hade gjort det tidigare hade vi inte vart här ikväll. Klockan är nu 21:45 och vi fortsätter…

Gustav out!

Scaling och opacity

Oj vilken vecka det har varit. Allt började med beta redovisningen på måndag som gick sådär men vi fick en massa användbar och bra feedback som vi nu ska implementera i spelet, sen har vi i gruppen också kommit överens om ganska många och stora ändringar i projektet. Vi har nu (alldeles för sent) bestämt oss för ett nytt aspect ratio, ett normalt sådant, 1920 x 1080. Detta har skapat lite mer rum för oss att leka med, till exempel att vi ska ha en sidebar där vi har alla hud element så att spelare kan fokusera på spelet lite bättre. Vi har också bestämt oss för lite mer feedback iallafall när det gäller power ups och när man väl får de. Spelaren måste veta ordentligt när hen får en ny power up och vilken power up de får. Jag har fått tre uppgifter att göra under veckan. Jag ska fixa en av våra dåligt fungerande power ups SlowMo, jag ska fixa ett ljud problem på meny skärmen då hover ljudet bara fortsätter låta och jag ska gör en typ av ”power up obtained” effekt så att spelaren vet exakt när hen får en power up och vilken power up hen får. Den sista av de här tre uppgifterna har jag valt att försöka förklara i denna blogg post.

Så planen var att ha en sprite som är uppskalad ganska mycket så att den nästan täcker hela skärmen men att den är helt transparant och sedan när man får en power up så skalas spriten ner samtidigt som den blir mindre och mindre transparant.

I nuläget har jag klurat ut ungefär hur jag ska göra. I spelet får man en power up från att döda ett stort alien skepp eller vår ”boss”. Så när bossen dör ska det vara en for loop eller kanske till och med en while loop som loopar en ändring i spritens skala och en ändring i spritens alpha skala. Just nu har jag inte än fått det att fungera förmodligen för att for loopen går alldeles för snabbt för att märka det. Så jag kommer nog behöva använda mig av en klocka för att sakta ner for loopen så att det mänskliga ögat kan se. Men den generella tanken är en loop där spritens skala och spritens alpha skala minskar och ökar respektive. Detta kommer skapa en stark visuell effekt som spelaren definitivt kommer märka och använda sig av.

Ljud

I veckan har jag framför allt arbetat med att få ljud att fungera i spelet. Det finns två olika metoder att ladda in och spela ljud i sfml. Jag använde mig av Audio delen av sfml som kommer med. I början hade jag ganska stora problem eftersom att visual studio sa att jag hade externa errors. Jag letade runt på internet efter svar och såklart hade jag inte lagt till lib filen för audio, så jag lade till det i både debug och release versionerna. Detta gjorde så att jag lätt och smidigt kunde fortsätta med mitt å så viktiga arbete.

Den ena metoden innebär att använda sf::SoundBuffer och sf::Sound, detta fungerar likadant som sf::Texture och sf::Sprite. Det vill säga att man laddar in en fil, i det här laget en ljud fil till en SoundBuffer och sedan använder man sf::Sound funktionen setBuffer för att anknyta SoundBuffer variabeln till Sound variabeln. Denna metod används mestadels för att skapa ljud effekter i ett spel, till exempel skottljud, explosioner och vind bland många andra exempel.

Den andra metoden innebär att använda sig av sf::Music. Till skillnad från SoundBuffer metoden så laddas det aldrig in en fil i en sf::Music, istället så strömmas ljudet direkt från ljudfilen när sf::Musics play funktion kallas. Denna metod används mestadels för, you guessed it, musik och den är gjord för att spelas genom hela spelets gång, eller iallafall genom specifika delar av spelet.

Vi kan börja med ljud effekterna. Vi hade satt några av våra grafiker i arbete med att skapa några coola ljud effekter. I nuläget har vi ljud effekter för att skjuta, för när man får en power up, för byggandet av turrets, för kollision mellan projektiler och fiender, för kollision mellan fiender och planeten, för emp power up aktivering och för en fiendes teleport mekanism.

Att få ljuden att starta på rätt ställe var lätt, allt jag behövde göra var att leta upp  till exempel skjut funktionen och helt enkelt kalla på play funktionen i den Sound variabeln som jag ville spela när jag skjuter. Samma princip gäller för kollisionen och alla andra händelser i spelets gång.

Vi hade fått musik till spelet i koncept dokumentet till spelet men vi kom överens i gruppen att den musiken inte riktigt passade till vår vision av spelet. Samtidigt som jag skriver detta skapas/ hittas bra och passande musik till spelet som jag senare ska lägga till i koden. 

SlowMo

Denna vecka arbetade jag med en ny power up som vi ska ha i spelet som heter Slow Mo. Denna power up förklarar sig själv men för att förtydliga så simulerar den en slow motion effekt på spelet.

Jag började med att kolla på vilka objekt i spelet som faktiskt behövde sakta ner för slow motion simuleringen. Jag kom fram till att de enda objekten jag behövde sakta ner var fienden och projektilerna. Till att börja med har vi alla fiende objekt och projektil objekt i varsina vectorer, objekten har också en varsin variabel som heter movementSpeed som bestämmer i vilken hastighet objekten ska röra sig i spelet.

Jag började med att helt enkelt skapa en if sats för ett knapptryck. I denna if sats gjorde jag en for loop för varje vector, en för fienden, en för avatar projektilerna och en för turret projektilerna. Jag använder mig också av en counter integer för att veta vilken index i vectorn som ska ändras. For looparnas dependencies består av en iterator för varje vector som är lika med vector.begin(), att iteratorn ska vara mindre än vector.end() och att iteratorn ökar med ett för varje loop. I for looparna ändrar jag variabeln movementSpeed för vector indexen som är lika med min counter och sedan ökar jag countern med ett i loopen. Innan varje loop gör jag counter lika med noll för att kunna använda om den i alla loopar.

I nuläget fungerar det bra men bara på objekten som redan finns i världen och för alltid tills de förstörs. I resten av veckan vilket betyder idag och imorgon ska jag fixa en timer så att objekten slutar vara långsamma och fixa så att de objekten som spawnas in under power upens tid också är långsamma. När dessa saker är klara ska jag tillsammans med hela gruppen på fredag balansera denna power up tillsammans med andra nya tillägg som de andra programmerarna har arbetat på. Vi ska till exmpel bestämma hur mycket långsammare saker ska gå och hur länge power upen ska vara. Jag inser i eftertanken att jag skulle ha gjort en SlowMo klass istället för att göra allting i main men när jag väl pratade med vår programmeringslärare Tommi sa han att det inte är jätteviktigt att ha struktur i koden, utan att det var viktigare att det fungerade. Struktur är något som jag kommer att fokusera mer på i framtiden.

sf::View

I veckan hade jag som uppgift att lösa ett problem i spelet inför alphan. Konceptet som vi valde har en mekanik där man byter mellan fyra sektorer på planeten. Problemet var då att fixa något sätt att byta mellan de fyra sektorer som vi har.

När vi i gruppen brainstormade fram idéer för hur vi skulle lösa detta problem kom vi alla överens om att vi skulle använda oss av rotation i någon form. Antingen skulle vi rotera hela världen runt kameran, det vill säga ALLA objekt i hela spelvärlden relativt till en nollpunkt, eller så skulle vi bara rotera kameran. Vi bestämde oss för att rotera kameran för att det skulle varit lättast.

Sfml biblioteket har en klass som heter sf::View som agerar som en kamera i spelvärlden, den har flera olika funktioner som man kan använda sig av som till exempel move funktionen som man oftast använder om man vill att kameran ska scrolla i spelets värld. Den funktionen som jag brydde mig om var dock rotate och setRotation. Med hjälp utav dessa kunde jag rotera kameran precis som jag ville. För att visa kameran i spelfönstret är man tvungen att skriva window.setView(view), så det gjorde jag. Men ingenting fungerade som det skulle, jag hade gjort en if sats för ett visst knapptryck som skulle rotera min view, men det fungerade inte.

Så jag pratade med mina kollegor och vi bestämde oss alla för att dumma ner lösningen på problemet. Den nya lösningen på problemet var att göra fyra olika kameror eller views för vardera sektor som man skiftar mellan. Detta fungerade men fler problem följde. Jag var tvungen att spawna nya fiender i de nya kamerorna, jag var tvungen att flytta avataren varje gång jag bytte kamera. Dessa problem löste jag relativt snabbt eftersom att jag redan hade löst de en gång innan.

Så vi hade vår lösning på problemet men jag ville fortfarande få rotationen att fungera. Jag började tänka lite grann och tänkte på en view som vilke spel objekt i spelet so  helst. För att se förändringar på objekten i spelet kan man inte bara rita ut objektet en gång, då ser man inte om man flyttar på objektet eller förändrar utseendet på något sett. Därför ritar man ut objekt hela tiden i update. Jag tänkte likadant med views. Jag satte min view till window bara en gång och den uppdaterades inte. Så jag gjorde som om jag ritar ut min view i varje frame i update och så fungerade det i slutändan. Vi har kvar vår lättare lösning på problemet för alpha deadlinen men vi kanske byter till rotationen till beta och release.

HUD

I veckan hade jag som uppgift att göra en grundläggande ”heads up display” för vår alpha deadline. Jag insåg snabbt att man inte kan omvandla en integer till en string bara sådär. Det var lätt nog att bara skriva ut en string med sf::Text klassen, men problemet kom när jag skulle skriva ut poängen och livsmätaren som inte bara var integer variabler men som också skulle uppdateras varje frame.

Så det första problemet var att göra om integer variablerna till string variabler och då kollade jag omkring på internet och hittade först stringstream metoden. Denna metod kan både läsa och skriva från en string variabel som om den läser från en text fil. Den kan också läsa in värden från en integer variabel för att sedan skriva ut det i en string. Detta löste ett av mina problem vilket var att jag kunde skriva ut en integer som en string. Men när jag uppdaterade texten adderades siffrorna som separata strings istället för att de adderades i värdet på integern. Så när spelet hade gått i 5 sekunder såg poängen ut såhär: 12345. Istället för såhär: 5.

Så jag var tvungen att använda en annan metod. Då hittade jag sprintf metoden. Denna metod använder sig av en array av characters för att ladda in integer värdet, en så kallad ”buffer” och en definition av vilken sorts variabel man vill ändra till string, i detta tillfälle var det ”%i”. Sedan skrev jag in vilken integer jag ville ta värdet från och skrev ut ”buffer” arrayen i sf::Text objektet som jag hade skapat. Sprintf metoden är inte bara användbar för att skriva ut integer variabler men egentligen för många olika slags variabler som såklart integer men också float points, doubles, pointer adresser, strings, characters. Allt som allt en väldigt användbar metod för att omvandla alla möjliga variabler till string.

Denna metod fungerade som bäst för att den löste båda problemen som jag hade i början. Stringstream metoden skulle jag kunna se vara användbar till andra tillfällen än den här. Till exempel om man vill skriva ut en sekvens av siffror istället för att uppdatera värdet på en integer.  Man kan också skriva ut en integers hexadecimal och octal värde med hjälp av stringstream metoden.

Senare upptäckte jag att det fanns en annan metod som jag kunde ha använt som jag också kanske använder i framtiden istället för stringstream och sprintf metoderna. Den metoden var to_string metoden. Denna metod var lättast av alla och fungerade lika bra som sprintf metoden.