[ARHIIV] mängumeistrid
Pole sisse logitud. [Logi sisse ]
Mine lehekülje algusesse
Prinditav versioon | Telli teema e-mailile | Lisa lemmikutesse  
Teooria: Parem takistuse kontroll
InCreator
baksjor!
Avatar

Liitunud: 18.12.2005
Postitusi: 1230
[EEMAL]




postitati 23.1.2010 23:45 Tsiteeri
Teooria: Parem takistuse kontroll



[tldr] Avastasin paar päeva tagasi Game Maker 8-l koletu bugi, mis umbes 1-3% juhtudest teeb seda, et position_meeting(x,y,obj) funktsioon eksib. Jah, miskipärast lihtsalt ei tööta mingil x-momendil. Kuna yoyogames on suht ennasttäis punt, kelle foorumis isegi puuduvad muidu nii tavalised bug report ja feature request alafoorumid, polnud lootustki niipea seda jutti saada - hakkasin otsima uusi võimalusi sama asja erinevalt teha.[/tldr]

Nii.
Tavaliselt otsitakse platvormikates (ja ka muudes mängudes) tegelase alt maapinda (hüppamise ja kukkumise jaoks) ja eest-tagant seinu järgmiste funktsioonidega:

position_meeting(x,y,sein)
place_free(x,y)

Ja hüppamise täpsust ja seina kinni jäämist koordineerivad tavaliselt

move_outside_solid(suund,kaugus)
move_contact(suund,kaugus)

Need 4 funktsiooni on peamine raskus näiteks platvormika tegemisel -- nad on ebatäpsed ja ebamugavad kasutada.

Mõistlik on kontrollida pikslit tegelase jalge all, eks?

if (position_meeting(x,y+1,sein))
{
}

http://www.indrek.org/i/plat1.png

Kollane piksel näitab siis, mida kontrollitakse. Tavaliselt see ka töötab.

Aga mis juhtub, kui tegelane parajast kukub? Ütleme, hästi kiiresti, ja läbib stepis rohkem piksleid kui on maapinna tüki suurus?

http://www.indrek.org/i/plat2.png

Tegelane kukub põrandast läbi, sest kontrollitav piksel ei satu iial maapinnale! Ei ole oluline, kas liidad vspeed kontrollitavale punktile või ei, samamoodi võib läbi kukkuda.

Olgu, aga ütleme, et toimis. Tegelase kontrollpunkt tõepoolest tabas maapinda. Nüüd tuleks tegelase kukkumine lõpetada! Juhtus aga nii, et tegelane ei olnud täpselt 1 piksel kõrgemal maapinnast, vaid selle sees.

Vaatasin läbi 11 või 12 platvormi näidet, mis netis ringi liiguvad. Peaaegu kõik lahendavad "probleemi" käsuga "move_outside_solid" (kui tegelane on maa sees) või "move_contact_solid" (kui tegelane tabab maapinda järgmine step).

http://www.indrek.org/i/plat3.png

move_contact_solid on natuke parem, aga see ei luba tegelasel tulla altpoolt.

move_outside_solid lubab. Aga kui tegelane tuleb altpoolt?

http://www.indrek.org/i/plat4.png

Näiteks hüppab seina sisse. kohe, kui kollane piksel tuvastab maapinna, viskab "move_outside_solid" tegelase põrandast välja. See veidrus on mängus VÄGA märgatav, ja ei näe üldse hea välja.

järeldus: Punktipõhine kontroll on ebakindel, ei ole universaalne ja ei ole väga hea.

minu meetod

collision_line !
Tekitame tegelase alla mõttelise joone, mis ulatub natukene allapoole ja kui tegelane peaks kukkuma, on kukkumise kiiruse jagu veel pikem.

http://www.indrek.org/i/plat5.png
Enam me ei kontrolli mitte ühte punkti, vaid tervet pikka joont.

Kui nüüd tegelane peaks kukkuma küllalt kiiresti, et oleks põranda "puhtalt" läbimise oht, ei läheks see läbi, sest me kontrollime iga pikslit tegelase kukkumise teekonnal:

http://www.indrek.org/i/plat6.png

Kuidas?

Tee tegelasele mingi muutuja, märkimaks kontrolljoone pikkust:

create:
joon = 5;

Säti see kiirusele vastavaks:

step:
joon = 5 + vspeed;

Kontrolli!
step:

if (collision_line(x,y+1,x,y+joon,sein))
{
// peatumise kood, näiteks
var aa;
aa = -1;
aa = objecti_position(x,y+joon,sein,true,false)
if (aa != -1)
{
y = (aa).y-32;
vspeed = 0;
}
}
else
{
//kukkumise kood, näiteks
if (vspeed < 10) vspeed +.5;
}

Pidurdamisel tuleb tegelane maaga põkkumisel panna lihtsalt maatüki peale:

peatumise kood:
y = (instance_position(x,y+joon,sein)).y - 1;

Töötab imehästi ka kontrollimaks seinu tegelase ees ja taga, takistusi pea kohal ja nii edasi. Muidugi tuleb natuke täpsemaks muuta, vastavalt mängule.

Ja altpoolt lähenemiseks saab sellist kontrolli palju lihtsamalt täpsemaks muuta -- näiteks kasutada väga lühikest joont, et teleportimine tüki seest tüki peale oleks vähem märgatav.

Mõtteid?

A window is technically a wallhack.
Emo2: InCreator
Vaata kasutaja profiili Otsi kasutaja postitusi Saada privaatsõnum
jnt
Veebiguru
Avatar

Liitunud: 3.2.2005
Postitusi: 731
[EEMAL]




postitati 24.1.2010 11:42 Tsiteeri


Väga õige mõttekäik ja mõni aeg tagasi isegi tulin selle peale, kui mõtsin, et võiks mõne platvormika teha... aga sinna see ka jäi. :D
GigAHerZ Web - http://jnt.pri.ee/
Banner Exchange - http://be.jnt.pri.ee/
Mission Possible - http://web.zone.ee/mispos/
Black Nova Traders - http://bnt.jnt.pri.ee/
Aktsioon I: jnt
Vaata kasutaja profiili Külasta kasutaja kodulehte Otsi kasutaja postitusi Saada privaatsõnum
valter
1


Liitunud: 19.1.2005
Postitusi: 1553
[EEMAL]




postitati 7.4.2010 17:49 Tsiteeri


Jah, huvitav.
Kuigi ma olen alati tavaliselt nii teinud, et tegelasel on kukkumiskiiruselimiit peal. See limiit on siis nii suur kui kõige väiksema bloki suurus. päris 1x1 ei tee, mingi 32x32 siis ütleme.

aga collision_line on hea lahendus, jah.

http://www.dmgamez.pri.ee/GRONGO1/uss_walk.gif
Ralli I: dm11Veresaun III: dm11<br>Emo1: icedude, valter8bit I: võistlus kestabAktsioon III (2009): -<br>Aasta mäng 2009: Pilvemees, valter<br>Vabateema II: valter
Vaata kasutaja profiili Külasta kasutaja kodulehte Otsi kasutaja postitusi Saada privaatsõnum

Hetkel loevad seda teemat:
Mitte ühtegi - 1 külaline

Mine lehekülje lõppu





Foorumi algbaas põhineb XMB mootoril, modifitseeritud Valter Pundi poolt
Kodulehekülg on tehtud Valter Pundi poolt vpundi ät gmail punkt komm