fb:porticula NoPaste
(k)einspurmodell
Uploader: | Muttonhead |
Datum/Zeit: | 31.10.2011 21:08:50 |
'Einspur-Achsenmodel_00.bas
'weit entfernt von Physik und Realität
#include "fbgfx.bi"
const as integer Xo=400,Yo=300
const as double pi =atn (1) * 4
const as double doublepi=pi*2
screenres Xo*2,Yo*2,32
type vector
x as double
y as double
end type
declare function GetAngle(b as vector,v as vector) as double
declare function GetVector(align as double) as vector
type axle
prevaxle as axle ptr 'Zeiger auf Vorgänger
nextaxle as axle ptr 'Zeiger auf Nachfolger
position as vector
dist as integer 'Entfernung dieser Achse zum Vorgänger, 0 bei erster Achse
end type
type set
alignment as double 'globale Richtung des "Zugfahrzeugs"(definiert durch die Lage von 1. und 2. Achse)
steer as double 'Lenkwinkel/ Bewegungsrichtung der ersten Achse
speed as double 'Geschwindigkeit Einheiten/Sekunde im Koordinatensystem
reverse as integer '1 wenn Rückwärtsgang, Speed muß 0 sein
tmr as double 'Zeitpunkt der letzten Bewegung/Berechnung
firstaxle as axle ptr 'Zeiger auf erste Achse
lastaxle as axle ptr 'Zeiger auf letzte Achse
declare function AddAxle(dist as integer=0,align as double=0) as integer
declare sub MoveAxles
declare sub CalcAlignment
declare sub DrawAxles
declare sub Faster
declare sub Slower
declare sub ToLeft
declare sub ToRight
declare destructor
end type
'Achsenfolge wird immer vom Koordinatenursprung erzeugt, soll heißen: 1. Achse ist immer in (0,0)
function set.AddAxle(dist as integer=0,direction as double=0) as integer
dim as axle ptr tmp
dim as vector v
tmp=new axle
if tmp then
if lastaxle=0 then'wenn noch keine Achse, dann...
tmp->prevaxle=0
tmp->nextaxle=0
tmp->dist=0
tmp->position.x=0
tmp->position.y=0
firstaxle=tmp 'als Erste setzen
else'ansonsten normales Erzeugen und Verlinken der nachfolgenden Achsen
'Verlinken
lastaxle->nextaxle=tmp
tmp->prevaxle=lastaxle
'Positionieren der Achse relativ zum vorhergehenden Punkt
v=GetVector(direction)'Richtungsvektor erzeugen, dessen Länge ist 1
'Position der vorhergehenden Achse + Skalarmultiplikation des Vektors mit dist... Keine Ahnung davon
tmp->position.x=lastaxle->position.x + v.x*dist
tmp->position.y=lastaxle->position.y + v.y*dist
'Entfernung merken
tmp->dist=dist
end if
lastaxle=tmp' erzeugt Achse als Letze definieren
function=1
end if
end function
sub set.MoveAxles
dim as axle ptr axl=firstaxle
dim as vector v
dim as double t,l
'Timersteuerung
if tmr then t= timer-tmr else t=0'Zeit seit letzter Bewegung
CalcAlignment'Ausrichtung der 1.Achse neuberechnen
do
if axl=firstaxle then 'betrifft nur die erste Achse
l=speed*t 'aus Geschwindigkeit und Zeit den Weg ermitteln
'Bewegung der 1. Achse
v=GetVector(alignment + steer) 'Summe aus Richtungswinkel der 1. Achse und der Steuerungswinkel ergibt einen Vektor für die Bewegungsrichtung
print alignment,steer
axl->position.x +=v.x*l
axl->position.y +=v.y*l
else 'alle anderen Achsen jeweils in Richtung ihrer Vorgängerin ziehen
'Vektor von vorhergehender Achse neue Position in Richtung diese Achse alte Position.
v=GetVector(GetAngle(axl->prevaxle->position,axl->position))
axl->position.x=axl->prevaxle->position.x + v.x*axl->dist
axl->position.y=axl->prevaxle->position.y + v.y*axl->dist
end if
axl=axl->nextaxle
loop until axl=0
tmr=timer 'aktuelle Zeit für das nächstemal merken
end sub
sub set.CalcAlignment
if lastaxle<>firstaxle then
alignment=GetAngle(firstaxle->nextaxle->position,firstaxle->position)'Ausrichtung der 1.Achse neuberechnen
end if
end sub
sub set.DrawAxles
dim as axle ptr axl=firstaxle
dim as integer c
do
if axl=firstaxle then c=&HFFFFFF else c=&HFF7F00
circle(Xo + axl->position.x , Yo - axl->position.y ),5,c
if axl<>firstaxle then line(Xo + axl->prevaxle->position.x , Yo - axl->prevaxle->position.y )-(Xo + axl->position.x , Yo - axl->position.y ),&HFFFFFF
axl=axl->nextaxle
loop until axl=0
end sub
sub set.Faster
speed +=1
if speed>50 then speed=50
end sub
sub set.Slower
speed -=1
if speed<-20 then speed=-20
end sub
sub set.ToLeft
steer +=1
if steer>30 then steer=30
end sub
sub set.ToRight
steer -=1
if steer<-30 then steer=-30
end sub
destructor set
dim as axle ptr naxl,axl=firstaxle
if axl then
do
naxl=axl->nextaxle
delete axl
axl=naxl
loop until axl=0
end if
end destructor
'liefert die globale Richtung eines Punktes v vom Standpunkt b aus gesehen (in Grad)
function GetAngle(b as vector,v as vector) as double
dim as double arcus
dim as vector d
d.x= v.x - b.x
d.y= v.y - b.y
arcus=atan2(d.y,d.x)
if sgn(arcus)=-1 then arcus= doublepi + arcus
function=(arcus/doublepi) * 360
end function
'liefert eine Richtung (in Grad) als Richtungsvektor
function GetVector(align as double) as vector
dim as double arcus
dim as vector v
if align>=360 then align=align-360
if align<0 then align=360+align
arcus=(align/360) * doublepi
v.x=cos(arcus)
v.y=sin(arcus)
function=v
end function
'****************************************************************************************
dim as set truck
truck.AddAxle()
truck.AddAxle(40,0)
truck.AddAxle(90,30)
truck.speed=0
truck.steer=0
dim as integer exitsignal=0
do
if multikey(fb.sc_w) then truck.Faster
if multikey(fb.sc_s) then truck.Slower
if multikey(fb.sc_a) then truck.ToLeft
if multikey(fb.sc_d) then truck.ToRight
if multikey(fb.sc_escape) then exitsignal=1
screenlock
cls
'Koordinatensystem
line (0,Yo)-(Xo*2-1,Yo),&H007f00
line (Xo,0)-(Xo,Yo*2-1),&H7F0000
pset(Xo,Yo),&HFFFFFF
truck.DrawAxles
screenunlock
truck.MoveAxles
sleep 1
loop until exitsignal
end