Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: QB: Ajastuksesta, törmäyksistä ja muusta pienestä

Sivun loppuun

Claw [31.03.2006 15:16:37]

#

Ajattelin tässä tehdä pienen pelin, luulin että tekisin tämän täysin ilman muiden apuja.

Pelissä liikutellaan palloa "sokkelossa". Karttaeditori valmiina ja itse pelin kehittäminen vois alkaa, mutta tuli pari pulmaa:

Mitenkäs onnistuis saada pelin nopeuden olemaan fps-riippumaton?

Eka ajattelin että seen jonkun delay subin, joka ajetaan about 30-60 kertaa /s, mutta sitten päädyin sihen tulokseen ettei sekään ole tarpeeksi tarkka.

Vähän matematiikasta:

Minulla on piste x ja piste y, joiden välille on piirretty viiva. Nyt pitäis sit saada selville että millon objekti liikkuessaan leikkaa tuon viivan.

Sitten, pitäis saada laskettua viivan kulma myös, jotain olen katellut koodivinkeistä, muta kunnollista ja helppoa tapaa ei oikein ole löytynyt.


Varmaan koulussa jotain allu noista, mutta ei nyt ole parinpäivän aikana tullut mitään kunnollista metodia mieleen millä noita sais toteutettua.

Kieli on QB, mutta sillä ei sinänsä väliä, koska en nyt heti valmista koodia halua. :)

Metabolix [01.04.2006 16:59:00]

#

Ajastussysteemi toimii sillä, että katsot framen alussa, paljonko aikaa on kulunut, ja suhteutat liikkeet siihen. Tällöin et voi pitäytyä Integer-tyypissä, vaan tarvitset desimaalilukuja, mutta se ei ole ongelma. Ideana kuitenkin, että liikut (aika*nopeus) yksikköä joka framella.

Pisteen etäisyys suorasta selviää helposti muutamalla matemaattisella kaavalla, jotka hakukoneiden avulla löytyvät kyseisillä sanoilla.
Kahden pisteen (x0, y0) ja (x1, y1) kautta kulkevan suoran yhtälö saadaan seuraavasta lausekkeesta:
y - y0 = (y1 - y0)/(x1 - x0) * (x - x0)
Jos x0 = x1, tuota ei tietenkään ole määritelty, vaan yhtälöksi tulee x = x0.

Tämä yhtälö pitää pyöräyttää normaalimuotoon, eli toiselle puolelle pitää saada nolla:
ax + by + c = 0

Pisteen etäisyys tästä suorasta selviää sijoittamalla tuonne pisteen koordinaatit x:n ja y:n paikalle ja jakamalla lauseke arvolla neliöjuuri(a^2 + b^2). Yleensä tämä jako kannattaa tehdä jo aiemmin (muuttujille a, b ja c), jotta säästyy toistamasta sitä useampaan kertaan.

En tiedä, mitä viivan kulmaa tarkoitat, mutta trigonometristen funktioiden käänteisfunktiot ovat varsin suositeltavia.

Jäikö jotain vielä epäselväksi?

Lumi-ukkeli [01.04.2006 19:13:57]

#

Tuo ajastushomma tulee ihan fysiikan kaavoilla tähän tyyliin:


(Kiihtyvyys = Voima / Massa)
Nopeus = Nopeus + Kiihtyvyys * Ajanmuutos
Sijainti = Sijainti + Nopeus * Ajanmuutos

Claw [01.04.2006 19:27:24]

#

Tänään tuli vähän leikittyä, ja juurikin tuo pythagoran lause auttaa tuossa pisteiden välimatkassa.

Kiitos myös tuosta ajastuksesta, ja kaikesta muusta. Pitää alkaa soveltamaan tässä lähiaikoina kunhan itsekkin ymmärrän täysin nuo. :P

Metabolix [01.04.2006 19:39:21]

#

Ongelmana tuossa muuttuvan kiihtyvyyden kanssa on se, että tuossa tulee laskettua sijainti väärin, kuin olisi koko ajan liikuttu lopullisella nopeudella. Pitäisi siis laskea keskinopeus tuolle ajalle. Jos kiihtyvyyskin ehtii välissä muuttua, pitää nopeutta muuttaa keskimääräisen kiihtyvyyden mukaan. Jos sattuu, että jokin mainituista muuttujista ei muutu lineaarisesti, sen keskiarvon määrittäminen käy jo melkoisen kiinnostavaksi puuhaksi.

Eli toisin sanoen, opiskelemaan matematiikkaa ja fysiikkaa, niillä nuo selviävät :) Todennäköisesti suurpiirteinen integrointi on paras menetelmä.

Yleensä (ainakin muissa kielissä) ajan saa helpoiten esimerkiksi millisekunteina, jolloin tuollaiset voi laittaa silmukkaan. Nuo eivät kuitenkaan ole niitä laskutoimituksia, jotka nykyään koneen jumittaisivat. Hyvä tulos saadaan siis raa'asti tähän malliin:

FOR a = 1 TO Kulunut_Aika
  Kiihtyvyys = Kiihtyvyys + Kiihtyvyyden_Muutos
  Nopeus = Nopeus + Kiihtyvyys
  Sijainti.X = Sijainti.X + Suunta.X * Nopeus
  Sijainti.Y = Sijainti.Y + Suunta.Y * Nopeus
NEXT a

Isoissa ja mutkikkaissa peleissä sitten voi jo olla merkittäviä eroja tuon ja hienompien tapojen välillä, varsinkin siinä vaiheessa, kun framen kesto alkaa nousta sinne 40 millisekuntin tietämille.

Grey [01.04.2006 19:52:58]

#

Kokeile tickiä. Koodi esimerkki löytyy täältä päin. Melko varma ja tarkka tuo. Tosin, jos ohjelmaa vaihtaa kesken suorituksen pois, voi tulla kivaa vilinää ruudulle, mutta sitä varten kannattaakin jokin varmistus tehdä..

-Grey-

Claw [01.04.2006 20:25:38]

#

Ilmeisesti pitää kääntää freeBASICille, jotta saan käytettyä äytön Hz taajuutta viiveen aikaansaamiseksi. :)

tai alkaa käyttämään WAIT &H3DA,8 systeemiä synkkaamiseen, ainut vaan että toisilla voi olla hertsit siellä +100, ja toisilla 60. :D

Metabolix [02.04.2006 16:10:54]

#

Suosittelen edelleenkin, ettet ala millään viiveillä leikkiä, koska se ei kuitenkaan tule toimimaan kunnolla. Enintään jos fps on päälle muutaman sadan, voi hieman viivettä lisätä, mutta aina pitää huomioida, että hitaammilla koneilla jokainen viive tekee pelistä entistä pätkivämmän. Ajanottofunktio käyttöön ja suhteuttamaan liikkeitä aikaan, sanon minä. Vaikka QB:n timer nyt näyttikin kulkevan noiden tickien tahdissa eli suunnilleen 0,05s välein, niin se on silti sekunteina ja sitä voi käyttää aivan hyvin odottamatta hetkeäkään.

Claw [02.04.2006 21:40:46]

#

Niinhän se kyllä on. :)

Harjoitushan tämän projektin pääidea on, joten taidan sittenkin vaan tehdä sen tuolla sinun edellämainitsemalla tavalla. :)

Grey [02.04.2006 22:10:34]

#

Väsäsin tässä piruuttani tickiin perustuvan ajastuksen, kun kerran otin moisen puheeksi :-P

DIM Tiku AS INTEGER, Taku AS INTEGER, X AS INTEGER, Y AS INTEGER
DIM I AS INTEGER, Z AS INTEGER, C AS INTEGER
CLS
RANDOMIZE TIMER
DO
 W$ = INKEY$
 IF Tiku <> Taku OR Tiku = 0 THEN
  Taku = Tiku
   DEF SEG = 0: Taku = PEEK(&H46C): DEF SEG
   FOR I = 1 TO 60
   X = INT(RND * 80 + 1): Y = INT(RND * 25 + 1): Z = INT(RND * 223 + 32)
   C = INT(RND * 16): COLOR C
   LOCATE Y, X: PRINT CHR$(Z);
   NEXT
  END IF
 IF W$ = CHR$(27) THEN EXIT DO
LOOP

Pikainen kyhäelmä, eli saa korjata. Pysähtyminen tosin näköjään johtuu enemmänkin Windowsista itsestään. Vaan eiköhän tuossa ole perusajatus aika toimiva..

-Grey-


Sivun alkuun

Vastaus

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

Tietoa sivustosta