TilemapCollision
Author: MaGetzUb
Added: 13. huhtikuuta 2015 kello 1.23
Edited: 13. huhtikuuta 2015 kello 1.29
Category: Kartat
Description
Hoitaa laatikko -> kartta -törmäystarkistuksen lähes ikiwanhan CoolBasic Beta #5 tyylisesti. Törmäyspiste palautetaan Globaalien Collision_X ja Collision_Y mukana. Törmäys suunnan palautetaan CollisionNormal_X ja CollisionNormal_Y mukana.
TilemapCollision -funktiolle välitetään parametreina testattavan "objektin" entiset maailmakoordinaatit (oldx, oldy) ja uudet koordinaatit (x, y) sekä koko (width, height).
Huom, törmäyspiste ei ole todellakaan tarkka, koska Collision_ -muuttujat päivitetään old-muuttujilla. Päivittelen koodin vielä joskus tekemään sweep -törmäystarkistuksen, joka palauttaa tarkat törmäyskoordinaatit. Nykyiset törmäyskoordinaatit ovat kyllä tarpeeksi tarkat varsinkin jos liikutaan pelkästään vaaka- tai pystysuorasti, mutta ei välttämättä vinoissa kulmissa.
Code
Select all1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | Global Collision_X As Float
Global Collision_Y As Float
Global CollisionNormal_X As Float
Global CollisionNormal_Y As Float
Const MaxFPS = 40
Framelimit MaxFPS
map = LoadMap("Media\cdm2.til", "Media\tileset.bmp")
//Alustetaan "entiteetille" oleelliset muuttujat
//Nykyinen sijainti
x As Float = 0
y As Float = 0
//Edellinen sijainti
oldx As Float = x
oldy As Float = y
//Koko
w As Float = 20
h As Float = 20
//Entiteetin nopeus
entitySpeed As Float = 3 * MaxFPS
//Menosuunta
ang As Float = 0
//Alustetaan deltatime -muuttuja jota voidaan hyödyntää fysiikkasimulaatiossa
deltaTime As Float = 0.0
//Alustetaan lastTime -muuttuja, mitä hyödynnetään ajanmittauksessa
lastTime As Float = Timer()
Repeat
//Otetaan entiteetin nykyiset koordinaatit talteen.
prevX As Float = x
prevY As Float = y
//Integroidaan objektille uudet koordinaatit vanhojen perusteella Verlet-integraatiolla
// Eli kaavalla: a' = (2.0 - f)*a - (1.0 - f)*olda + force * time ^ 2), f simuloi kitkaa
x = 1.999*x - 0.999*oldX + (Cos(ang) * entitySpeed * (UpKey() - DownKey())) * deltatime * deltatime
y = 1.999*y - 0.999*oldY - (Sin(ang) * entitySpeed * (UpKey() - DownKey())) * deltatime * deltatime
//Päivitetään edelliset koordinaatit
oldx = prevX
oldy = prevY
//Päivitetään objektin kulma
ang = ang + (RightKey() - LeftKey()) * 5
//Piirretään piirtokomennot
DrawGame
//Asetetaan primitiivien piirto maailmakoordinaatteihin
DrawToWorld ON
//Testataan, tapahtuiko törmäys
If TilemapCollision(oldx - w / 2, oldy - h / 2, x - w / 2, y - h / 2, w, h) = True Then
//Törmäys tapahtui, lasketaan paljonko entiteetillä on liike-energiaa
xvel# = (x - oldx)
yvel# = (y - oldy)
speed# = Sqrt(xvel*xvel + yvel*yvel)
//Käsitellään törmäys
x = Collision_X + w / 2 + CollisionNormal_X * speed * 0.15
y = Collision_Y + h / 2 + CollisionNormal_Y * speed * 0.15
EndIf
//Piirretään nyt itse entiteetti
Color cbMagenta
Box x - w/2, y + h/2, w, h, 0
Line x, y, x + Cos(ang) * w, y - Sin(ang) * w
//Sijoitetaan kamera entiteetin kohtaan
PositionCamera x, y
//Päivitetään aika
deltaTime = (Timer() - lastTime) / 1000.0
lastTime = Timer()
DrawScreen
Forever
Function TilemapCollision(oldx As Float, oldy As Float, x As Float, y As Float, width As Float, height As Float)
//Oletetaan ettei törmäystä ole vielä tapahtunut, alustetaan siis IsCollision -muuttuja false:si
IsCollision As Integer = False
//Asetetaan törmäyssijainti alustavasti uusiin koordinaatteihin
Collision_X = x
Collision_Y = y
//Nollataan törmäyssuunta -muuttujat
CollisionNormalX = 0.0
CollisionNormalY = 0.0
//Testataan ensiksi vaakasuoralla akselilla olevat törmäykset
If GetMap(2, x, oldy) Or GetMap(2, x, oldy+height) Then
//Vasen puoli
Collision_X = oldx
CollisionNormalX = 1.0 //Törmäys tapahtui oikealle päin (->)
IsCollision = True
ElseIf GetMap(2, x+width, oldy) Or GetMap(2, x+width, oldy+height) Then
//Oikea puoli
Collision_X = oldx
CollisionNormalX = -1.0 //Törmäys tapahtui vasemmalle päin (<-)
IsCollision = True
EndIf
//Sitten testataan pystysuoralla akselilla olevat törmäykset
If GetMap(2, oldx, y) Or GetMap(2, oldx+width, y) Then
//Ala-laita
CollisionNormalY = 1.0 //Törmäys tapahtui ylös päin (^)
Collision_Y = oldy
IsCollision = True
ElseIf GetMap(2, oldx, y+height) Or GetMap(2, oldx+width, y+height) Then
//Ylälaita
CollisionNormalY = -1.0 //Törmäys tapahtui alas päin (v)
Collision_Y = oldy
IsCollision = True
EndIf
//Palautetaan totuusarvona, tapahtuiko törmäys.
Return IsCollision
EndFunction
|
Comments
No comments. You can be first!
Leave a comment
You must be logged in to comment.