Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: VB6: Reaaliaikainen moottori peliin

Sivun loppuun

Meitzi [29.05.2004 20:12:59]

#

Tämä vinkki näyttää yleispätevän rungon siihen, miten tehdään vaikka peliin moottori joka osaa käsitellä näppäimistöä, siirtää objektia kellon mukaan ja "piirtää" tämä ruudulle. Lisäksi tämä kaikki pitää tietysti tehdä mahdollisimman tehokkaasti.

Perusperiaate tässä on, että ohjelman silmukkaa pyöritetään kokoajan täysillä ja joka kerta silmukka siirtää objektia uuten paikaan. Koska laskussa otetaan huomioon myös kello, ei koneen nopeus vaikuta objektin nopeuteen. Mitä nopeampi kone, sitä paremman näköinen liike on. Koskaan ohjelmassa jossa tarvitaan reaaliaikaista grafiikka ei ohjelmaa saa hidastaa kellolla tjsp.

Eri versiot sekä VB6:lle että .NET:lle

Käännettyä EXE tiedostoa en pistä jakoon koska liikkuvan pictureboxin katsominen ei nyt niin hirvittävän jännää ole. Käytä nuolinäppäimiä laatikon siirtämiseen.

VB6

Vaatii PictureBox1:n.

Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long 'Kertoo tarkan ajan
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'Nukkuu eli idlaa

Private Nappaimet(255) As Boolean 'Sisältää kaikkien näppäimistön näppäinten tilan
Private NopeusX As Single 'Vaakanopeus
Private NopeusY As Single 'Pystynopeus
Private PaikkaX As Single 'PictureBoxin kokonaislukutarkkuus ei riitä sujuvaan liikkumiseen joten,
Private PaikkaY As Single 'se pitää tallentaa omaan muuttujaan

Const Kitka As Single = 0.997 '1=ei kitkaa
Const Teho As Single = 0.002 '0=ei tehoa

Private Sub Form_Activate()
  Dim Aika As Long
  Dim VanhaAika As Long

  Do
    VanhaAika = Aika
    Aika = GetTickCount 'Merkitään kulunut aika jolloin osataan siirtää objektia oikea matka

    If Nappaimet(38) = True Then NopeusY = NopeusY + (Teho * (Aika - VanhaAika)) 'Kiihdytys
    If Nappaimet(40) = True Then NopeusY = NopeusY - (Teho * (Aika - VanhaAika))
    If Nappaimet(37) = True Then NopeusX = NopeusX + (Teho * (Aika - VanhaAika))
    If Nappaimet(39) = True Then NopeusX = NopeusX - (Teho * (Aika - VanhaAika))

    NopeusY = NopeusY * (Kitka ^ (Aika - VanhaAika)) 'Kitka
    NopeusX = NopeusX * (Kitka ^ (Aika - VanhaAika))

    PaikkaX = PaikkaX - (NopeusX * (Aika - VanhaAika))
    PaikkaY = PaikkaY - (NopeusY * (Aika - VanhaAika))

    Picture1.Left = PaikkaX
    Picture1.Top = PaikkaY

    'Tämä on vain debuggia varten, näytetään nopeudet ikkunan otsikkossa
    Form1.Caption = "X = " & Format(NopeusX, "###0.00") & " Y = " & Format(NopeusY, "###0.00")

    DoEvents 'Päivitetään ruutu ja tehdään työt jotta ohjelma ei jumi
    'Sleep (50) 'Tällä voi simuloida hidasta konetta
  Loop
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  Nappaimet(KeyCode) = True 'Merkitään näppäin pohjaan
End Sub

Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
  Nappaimet(KeyCode) = False 'Merkitään näppäin vapaaksi
End Sub

Private Sub Form_Load()
  Form1.KeyPreview = True
  Form1.ScaleMode = 3
  Form1.WindowState = 2
  Picture1.Width = 50
  Picture1.Height = 50
  Picture1.Appearance = 0
  PaikkaX = 100
  PaikkaY = 100
End Sub

Private Sub Form_Unload(Cancel As Integer)
  End 'Koska ollaan loputtomassa luupissa pitää se katkaista
End Sub

.NET

Public Class Form1
    Inherits System.Windows.Forms.Form

    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'Nukkuu eli idlaa

    Private Picture1 As New PictureBox
    Private Nappaimet(255) As Boolean 'Sisältää kaikkien näppäimistön näppäinten tilan
    Private NopeusX As Single 'Vaakanopeus
    Private NopeusY As Single 'Pystynopeus
    Private PaikkaX As Single 'PictureBoxin kokonaislukutarkkuus ei riitä sujuvaan liikkumiseen joten,
    Private PaikkaY As Single 'se pitää tallentaa omaan muuttujaan

    Const Kitka As Single = 0.997 '1=ei kitkaa
    Const Teho As Single = 0.002 '0=ei tehoa

'Poistin #Region " Windows Form Designer generated code "
'koska ikkunaan ei tarvitse tehdä mitään

    Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
        Nappaimet(e.KeyCode) = True 'Merkitään näppäin pohjaan
        Form1.ActiveForm.Text = CStr(e.KeyCode)
    End Sub

    Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyUp
        Nappaimet(e.KeyCode) = False 'Merkitään näppäin vapaaksi
    End Sub

    Private Sub Form1_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated
        Dim Aika As Long
        Dim VanhaAika As Long

        Me.Controls.Add(Picture1) 'Lisätään pictureboxi lennosta
        Form1.ActiveForm.WindowState = FormWindowState.Maximized

        Do
            VanhaAika = Aika
            Aika = CLng(Now.Ticks / 10000) 'Merkitään kulunut aika jolloin osataan siirtää objektia oikea matka

            If Nappaimet(38) = True Then NopeusY = NopeusY + (Teho * (Aika - VanhaAika)) 'Kiihdytys
            If Nappaimet(40) = True Then NopeusY = NopeusY - (Teho * (Aika - VanhaAika))
            If Nappaimet(37) = True Then NopeusX = NopeusX + (Teho * (Aika - VanhaAika))
            If Nappaimet(39) = True Then NopeusX = NopeusX - (Teho * (Aika - VanhaAika))

            NopeusY = CSng(NopeusY * (Kitka ^ (Aika - VanhaAika))) 'Kitka
            NopeusX = CSng(NopeusX * (Kitka ^ (Aika - VanhaAika)))

            PaikkaX = PaikkaX - (NopeusX * (Aika - VanhaAika))
            PaikkaY = PaikkaY - (NopeusY * (Aika - VanhaAika))

            Picture1.Left = CInt(PaikkaX)
            Picture1.Top = CInt(PaikkaY)

            'Tämä on vain debuggia varten, näytetään nopeudet ikkunan otsikkossa
            Form1.ActiveForm.Text = "X = " & Format(NopeusX, "###0.00") & " Y = " & Format(NopeusY, "###0.00")

            Application.DoEvents() 'Päivitetään ruutu ja tehdään työt jotta ohjelma ei jumi
            'Sleep(50)  'Tällä voi simuloida hidasta konetta
        Loop
    End Sub

    Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
        End 'Koska ollaan loputtomassa luupissa pitää se katkaista
    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Picture1.Height = 50
        Picture1.Width = 50
        Picture1.BorderStyle = BorderStyle.FixedSingle
        PaikkaX = 100
        PaikkaY = 100
    End Sub
End Class

Antti Laaksonen [29.05.2004 23:50:55]

#

Todella hyvä esimerkki, noin pelin saa toimimaan varmasti samalla nopeudella eri koneilla.

sooda [29.05.2004 23:52:50]

#

Ekstriim hyödyllinen pohja.

Blaze [30.05.2004 00:44:38]

#

^ Täysin samaa mieltä.

setä [30.05.2004 09:07:27]

#

Hienosti pelaa. Prossun teho näyttää 100% mutta kuitenkaan ei vaikuta muiden ohjelmien nopeuteen tiettyyn rajaan saakka. Pyöritin VB5:llä, joka ei hyväksynyt tuota Appearance-asetusta.

