[JS] Collision Detection

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Don3k
  • Registratie: Februari 2001
  • Laatst online: 06-09 06:49
Zit al een week met een probleem, waar ik maar niet uitkom. Op internet zijn er talloze antwoorden te vinden, maar geen die eigenlijk geschikt zijn voor mijn situatie.

Het is als volgt, ben op dit moment bezig met een simpele html spel, waarbij ik hierbij dom manipulatie gebruik. De speler kan een vervoersmiddel met de pijltjestoetsen over het scherm bewegen. In het speelveld wil ik objecten hebben waar de speler tegen aan zou kunnen botsen.

Op zich geen probleem denk je. Collisions detecteren met vierkanten of rondje objecten is redelijk makkelijk te realiseren. Omdat je het voertuig kan roteren, maakt het gelijk een stuk lastiger.

Afbeeldingslocatie: http://www.adamdawes.com/programming/tokamak/files/05_AABB.gif

Om hierbij collisions te kunnen berekenen tussen twee objecten (beide een div, met een achtergrondplaatje), zou ik eerst van object 2 de linkerbovenpunt en linkeronderpunt moeten berekenen ( als voorbeeld) en moeten vergelijken met het ander object om te kijken of de rechter boven- of onderpunt zich tussen die 2 waardes bevind. Dat lijkt mij de makkelijkste manier.

Het bewegent object verplaats ik met de volgende code als er op een knop wordt gedrukt:

code:
1
2
3
4
5
var VoertuigY= -Math.cos(rotatie * Math.PI / 180) * acceleratie;
var VoertuigX = Math.sin(rotatie  * Math.PI / 180) * acceleratie;
        
var NewY = VoertuigY+(parseInt($('.userBlock[id=' + UserID + ']').css('top')));
var NewX = VoertuigX+(parseInt($('.userBlock[id=' + UserID + ']').css('left')));


Nu wil ik deze uitbreiden door alle 4 de coordinaten van het object (als css top & left) te hebben zodat ik hier weer verder in javascript kan rekenen. Hier loop ik eigenlijk een beetje vast. Dus kort gezegd, hoe bereken ik de 4 punten van een object nadat deze geroteerd is met bv de CSS functie:

code:
1
$('.user').css({'-webkit-transform': 'rotate(' + rotatie+ 'deg)'});


Na een week lang onderzoek en van alles en nog wat te hebben geprobeerd, kwam ik op het volgende uit, wat het meest relevant zou kunnen zijn:

- Informatie over collisions in games
http://www.metanetsoftware.com/technique/tutorialA.html
- Soort gelijk probleem
http://gamedev.stackexcha...of-a-rotated-rectangle-2d

De code daaruit heb ik aangepast, maar ik krijg nog steeds de verkeerde waardes eruit:

code:
1
2
3
4
5
6
7
8
var width = 64;
var height = 64;

x1 = (VoertuigX * Math.cos(rotatie)) - (VoertuigY* Math.sin(rotatie));
y1 = (VoertuigX  * Math.sin(rotatie)) + (VoertuigY* Math.cos(rotatie));

x2 = (VoertuigX +width/2 * Math.cos(rotatie)) - (VoertuigY+height/2 * Math.sin(rotatie));
y2 = (VoertuigX +width/2 * Math.sin(rotatie)) + (VoertuigY+height/2 * Math.cos(rotatie));


Ben ik wel op de goede weg?

Acties:
  • 0 Henk 'm!

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Niet helemaal. Een paar tips:

- Scheid de code van de graphics. Je wilt de positie van elk object echt niet 25 keer per seconde via CSS achterhalen. Een voertuig is een object met een bepaalde positie (x,y), afmetingen (w,l), rotatie a, snelheid (vx,vy), etc. Op het scherm teken je simpelweg een afspiegeling van dat object, die je met enige regelmaat update. Je kunt bijvoorbeeld al een snelheidswinst halen door stilstaande objecten niet opnieuw te tekenen!
- Programmeren is wiskunde... lineaire algebra in dit geval. De voorbeelden die je aanhaalt implementeren netjes 2D vector rotatie rondom de oorsprong, met een zogeheten rotatiematrix. Lees je in in dat soort basisstof.
- Netjes en snel testen of twee geroteerde vierkanten elkaar raken is al wat lastiger. Google helpt je hier wel mee, en anders is het leuk om zelf een algoritme in elkaar te prutsen.
- Ik denk dat her verstandig is om eerst vals te spelen en de collision detection met cirkels ipv rechthoeken doen, totdat je dat onder de knie hebt.

Succes ermee :)

TabCinema : NiftySplit


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-09 16:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Don3k schreef op zondag 26 augustus 2012 @ 11:22:
De code daaruit heb ik aangepast, maar ik krijg nog steeds de verkeerde waardes eruit:

code:
1
2
3
4
5
6
7
8
var width = 64;
var height = 64;

x1 = (VoertuigX * Math.cos(rotatie)) - (VoertuigY* Math.sin(rotatie));
y1 = (VoertuigX  * Math.sin(rotatie)) + (VoertuigY* Math.cos(rotatie));

x2 = (VoertuigX +width/2 * Math.cos(rotatie)) - (VoertuigY+height/2 * Math.sin(rotatie));
y2 = (VoertuigX +width/2 * Math.sin(rotatie)) + (VoertuigY+height/2 * Math.cos(rotatie));


Ben ik wel op de goede weg?
Afgezien van de terechte punten die Bozozo noemt (DOM en CSS hebben niets in je collision detection te zoeken), vind ik het wel opvallend dat je hier radialen gebruikt, terwijl 'rotatie' eerder in graden werd gespecificeerd (aangezien je het vermenigvuldigt met pi/180). Daarnaast lijkt me dat je berekening überhaupt niet klopt. Waarom tel je de halve breedte en hoogte bij x2 en y2 erbij op, maar bij x1 en y1 niet?

Het is overigens wel praktisch om te leren denken in radialen ipv graden, het is nou eenmaal de standaard in wiskunde en API functies.

En pak een vector/matrix math library voor javascript. Alles werkt veel simpeler als je gewoon gebruik kunt maken van standaard vectoren en transformaties, in plaats van met de hand alle vergelijkingen uit te schrijven. Dan maak je gewoon een matrix die de coordinaten van een box van local space naar world space transformeert (roteren met 'rotatie' gevolgd door een translatie van (VoertuigX, VoertuigY)). Die matrix gebruik je vervolgens om de vier punten van de box in local space {(-w/2, -h/2), (w/2, -h/2), (-w/2, h/2), (w/2, h/2)} te transformeren naar world space en dan ben je klaar. Hoef je ook niet uit te gaan zoeken hoe je dat uitschrijft.

[ Voor 27% gewijzigd door .oisyn op 27-08-2012 00:23 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.