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
Todella 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.