Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Törmäyksen tunnistus

Sivun loppuun

kayttaja-3842 [03.05.2007 15:00:56]

#

Joo eli olen tehnyt tässä omaap eliä ja tein sille täysin oman kartta formaatin. Eli siis mappi formaatti käyttää tilesettejä. Nytten olen tekemässä tormaystunnistus pintaa. Eli jos palikan tyyppi on 2 nii sitten siihen törmätään. Noh olen saanut tehtyä jonkinlaisen törmäyksen tunnistuksen, mutta aina on bugi ilmentynyt. Joskus tormäyksen tunnistus pettää ja joskus se taas tulee esille kun sitä ei tarvita. Eli siis tarkoitus olisi, saada 32x32 palikalle täydellinen törmäyksen tunnistus. Eli jos pelaaja osuu niin se ei mene läpi vaan törmää. Itse sain tehtyä tämän jotenkin, mutta tosiaanki välillä ukkon vauhti oli niin suuri, ettei ukko keretty pysäyttää ja se liukui kappaleen sisälle. Miten tämä tulisi toteuttää niin, että pelaaja ei joutuisi kappaleen sisälle?

Lahha [03.05.2007 15:23:34]

#

Eikös tuo nyt ole aika simppeliä. Tarkistetaan ennen ukon siirtämistä että onko ukkopalikan minkään kulman uusi siirron jälkeinen sijainti seinäpalikan sisällä ja jos menee niin siiretään ukko vain sen verran ettei se mene seinänä sisään.
Minulla on vähän saman tyylinen projekti menossa.

kayttaja-3842 [03.05.2007 15:31:36]

#

joo, itsekkin luuni että tuo on todella simppeli, mutta kun tuossa pitää ottaa niin paljon asioita huomioon , vetovoima jne jne. Eli ei mee tolla pelkästään.. Toki se toimi, mutta bugeja ilmeni.

Edit1: Tai oikeestaan tein niin, että jos painetaan esim vasemmalle, jos ukko törmää seinään, niin sitten liikuta = false ja ukkoa ei sitten liikuteta. ja tänä bugasi minulla, koska vauhti kertaantuu aina sitä lujemmaksi mitä korkeemmalta ukkoa putoaa, koska vetovoima kerrotaan sen painolla. Esim jos ukko on ilmassa olevan palikan päällä ja hyppää siitä maahan, nii sitten vauhti on niin luja, että se kerkee liikkua palikan seinän yli. Sitten pitää muistaa myös, että vetovoima vaikuttaa koko ajan

Lahha [03.05.2007 15:41:44]

#

Sittenhän pitää vain tuo osuman tarkastinen tehdä aina 32 pikselin välein.

Elikkäs. Jos liikuttava määrä on enemmän kuin 32, tarkastetaan että voiko ukko liikkua 32 pikseliä. Jos voi liikkua, niin liikutaan ja taas tarkastetaan kunnes on liikutte halutta määrä. Jos ei voi liikkua koko 32 pikseliä liikutaan vain sen verran kuin voi ja jäädään siihe.

kayttaja-3842 [03.05.2007 18:42:44]

#

hmm, tuota meinasitko, että laitan for silmukaan 32 eli jos for(i = 0; i < 32; i++) ja mitä sitten?

Edit itse olen tehnyt tähän mennessä sen x y sijaineilla. Eli jos esim pelaaja.x+leveys > box.x sitten esim törmätään.

neau33 [03.05.2007 20:03:43]

#

Höpö höpö Nail Eye!

Screenillä se ukko ei siirry yhtään mihinkään positioon, jos sitä ei siirretä eli piirretä...

// määrittele esim. public int max = 500 - ukko.width;

//...

  int vastukset = (tuulet + sun_muut_kertoimet);

  if((kuljettu + (32 - vastukset)) < max)
  for (i=0; i < (32 - vastukset); i++){
  ukko.x += i;
 }

  else

  for(i=0; i < (max -(kuljettu  - vastukset)); i++){
  ukko.x += i;
 }

  kuljettu += i;

//...

kayttaja-3842 [03.05.2007 20:36:24]

#

ööh, eli tuossahan ukko pystyy vain liikkumaan hetken eteenpäin, kunnes törmää seinään, mutta jos eessä onkin palikka ja sen yli hypätään tai ollaan ylempänä, sitten kuljettu muuttuja voi olla suurempi kuin tuo max.

Edit1: Olet oikeassa että pelaajan sijaintia ei muuteta, mutta mapin sijaintia kylläkin. Eli kun liikutetaan kaikki palikoita, näin ollen palikoitten sijainti muuttuu. Eli minulla on taulukko mikä sisältää jokaisen kartassa olevan kuution x ja y:N eli eikös kannattaisi mieluummin käyttää hyväksi x ja y koordinaatteja?

neau33 [03.05.2007 20:58:19]

#

Heippa taas Nail Eye!

Ehdottomasti myös z-koordinaatti käyttöön...

kayttaja-3842 [03.05.2007 21:01:32]

#

Hmm, Z? mitä teen z Koordinaatilla 2D grafiikassa? Mut taisin keksiä yhden tavan kokeilen sitä jos ei toimi, nii kysyn taas apua.. :D

Metabolix [03.05.2007 21:21:33]

#

Ensin vaikkapa lasketaan nopeuden perusteella, paljonko pitäisi liikkua, sitten liikutaan tähän malliin:

while (koko_liikuttava_matka > 0) {
    // Jos pitäisi liikkua yli ruudun verran, liikutaan vain yksi ruutu, muuten sen oikean verran. Voi toki pienentää vaikka pienimmän mahdollisen objektin kokoiseksi (tai yhtä alle).
    if (koko_liikuttava_matka > 32) {
        kerralla_liikuttava_matka = 32;
    } else {
        kerralla_liikuttava_matka = koko_liikuttava_matka;
    }
    // Vähennetään jäljellä olevasta matkasta tämä nyt liikuttava
    koko_liikuttava_matka -= kerralla_liikuttava_matka;

    // Ja sitten voit ihan normaalisti tarkistaa törmäyksen (liikutaan siis kerralla_liikuttava_matka), siis aivan kuten ennenkin.
}

kayttaja-3842 [03.05.2007 21:43:14]

#

Joo, eli tässä on kuva mapista johon pitäisi saada törmäuyksen tunnistus.

http://img77.imageshack.us/img77/7994/mappifn7.jpg

Metabolix [03.05.2007 21:45:54]

#

Joo, eli tee niin, kuin neuvottiin.

kayttaja-3842 [03.05.2007 21:47:46]

#

Tota sovelsin näin, en tie onko oikein :P.

if(nappi[SDLK_RIGHT]){
t_map[id].tormaa =  t_map[id].x - (pelaaja.x + abkuva->w + 32);

while(t_map[id].tormaa > 0){

if(t_map[id].tormaa > 32){
 kerralla_l_m = 32;
}else{
 t_map[id].tormaa = kerralla_l_m;
}

t_map[id].tormaa -= kerralla_l_m;

if(pelaaja.x < t_map[id].x){
if(pelaaja.x+abkuva->w >= t_map[id].x){
}else{
//Liikuta oikealle
liikuta_pe(false);
}
}

}




}

Metabolix [03.05.2007 22:00:16]

#

Katsopa uudestaan, missä kohti oli se kokonaismäärä ja missä se kerralla liikuttava. Koodissasi on äärimmäisen epälooginen nimeäminen muuttujilla (mikä ihmeen "törmää", liikemäärähän se on), mutta kaiketi siis toisella rivillä pitäisi olla se uusi muuttuja kokonaisliikkeelle, ja tuo joku.tormaa olisi se kerralla liikuttava.

kayttaja-3842 [03.05.2007 22:04:01]

#

Meinaatko, että pelaaja liikuu joka napin painauksen jälkeen 32px?

Lahha [03.05.2007 22:14:32]

#

