Page 1 of 1

Rotating balls

Posted: Mon Jan 19, 2004 6:10 pm
by Psychophanta

Code: Select all

#bitplanes=32:#RX=1024:#RY=768:#PI=3.14159265
If InitMouse()=0 Or InitSprite()=0 Or InitKeyboard()=0 Or InitSprite3D()=0
  MessageRequester("Error","Can't open DirectX",0)
  End
EndIf
If OpenScreen(#RX,#RY,#bitplanes,"Balls")=0:End:EndIf
CreateSprite(0,64,64,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(0))
BackColor(0,0,0)
For t.l=32 To 1 Step -1:Circle(32,32,t,RGB(220-t*2,220-t*2,220-t*2)):Next
Line(32,0,0,64,$0):Line(0,32,64,0,$0)
FillArea(33,31,0,$99AAAA):FillArea(31,33,0,$AAAAAA)
StopDrawing()
CreateSprite3D(0,0):ZoomSprite3D(0,100,100)
CreateSprite(1,128,128,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(1))
BackColor(0,0,0)
For t.l=64 To 1 Step -1:Circle(64,64,t,RGB(200-t*2,240-t*2,240-t*2)):Next
Line(64,0,0,128,$0):Line(0,64,128,0,$0)
FillArea(65,63,0,$99BB99):FillArea(63,65,0,$99AAAA)
StopDrawing()
CreateSprite3D(1,1):ZoomSprite3D(1,128,128)

CursorCentreX.w=SpriteWidth(0)/2:CursorCentreY.w=SpriteHeight(0)/2;<-centro de Cursor
BallCentreX.w=SpriteWidth(1)/2:BallCentreY.w=SpriteHeight(1)/2;<-centro de Ball
CursorDimension.w=(SpriteWidth(0)+SpriteHeight(0))/2
BallDimension.w=(SpriteWidth(1)+SpriteHeight(1))/2
CursorMass.f=4*#PI*Pow(CursorDimension.w/2,3)/3;<-masa de Cursor
BallMass.f=4*#PI*Pow(BallDimension.w/2,3)/3;<-masa de Ball

mouseX=Random(#RX-50):mouseY=Random(#RY-50);<-Posición inicial de Cursor
BallX.f=Random(#RX-50):BallY.f=Random(#RY-50);<-Posición inicial de Ball
CursorX.f=mouseX:CursorY.f=mouseY
MouseLocate(mouseX,mouseY);<-Posicionamiento del Cursor
dirCursorX.f=Random(600000)/100000+1:dirCursorY.f=Random(600000)/100000+1
dirBallX.f=Random(600000)/100000+1:dirBallY.f=Random(600000)/100000+1

;-MAIN:
Repeat
  ExamineKeyboard()
  ExamineMouse()
  ClearScreen(0,0,0)
  ; Cursor position and vector:
  prevCursorX.f=CursorX.f:prevCursorY.f=CursorY.f;<-Coordenadas anteriores de Cursor
  CursorX.f=MouseX():CursorY.f=MouseY();<-Coordenadas actuales de Cursor
  dirCursorX.f=CursorX.f-prevCursorX.f:dirCursorY.f=CursorY.f-prevCursorY.f;<-vector director del movimiento de Cursor
  ; Ball-moving
  BallX.f+dirBallX.f:BallY.f+dirBallY.f;<-Coordenadas actuales de Ball (se suma a las anteriores el vector director)
  ; Ball-Screen limits:
  If BallX.f<=-BallCentreX:dirBallX.f=Abs(dirBallX.f):EndIf
  If BallX.f+BallCentreX>=#RX:dirBallX.f=-Abs(dirBallX.f):EndIf
  If BallY.f<=-BallCentreY:dirBallY.f=Abs(dirBallY.f):EndIf
  dirBallY.f+0.1
  If BallY.f+BallCentreY>=#RY:dirBallY.f=-Abs(dirBallY.f)+0.1
  EndIf
  ; Ball-Cursor collision
  If SpritePixelCollision(0,CursorX.f,CursorY.f,1,BallX.f,BallY.f);Si hay colisión:
    Gosub Shock
    ;Reposicionamos el cursor:
    CursorX.f+dirCursorX.f:CursorY.f+dirCursorY.f
    Gosub PreserveDistance
    MouseLocate(CursorX.f,CursorY.f)
  EndIf
  ; Rotation:
  Ballangle.f+Ballanglefactor.f:RotateSprite3D(1,Ballangle.f,0)
  Cursorangle.f+Cursoranglefactor.f:RotateSprite3D(0,Cursorangle.f,0)
  ; Displaying:
  Start3D()
  DisplaySprite3D(0,CursorX.f,CursorY.f,255)
  DisplaySprite3D(1,BallX.f,BallY.f,255)
  Stop3D()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
End
;-SUBROUTINES:
Shock:
  DiffX.f=BallX.f+BallCentreX-CursorX.f-CursorCentreX:DiffY.f=BallY.f+BallCentreY-CursorY.f-CursorCentreY;<-Vector de contacto Cursor->Ball
  K.f=(DiffX.f*dirCursorX.f+DiffY.f*dirCursorY.f)/(DiffX.f*DiffX.f+DiffY.f*DiffY.f);<-constante de proyección del actual vector del movimiento de Cursor sobre la línea de choque
  dirCursorXK.f=K.f*DiffX.f:dirCursorYK.f=K.f*DiffY.f;<-vector componente en línea de choque de la velocidad de Cursor.
  K.f=(-DiffX.f*dirBallX.f-DiffY.f*dirBallY.f)/(-DiffX.f*-DiffX.f+-DiffY.f*-DiffY.f);<-constante de proyección del actual vector del movimiento de Ball sobre la línea de choque.
  dirBallXK.f=K.f*-DiffX.f:dirBallYK.f=K.f*-DiffY.f;<-vector componente en línea de choque de la velocidad de Ball.
  CX.f=(2*BallMass.f*dirBallXK.f+CursorMass.f*dirCursorXK.f-BallMass.f*dirCursorXK.f)/(CursorMass.f+BallMass.f)
  CY.f=(2*BallMass.f*dirBallYK.f+CursorMass.f*dirCursorYK.f-BallMass.f*dirCursorYK.f)/(CursorMass.f+BallMass.f)
  BX.f=(2*CursorMass.f*dirCursorXK.f+BallMass.f*dirBallXK.f-CursorMass.f*dirBallXK.f)/(CursorMass.f+BallMass.f)
  BY.f=(2*CursorMass.f*dirCursorYK.f+BallMass.f*dirBallYK.f-CursorMass.f*dirBallYK.f)/(CursorMass.f+BallMass.f)
  Cursoranglefactor.f=-((dirBallX.f-dirCursorX.f)*DiffY.f-(dirBallY.f-dirCursorY.f)*DiffX.f)/(CursorDimension+BallDimension)
  Ballanglefactor.f=-((dirCursorX.f-dirBallX.f)*-DiffY.f-(dirCursorY.f-dirBallY.f)*-DiffX.f)/(CursorDimension+BallDimension)
  dirBallX.f-dirBallXK.f+BX.f:dirBallY.f-dirBallYK.f+BY.f;<-se suman, obteniendo el vector buscado.
  dirCursorX.f-dirCursorXK.f+CX.f:dirCursorY.f-dirCursorYK.f+CY.f;<-se suman, obteniendo el vector buscado.
Return
PreserveDistance:
  Distance.f=Sqr(DiffX.f*DiffX.f+DiffY.f*DiffY.f);<-Distancia entre los objetos en el instante del contacto.
  Clip.f=(CursorDimension/2+BallDimension/2)-Distance.f
  If Clip.f>0:Clip.f/2
    BallX.f+DiffX.f*Clip.f/Distance.f
    BallY.f+DiffY.f*Clip.f/Distance.f
    CursorX.f-DiffX.f*Clip.f/Distance.f
    CursorY.f-DiffY.f*Clip.f/Distance.f
  EndIf
Return

Posted: Mon Jan 19, 2004 6:27 pm
by Kale
impressive! 8O

Posted: Mon Jan 19, 2004 7:43 pm
by Rings
very nice physics :)

Posted: Mon Jan 19, 2004 8:20 pm
by LarsG
8O 8O damn you.... damn, I tell you..!!!! :lol:

that was almost too good!!! :wink:

Re: Rotating balls

Posted: Mon Jan 19, 2004 8:42 pm
by traumatic
Great! :D

Posted: Mon Jan 19, 2004 8:45 pm
by Psychophanta
damn you.... damn, I tell you..!!!!

that was almost too good!!!
:lol:
Thanks! it is a work with simple 2D vectors. To do it in 3D would be equally easy, only add Z dimension to vectors, and blah, blah...

Posted: Mon Jan 19, 2004 10:06 pm
by GPI
Nice.

When you have to much time, you can add a "drill".

For example:

The ball rotate clockwise and fall down (no movemet to left/right). after the contact with the botten, the ball jumps to the right, because the ball rotate.

GPI

Posted: Tue Jan 20, 2004 12:35 am
by Psychophanta
Just inserting:

Code: Select all

pr.f=dirBallX.f
    dirBallX.f+Ballanglefactor.f/2:Ballanglefactor.f=pr.f/2
after the "IF" at line 54 (bottom bound) you will get a simulation of it.

To get it as a perfect real emulation (like shown in shock kinetics conservation and collision rotations) the matter is to calculate the denominator value (i wrote 2 and it is nice, but may be other value which needs to be calculated using physics properties).

Of course you can do it similar for bounds on both sides (lines 50 and 51).

Posted: Tue Jan 20, 2004 12:53 am
by coma
what a great seal juggling simulator ! :D

Posted: Tue Jan 20, 2004 1:19 am
by Dare2
HaHa. :)

Too good!

*steals code*

Re: Rotating balls

Posted: Tue Jan 20, 2004 1:23 am
by NoahPhense
omg.. i have too much time on my hand.. was playing with that for about 10 minutes..

very good physics

- np

Posted: Tue Jan 20, 2004 7:12 am
by J. Baker
Very nice! :D

Posted: Tue Jan 20, 2004 11:17 am
by einander
It's so good that it deserves to be used for a game :lol: