Login Register
Frontpage Code library Pastebin

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 all
  1
  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.