Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: VB6: Monta spriteä

Sivun loppuun

JoreSoft [06.07.2004 15:07:26]

#

Katsoin jo tarpeelliseksi tehdä uuden Strite-esimerkin.
Tässä esimerkissä spritejä on 6 kpl. 5 nelötä ja yksi olio
Tässä tehdään myös törmäys tarkistukset.
Tarvitset yhden formin nimi PL
Picturebox-kontrooleja:
Pkuva,Buffer1,Buffer2 laita mäihin sama peli-kuva. esim 320*240
pSprite(0 - 5) 0-4 neliöt (32*32), 5 = olio (37*37)
pVanha(0 - 5) 0-4 nelöt (32*32), 5 = olio (37*37)
pMask(0 - 1) 0 neliöt (32*32), 1 = olio (37*37)
Timer1

Tekniikkana on käyttää kahta puskuria, Buffer1 on paikka jonne kaikki piirretään, Buffer2 on paikka jossa on koko ajan "alkuperäinen kuva", tarvitaan vain jos, liikkuvia kuvaelementtejä on muitakin kuin nämä, ja halutaan että gfafiikka ei laahaudu, spritejen mennessä päällekkäin.
Buffer1:n kuva kopioidaan pKuvaan.
Esimerkki ei ole törmäyksen osalta täydellinen, varsinkin kun kaikki sulloutuvat samaan nurkkaan, mutta täytyyhän ihmisille jättää vähän paranneltavaakin...

Esimerkin Zip-Versio: http://koti.mbnet.fi/joresoft/Download/Esim/SpriteEsim2.zip

Moduliin

Option Explicit

'Muuttujat

Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Type SpriteType  'Pelinapin yms. Muuttuja määrittely
    Value As Integer    ' Arvo
    On As Boolean       ' On/Off
    X As Integer        ' X-paikka ruudulla
    Y As Integer        ' Y-paikka
    Z As Integer        ' Z-paikka
    VX As Integer       ' Vanha X
    VY As Integer       ' Vanha Y
    VZ As Integer       ' Vanha Z
    SX As Integer       ' Lisäyslaskuri
    SY As Integer
    Temp As Integer     ' Väliaikainen tieto
    'Kuvankäsittelyyn liittyvät muuttujat
    Old As Integer      ' Mikä spitren vanha kuva käytössä
    Mask As Integer     ' Mikä Spriten Maski käytössä
    ScaleX As Integer   ' Spriten X-koko
    ScaleY As Integer   ' Spriten Y-koko
End Type

Global Sprite(0 To 5) As SpriteType
Global zz&


Function Rand(R As Integer)
    Randomize Timer
    Rand = Int(Rnd(1) * R)
    DoEvents
End Function

Sub PalautaVanha(I As SpriteType, X As Integer)
If I.On Then
        'Palautetaan
        zz = BitBlt(PL!pBuffer1.hDC, I.VX, I.VY, I.ScaleX, I.ScaleY, PL!pVanha(X).hDC, 0, 0, vbSrcCopy)
End If
End Sub

Sub OtaKuvatalteen(I As SpriteType, X%)
If I.On Then
      If I.VX <> -100 Then
        'otetaan kuva talteen (Nappi)
        zz = BitBlt(PL!pVanha(X).hDC, 0, 0, I.ScaleX, I.ScaleY, PL!pBuffer1.hDC, I.X, I.Y, vbSrcCopy)
      Else
        'Haetaan ensimmäinen Kuva puuhtaalta pelipöydältä
        zz = BitBlt(PL!pVanha(X).hDC, 0, 0, I.ScaleX, I.ScaleY, PL!pBuffer2.hDC, I.X, I.Y, vbSrcCopy)
      End If
      PL!pVanha(X).Refresh
End If
End Sub

Sub PiirräSprite(I As SpriteType, X%, Y%)
Dim J%
   If I.On Then
        If I.VX <> -100 Then
        'Piirretään
        zz = BitBlt(PL!pBuffer1.hDC, I.X, I.Y, I.ScaleX, I.ScaleY, PL!pMask(Y).hDC, 0, 0, vbSrcAnd)
        zz = BitBlt(PL!pBuffer1.hDC, I.X, I.Y, I.ScaleX, I.ScaleY, PL!pSprite(X).hDC, 0, 0, vbSrcInvert)
        End If
        I.VX = I.X: I.VY = I.Y
    End If
End Sub

Function OnkoTörmäys(X1%, Y1%, X2%, Y2%, SX%, SY%) As Boolean
    If X1 + SX > X2 Then
        If X1 < X2 + SX Then
            If Y1 + SY > Y2 Then
                If Y1 < Y2 + SY Then
                    OnkoTörmäys = True
                End If
            End If
        End If
        End If
End Function

Formiin

Option Explicit

Private Sub Form_Load()
Dim I%, J%, T As Boolean
    For I = 0 To 5
    If I < 5 Then
        Sprite(I).X = Rand(pKuva.Width)
        Sprite(I).Y = Rand(pKuva.Height)
    End If
    Do
    Sprite(I).SX = (Rand(2) - 1) * Rand(3)
    Sprite(I).SY = (Rand(2) - 1) * Rand(3)
    Loop Until Sprite(I).SX <> 0 And Sprite(I).SY <> 0
    Sprite(I).Z = 1
    Sprite(I).On = True
    Sprite(I).Value = I
    Sprite(I).Mask = 0
    Sprite(I).Old = I
    Sprite(I).VX = -100
    Sprite(I).ScaleX = pSprite(I).ScaleWidth
    Sprite(I).ScaleY = pSprite(I).ScaleHeight

    Next I
    'Asetetaan olio
    Sprite(5).Mask = 1
    Sprite(5).SX = Rand(2) - 1
    Sprite(5).SY = Rand(2) - 1
    Do
        Sprite(5).X = Rand(pKuva.Width)
        Sprite(5).Y = Rand(pKuva.Height)
        For J = 0 To 4 'Jos törmäys sijoitetaan olio uudestaan
            T = OnkoTörmäys(Sprite(5).X, Sprite(5).Y, Sprite(J).X, Sprite(J).Y, Sprite(5).ScaleX, Sprite(5).ScaleY)
            If T Then Exit For
        Next J
    Loop Until Not T
    Timer1.Enabled = True
End Sub

Private Sub Form_Unload(Cancel As Integer)
    End
End Sub

Private Sub Timer1_Timer()
Dim I%, J%
    Timer1.Enabled = False
    For I = 0 To 5  'Palautetaan kaikki vanhat
        PalautaVanha Sprite(I), Sprite(I).Old
    Next I

    For I = 0 To 5
        Sprite(I).X = Sprite(I).X + Sprite(I).SX
        For J = 0 To 5
            If I <> J Then
            If OnkoTörmäys(Sprite(J).X, Sprite(J).Y, Sprite(I).X, Sprite(I).Y, Sprite(J).ScaleX, Sprite(J).ScaleY) Then
            Sprite(I).SX = -Sprite(I).SX
            Sprite(I).X = Sprite(I).X + Sprite(I).SX
            End If
            End If
        Next J
        If Sprite(I).X + Sprite(I).ScaleX > pKuva.Width Then Sprite(I).SX = -1: Sprite(I).X = Sprite(I).X - 1
        If Sprite(I).X < 0 Then Sprite(I).SX = 1: Sprite(I).X = Sprite(I).X + 1
        Sprite(I).Y = Sprite(I).Y + Sprite(I).SY
        'Onko spritet tärmänneet toisiinsa?
        For J = 0 To 5
            If J <> I Then
            If OnkoTörmäys(Sprite(J).X, Sprite(J).Y, Sprite(I).X, Sprite(I).Y, Sprite(J).ScaleX, Sprite(J).ScaleY) Then
            Sprite(I).SY = -Sprite(I).SY
            Sprite(I).Y = Sprite(I).Y + Sprite(I).SY
            End If
            End If
        Next J
        If Sprite(I).Y + Sprite(I).ScaleY > pKuva.Height Then Sprite(I).SY = -1: Sprite(I).Y = Sprite(I).Y - 1
        If Sprite(I).Y < 0 Then Sprite(I).SY = 1: Sprite(I).Y = Sprite(I).Y + 1
    Next I

    For I = 0 To 5  'Annetaan kaikille "puhdas" kuva (Ilman toisia spritejä)
        OtaKuvatalteen Sprite(I), Sprite(I).Old
    Next I
    For I = 0 To 5  'Piirretään kuvat
        PiirräSprite Sprite(I), Sprite(I).Value, Sprite(I).Mask
    Next I
zz = BitBlt(PL!pKuva.hDC, 0, 0, PL!pKuva.ScaleWidth, PL!pKuva.ScaleHeight, PL!pBuffer1.hDC, 0, 0, vbSrcCopy)
    PL!pKuva.Refresh
    'PL!pBuffer1.Refresh 'Ota kommentti merkki pois, niin näet Bufferin
    Timer1.Enabled = True
End Sub

tuomas [07.07.2004 23:37:49]

#

Hyvin toimii :)
Ja asiahan on näin että näitä bitblt virityksiä ei ole koskaan liikaa.

Blaze [08.07.2004 00:31:10]

#

Ei mutta tämähän on aivan mahtava :o
Pitää ottaa osote ylös, että voi ohjata tänne kaikki "mITEN SAA NIIN ETTÄ UKKO EI MEE SEINÄSTÄ LÄPI NIINQ TGFLLÄ!11111" -kysyjät.

sooda [08.07.2004 14:27:56]

#

tuomas kirjoitti:

Ja asiahan on näin että näitä bitblt virityksiä ei ole koskaan liikaa.

Just niin. Mahtava.

hunajavohveli [08.07.2004 23:12:07]

#

Oikein hyvältä vaikuttaa. (noita [koodivb]-tageja tosin ei tarvita koodivinkeissä, joten ne voit ottaa pois)
Blaze: Tässä on tosiaan loistavia funktioita tuon sortin kyselijöille. Toivotaan vain, että ymmärtäisivät koodistakin jotain.

Puhveli [09.07.2004 13:15:29]

#

bitblt toimii kyllä munkäsittääkseni niinkin, että sitä kutsuu tavallisena subina... mutta loistava esimerkki spriteistä!

JoreSoft [09.07.2004 19:18:48]

#

lainaus:

bitblt toimii kyllä munkäsittääkseni niinkin, että sitä kutsuu tavallisena subina... mutta loistava esimerkki spriteistä!

Todellakin.
Alustus on silloin:

Public Declare Sub BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long)

Ja kutsuminen (Esim.)

BitBlt PL!pVanha(X).hDC, 0, 0, I.ScaleX, I.ScaleY, PL!pBuffer2.hDC, I.X, I.Y, vbSrcCopy

JoreSoft [13.07.2004 16:31:04]

#

Tässä uusi esimerkki. lisäys esimerkkiin.
Ohjelma käyttää kahta puskuria, muttei varastoi spriten vanhaa grafiikkaa.
Spritejä voi olla 1- 200 kpl.
Linkki muuttettu 5.1.2006 http://koti.mbnet.fi/joresoft/Download/Esim/SpriteEsim2.zip

Ohjelman tekniikka:
PL!pKuva - pelikentän näkyvä kuva
F1!pBuffer1 ' Piirto puskuri
F2!pBuffer2 ' Taustakuvan alkuperäinen versio.

1) Asetetaan pBuffer2 kuva pBuffer1:een.
2) Liikutetaan kaikkia Spritejä.
3) Piirretään kaikki Spritet pBuffer1:een.
4) Kopioidaan pBuffer1, pKuva:aan.

Reima [07.04.2006 20:12:32]

#

Mielen-kiinyoinen.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta