Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Apua lentelyyn png kuvassa

Sivun loppuun

DumTom [01.03.2012 18:22:07]

#

while(F.GameOn==true)
     {
     //Bar(screen,0,0,800,600,0,0,0);
     short done=Ohjaus();
     if (done==666) {F.GameOn=false;while(done==666) done=Ohjaus();}
     if (k.left==true) s->DecAngle(4);
     if (k.right==true) s->IncAngle(4);

     double ax=s->GetAX(),ay=s->GetAY();
     if (k.up==true)
        {
        static double acc=0;
        acc+=s->GetEngine();
        s->IncXSpeed(al.COS[s->GetAngle()]*acc);
        s->IncYSpeed(al.SIN[s->GetAngle()]*acc);
        if (s->GetYSpeed()>4.99) s->SetYSpeed(5);
        if (s->GetXSpeed()>4.99) s->SetXSpeed(5);

        }
//-g t 2

     ay+=0.5;ay+=s->GetYSpeed();ax+=s->GetXSpeed();
     s->SetAX(ax);
     s->SetAY(ay);

     DrawAlue();

     s->CountKarjet();
     s->Draw();
     SDL_Flip(screen);
     SDL_framerateDelay(&fpsm);
     }
Game=MainMenu;return 0;
return -1;
}
void DrawAlue(void)
{
short dx=(short)s->GetAX(),dy=(short)s->GetAY();
SDL_Rect kuvaalue; // alue, mikä kuvasta piirretään
kuvaalue.x = dx;
kuvaalue.y = dy;
kuvaalue.h = 600; // korkeus
kuvaalue.w = 800;
SDL_Rect nayttoalue; // alue näytöllä, jolle kuva piirretään
nayttoalue.x = 0;
nayttoalue.y = 0;
SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);

}

Koodissa käytetään 6400x6400 png kuvaa ja ihmettelen missä vika on kun alus ei seuraa kuvaa orjallisesti?

Metabolix [01.03.2012 18:24:42]

#

Tämän on pakko olla jokin vitsi. Vai meinaatko oikeasti, että tuosta koodista pitäisi a) tajuta jotain tai b) pystyä löytämään virhe? Ongelmakin jäi hyvin epäselväksi, kun koodin perusteella kuitenkin alusta ohjataan luultavasti näppäimistöllä eikä se edes yritä seurata mitään kuvaa.

DumTom [01.03.2012 19:27:33]

#

void InitGlobals(void);

class GlobalData
{
private:
Sint16 MOUX,MOUY;
short HOTX,HOTY;
short Icon;
bool MOUL,MOUR;
public:
Sint16 GetMouseX(void) {return MOUX+HOTX;}
Sint16 GetMouseY(void) {return MOUY+HOTY;}
bool GetLeftButton(void) {return MOUL;}
bool GetRightButton(void) {return MOUR;}
bool GetBothButtons(void) {if (MOUL==true || MOUR==true) return true;else return false;}
void SetMouseX(Sint16 a) {MOUX=a;}
void SetMouseY(Sint16 a) {MOUY=a;}
void SetLeftButton(bool a) {MOUL=a;}
void SetRightButton(bool a) {MOUR=a;}
void InitMouse(void);
void SetMousePointer(short a) {Icon=a;}
short GetMousePointer(void) {return Icon;}
void SetHotX(short a) {HOTX=a;}
void SetHotY(short a) {HOTY=a;}
};
void GlobalData::InitMouse(void)
{
MOUX=400;MOUY=300;HOTX=0;HOTY=0;
MOUL=false;MOUR=false;
SDL_WarpMouse(MOUX,MOUY);
Icon=0;
}

GlobalData *G=new GlobalData;



struct Algebra
{
float SIN[360],COS[360];
};
Algebra al;
void InitGlobals(void)
{
for (short t=0;t<360;t++)
    {
    float ksuu=deg2rad(t);
    al.COS[t]=cos(ksuu)*1;
    al.SIN[t]=sin(ksuu)*1;

    }


}