Bill Keltanen [30.05.2004 09:22:37]

#

Uuh, hieno on

tuomas [30.05.2004 10:24:28]

#

Ihan hienohan tuo on.
Tuohon pictureboxin voisi lisätä vielä jonkin kuvan joka
blittaisiin läpinäkyväksi.
Tai senhän voi oikeastaan tehdä itse jos haluaa...

hunajavohveli [30.05.2004 10:58:29]

#

Hyvän näköinen pohja. Varmasti hyötyä niille, jotka suunnittelevat ensimmäisiä pelimoottoreitaan, ja miksei myös muillekin.

Meitzi [30.05.2004 11:13:04]

#

Nooh eka vinkki ja ainakin keskustelualueella seikkailun pohjalta tuntui, että tämä voisi olla hyödyllinen jollekkin.

Mietin kirjoittaessa että jos tuohon tekisi vaikka hieman autopelin fysiikkä, eli kaasu, jarru ja ratti, mutta sitten koodista olisi voinut tulla äkkiäsenverran isompi että itse pääasia hämärtyy.

setä: juu 100% se vie niinkuin pelin pitääkin, jos pistät vaikka sleep(1) niin rauhottuu heti, eikä se vielä tuossa kovin paljoa näy tökkimisenä.

rndprogy [30.05.2004 11:40:15]

#

Tuotahan voi käyttää jossain Slicks'n'slide tyyppisessä pelissä.

PeQ [30.05.2004 16:16:04]

#

smuutti

ez [30.05.2004 17:49:07]

#

En käyttäisi pelissä kyllä pictureboxia, vaan tekisin oman luokan... Voi itse koodata hyvän kaksoispuskuroinnin yms.. Aika kehno peli koodiksi...

makeuu [30.05.2004 18:14:44]

#

Tohon ku vielä tekis sen blittauksen josta tuomas puhui ja rotaten niin siinä olisi autopeli :D

Meitzi [30.05.2004 21:20:49]

#

lainaus:

En käyttäisi pelissä kyllä pictureboxia, vaan tekisin oman luokan...

Esim DirectX on hyvä grafiikan piirtämiseen, mutta tämä vinkki kun ei liity grafiikkaan sitten yhtään.

tuomas [31.05.2004 08:26:23]

#

Itse yritin tehdä tuohon blittausta mutta rupesi vain välkkymään..

efteri [30.09.2004 16:14:48]

#

Kiitos Tälläistä olen tarvinnut


Edit: Mitenköhän tuhon tehätäisii niin että jos siinä olisi nyt vaikka ukon kuva ladattuna että kun kääntyy oikealle tulee se ukon kuva joka näyttää että se menee oikalle elikkä kuvia olisi yhteensä 32 niin tulisi hyvä ympyrä |siis voisitko tehdä yuohon vielä sellaisen lisäyksen jos se on mahdollista?

Lumi-ukkeli [02.05.2005 21:23:07]

#

lainaus:

Kiitos Tälläistä olen tarvinnut


Edit: Mitenköhän tuhon tehätäisii niin että jos siinä olisi nyt vaikka ukon kuva ladattuna että kun kääntyy oikealle tulee se ukon kuva joka näyttää että se menee oikalle elikkä kuvia olisi yhteensä 32 niin tulisi hyvä ympyrä |siis voisitko tehdä yuohon vielä sellaisen lisäyksen jos se on mahdollista?

Onnistuu ihan portaattomasti DX:llä, mutta teoriassa tuo 32-asentoinen tyyppi vaikkapa BitBlt:llä:

1.Piirrä kaikki kuvat samankokoisina, ja piirrä ne yhteen kuvatiedostoon vierekkäin.

2.Tee joku muuttuja, joka kertoo ukon asennon.

3.Kun piirrät ukon kuvaa, blittaa ukko oikeasta kohdasta kuvatiedostosta riippuen sen asennosta.


Sivun alkuun

Vastaus

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

Tietoa sivustosta