[pong kloon] hoe balletje van muur af laten 'ketsen'

Pagina: 1
Acties:
  • 124 views sinds 30-01-2008
  • Reageer

  • MisterData
  • Registratie: September 2001
  • Laatst online: 21-08 20:35
Ik ben bezig met soort 3d-versie van pong (er is ooit een flashspelletje geweest dat hetzelfde deed, heb het even niet bij de hand). Nu heb ik voor het balletje de volgende struct:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct Vector {
    Vector(float ax,float ay,float az) {
        x = ax;
        y = ay;
        z = az;
    }
    Vector() {
        x = y = z = 0;
    }
    float x,y,z;    
};

struct Ball {
    Ball() {
    }
    int xx,yy;
    Vector direction;
    Vector position;
    int speed;
    int pixelsize;
};


Zoals je ziet heeft het balletje een position en een direction Vector. Iedere gametick wordt de direction opgeteld bij de position zodat het balletje beweegt. Vervolgens wordt xx en yy gevuld met de geprojecteerde schermcoordinaten van de bal (het midden van de bal, de int pixelsize heeft de breedte van de bal aan, maar dat is in dit geval niet belangrijk).

De bal heeft een kubusvormige ruimte waarin deze mag bewegen. Het controleren of de bal buiten die kubus komt is eenvoudig:

C++:
1
2
3
4
5
6
7
if(ball.position.x<-1.0f) {
// oeps, verder naar links dan de linkse muur :o
}

if(ball.position.x>1.0f) {
// oeps, verder naar rechts dan de rechtse muur :o
}


Nu wil ik als het balletje tegen een muur aankomt, het balletje laten stuiteren in de andere richting (dus gewoon hoek van inval = hoek waarmee ie van de muur weggaat). In 2D weet ik wel hoe dat werkt, maar hoe doe je zoiets in 3D? Ik zit nu in de 4e en we hebben nog niet zoiets gehad bij wiskunde, en het zal vast heel simpel zijn, maar kan iemand me dat even (kort) uitleggen? Het gaat er dus om de direction-vector aan te passen als je een muur raakt met het balletje :)

  • Opi
  • Registratie: Maart 2002
  • Niet online

Opi

3D is 2D met een extra dimensie. ;)
Hoek van inval voor x-coordinaat is hoek van uitval voor x-coordinaat.
Hoek van inval voor y-coordinaat is hoek van uitval voor y-coordinaat.
Hoek van inval voor z-coordinaat is hoek van uitval voor z-coordinaat.

  • Eskimootje
  • Registratie: Maart 2002
  • Nu online
Hetzelfde als 2d er veranderd maar 1 deel van de vector en wel degene die over het limiet heengaat.

Stel je voor de vector van de bal is 2x 3y 4z je raakt een muur op het yz vlak word je vector -2x

  • Avalanchez
  • Registratie: Juni 2002
  • Laatst online: 25-06-2012

Avalanchez

Phr34k

geef aan je balletje een richtingscoefficient mee (wel bekend van wiskundige grafieken ed). bij het ketsen wordt deze dan omgekeerd (+ wordt -, - wordt +).

[ Voor 17% gewijzigd door Avalanchez op 12-09-2003 21:15 ]

Computers are stupid, they can only give you answers. -Picasso


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Uhm, als de bal buiten het x-bereik gaat, dan wordt de x-snelheid toch gewoon geinverteerd :? Helemaal geen moeilijke berekeningen voor nodig

C++:
1
2
3
4
if (ball.pos.x < -1 || ball.pos.x > 1)
    ball.speed.x = -ball.speed.x;

//en hetzelfde voor y en z

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.


  • Ericston
  • Registratie: Maart 2001
  • Laatst online: 05-08 18:36
Mathworld (bookmark) -> Reflection
Moet je alleen de normaal van de muur zien te krijgen en je vector class scalar multiplication en een dot product geven. :)

  • Opi
  • Registratie: Maart 2002
  • Niet online

Opi

