Tiled hitboxes

Förra veckan spenderades mestadels med att komma på ett sätt att exportera hela vår karta från Tiled till spelet och få hitboxes att fungera. Det var inte det lättaste jag har gjort.

cave_floor

Det hela började med att grafikerna ritat upp hela kartan i programmet Tiled. Det som är väldigt trevligt med det programmet är att det funkar som ett ritprogram där man laddar in ett så kallat ”Tile sheet” som innehåller alla väggar och golv som ska vara med i kartan.

Sedan väljer man en av rutorna, våra är 32×32 pixlar, och börjar måla. Vi hade redan en design på hur kartan skulle se ut så grafikerna tog den mallen på ett lager bakom själva banan som de ritade på och bara följde linjerna. När detta blev klart så blev det väldigt snyggt, men detta var det lättaste steget.

level_1_v2

Tiled har en funktion i sig som är mycket användbar för programmerare och folk som vill göra spel som är byggda på tiles. Det funkar genom att man kan exportera hela banan som en .csv fil eller .tmx fil. Detta är ungefär som textfiler som skriver ut siffror. Massa siffror. Närmare sagt 17050 siffror, eftersom vår bana är 155×110 tiles. Det man gör som programmerare då är att ta denna ofantligt stora textfil och laddar in den i c++ med den inbyggda funktionen fstream. Den tar en fil och läser varje rad och lägger in raderna i en lista. Denna lista konverteras sedan till en integerlista som tolkas av c++. Hur kan den tolka siffrorna? Jo den tar siffrorna i listan och samtidigt laddas ”tile sheet” in tillsammans och alla tiles i den bilden har ett id. Dessa id nummer är samma nummer som hamnar i den mycket stora listan. Så nu kan c++ associera siffrorna i listan med en tile i bilden som laddades in. Nästa steg är att rita ut dessa tiles i rätt ordning med rätt bild tillsammans så kartan syns. Detta görs genom att göra en loop som kollar igenom den långa listan, som är en 2D array, och placerar ut alla tiles på sin position. Tile nummer 5 som på vår karta har id nummer 9 placeras på pixel nummer 32*5 (32 pga. tiles bredd) vilket blir 160, så c++ ritar ut en tile nr 9 på plats 160 etc.

När detta är klart så ritas kartan ut rätt, problemet är att det inte finns någon kollision. Jag själv hade mycket svårt att greppa hur jag skulle kunna få till kollision eftersom man inte ska kolla kollision på alla tiles på hela kartan för det skulle ta alldeles för mycket minne på samma gång och spelet skulle spela väldigt segt. Så tanken är att kolla kollision med endast de tiles som finns i närheten av spelaren, helst endast de som spelaren ser på skärmen. För att lista ut det så tog jag positionen av spelaren i x subtraherade hälften av bredden på skärmen och dividerade med 32 för att få vilken tile som låg längst till vänster. Jag gjorde samma sak på y led men subtraherade hälften av höjden istället. Nu hade jag ett minsta x värde och ett minsta y värde på tilesen som spelaren ser. För att vara säker så tog jag minus en tile så att hitboxes kollas precis utanför skärmen. Nästa steg är att ta reda på de tiles som ligger utanför till höger och neråt, det gör man enkelt på samma sätt som innan men ändrar ekvationen till spelarens position i x adderat med hälften av skärmens bredd och dividerat med 32 och såklart samma som tidigare med y led.

minX = (shipPos.x – viewSize.width) / 32;

maxX = (shipPos.x + viewSize.width) / 32;

Samma för y led.

För debugging syfte så kan man rita ut rektanglar runt dessa fyrkanter som visar ifall hitboxes räknas ut korrekt. Om allt har blivit korrekt så kan man börja ge kommandon till spelaren när den träffar denna box. Boxen som vi har som är vägg är id nummer 9, så det är dessa som kollar ifall spelaren nuddar, varje update i spelet. Jag tänkte först att lättaste sättet att veta ifall spelaren nuddar en box uppifrån eller nerifrån eller från sidan är att kolla hur vinklad spelarens skepp är. Så ifall spelarens skepp är vinklad mellan 0 och 180 grader så pekar spelaren neråt, pga. C++ som läser 0 från höger Rotation-differences, eller om vinkeln är mellan 0 och -180 så pekar spelaren uppåt. Samma sak med sidorna mellan -90 och 90 så pekar den åt höger eller vänster.

Men så lätt var det inte eftersom 76 grader är både emellan 0 och 180 och -90 och 90 så skeppet flyttades runt oberäkneligt på skärmen. Efter ett tag gav jag upp och frågade en kompis som hjälpte mig att förstå hur det borde utföras. Om spelarens x position subtraherat med tiles x position är positivt så vet vi att spelaren är på höger sida. Detta eftersom c++ räknar origo högst uppe till vänster och positiva x är till höger och positiva y är neråt. Samma sak ifall vi får ut ett negativt tal så vet vi att spelaren befinner sig på vänster sida. I y led är det inte annorlunda, ifall differensen blir positiv befinner sig spelaren under tilesen och ifall differensen blir negativ befinner spelaren sig över. Nu visste jag exakt vart spelaren träffar tilen och kan, från den fina intersect funktionen få ett return värde som berättar hur mycket två boxar träffar i bredd och höjd och putta tillbaka spelaren eller flytta den i motsatta riktningen som den träffar tilen.

Vi hörs nästa vecka!

About Erik Jigvall

2015 Programming