Ei, kun pelaaja liikkuu joka napin painalluksen jälkeen niin paljon kuin sen kuuluukin liikkua, mutta tämä liikkuminen tehdään vain 32px:n pätkissä.

kayttaja-3842 [03.05.2007 22:32:14]

#

joo tuota tietoa hain. No entäpä tuo, kun while (koko_liikuttava_matka > 0) { jos ukkoa ei liikutetakkaan 32 pixeliä, vaan ukko päättääki puolessa välissää vaihtaa suuntaa, niin sitten ohjelmahan jää ikuiseen loopiin? Koska koko_liikuttava_matka ei koskaan saavuta 0.

Lahha [03.05.2007 22:44:26]

#

Silloin sinne täytyy laittaa jotain joka pistää sen nollaksi. Tai sitten kiellät ukkoa vaihtamasta suuntaa.

Tuo sinun systeemisi on hieman oudon näköinen. Mistä tuo liikuta_pe() saa edes tietää että kuinka paljon liikutetaan? Onko kerralla_l_m globaali ?

kayttaja-3842 [03.05.2007 23:02:34]

#

Tuota nytten koodi on tämän näköinen

int koko_liikuttava_matka;
int kerralla_liikuttava_matka;


koko_liikuttava_matka = t_map[id].x - (pelaaja.x + abkuva->w);

if(nappi[SDLK_RIGHT]){
while (koko_liikuttava_matka > 0) {

if (koko_liikuttava_matka > 32) {
        kerralla_liikuttava_matka = 32;
    } else {
        kerralla_liikuttava_matka = koko_liikuttava_matka;
    }

    koko_liikuttava_matka -= kerralla_liikuttava_matka;

    liikuta_pe(false,koko_liikuttava_matka);

}



}

mutta tuossahan on ainakin yksi risti riita, meinaan kun kuutio taulukkoa käydään läpi, niin jos vaikka 230 poksi "sanoo", että koko_liikuttava_matka on 0, niin sittenhän seuraava eli 231 "sanoo", että koko_liikuttava_mata == 32 ja pelaaajaa voidaan taas liikuttaa, ja sittenhän se menee tuon 230 laation läpi?

Lahha [03.05.2007 23:10:16]

#

Miksi siinä edes käydään koko kenttä läpi?

Ootapa hetki niin viimeisteleen vielä koodiani jonka pitäisi edes näyttää sellaiselta että se tarkistelee törmäyksiä.

Edit:
Tuolta pitäisi näyttää törmäyksiä tarkistava koodi:
Tuossa on varmaa jonkin verran virheitä kun en voi testata.

int koko_liike_x, koko_liike_y, liike;

if(nappi[SDLK_LEFT]) koko_liike_x=-1*ukon_kävely_nopeus;
else if(nappi[SDLK_LEFT]) koko_liike_x=ukon_kävely_nopeus;

//TÄSTÄ PUUTTUU TIPPUMISEN ALKUUN LÄHTÖ JA VAUHDIN KASVU!

//korkeus suuntainen tarkistus
while(koko_liike_y != 0)
{

	if(koko_liike_y > 32 )// ylös
		liike_x=32;
	else if(koko_liike_y < -32) // alas
		liike_y=-32;
	else
		liike=koko_liike_y;

	koko_liike_y-=liike;

	if(pelaaja.y+liike+32 > t_map[ruutu_joka_on_ukon_alla].y)//ukko menee ainakin osiittain alla oleviin ruutuihin
		if(/*ruutu jonka alueella on ukon vasen alakulma (pelaaja.x,pelaaja.y+liike+32)*/ == /*seinä*/ || /*ruutu jonka alueella on oikea alakulma(pelaaja.x+32,pelaaja.y+liika+32)*/ == /*seinä*/)
		{
			liike=t_map[ruutu_joka_on_ukon_alla].y-pelaaja.y+32;
			koko_liike_y=0;
		}

	else ifpelaaja.y+liike < t_map[ruutu_joka_on_ukon_yllä].y+32)//ukko menee ainakin osiittain yllä oleviin ruutuihin
		if(/*ruutu jonka alueella on ukon vasen yläkulma (pelaaja.x,pelaaja.y+liike)*/ == /*seinä*/ || /*ruutu jonka alueella on oikea yläkulma(pelaaja.x+32,pelaaja.y+liike)*/ == /*seinä*/)
		{
			liike=pelaaja.y-t_map[ruutu_joka_on_ukon_yllä].y+32;
			koko_liike_y=0;
		}

	//liikuta pelaaja y akselilla liike muuttujan verran
}

