Kreiskollision
Verfasst: 12.05.2008 09:14
Ich hab da eine Simulation für eine Kreiskollision geschrieben, ist zwar noch von der Übersicht verbesserbar, aber sonst sieht sie, denk ich, ganz realistisch aus...
Andreas
Code: Alles auswählen
EnableExplicit
#Deg2Rad = #PI/180
#Rad2Deg = 180/#PI
#Screen_Width = 1280 ; <--- Ändern
#Screen_Height = 800 ; <--- Ändern
#Screen_Depth = 32 ; <--- Ändern
#Screen_Title = "Kreiskollision"
Enumeration
#Sprite_Circle_Static
#Sprite_Circle_Ball
#Sprite_Mouse
EndEnumeration
#Sprite_Circle_Static_Width = 500
#Sprite_Circle_Static_Height = 500
#Sprite_Circle_Ball_Width = 50
#Sprite_Circle_Ball_Height = 50
#Sprite_Mouse_Width = 10
#Sprite_Mouse_Height = 10
Structure Circle
x0.d
y0.d
r.d
vx0.d
vy0.d
x.d
y.d
xM.d
yM.d
vx.d
vy.d
ax.d
ay.d
EndStructure
Procedure pythagorasK(h1.d, h2)
ProcedureReturn Sqr(h1 * h1 + h2 * h2)
EndProcedure
Procedure high(num1.d, num2.d)
If num1 > num2
ProcedureReturn num1
Else
ProcedureReturn num2
EndIf
EndProcedure
Procedure low(num1.d, num2.d)
If num1 < num2
ProcedureReturn num1
Else
ProcedureReturn num2
EndIf
EndProcedure
Procedure normal(x1, y1, x2, y2, toX.d, width, rgb=0)
Protected dx, dy, k.d, alfa.d, xx.d, yy.d
dx = x2 - x1
dy = y2 - y1
k = dy / -dx
alfa = ATan(k)
xx = Sin(alfa) * width/2
yy = Cos(alfa) * width/2
Line(x1 + (toX - xx), y1 - (yy + k * toX), 2*xx, 2*yy, rgb)
EndProcedure
Define Circle_Static.Circle
Circle_Static\r = #Sprite_Circle_Static_Width/2
Circle_Static\x0 = #Screen_Width/2 - Circle_Static\r
Circle_Static\x = Circle_Static\x0
Circle_Static\xM = Circle_Static\x + Circle_Static\r
Circle_Static\y0 = #Screen_Height/2 - Circle_Static\r
Circle_Static\y = Circle_Static\y0
Circle_Static\yM = Circle_Static\y + Circle_Static\r
Define Circle_Ball.Circle
Circle_Ball\r = #Sprite_Circle_Ball_Width/2
Circle_Ball\x0 = #Screen_Width - 2 * Circle_Ball\r
Circle_Ball\x = Circle_Ball\x0
Circle_Ball\xM = Circle_Ball\x + Circle_Ball\r
Circle_Ball\y0 = 105
Circle_Ball\y = Circle_Ball\y0
Circle_Ball\yM = Circle_Ball\y + Circle_Ball\r
Circle_Ball\vx0 = -70
Circle_Ball\vx = Circle_Ball\vx0
;Circle_Ball\ay = 40
Define dx.l, dy.l
Define distance.d
Define k.d
Define alfa.d
Define dbx.l, dby.l
Define kb.d
Define alfab.d
Define dmx.l, dmy.l
Define distancem.d
Define km.d
Define alfam.d
Define time.d, time_start, time_yet
Define reached.b
Define sum.d, calcX.d, calcY.d, factor.d, a.d, b.d
Define mx.l, my.l
InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(#Screen_Width, #Screen_Height, #Screen_Depth, #Screen_Title)
CreateSprite(#Sprite_Circle_Static, #Sprite_Circle_Static_Width, #Sprite_Circle_Static_Height)
StartDrawing(SpriteOutput(#Sprite_Circle_Static))
Circle(#Sprite_Circle_Static_Width/2, #Sprite_Circle_Static_Height/2, #Sprite_Circle_Static_Width/2, RGB(255, 0, 0))
StopDrawing()
CreateSprite(#Sprite_Circle_Ball, #Sprite_Circle_Ball_Width, #Sprite_Circle_Ball_Height)
StartDrawing(SpriteOutput(#Sprite_Circle_Ball))
Circle(#Sprite_Circle_Ball_Width/2, #Sprite_Circle_Ball_Height/2, #Sprite_Circle_Ball_Width/2, RGB(255, 255, 0))
StopDrawing()
CreateSprite(#Sprite_Mouse, #Sprite_Mouse_Width, #Sprite_Mouse_Height)
StartDrawing(SpriteOutput(#Sprite_Mouse))
Line(0, #Sprite_Mouse_Height/2, #Sprite_Mouse_Width, 0, RGB(255, 255, 255))
Line(#Sprite_Mouse_Width/2, 0, 0, #Sprite_Mouse_Height, RGB(255, 255, 255))
StopDrawing()
time_start = ElapsedMilliseconds()
Repeat
mx = MouseX()
my = MouseY()
Circle_Ball\xM = Circle_Ball\x + Circle_Ball\r
Circle_Ball\yM = Circle_Ball\y + Circle_Ball\r
dmx = mx - Circle_Static\xM
dmy = my - Circle_Static\yM
km = dmy / dmx
alfam = ATan(km)
If (dmx < 0 And dmy > 0) Or (dmx < 0 And dmy < 1)
alfam + #PI
EndIf
If dmx = 0 And dmy = 0
alfam = 0
EndIf
dbx = Circle_Ball\vx
dby = Circle_Ball\vy
kb = dby / dbx
alfab = ATan(kb)
If (dbx < 0 And dby > 0) Or (dbx < 0 And dby < 1)
alfab - #PI
EndIf
If dbx = 0 And dby = 0
alfab = 0
EndIf
dx = Circle_Ball\xM - Circle_Static\xM
dy = Circle_Ball\yM - Circle_Static\yM
k = dy / dx
alfa = ATan(k)
If (dx < 0 And dy > 0) Or (dx < 0 And dy < 1)
alfa + #PI
EndIf
If dx = 0 And dy = 0
alfa = 0
EndIf
distance = pythagorasK(dx, dy)
If distance < Circle_Static\r + Circle_Ball\r
a = Circle_Static\r + Circle_Ball\r + 1
Circle_Ball\x = Circle_Static\xM + Cos(alfa) * a - Circle_Ball\r
Circle_Ball\y = Circle_Static\yM + Sin(alfa) * a - Circle_Ball\r
Circle_Ball\x0 = Circle_Ball\x
Circle_Ball\y0 = Circle_Ball\y
reached = 1
EndIf
FlipBuffers()
ClearScreen(RGB(0, 0, 0))
DisplayTransparentSprite(#Sprite_Circle_Static, Circle_Static\x, Circle_Static\y)
DisplayTransparentSprite(#Sprite_Circle_Ball, Circle_Ball\x, Circle_Ball\y)
DisplayTransparentSprite(#Sprite_Mouse, mx - #Sprite_Mouse_Width/2, my - #Sprite_Mouse_Height/2)
If MouseButton(#PB_MouseButton_Left)
Circle_Ball\x = mx - Circle_Ball\r
Circle_Ball\y = my - Circle_Ball\r
Circle_Ball\x0 = Circle_Ball\x
Circle_Ball\y0 = Circle_Ball\y
time_start = ElapsedMilliseconds()
Circle_Ball\vx0 = MouseDeltaX() * 10
Circle_Ball\vy0 = MouseDeltaY() * 10
Circle_Ball\vx = Circle_Ball\vx0
Circle_Ball\vy = Circle_Ball\vy0
Else
If Not reached
Circle_Ball\vx = Circle_Ball\vx0 + Circle_Ball\ax * time
Circle_Ball\vy = Circle_Ball\vy0 + Circle_Ball\ay * time
Circle_Ball\x = Circle_Ball\x0 + Circle_Ball\vx0 * time + (Circle_Ball\ax * time * time)/2
Circle_Ball\y = Circle_Ball\y0 + Circle_Ball\vy0 * time + (Circle_Ball\ay * time * time)/2
Else
sum = Abs(Circle_Ball\vx) + Abs(Circle_Ball\vy)
a = 2*alfa - alfab
b = Abs(Circle_Ball\vx) + Abs(Circle_Ball\vy)
calcX = -Cos(a) * b
calcY = -Sin(a) * b
factor = sum / (Abs(calcX) + Abs(calcY))
If Abs(calcX) + Abs(calcY) = 0
factor = 0
EndIf
Circle_Ball\vx = calcX * factor
Circle_Ball\vy = calcY * factor
time_start = ElapsedMilliseconds()
time = 0
Circle_Ball\vx0 = Circle_Ball\vx
Circle_Ball\vy0 = Circle_Ball\vy
a = Circle_Static\r + Circle_Ball\r
Circle_Ball\x0 = Circle_Static\xM + Cos(alfa) * a - Circle_Ball\r
Circle_Ball\y0 = Circle_Static\yM + Sin(alfa) * a - Circle_Ball\r
Circle_Ball\x = Circle_Ball\x0
Circle_Ball\y = Circle_Ball\y0
reached = 0
EndIf
EndIf
If IsScreenActive()
StartDrawing(ScreenOutput())
LineXY(Circle_Static\xM, Circle_Static\yM, Circle_Ball\xM, Circle_Ball\yM, RGB(0, 255, 0))
normal(Circle_Static\xM, Circle_Static\yM, Circle_Ball\xM, Circle_Ball\yM, Cos(alfa) * Circle_Static\r, 400, RGB(255, 255, 255))
DrawText(0, 0, StrD(distance - 275))
DrawText(0, 30, Str(Circle_Ball\xM) + " , " + Str(Circle_Ball\yM))
DrawText(0, 60, StrD(alfa * #rad2deg))
DrawText(0, 90, StrD(alfab * #rad2deg))
LineXY(Circle_Static\xM, Circle_Static\yM, mx, my, RGB(127, 127, 127))
normal(Circle_Static\xM, Circle_Static\yM, mx, my, Cos(alfam) * Circle_Static\r, 400, RGB(127, 127, 127))
StopDrawing()
EndIf
Delay(1)
ExamineKeyboard()
ExamineMouse()
time_yet = ElapsedMilliseconds()
time = (time_yet - time_start) / 1000
Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
Andreas