.oisyn schreef op 12 September 2003 @ 21:17:
Uhm, als de bal buiten het x-bereik gaat, dan wordt de x-snelheid toch gewoon geinverteerd :?
Inverteren kan je hier beter niet doen:
x -> x-1 gaat niet op, maar x -> -x :)

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
om het ineens wat fysischer (hoe in godsnaam spel je dat?:) te maken kun je het beste

position, velocity en acceleration gebruiken.

waardat:

velocity = old velocity + acceleration * dt; //delta tijd
new pos = old pos + velocity * dt;

natuurlijk om je botsing goed te hebben moet je er ook mee rekening houden dat het wel eens 2 keer of meer per beurt kan botsen (ie in een hoekje bijvoorbeeld). Om het echt correct te hebben zul je de intersectie van het plane moet nemen (eenvoudig in een kubus) en zo het blijven 'volgen' totdat je de hele delta-time af hebt.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

OpifexMaximus schreef op 12 September 2003 @ 21:21:
[...]

Inverteren kan je hier beter niet doen:
x -> x-1 gaat niet op, maar x -> -x :)
De additieve inverse is nog altijd de -
Jij hebt het over de multiplicatieve inverse

(mierenneuken kan ik ook >:))

[ Voor 48% gewijzigd door .oisyn op 12-09-2003 21:24 ]

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.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ericston schreef op 12 September 2003 @ 21:18:
Mathworld (bookmark) -> Reflection
Moet je alleen de normaal van de muur zien te krijgen en je vector class scalar multiplication en een dot product geven. :)
een uitleg zou wel leuk zijn :)

Stel je hebt een vlak, met een normaal. Die normaal staat dus loodrecht op het vlak, en heeft lengte 1.

Als je een willekeurig punt hebt, hoe spiegel je dat dan tov het vlak?

Goed, dan definieren we eerst wat een spiegel precies doet. De afstand van het punt tot het vlak blijft hetzelfde, alleen aan de andere kant van de spiegel. Als je een lijn trekt van het origineel naar het gespiegelde punt, dan loopt die lijn evenwijdig aan de normaal. Goed, je weet dus de richting waarin je het punt moet verplaatsen, aangezien je de normaal van het vlak hebt. Dan is het simpel: je bepaald de afstand van het punt tot het vlak. Als je dan het punt beweegt in tegengestelde richting van de normaal, en dat [afstand] keer, dan kom je op het vlak zelf (dit is overigens het punt op het vlak dat het dichtst bij het te spiegelen punt ligt). Vervolgens moet je nog [afstand] verder bewegen, aangezien de afstanden tussen de punten en het vlak gelijk moeten blijven.

Even wat variabelen: het vlak wordt gedefinieerd door een normaal n, en de (negatieve) afstand tot de oorsprong d
Verder heb je het punt v dat je wilt spiegelen, en het gespiegelde punt v' dat je wilt berekenen.

De afstand van een punt tot een vlak dat door de oorpsrong loopt is gelijk aan de lengte van dat punt geprojecteerd op de normaal van het vlak. Oftewel v*n. Goed, nu loopt een willekeurig vlak niet door de oorsprong, maar je weet wel de afstand van het vlak tot de oorprong, dat was d. Dus de uiteindelijke uitkomst is v*n-d

Nu je de afstand van een punt tot een vlak kunt berekenen, is het simpelweg het schalen van de omgekeerde normaal met de afstand van het vlak tot het punt. Dan weet je hoeveel je moet verplaatsen, en dat kun je dan bij het origineel optellen

Dus: v' = v - 2 * (v * n - d) * n

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.


  • Avalanchez
  • Registratie: Juni 2002
  • Laatst online: 25-06-2012

Avalanchez

Phr34k

.oisyn schreef op 12 september 2003 @ 21:24:
[...]


De additieve inverse is nog altijd de -
Jij hebt het over de multiplicatieve inverse

(mierenneuken kan ik ook >:))
over 't algemeen is x-1 inverse, en -x tegengestelde (of was het omgekeerde...)

[ Voor 7% gewijzigd door Avalanchez op 12-09-2003 22:07 ]

Computers are stupid, they can only give you answers. -Picasso


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21-08 20:35
.oisyn schreef op 12 September 2003 @ 21:17:
Uhm, als de bal buiten het x-bereik gaat, dan wordt de x-snelheid toch gewoon geinverteerd :? Helemaal geen moeilijke berekeningen voor nodig

C++:
1
2
3
4
if (ball.pos.x < -1 || ball.pos.x > 1)
    ball.speed.x = -ball.speed.x;

//en hetzelfde voor y en z
Dan gaat het balletje de tegengestelde richting in als dattie vandaan kwam, toch? Dat geldt alleen als het balletje recht op de muur komt, want hoek van inval = hoek van 'uit'val :)

  • Avalanchez
  • Registratie: Juni 2002
  • Laatst online: 25-06-2012

Avalanchez

Phr34k

MisterData schreef op 12 September 2003 @ 22:27:
[...]


Dan gaat het balletje de tegengestelde richting in als dattie vandaan kwam, toch? Dat geldt alleen als het balletje recht op de muur komt, want hoek van inval = hoek van 'uit'val :)
nope...

Computers are stupid, they can only give you answers. -Picasso


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21-08 20:35
Ohja, ik zie net dat er ipv speed speed.x staat.... dus in mijn geval direction.x, daarom was ik in de war :|

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

MisterData schreef op 12 September 2003 @ 22:27:
[...]


Dan gaat het balletje de tegengestelde richting in als dattie vandaan kwam, toch? Dat geldt alleen als het balletje recht op de muur komt, want hoek van inval = hoek van 'uit'val :)
nee, want als het balletje tegen de x-muur aan komt zeg maar, dan blijven de y en z richting gelijk. Je veranderd alleen de x
(ok, ik gebruikte de speed variabele, was misschien niet helemaal conform jouw definities, ik had direction moeten gebruiken)

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.


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21-08 20:35
.oisyn schreef op 12 september 2003 @ 22:30:
[...]


nee, want als het balletje tegen de x-muur aan komt zeg maar, dan blijven de y en z richting gelijk. Je veranderd alleen de x
(ok, ik gebruikte de speed variabele, was misschien niet helemaal conform jouw definities, ik had direction moeten gebruiken)
Zie mijn reply hierboven, ik had het zelf ook al ontdekt :) Verder bedankt voor alle uitleg, ik ga nu proberen of het werkt :)

  • Ericston
  • Registratie: Maart 2001
  • Laatst online: 05-08 18:36
.oisyn schreef op 12 september 2003 @ 21:37:
[...]
een uitleg zou wel leuk zijn :)
[...]
Ik had nog overwogen om een uitleg te geven, maar aangezien dat redelijk okay op die site staat besloot ik maar om het niet te doen.

Het lijkt mij trouwens het handigst om alleen de snelheidsvector te spiegelen en niet bezig te gaan met de absolute punten ten opzichte van het vlak en dus die d achterwege te laten. (Correct me if I'm wrong).

Dus:
code:
1
2
3
4
als botsing(balletje this, vlak x):
    this.snelheid = this.snelheid - 2 * (this.snelheid* x.normaal) * x.normaal // spiegel

this.positie += this.snelheid

ipv
code:
1
2
3
4
this.positie += this.snelheid

als botsing(balletje this, vlak x):
    this.positie = this.positie - 2 * (this.positie * x.normaal - x.positie ) * x.normaal // spiegel

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ericston schreef op 13 September 2003 @ 15:04:
Het lijkt mij trouwens het handigst om alleen de snelheidsvector te spiegelen en niet bezig te gaan met de absolute punten ten opzichte van het vlak en dus die d achterwege te laten. (Correct me if I'm wrong).
maar dat is inherent aan vectoren :) Vectoren hebben geen positie, en dus vervalt d idd gewoon. Alleen de normaal van het vlak is dan ook nodig, en dan krijg je idd de berekening zoals die op mathworld staat

(hmm ik dacht dat ik dat erbij gezet had, maar blijkbaar ben ik dat dus vergeten)

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