Seite 1 von 4

Hilfe bei Vertikal-Autorennspiel

Verfasst: 21.01.2007 18:24
von real
Hi,

ich wollte neben sinnvollen Tools mal ein wenig aus Spaß programmieren und bin dabei sofort auf ein Problem gestoßen: Wie kann ich ein Auto auf einem unebenen Gelände fahren lassen. Hat von Euch schon jemand sowas programmiert und gibt mir einen Denkanstoß oder ein Stück Quellcode, an dem ich mich weiterhangeln kann? :freak:

So mein ich das ungefähr:
Bild

Dank und Gruß
René

Verfasst: 21.01.2007 18:36
von ZeHa
Sowas direkt gemacht habe ich noch nicht, aber da wirst Du Dich mit ein paar grundlegen physikalischen Gegebenheiten beschäftigen müssen.

Mal ganz grob gesagt solltest Du Dir das alles einfach in Vektoren vorstellen. Das heißt, das Gelände besteht aus einigen Vektoren, und auch das Auto kannst Du Dir erstmal nur als gedachte Linie vorstellen. Vielleicht kommst Du von hier aus ein Stück weiter.

Es gibt da doch haufenweise Spiele mit Motorrädern oder Fahrrädern, wo man so von der Seite aus sieht, wie man über alle möglichen seltsamen Gelände fährt (Elasto-Mania z.B.), vielleicht gibt's da auch eins mit offenem SourceCode.

Verfasst: 21.01.2007 18:38
von ZeHa
Hier ein interessanter Thread genau zum Thema:

http://www.gamedev.net/community/forums ... _id=397791

Verfasst: 21.01.2007 18:46
von real
Danke erstmal für die Antwort. Aber da das Thema nicht sooo trivial zu sein scheint: hast Du auch was auf deutsch für mich?

Verfasst: 21.01.2007 23:09
von ZeHa
Naja wie gesagt, hab sowas noch nie programmiert und es ist nicht leicht, die passenden Suchbegriffe zu finden ;) aber ich hab hier was interessantes gefunden, und zwar eine Spiel, das ElastoMania sehr ähnlich ist, und zudem aber als OpenSource vorliegt.

Zudem gibt's dort ein Forum, da könntest Du ja mal nach den physikalischen Grundlagen fragen, ob Dir das einer in normalen Worten erklären kann. Weiß aber nicht ob da deutsch gesprochen wird (hab nicht reingeschaut).

http://xmoto.sourceforge.net/

Verfasst: 22.01.2007 10:39
von real
Danke, da werd ich mich mal reinlesen.

Verfasst: 22.01.2007 10:57
von real
Hab mir jetzt mal einen Einblick verschafft. Leider basiert XMoto auch auf der bereits bestehenden ODE-Bibliothek. D.h. die physikalischen Berechnungen werden per ODE durchgeführt.

:cry:

Verfasst: 22.01.2007 11:37
von Kaeru Gaman
also, wenn dir sowas wie "MoonBuggy" vorschwebt,
kannst dus etwas lockerer angehen als "Elastomania".

der weit simplere ansatz wäre, dass du ein array erstellst,
in dem du die höhenwerte für die landschaft speicherst.
in diesem falle müsste das ja nur 1D sein.
von diesem array ausgehend kannst du sowohl deine landschaft zeichnen,
als auch checken, auf welcher höhe sich die räder befinden müssen.

Verfasst: 23.01.2007 15:03
von Scarabol
Ich kann nur folgendes Beispiel hier aus dem Forum beisteuren weiß aber nicht mehr genau ob es aus dem Forum oder Code Archiv ist.

Code: Alles auswählen

 Structure XY
  x.f
  y.f
EndStructure


#FACTOR = 300.0
#TRANSL = 0.5 ; >0.5=Täler, <0.5=Berge

#PIXELS = 100 ; hier bis 500!
Global Dim ALine.f(#PIXELS)
Global mv.f, d.l, max.l


Procedure Split(low.l, high.l)
   Protected m.l
   
   m = (high + low) / 2
   d = high - low
   If d <= 1
      ProcedureReturn 0
   EndIf
   
   mv = (ALine(high) + ALine(low)) / 2.0
   
   ALine(m) = mv - (Random(10000) / 10000.0 - #TRANSL) * #FACTOR * d / (max)
   
   
   Split(m, high)
   Split(low, m)
   
EndProcedure


Procedure.f LineLineCol(*P.XY, *r.XY, *A.XY, *B.XY, *OUT.XY)
  Protected t.f, s.f
  Protected AB.XY
 
  s = *A\x * *r\y - *A\y * *r\x
  t = (s - *P\x * *r\y + *P\y * *r\x) / (s - *B\x * *r\y + *B\y * *r\x)
 
  AB\x = *B\x - *A\x
  AB\y = *B\y - *A\y
 
  If t >= -0.0001 And t <= 1.0001
     *OUT\x = *A\x + t * AB\x
     *OUT\y = *A\y + t * AB\y
     
     ProcedureReturn Pow(*OUT\x - *P\x, 2) + Pow(*OUT\y - *P\y, 2)
  EndIf
 
  ProcedureReturn 99999999.0
EndProcedure

Procedure.l LineCollideArray(*Start.XY, *Dir.XY, *Out.XY)
   Protected i.l, shortestDis.f, t.f
   Protected A.XY, B.XY, Out2.XY
   
   shortestDis = 99999999.0
   For i = 0 To #PIXELS - 1
      A\y = 1.0 + ALine(i) + 250.0
      A\x = 1.0 * i / #PIXELS * 500
      B\y = 1.0 + ALine(i + 1) + 250.0
      B\x = 1.0 * (i + 1) / #PIXELS * 500
      
      t = LineLineCol(*Start, *Dir, @A, @B, @Out2)
      If t < shortestDis
        shortestDis = t
        *Out\x = Out2\x
        *Out\y = Out2\y
      EndIf
   Next
EndProcedure



max = #PIXELS
Split(0, #PIXELS)


CreateImage(0, 500, 500)

OpenWindow(0, 200, 200, 500, 500, "Drawing", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
   ImageGadget(1, 0, 0, 500, 500, ImageID(0))






SetGadgetState(1, ImageID(0))
Repeat
   hdc = StartDrawing(ImageOutput(0))
     Box(0,0, 500,500, 0)
      For z = 1 To #PIXELS
         LineXY(1.0 * (z - 1) / #PIXELS * 500, ALine(z - 1) + 250, 1.0 * z / #PIXELS * 500, ALine(z) + 250, $FF)
      Next
      
      P.XY
      P\x = 250
      P\y = 0
      Dir.XY
      Dir\x = WindowMouseX(0) - 250
      Dir\y = WindowMouseY(0)
      Out.XY
      LineCollideArray(@P, @Dir, @Out)
      Circle(Out\x, Out\y, 10, $FF00)
      Line(P\x, P\y, Dir\x, Dir\y, $FF0000)
   StopDrawing()
   SetGadgetState(1, ImageID(0))
   
   
   Delay(10)
Until WindowEvent() = #PB_Event_CloseWindow 
Hoffe es hilft
Scarabol

Verfasst: 23.01.2007 15:57
von remi_meier
@Scarabol
Das ist mein Code hier aus dem Forum :)

Übrigens war doch in ZeHas Thread ein Link zu einer guten Seite dabei:
http://www.d6.com/users/checker/dynamics.htm