Toon posts:

[Flash] Collision Detection

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met een flash-game. Het is een racegame waar ik collision detection heb ingebouwd. hiervoor gebruik ik een alpha-map van de baan, en door middel van een hittest kijk ik of de auto collide of niet. Dit gaat goed. Bij collision stuitert de auto weer netjes terug. Maar dit vind ik niet realistisch genoeg, ik wil weten met welke hoek de auto inslaat zodat ik een realistische reactie kan maken. Ik weet de bewegingsvector van de auto, nu moet ik alleen de normaal weten van de muur waar hij inslaat. Omdat ik echt een alpha-map gebruik geeft deze geen informatie hierover.

Ik dacht aan een tweetal oplossing. Ten eerste om gebruik te maken van alleen horizontale en verticale vlakken, en doormiddel van een tweede hittest te kijken welke muur wordt geraakt. Een andere oplossing was om alle hoekpunten hun coordinaten in een array op te slaan en deze te bekijken bij de inslag.

Ik ben benieuwd wat jullie ideeen zijn hierover!

Verwijderd

Stel je hebt deze weg...
code:
1
2
3
4
5
6
7
8
9
10
11
+------------------------+
|       1/ W E G  /7     |
|      2/        /8      |
|     3|        |9       |
|      | W E G  |        |
|      |        |        |
|     4|        |10      |
|    5/        /11       |
|    / W E G  /          |
|  6/        /12         |
+------------------------+


Je moet dan voor elk rechte wegdeel de coordinaten opslaan. Dus coordinaten van 1-2, 3-4, 5-6, 7-8, 9-10 en 11-12. Je hebt de auto en waarschijnlijk is dat een gewoon vierkant blokje. Je moet dus constant voor alle vier de hoeken van de auto controleren of hij snijdt met één van de lijnen. Dat kan d.m.v. simpele wiskundige functies. Je moet dus een formule opstellen voor de lijn/wegdeel en kijken of hij collide met de auto.

Verwijderd

Topicstarter
Nee, de auto is 1 punt (x, y). Door middel van een hitTest kijk ten eerste of er een collision is. Daarna ga ik dus over op een geavanceerde hitTest. Wat jij zegt is dus hoekpunten registreren en dmv. een lijnformule kijken of er een botsing plaatsvind wordt. Dit hoeft in mijn geval niet meer omdat ik al gecontroleerd heb of er een botsing is.

Wat ik nu wil doen is dat de engine zelf alle punten bijlangs loopt en de normalen daarvan registreert. tijdens een botsing heb ik een x en een y. Ik loop dan een array door met de x en y waarde en kijk of de botsing x en y tussen deze waarden valt. Zo ja, dan pak ik de normaal en bereken ik de hoek.

Enige nadeel is dat ik dus alle movieclips moet plaatsen op de hoeken :| niet echt leuk werk...

  • tie-rep
  • Registratie: Oktober 2001
  • Laatst online: 19-02 15:56

tie-rep

nu met ir. !

kan je de 'alpha map' even toelichten? dus is dat een ill. bestand oid?

  • Opi
  • Registratie: Maart 2002
  • Niet online

Opi

Ik weet niet of een alpha map uit pixels of punten bestaat, maar je zou kunnen proberen om aan de hand van de punten in de regio een lijn te extrapoleren; wellicht zou je de kleinste-kwadraten methode kunnen beschouwen. De nauwkeurigheid van de methode lijkt me volledig af te hangen van het detail dat de map heeft.

Als een alpha map niet uit punten bestaat, zou ik moeten weten waar hij wel uit opgebouwd is, wil ik je kunnen helpen. :)

Verwijderd

Topicstarter
De alpha map is een bitmap die getraced is in Flash. Het bestaat dus uit vectoren.

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 22-05 23:32

alienfruit

the alien you never expected

Kun je je alpha map niet in stukken delen? Waarvan je de x,y cooridnaten weet, vervolgens pak jij deze lijst erbij om te kijken waar je auto tegent de railing aan knalt. Volgens mij kan je dan wel via Pythogoras de hoek uitrekenen.

Verwijderd

Je kunt ook overwegen om je auto te laten "onthouden" in welke richting hij gaat. Waarschijnlijk heb je een function die de richting van de auto op basis van Key input aangeeft. pseudo: if(key == "rechts") auto._x += 15;
Maak een class Auto en definieer daarin een methode direction oid. die methode wordt in je gameloop aangeroepen en zet de dán geldende x en y waarden in een array. Indien een collision optreed, kun je in feite de richting van de auto veranderen in de omgekeerde waardes die in de array zijn opgeslagen.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Auto extends MovieClip {
var dirX:Array;
var dirY:Array;
function Auto() {
dirX = new Array(5);
dirY = new Array(5);
}
function setDirectionArr():Void { // aanroepen in gameloop (onEnterFrame oid)
dirX.push(this._x); 
dirY.push(this._y); 
}
function getInverseDir() {
// hier code om de array in omgekeerde volgorde (dir.pop()) en met negatieve waardes terug te krijgen
}
}


stel:
dirx[1] = 15;
diry[1] = 30;
dirx[2] = 30;
diry[2] = 60;
enz
een collision treed op dan omgekeerde, negatieve waardes uit array ophalen en _x en _y van de auto zetten in je loop
_x = -15;
_y = -30
_x = -30;
_y = -60

get it?


edit:
per ongeluk op verstuur geklikt ;)

[ Voor 10% gewijzigd door Verwijderd op 02-09-2004 02:45 ]


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23:25

Janoz

Moderator Devschuur®

!litemod

^^ Hij heeft zelfs al een richtings vector van de auto. Dat is dus niet het probleem. De hoek die deze vector heeft met de baanrand is hetgeen hij nodig heeft.

Je zou voor elk recht stuk rand een vlak kunnen maken waarmee je vergelijkt. De rand hiervan is bekend en die zou je kunnen gebruiken. Ook voor een circel is een formule te bepalen die adhv het middelpunt en de huidige positie de hoek met de rand kan bepalen*.

Je zult in dat geval de rand van de baan redelijk aan moeten kleden met een hele berg vlakken waarmee collision detection moet worden gedaan.


*formule is iets als:
hoek = tan-1(Xauto - Xmiddelpunt / Yauto - Ymiddelpunt)

[ Voor 10% gewijzigd door Janoz op 02-09-2004 09:56 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 22-05 23:32

alienfruit

the alien you never expected

Hij wilde geen vlakken/blokjes gebruiken :)

Verwijderd

Janoz schreef op 02 september 2004 @ 09:52:
^^ Hij heeft zelfs al een richtings vector van de auto. Dat is dus niet het probleem. De hoek die deze vector heeft met de baanrand is hetgeen hij nodig heeft.

Je zou voor elk recht stuk rand een vlak kunnen maken waarmee je vergelijkt. De rand hiervan is bekend en die zou je kunnen gebruiken. Ook voor een circel is een formule te bepalen die adhv het middelpunt en de huidige positie de hoek met de rand kan bepalen*.

Je zult in dat geval de rand van de baan redelijk aan moeten kleden met een hele berg vlakken waarmee collision detection moet worden gedaan.