class Shuttle
{
private:
short shx[4],shy[4],dhx[2],dhy[2],lfootx,lfooty,rfootx,rfooty;
short angle;
double x,y,ax,ay,engine,xspeed,yspeed;
public:
void SetAngle(short a) {while(a>359) a-=360;while(a<0) a+=360;angle=a;}
short GetAngle(void) {return angle;}
void IncAngle(short a) {angle+=a;while(angle>359) angle-=360;}
void DecAngle(short a) {angle-=a;while(angle<0) angle+=360;}
void SetX(double a) {x=a;}
double GetX(void) {return x;}
void SetY(double a) {y=a;}
double GetY(void) {return y;}
void SetAX(double a) {ax=a;}
double GetAX(void) {return ax;}
void SetAY(double a) {ay=a;}
double GetAY(void) {return ay;}

void SetYSpeed(double a) {yspeed=a;}
double GetYSpeed(void) {return yspeed;}
void SetXSpeed(double a) {xspeed=a;}
double GetXSpeed(void) {return xspeed;}
void IncXSpeed(double a) {xspeed+=a;}
void IncYSpeed(double a) {yspeed+=a;}
void SetEngine(double a) {engine=a;}
double GetEngine(void) {return engine;}

short GetLFootX(void) {return lfootx;}
short GetLFootY(void) {return lfooty;}
short GetRFootX(void) {return rfootx;}
short GetRFootY(void) {return rfooty;}

void CountKarjet();
void Draw();
};
void Shuttle::CountKarjet(void)
{
short ak;
short ker=10;
short kx,ky;
ak=angle-25;if (ak<0) ak+=360;
kx=x+al.COS[ak]*ker;
ky=y+al.SIN[ak]*ker;
dhx[0]=kx;dhy[0]=ky;

ak=angle+25;ker=10;if (ak>359) ak-=360;
kx=x+al.COS[ak]*ker;
ky=y+al.SIN[ak]*ker;
dhx[1]=kx;dhy[1]=ky;


ker=16;ak=angle;if (ak>359) ak-=360;
kx=x+al.COS[ak]*ker;
ky=y+al.SIN[ak]*ker;
shx[0]=kx;shy[0]=ky;

ker=12;ak=ak+135;if (ak>359) ak-=360;
kx=x+al.COS[ak]*ker;
ky=y+al.SIN[ak]*ker;
shx[1]=kx;shy[1]=ky;
rfootx=kx;
rfooty=ky;

ker=2;ak=ak+45;if (ak>359) ak-=360;
kx=x+al.COS[ak]*ker;
ky=y+al.SIN[ak]*ker;
shx[2]=kx;shy[2]=ky;

ker=12;ak=ak+45;if (ak>359) ak-=360;
kx=x+al.COS[ak]*ker;
ky=y+al.SIN[ak]*ker;
shx[3]=kx;shy[3]=ky;
lfootx=kx;
lfooty=ky;

}


void Shuttle::Draw(void)
{
SDL_LockSurface(screen);
Line(shx[0],shy[0],shx[1],shy[1],255,255,255);
Line(shx[1],shy[1],shx[2],shy[2],255,255,255);
Line(shx[2],shy[2],shx[3],shy[3],255,255,255);
Line(shx[3],shy[3],shx[0],shy[0],255,255,255);
SDL_UnlockSurface(screen);
Plot(dhx[0],dhy[0],255,255,0);
Plot(dhx[1],dhy[1],255,255,0);
Plot(lfootx,lfooty,0,255,0);
Plot(rfootx,rfooty,0,255,0);
Plot(shx[0],shy[0],255,255,0);
}
Shuttle *s=new Shuttle;



while(F.GameOn==true)
     {
     Bar(screen,0,0,800,600,0,0,0);
     short done=Ohjaus();
     if (done==666) {F.GameOn=false;while(done==666) done=Ohjaus();}
     if (k.left==true) s->DecAngle(4);
     if (k.right==true) s->IncAngle(4);

     double x=s->GetX(),y=s->GetY();
     if (k.up==true)
        {
        static double acc=0;
        acc+=s->GetEngine();
        s->IncXSpeed(al.COS[s->GetAngle()]*acc);
        s->IncYSpeed(al.SIN[s->GetAngle()]*acc);
        if (s->GetYSpeed()>4.99) s->SetYSpeed(5);
        if (s->GetXSpeed()>4.99) s->SetXSpeed(5);
        if (s->GetYSpeed()<-4.99) s->SetYSpeed(-5);
        if (s->GetXSpeed()<-4.99) s->SetXSpeed(-5);

        }
//-g t 2

     y+=0.5;y+=s->GetYSpeed();x+=s->GetXSpeed();
     if ((short)y>600-30) y=600-30;
     if ((short)y<30) y=30;
     if ((short)x>800-30) x=800-30;
     if ((short)x<30) x=30;
     s->SetX(x);
     s->SetY(y);

     //DrawAlue();

     s->CountKarjet();
     s->Draw();
     SDL_Flip(screen);
     SDL_framerateDelay(&fpsm);
     }
