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 ClassTodella hyvä esimerkki, noin pelin saa toimimaan varmasti samalla nopeudella eri koneilla.
Ekstriim hyödyllinen pohja.
^ Täysin samaa mieltä.
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.
Uuh, hieno on
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...
Hyvän näköinen pohja. Varmasti hyötyä niille, jotka suunnittelevat ensimmäisiä pelimoottoreitaan, ja miksei myös muillekin.
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ä.
Tuotahan voi käyttää jossain Slicks'n'slide tyyppisessä pelissä.
smuutti
En käyttäisi pelissä kyllä pictureboxia, vaan tekisin oman luokan... Voi itse koodata hyvän kaksoispuskuroinnin yms.. Aika kehno peli koodiksi...
Tohon ku vielä tekis sen blittauksen josta tuomas puhui ja rotaten niin siinä olisi autopeli :D
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.
Itse yritin tehdä tuohon blittausta mutta rupesi vain välkkymään..
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?
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.
Aihe on jo aika vanha, joten et voi enää vastata siihen.