*formule is iets als:
hoek = tan-1(Xauto - Xmiddelpunt / Yauto - Ymiddelpunt)
Volgens mij kun je met mijn oplossing de baan als het ware "uitsnijden" uit een mc en die kun je dan controlleren op collisions met de auto (of andersom). Je krijgt dan drie lagen (of drie opelkaar geplaatste mc's als je wilt): container (de uitsnede), track en de auto. Vervolgens kun je in de class Auto o.a. het volgende in een methode checkCollisions plaatsen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
class Auto extends MovieClip {
  var container:MovieClip; // referentie naar de onderste laag (uitsnede track)
function Auto(container:MovieClip) {
  this.container = container;
}

function checkCollisions():Void { 
  if(container.hitTest(this._x, this._y, true) {
    // voer hier iets uit
  }
}
}


Oja, de vector van de verplaatsing reken je als volgt uit:
zijwaardseverplaatsing = snelheid * Sin(hoek), oftewel
code:
1
2
_x = velocity * Math.sin(_rotation * (Math.PI / 180));
_y = velocity * Math.cos(_rotation * (Math.PI / 180));

Verwijderd

Ik heb het net even snel getest in een vies geprogrammeerd fla'tje en het werkt als een tiet! Het uitsnijden van de track in een container mc, icm de collision detection binnen de auto class / mc is de snelste manier. Ik heb het voorbeeldje op aanvraag verkrijgbaar, stuur me een mailtje oid en je krijgt hem extragratis thuisbezorgd ;)

edit:

De swf staat even hier http://www.newbit.nl/jon/flash/testtrack.html geparkeerd. Met behulp van de bovenstaande code voorbeelden en de gedachte erachter moet je het eea snel voorelkaar kunnen krijgen. (In dit voorbeeld loopt het autootje over een motionGuide, dus dit dien je natuurlijk zelf allemaal te doen ;) )

[ Voor 34% gewijzigd door Verwijderd op 03-09-2004 01:36 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik move je topic even naar Programming & Webscripting als je het niet erg vind, hoewel het om flash gaat is P&W meer de plaats voor een onderwerp als collision detection :)

Check ook even deze topics:
[rml][ Java] Hulp gevraagd :collision detection Space Invaderclone[/rml]
[rml][ Alg] advanced collision detection (uitvoer in flashMX) *[/rml]

.edit: oh lol die 2e topic was ook van jou :P

[ Voor 6% gewijzigd door .oisyn op 03-09-2004 03:44 ]

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.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23:25

Janoz

Moderator Devschuur®

!litemod

@Doktoranders

In zijn startpost staat:
Ik weet de bewegingsvector van de auto
Dus deze heeft hij niet meer nodig.

daarnaast is zijn probleem dat hij niet de juiste terugkaats hoek kan bepalen. En dat probleem zie ik je nergens oplossen. Die hittest heeft hij al (zoals je in zijn startpost kunt lezen) maar hij wil graag weten hoe autotjes realistisch hier vanaf stuiteren.

Mijn voorstel was om juist per stuk baan een collision vlak langs de baan te maken. Dit zou natuurlijk lastig worden bij bochten, maar hiervoor was dan dat andere stuk waarmee je een normaal kon tekenen op een circelvormige baanrand.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Janoz schreef op 03 september 2004 @ 09:05:
@Doktoranders

In zijn startpost staat:

Ik weet de bewegingsvector van de auto

Dus deze heeft hij niet meer nodig.

daarnaast is zijn probleem dat hij niet de juiste terugkaats hoek kan bepalen. En dat probleem zie ik je nergens oplossen. Die hittest heeft hij al (zoals je in zijn startpost kunt lezen) maar hij wil graag weten hoe autotjes realistisch hier vanaf stuiteren.
....
Indd niet goed gelezen (was al laat) :z
Echter:
Verwijderd schreef op 03 september 2004 @ 00:58:
[...]
code:
1
2
_x = velocity * Math.sin(_rotation * (Math.PI / 180));
_y = velocity * Math.cos(_rotation * (Math.PI / 180));
i.s.m. de voorgestelde "omkeer" methode kan dit zekers te weten het gewenste resultaat opleveren (het terug stuiteren van het object). In feite maak je van de verplaatsingsfactor van óf _x óf _y een neatieve waarde, afhankelijk van de collision. Dit heb ik ooit een voor een pinball spelletje gebruikt... De preciese implementatie moet de TS zelf maar uitzoeken :P

edit:
Trouwens, ik wou eventjes nagaan of de TS OOP (goed) in AS2.0 toepast of niet, vandaar ook het voorbeeld; de class Auto.

[ Voor 10% gewijzigd door Verwijderd op 03-09-2004 19:17 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:13
Ik weet niet precies hoe alpha-channels werken in Flash en deze post doet vermoeden dat mijn suggestie niet gaat werken, maar eventueel zou je de normaalvector in de alpha channel kunnen coderen. Een pixel in de alpha channel is dan bijvoorbeeld 0 als het geen muur is, en tussen de 0 en 256 als het wel een muur is; de preciese waarde geeft dan de hoek van de normaalvector aan.

Dit maakt het ontwerpen van de alpha channel wel een stuk lastig, maar collision detection een stuk makkelijker.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op zich hoeft het natuurlijk niet per se een alpha channel te zijn, ik neem aan dat je ook gewoon een pixel van een bitmap op kunt vragen

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.

Pagina: 1