Game=MainMenu;return 0;
return -1;
}

Tämä ei ole vitsi.
Tällä koodilla alus lenteli ihan näppäinten mukaan ruudulla mutta heti kun yritin sen myöhemmässä koodissa saada seuraamaan kuvaa niin ongelmat alkoivat.

Macro [01.03.2012 19:36:27]

#

Osaatko itse lukea tuota?

Metabolix [01.03.2012 19:40:25]

#

Joo, ihan mahdotonta sotkua. Jos oma panostuksesi ongelman esittämiseen on tuota tasoa (200 riviä äärimmäisen sekavaa koodia ilman kommentteja), on aika turha odottaa sen suurempaa panostusta vastauksiinkaan.

Mutta jos kerran ohjaus näppäimillä toimii, eihän sitten tarvitse kuin laskea aluksen kulkusuunnan ja halutun suunnan (aluksesta kohteeseen) välinen kulma ja asettaa k.left ja k.right sen etumerkin mukaan.

DumTom [01.03.2012 20:17:32]

#

No en juuri kommentoi.
Sain systeemin toimimaan.
Mutta kaipaisin apua seuraavissa tilanteissa:
(Näissä Metabolix loistaa:))
Alus on siis koko ajan keskellä ruutua ja kääntyy sinin ja cosinin ja kaasun avulla juuri sinnepäin minne nenä näyttää.Piirtorutiinit ovat tosiaan mystisiä...:)
Mutta kun tullaan alueelle että kuva alkaa vaikkapa x-pisteestä 6300 ja päättyy pisteeseen 7100 eli 800 levuinen pala.
Tarvitsisin piirtorutiinit juuri noille erikoisalueille jossa kuvan reuna 6400 eli 0 on piirron keskivaiheilla...
Y-suunnan olen ajatellut ratkaista niin että kun alus tulee tiettyyn pisteeseen niin lopetetaan kuvan vieritys ja aloitetaan aluksen siirto.
Tässä nyt jonkinlaista selitystä.

Grez [01.03.2012 21:04:25]

#

DumTom kirjoitti:

Piirtorutiinit ovat tosiaan mystisiä...:)

No mitä jos tekisit niistä piirtorutiineista vähemmän mystisiä? Voisi olla helpompi toteuttaa tarvitsemasi jututkin.

DumTom kirjoitti:

Tarvitsisin piirtorutiinit juuri noille erikoisalueille jossa kuvan reuna 6400 eli 0 on piirron keskivaiheilla...

En löytänyt koodista kohtaa jossa se ylipäärtään piirtäisi taustan, joten paha sanoa miten sitä pitäisi muuttaa. Jos piirrät taustan tällä hetkellä piirtämällä pinnalle jonkun kuva, niin jos reuna menee kuva-alueella niin piirrät sen vaan kaksi kertaa (tyyliin Piirrä(-6300,-700); Piirrä(100,-700) ) ja jos menee myöskin Y:n kohdalta poikki, niin sitten 4 kertaa.

Helposti menee jotenkin tähän tyyliin

void DrawBackground(int x, int y) {
	for (int px=-x; px<800; px+=800) for (int py=-y; py<800; py+=800) {
		Background->Draw(px,py);
	}
}

DumTom [01.03.2012 21:53:09]

#

void DrawAlue(void)
{
short dx=(short)s->GetAX(),dy=(short)s->GetAY();
SDL_Rect kuvaalue; // alue, mikä kuvasta piirretään
SDL_Rect nayttoalue; // alue näytöllä, jolle kuva piirretään
if (dx+800<6400)
   {
   kuvaalue.x = dx;
   kuvaalue.y = dy;
   kuvaalue.h = 600; // korkeus
   kuvaalue.w = 800;
   nayttoalue.x = 0;
   nayttoalue.y = 0;
   SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);
   DrawText(300,0,"NORMAL",0);
   }
if (dx+800>6399)
   {

   short raja=6400-dx;
   kuvaalue.x = dx;
   kuvaalue.y = dy;
   kuvaalue.h = 600; // korkeus
   kuvaalue.w = raja;
   nayttoalue.x = 0;
   nayttoalue.y = 0;
   SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);
   kuvaalue.x = 0;
   kuvaalue.y = dy;
   kuvaalue.h = 600; // korkeus
   kuvaalue.w = 800-raja;
   nayttoalue.x = 800-raja;
   nayttoalue.y = 0;
   SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);

   DrawText(300,0,"OVER6400",0);
   }
}