//sivuttais suuntainen tarkistus
while(koko_liike_x != 0)
{
	int liike;

	if(koko_liike_x > 32 )//oikeaan
		liike=32;
	else if(koko_liike_x < -32) // vasempaan
		liike=-32;
	else
		liike=koko_liike_x;

	koko_liike_x-=liike;

	if(pelaaja.x+liike < t_map[ruutu_joka_on_ukon_vasemmalla].x+32)//ukko menee ainakin osiittain vasemmalla oleviin ruutuihin
		if(/*ruutu jonka alueella on ukon vasen yläkulma (pelaaja.x+liike,pelaaja.y)*/ == /*seinä*/ || /*ruutu jonka alueella on vasen alakulma(pelaaja.x+liike,pelaaja.y+32)*/ == /*seinä*/)
		{
			liike=pelaaja.x-t_map[ruutu_joka_on_ukon_vasemmalla].x+32;
			koko_liike_x=0;
		}
	else if(pelaaja.x+liike+32 > t_map[ruutu_joka_on_ukon_oikealla].x)//ukko menee ainakin osiittain oikealla oleviin ruutuihin
		if(/*ruutu jonka alueella on ukon oikea yläkulma (pelaaja.x+liike+32,pelaaja.y)*/ == /*seinä*/ || /*ruutu jonka alueella on oikea alakulma(pelaaja.x+liike+32,pelaaja.y+32)*/ == /*seinä*/)
		{
			liike=t_map[ruutu_joka_on_ukon_oikealla].x-pelaaja.x+32;
			koko_liike_x=0;
		}

	//liikuta pelaaja x akselilla liike muuttujan verran
}

neau33 [04.05.2007 02:44:57]

#

Heippa taas!

Minusta tässäkin kannattaisi nyt ruveta soveltaamaan sen QBASIC (DOS 5.0) mukana tulevan apinajutun oppeja ballistisista kuvioista, jos on kerran tarve alkaa hyppimään esteiden yli ja vielä vastatuuleen...

kayttaja-3842 [04.05.2007 14:04:45]

#

Vastatuuleen? Ei pelissä ole vasta tuulta. :D Vain painovoima!

kayttaja-3842 [04.05.2007 15:49:25]

#

Missä esim, tuo liike_x määritellään?
Tai saadaanko ruutu_joka_on_ukon_alla

t_map[ruutu_joka_on_ukon_alla].y

selvitettyä niin, että esim.

if(pelaaja.y+korkeus > t_map[i].y && pelaaja.x  < t_map[i].x+32 && pelaaja.x+leveys >  t_map[i].x)

kayttaja-3842 [04.05.2007 17:16:44]

#

Itse löysin tälläseen törmäyksen tunnistus funktion googelin avulla.

//Itse funktio
int SDL_CollideBoundingBox(SDL_Surface *sa , int ax , int ay ,
                             SDL_Surface *sb , int bx , int by)
{
	if(bx + sb->w < ax)	return 0;	//just checking if their
	if(bx > ax + sa->w)	return 0;	//bounding boxes even touch

	if(by + sb->h < ay)	return 0;
	if(by > ay + sa->h)	return 0;

	return 1;				//bounding boxes intersect
}



if(SDL_CollideBoundingBox(abkuva,pelaaja.x,pelaaja.y , tset,t_map[id].x,t_map[id].y)){

kimpoaa = true;
vauhti = 0;

}

Tämä toimii nytten niin kuin pitää...


Sivun alkuun

Vastaus

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

Tietoa sivustosta