tässä nyt tämmöstä räpellystä mikä ei toimi
Grez miten tuon silmukkasi saisi tähän?

Lisäys:

Jonnekin sitten kai tälläiset ehdot?

if (ax>7199) ax=-800;
if (ax<-800) ax=7200;

DumTom [01.03.2012 22:03:05]

#

for (int px=-x; px<800; px+=800)

mitä tuo -x tuossa tekee?
voiko silmukkaa käyttää joka tapauksessa vaikka piirtoja ei tulisi kuin yksi?
olen koko päivän tätä miettinyt ja alkaa jo ketuttaa....

Grez [01.03.2012 22:14:25]

#

Siinä -:ssa oli ideana, että jos piirtorutiini huolehtisi itse kuvan leikkaamisesta kohteen kokoon, niin kuva piirrettäisiin negatiiviseen kohtaan ruutua, jolloin oikea osa siitä piirtyisi. SDL_Blitsurfacella leikkaamiskohta täytyy itse määrittää.

Metabolix [01.03.2012 22:16:50]

#

Grez kirjoitti:

SDL_Blitsurfacella leikkaamiskohta täytyy itse määrittää.

Kyllä sen pitäisi itse osata leikata.

Grez [01.03.2012 22:24:14]

#

Voisin kuvitella, että se menisi jotenkin tälleen: (Voi olla virheitä kun en pääse testaamaan)

#define screenHeight 600
#define screenWidth 800
#define pictureWidth 6400
#define pictureHeight 6400

short Min(short a,short b) {
	if (a<b) return a;
	return b;
}

void DrawAlue(void)
{
	SDL_Rect kuvaalue; // alue, mikä kuvasta piirretään
	SDL_Rect nayttoalue; // alue näytöllä, jolle kuva piirretään

	nayttoalue.x = 0;
	for (short dx=(short)s->GetAX(); dx>-screenWidth; dx-=screenWidth) {
		nayttoalue.y = 0;
		for (short dy=(short)s->GetAY();dy>-screenHeight; dy-=screenHeight) {
			kuvaalue.x = (dx>0) ? dx : 0;
			kuvaalue.y = (dy>0) ? dy : 0;
			nayttoalue.w = kuvaalue.w = Min(screenWidth-nayttoalue.x, pictureWidth-kuvaalue.x);
			nayttoalue.h = kuvaalue.h = Min(screenHeight-nayttoalue.y, pictureHeight-kuvaalue.y);
			SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);
			nayttoalue.y = screenHeight-dy;
		}
		nayttoalue.x = screenWidth-dx;
	}
}

Metabolix kirjoitti:

Kyllä sen pitäisi itse osata leikata.

Ok, no sitten äskeiseen tuli tehtyä jonkin verran turhaa työtä.

DumTom [02.03.2012 06:11:18]

#

Grez jeesi vielä sen verran että irrotat ton y silmukan pois....
Kokeilen kohta et toimisko toi.
:)

Lisäys:

Eipä toi koodi toimi. Piirtää koko ajan samaa kuvaa jostain kohdasta kuvaa. Välillä tosin pientä vaihtelua...
Mikä lie mättää?

User137 [02.03.2012 07:16:09]

#

Jotain vaihtoehtoa:

Pelisilmukka:
  Aseta kamera pelaajan kohdalle.
  Jos kamera menee kuva-alueen ulkopuolelle, siirrä se takaisin sisäpuolelle.
  Piirrä pelikartta ja objektit suhteellisesti kameran osoittamaan kohtaan.

DumTom [02.03.2012 07:29:17]

#

User137:
Yritän luoda kolmea eri piirtofunktiota.

Normaali eli kun ax=0-5599

Iso eli kun ax>5599

Pieni eli kun ax<0

En vaan tajua missä vaiheessa ax:ää tulisi lisätä tai vähentää...

Lisäys:

void DrawAlue(void)
{
short dx=(short)s->GetAX(),dy=(short)s->GetAY();
SDL_Rect kuvaalue; // alue, mikä kuvasta piirretään
SDL_Rect nayttoalue; // alue näytöllä, jolle kuva piirretään
if (dx>-1 && dx<5600)
   {
   kuvaalue.x = dx;
   kuvaalue.y = dy;
   kuvaalue.h = 600; // korkeus
   kuvaalue.w = 800;
   nayttoalue.x = 0;
   nayttoalue.y = 0;
   SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);
   DrawText(300,0,"NORMAL",0);
   }
if (dx>5559 && dx<6399)
   {
   short alku=6400-dx,loppu=6400-alku;
   kuvaalue.x = dx;
   kuvaalue.y = dy;
   kuvaalue.h = 600; // korkeus
   kuvaalue.w = alku;
   nayttoalue.x = 0;
   nayttoalue.y = 0;
   SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);
   kuvaalue.x = 0;
   kuvaalue.y = dy;
   kuvaalue.h = 600; // korkeus
   kuvaalue.w = loppu;
   nayttoalue.x = alku;
   nayttoalue.y = 0;
   SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);
   DrawText(300,0,"OVER6400",0);

   }
}

Tossa perus ja iso alue toimivina mutta ei tietoa mitä ax:lle pitäisi tehdä...

Lisäys:

while(F.GameOn==true)
     {
     Bar(screen,0,0,400,60,0,0,0);
     short done=Ohjaus();
     if (done==666) {F.GameOn=false;while(done==666) done=Ohjaus();}
     if (k.left==true) s->DecAngle(4);
     if (k.right==true) s->IncAngle(4);

     double ax=s->GetAX(),ay=s->GetAY();
     if (k.up==true)
        {
        static double acc=0;
        acc+=s->GetEngine();
        s->IncXSpeed(al.COS[s->GetAngle()]*acc);
        s->IncYSpeed(al.SIN[s->GetAngle()]*acc);
        if (s->GetYSpeed()>4.99) s->SetYSpeed(5);
        if (s->GetXSpeed()>4.99) s->SetXSpeed(5);
        if (s->GetYSpeed()<-4.99) s->SetYSpeed(-5);
        if (s->GetXSpeed()<-4.99) s->SetXSpeed(-5);

        }
//-g t 2

     //y+=0.5;
     s->IncYSpeed(0.4);
     if (s->GetYSpeed()>4.99) s->SetYSpeed(5);

     ay+=s->GetYSpeed();ax+=s->GetXSpeed();
     if ((short)ay>6400-800) ay=6400-800;
     if ((short)ay<0) ay=0;

     if ((short)ax>6399) ax-=6400;
     if ((short)ax<0) ax+=6400;
     s->SetAX(ax);
     s->SetAY(ay);

     DrawAlue();
     char text[15];

     sprintf(text,"AX:%05hd",(short)ax);
     DrawText(0,0,text,0);
     sprintf(text,"AY:%05hd",(short)ay);
     DrawText(0,30,text,0);

     s->CountKarjet();
     s->Draw();
     SDL_Flip(screen);
     SDL_framerateDelay(&fpsm);
     }
Game=MainMenu;return 0;
return -1;
}

short Min(short a,short b) {
	if (a<b) return a;
	return b;
}




void DrawAlue(void)
{
short dx=(short)s->GetAX(),dy=(short)s->GetAY();
SDL_Rect kuvaalue; // alue, mikä kuvasta piirretään
SDL_Rect nayttoalue; // alue näytöllä, jolle kuva piirretään
if (dx>-1 && dx<5600)
   {
   kuvaalue.x = dx;
   kuvaalue.y = dy;
   kuvaalue.h = 600; // korkeus
   kuvaalue.w = 800;
   nayttoalue.x = 0;
   nayttoalue.y = 0;
   SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);
   DrawText(300,0,"NORMAL",0);
   }
if (dx>5559 && dx<6400)
   {
   short alku=6400-dx,loppu=6400-alku;
   kuvaalue.x = dx;
   kuvaalue.y = dy;
   kuvaalue.h = 600; // korkeus
   kuvaalue.w = alku;
   nayttoalue.x = 0;
   nayttoalue.y = 0;
   SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);
   kuvaalue.x = 0;
   kuvaalue.y = dy;
   kuvaalue.h = 600; // korkeus
   kuvaalue.w = loppu;
   nayttoalue.x = alku;
   nayttoalue.y = 0;
   SDL_BlitSurface(O_Cave,&kuvaalue,screen,&nayttoalue);
   DrawText(300,0,"OVER6400",0);
   }
}

Taisin saada toimimaan? Uskoakko vai ei?


Sivun alkuun

Vastaus

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

Tietoa sivustosta