Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Ympyrän keskuksen piirto

Sivun loppuun

ByteMan [15.12.2007 17:05:43]

#

tuli taas vastaan pieni ikävä probleemi, jollen en vaan keksi ratkaisua..(ja olen yrittänyt kaikkea mitä keksin..)
seuraava koodinpätkä sisältää jotain, mikä tuhoaa metapalloiltani keskukset kun toisen ympyrän kehän reuna leikkaa sen.. osaako joku sanoa mikä mättää?

#include <math.h>
#include <SDL/SDL.h>

void PiirraPikseli(SDL_Surface *naytto, int x, int y, Uint8 R, Uint8 G, Uint8 B);
int liikutax(int x);
int liikutay(int y);
void CLS(SDL_Surface *naytto, int x, int y);

int main(int argc, char *argv[])    {

    if(SDL_Init(SDL_INIT_VIDEO) < 0)    {

	return 0;
    }

    SDL_Surface *naytto;
    naytto = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);

//********************************************

    int x;
    int y;
    int i;

double vari=0.0;
double vari2=0.0;
int piirto=0;
int taulukko[640][480];
int pallot[2][3];
int rounds=150;
int apuvari=0;
int apuvari2=255;


pallot[0][0]=300;//1.pallon säde
pallot[0][1]=200;//1.pallon x koordinaatti
pallot[0][2]=200;//1.pallon y koordinaatti

pallot[1][0]=475;//2.pallon säde
pallot[1][1]=300;//2.pallon x koordinaatti
pallot[1][2]=300;//2.pallon y koordinaatti


int sade1=300;
int pallo1x=200;
int pallo1y=200;
int pallo2x=200;
int pallo2y=200;


while(rounds>0){

rounds--;


//luulisin, että vika löytyy tästä välistä alkaen

for(i=0; i<2;i++){
    for(x = 0; x < 639; x++)    {
        for(y = 0; y < 479; y++)    {

	    vari=( pallot[i][0] / ( ((pallot[i][1] - x)*(pallot[i][1] - x)) + ((pallot[i][2] - y)*(pallot[i][2]-y)) + 0.01));


	    if(vari>1) { vari=1; }
	    if(vari<0.01) { vari=0.0; }
	    vari=((vari)*255);



	    piirto=(int)(vari);

	    if(piirto>230) { piirto=255; }
	    taulukko[x][y]=((taulukko[x][y])+piirto);
        }
    }
    for(x=0; x<639; x++){
	for(y=0; y<479; y++){
	    PiirraPikseli(naytto, x, y, 2, 2, taulukko[x][y]);
}}}
    SDL_Flip(naytto);

for(x=0; x<640; x++){
    for(y=0; y<480; y++){
	taulukko[x][y]=0;
}}
//jonnekkin tähän väliin asti.. en tosin voi mennä vannomaankaan..

pallot[0][1]=liikutax(pallot[0][1]);
pallot[0][2]=liikutay(pallot[0][2]);
pallot[1][1]=liikutay(pallot[1][1]);
pallot[1][2]=liikutay(pallot[1][2]);




}
CLS(naytto, 640, 480);
    SDL_Delay(3000);
    SDL_FreeSurface(naytto);
    SDL_Quit();
    return 0;
}



void PiirraPikseli(SDL_Surface *naytto, int x, int y, Uint8 R, Uint8 G, Uint8 B)    {
    Uint32 color = SDL_MapRGB(naytto->format, R, G, B);
        {
            Uint32 *bufp;
            bufp = (Uint32 *)naytto->pixels + y*naytto->pitch/4 + x;
            *bufp = color;
        }


}


int liikutax(int x){
    if(x<100) { x=x+4; return x; }
    if(x>630) { x=x-4; return x; }
    //if(y<100) { y++; return 0; }
    //if(y>470) { y--; return 0; }
    if(x>300) { x=x+4; return x; }
    if(x<=300) { x=x-4; return x; }
}

int liikutay(int y){
    if(y<70) { y=y+4; return y; }
    if(y>420) { y=y-4; return y; }
    //if(y<100) { y++; return 0; }
    //if(y>470) { y--; return 0; }
    if(y>300) { y=y+4; return y; }
    if(y<=300) { y=y-4; return y; }
}

void CLS(SDL_Surface *naytto, int x, int y){
int apu1=10;
int apu2=10;
x=640;
y=480;
for(apu1=0; apu1<640; apu1++){
    for(apu2=0; apu2<480; apu2++){

	PiirraPikseli(naytto, apu1, apu2, 0,0,0);
}}

}

toivottavasti saa selvää..
meinaan ekaks saada ton toimii, ja optimoida vasta sitten, esim toi CLS funktio taitaa olla aika turha..

Pekka Karjalainen [15.12.2007 18:44:13]

#

Käytä assert()-toimintoa.

Esimerkiksi tässä näyttäisi, että haluat taulukossa olevan aina arvon väliltä 0 <= x <= 255. Kun se välitetään funktiolle PiirraPIkseli, voi sen kätevästi testata siellä.

kirjoitat

#include <assert.h>

assert (0 <= B && B <= 255);

Tässä B on PiirraPikseli-funktion parametri ja tuon voi laittaa heti funktion alkuun.

Assertit voi jättää ohjelmasta pois määrittelemällä option NDEBUG käännösvaiheessa (esikääntäjälle, joku kyllä neuvoo miten, jos et tunne asiaa), joten niiden hidastavaa vaikutusta ei tarvitse peljätä. Lisäksi ne kertovat meille koodin mahdollisille lukijoille enemmän, kuin pelkkä koodi, joka olettaa arvon olevan sillä ja sillä välillä.

Tällainen tuli siis mieleen äkkiä lukiessa. Kun ei ole SDL:ää tällä koneelle, en voi testatakaan ohjelmaa. Oliko oletukseni B:n arvoista edes oikea?

Assertista on paljon ohjeita verkossa. Putkassa ei taida olla ollut erikseen puhetta, kun haku ei paljastanut.

ByteMan [15.12.2007 20:21:54]

#

juu, ymmärsit B:n arvovälin oikein, mutta assertista ei ollu mitään hyötyä.. se kun ei päässyt edes kääntäjästä läpi.
kiitoksia kuitenkin yrityksestä.

tosin, löysin vian lopulta..
en jaksa miettiä asian matemaattista tai ohjelmakoodillista puolta sen enempää, mutta tuo väriarvon tarkistus ennen taulukkoon sijoitusta( if(piirto>230) ) olisi ilmeisesti pitänyt tehdä vasta taulukkoon sijoittamisen jälkeen.. tuohan kun teki asian silleen, että taulukossa saattoi hyvinkin löytyä arvoja tyyliin 460...
mistä SDL ei tosin valittanut mitään! :<
edit::sit vaa liikutteleen noit palloi vähä järkevämmin..
edit2:: äh, eihän SDL sieltä mitään olisi voinu löytää, ku eihän sille suoraan niitä virheellisiä arvoja tarjottu..

Mazzimo [16.12.2007 13:33:57]

#

assertin saat mukaan lisäämällä headerin:
#include <cassert>

ByteMan [16.12.2007 17:33:13]

#

ei, kun toi ei pääse kääntäjästä läpi, kun vertailu ei voi olla muuta kuin tosi.

Heikin SDL opas kirjoitti:

8-bittinen etumerkitön kokonaisluku (0 - 255)

kääntäjä kirjoitti:

comparasion is always true

tai jotain tonnepäin.
ja jätti kääntämättä.

*******

tosin, nyt sain metapalloni tehtyä ;)

TsaTsaTsaa [16.12.2007 19:38:47]

#

Määki tein metapallot :(

// *********************************************
// * M e t a p a l l o t * v e r s i o   1 . 5 *
// *********************************************
// - pallot vakiokokoisia
// - lasketaan FPS:sää

#include <SDL/SDL.h>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <iostream>

using std::cout;
using std::endl;

/************** VAKIOITA *************/

// Ikkunan korkeus ja leveys
const int KORKEUS = 700;
const int LEVEYS = 800;

// Pallojen määrä ja säde
int PALLOJA = 4;
const int SADEMIN = 100;

Uint32 kulunut_aika;

/******** TIETOTYYPPEJÄ ***********/

struct Pallo
{
   int x; // x-koord
   int y; // y-koord
   int vx; // x-suuntainen nopeus
   int vy; // y-suuntainen nopeus
};



/************ FUNKTIOIDEN ESITTELYT **********/

// Laskee aikaa
void laskeKulunutAika();

// Palauttaa luvun neliön
int nelio(int luku);

// Pikselin piirto
void piirraPikseli(SDL_Surface *naytto, int x, int y,
		   Uint8 R, Uint8 G, Uint8 B);

/*************** PÄÄOHJELMA *************/

int main(int argc, char* argv[])
{
   // Komentoriviparametri pallojen määräksi
   if (argc == 2)
   {
      PALLOJA = atoi(argv[1]);
   }

   cout << "\n Metapallot 1.5\n"
        << " **************\n"
        << " Palloja: " << PALLOJA << endl
        << " Ikkunan koko: " << LEVEYS << "x" << KORKEUS << endl;

   // SDL:n alustukset yms.
   cout << "\n - Alustetaan SDL....";
   if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0 )
   {
      cout << "\n   - SDL:n alustus epäonnistui: " << SDL_GetError()
        << endl;
      SDL_Quit();
      return EXIT_FAILURE;
   }

   cout << "OK\n";

   // Ikkuna kuntoon
   cout << " - Alustetaan ikkuna...";
   SDL_Surface *naytto;
   naytto = SDL_SetVideoMode(LEVEYS, KORKEUS, 32,
			     SDL_HWSURFACE|SDL_DOUBLEBUF);

   cout << "OK\n";

   // Ikkunan nimen vaihto
   SDL_WM_SetCaption("Metapallot 1.5", NULL);

   // Näppiksen käsittely mukaan
   Uint8 *nappi;
   SDL_Event tapahtuma;

   // Pallot ja väriarvotaulukko
   Pallo pallot[PALLOJA];
   int piirto[LEVEYS][KORKEUS] = { {0} };

   // Alustetaan satunnaisuushommat
   srand((unsigned)time(0));

   // Alustetaan pallot
   for (int i = 0; i < PALLOJA ; ++i)
   {
      pallot[i].x = (rand() % LEVEYS);
      pallot[i].y = (rand() % KORKEUS);
      pallot[i].vx = (rand() % 5) - 2;
      pallot[i].vy = (rand() % 5) - 2;
   }

   // Lasketaan pääsilmukassa käytettäviä arvoja valmiiksi taulukkoon
   // jotta pyörii sutjakkaammin.
   cout << " - Lasketaan...";

   // Jakajasta (pallo.x - x)^2
   int axat[LEVEYS];
   for (int x = 0; x < LEVEYS; ++x)
   {
      for (int xx = 0; xx < LEVEYS; ++xx)
      {
         axat[abs(xx-x)] = nelio(xx-x);
      }
   }

   // Jakajasta (pallo.y - y)^2
   int yyt[KORKEUS];
   for (int y = 0; y < KORKEUS; ++y)
   {
      for (int yy = 0; yy < KORKEUS; ++yy)
      {
         yyt[abs(yy-y)] = nelio(yy-y);
      }
   }

   // Väriarvot
   double varit[LEVEYS][KORKEUS];
   for (int x = 0; x < LEVEYS; ++x)
   {
      for (int y = 0; y < KORKEUS; ++y)
      {
         if ( axat[x]+yyt[y] == 0 )
         {
            varit[x][y] = 1.0;
         }
         else
         {
            varit[x][y] = 6000 /
              (axat[x]+yyt[y] + 0.001);
         }

         if (varit[x][y] > 1.0) varit[x][y] = 1.0;
         if (varit[x][y] < 0.01) varit[x][y] = 0.0;

         varit[x][y] *= SADEMIN * 0.01 * 255;

      }
   }

   cout << "OK\n";

   // Tieto ohjelman käynnissäolosta
   bool kaynnissa = true;

   laskeKulunutAika();

   // Lasketaan montako framea pyörähtää ja montako sekuntia käynnissä
   Uint32 frameja = 0;
   Uint32 alkuaika = SDL_GetTicks();
   Uint32 loppuaika = 0;

   cout << " - Pyörii.\n";

   // Pääsilmukka
   while (kaynnissa)
   {
      // Katsotaan, onko painettu ESC tai nurkkaruksia
      SDL_PollEvent( &tapahtuma );
      if ( tapahtuma.type == SDL_QUIT ) kaynnissa = false;
      if ( tapahtuma.type == SDL_KEYDOWN )
      {
         if ( tapahtuma.key.keysym.sym == SDLK_ESCAPE )
         {
            kaynnissa = false;
         }
      }

      // Siirretään palloja, lasketaan väriarvot ja piirrellään
      for (int i = 0; i < PALLOJA; ++i)
      {
         // Siirretään pallon keskipiste (hatusta heitetty kerroin)
         pallot[i].x += (pallot[i].vx * (kulunut_aika / 35));
         pallot[i].y += (pallot[i].vy * (kulunut_aika / 35));

         // Pallon suunnan ja nopeuden vaihto jos törmää reunaan
         if ( pallot[i].x < 0 )
         {
            pallot[i].x = 0;
            pallot[i].vx = 1;
         }
         else if ( pallot[i].x >= LEVEYS )
         {
            pallot[i].x = LEVEYS-1;
            pallot[i].vx = -1;
         }

         if ( pallot[i].y < 0 )
         {
            pallot[i].y = 0;
            pallot[i].vy = 1;
         }
         else if ( pallot[i].y >= KORKEUS )
         {
            pallot[i].y = KORKEUS-1;
            pallot[i].vy = -1;
         }

         // Kasvatetaan nopeutta
         if (pallot[i].vx < 0) pallot[i].vx--;
         else pallot[i].vx++;

         if (pallot[i].vy < 0) pallot[i].vy--;
         else pallot[i].vy++;


         // Lasketaan väriarvot
         for (int x = 0; x < LEVEYS; ++x)
         {
            for (int y = 0; y < KORKEUS; ++y)
            {
               // Laskenta
               piirto[x][y] +=
                 (int)(varit[abs(pallot[i].x-x)]
                       [abs(pallot[i].y-y)]);
            }
         }

      }

      // Piirretään pikselit ja nollataan taulukko samalla
      for (int x = 0 ; x < LEVEYS; ++x)
      {
         for (int y = 0; y < KORKEUS; ++y)
         {

            if (piirto[x][y] > 255) piirto[x][y] = 255;
            else if (piirto[x][y] < 0) piirto[x][y] = 0;
            piirraPikseli(naytto, x, y, piirto[x][y], 0, piirto[x][y]);
            piirto[x][y] = 0;

         }
      }

      // Roina näytölle
      SDL_Flip(naytto);

      laskeKulunutAika();
      frameja++;
   }

   // Lopetus
   cout << " - Lopetetaan...\n";
   loppuaika = SDL_GetTicks();
   cout << frameja << " frames in " << (loppuaika-alkuaika)/1000.0
     << " seconds = " << frameja/((loppuaika-alkuaika)/1000.0) << " FPS\n";
   SDL_Quit();
   return EXIT_SUCCESS;
}


/****************** FUNKTIOIDEN MÄÄRITTELYT *********/

// Ajanlasku
void laskeKulunutAika()
{
   static Uint32 vanha_aika, uusi_aika;
   vanha_aika = uusi_aika;

   // Pitää olla eri aika kun viimeksi
   while (vanha_aika == uusi_aika)
   {
      uusi_aika = SDL_GetTicks();
   }

   // Paljonko kulunut viime kerrast
   kulunut_aika = uusi_aika - vanha_aika;
}


// Palauttaa luvun neliön
int nelio(int luku)
{
   return luku*luku;
}


// Pikselin piirto
void piirraPikseli(SDL_Surface *naytto, int x, int y,
		   Uint8 R, Uint8 G, Uint8 B)
{
   Uint32 color = SDL_MapRGB(naytto->format, R, G, B);

   Uint32 *bufp;
   bufp = (Uint32*)naytto->pixels + y*naytto->pitch/4 + x;
   *bufp = color;
}

Parhaat FPS:t itse sain g++:n vivulla -O3.

tgunner [17.12.2007 15:57:58]

#

^Näyttää kivalta, mutten saanu toimimaan. Kääntyy kyllä. Tarviiko käynnistykseen mitään muuta kuin palloparametrin? Ainakaan koodista en nähny mitään erikoista.

Nii, ja ykskään cout-viesti ei mee perille.

TsaTsaTsaa [17.12.2007 17:40:00]

#

Tein pieniä muutoksia tuonne väriarvojen laskentaan ja muuallekkin. Nyt käynnistysparametrit ovat PALLOJEN_MÄÄRÄ IKKUNAN_LEVEYS IKKUNAN_KORKEUS SÄDE, joista ei ole pakko antaa mitään, mutta voi antaa pelkän pallojen määrän tai määrän ja ikkunan koon tai kaikki. Tässä muutokset:

// ... ... ...

/************** VAKIOITA *************/

// Ikkunan korkeus ja leveys
int KORKEUS = 700;
int LEVEYS = 800;

// Pallojen määrä ja säde
int PALLOJA = 4;
int SADEMIN = 550;

// ... ... ...

int main(int argc, char* argv[])
{
   // Komentoriviparametri pallojen määräksi
   if (argc >= 2)
   {
      PALLOJA = atoi(argv[1]);
   }

   if (argc >= 4)
   {
      LEVEYS = atoi(argv[2]);
      KORKEUS = atoi(argv[3]);
   }

   if (argc == 5)
   {
      SADEMIN = atoi(argv[4]);
   }

   // ... ... ...

   // Väriarvot
   double varit[LEVEYS][KORKEUS];
   for (int x = 0; x < LEVEYS; ++x)
   {
      for (int y = 0; y < KORKEUS; ++y)
      {
         if ( axat[x]+yyt[y] == 0 )
         {
            varit[x][y] = 1.0;
         }
         else
         {
            varit[x][y] = SADEMIN /
              (axat[x]+yyt[y] + 0.001);
         }

         if (varit[x][y] > 1.0) varit[x][y] = 1.0;
         if (varit[x][y] < 0.01) varit[x][y] = 0.0;

         varit[x][y] *= 255;

         if (varit[x][y] > 255) varit[x][y] = 255;

      }
   }

   // ... ...

   // Pääsilmukka
   while (kaynnissa)
   {

      // ... ... ...

      // Siirretään palloja, lasketaan väriarvot ja piirrellään
      for (int i = 0; i < PALLOJA; ++i)
      {
         // Siirretään pallon keskipiste (hatusta heitetty kerroin)
         pallot[i].x += (pallot[i].vx * (1+ kulunut_aika / 25));
         pallot[i].y += (pallot[i].vy * (1+ kulunut_aika / 25));

      // ... ... ...

         // Lasketaan väriarvot
         for (int x = pallot[i].x - SADEMIN;
              x < LEVEYS && x < pallot[i].x + SADEMIN; ++x)
         {
            if ( x < 0 ) continue;

            for (int y = pallot[i].y - SADEMIN;
                 y < KORKEUS && y < pallot[i].y + SADEMIN; ++y)
            {
               if ( y < 0 ) continue;

               // Laskenta
               // ... ... ...

Pallojen liikehdintä on vähän turhan säännöllistä ja rumaa.

ByteMan [17.12.2007 18:45:09]

#

reiluu.. kaikki tekee kaiken paremmin kuin minä :D
MITEN??
ihan vertailun vuoksi tosin voisin laittaa lopullisen koodin näkyviin..

#include <math.h>//en ole varma hyötyykö tästä mitään..
#include <SDL/SDL.h>

/*******************************************
 *** huomioikaatten, te jotka ohjelmaa   ***
 *** käytätte, että ohjelmaa ei voi py-  ***
 *** säyttää kesken ajon ilman muisti-   ***
 *** vuotoa. kyllä te nyt yhdet metapal- ***
 *** lot kestätte!   :D                  ***
 *******************************************/


void PiirraPikseli(SDL_Surface *naytto, int x, int y, Uint8 R, Uint8 G, Uint8 B);


int main(int argc, char *argv[])    {

    if(SDL_Init(SDL_INIT_VIDEO) < 0)    {//lopetetaan jos SDL ei alustu

	return 0;
    }

    SDL_Surface *naytto;
    naytto = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE|SDL_FULLSCREEN);
    SDL_ShowCursor(0);//koko näyttö(laajakuva näyttö vetää pallot soikeiksi..)ja ei kursoria
//********************************************

    int x;
    int y;
    int i;

double vari=0.0;

int piirto=0;
int taulukko[640][480];//näytön koko
int pallot[4][5];//pallot; 4 olisi suositus(heitin hatusta.. ajakaa tämä ohjelma, niin käsitätte miksi)
int rounds=500;//pyörii 500 kierrosta

//************************************pallot*******

//pallo 1
pallot[0][0]=2000;//1.pallon säde
pallot[0][1]=620;//1.pallon x koordinaatti
pallot[0][2]=221;//1.pallon y koordinaatti
pallot[0][3]=2;//suunta x; 1-> +  2-> -
pallot[0][4]=2;//suunta y


//pallo2
pallot[1][0]=3500;//2.pallon säde
pallot[1][1]=320;//2.pallon x koordinaatti
pallot[1][2]=240;//2.pallon y koordinaatti
pallot[1][3]=2;//suunta x
pallot[1][4]=1;//suunta y


//pallo3
pallot[2][0]=2500;//1.pallon säde
pallot[2][1]=20;//1.pallon x koordinaatti
pallot[2][2]=40;//1.pallon y koordinaatti
pallot[2][3]=2;//suunta x
pallot[2][4]=2;//suunta y


//pallo4
pallot[3][0]=3000;//1.pallon säde
pallot[3][1]=300;//1.pallon x koordinaatti
pallot[3][2]=350;//1.pallon y koordinaatti
pallot[3][3]=1;//suunta x
pallot[3][4]=2;//suunta y



//tähän tarvitaan rounds muuttujaa
while(rounds>0){

rounds--;

//lasketaan pallojen sijainti sekä mahdollinen suunnanmuutos ja yksi hauska lisäefekti ;)
for(i=0; i<4; i++){
    if((pallot[i][1])<100) {pallot[i][3]=1;}
    if((pallot[i][1])>540) {pallot[i][3]=2;}
    if((pallot[i][2])<100) {pallot[i][4]=1;}
    if((pallot[i][2])>380) {pallot[i][4]=2;}

    if((pallot[i][3])==1) {pallot[i][1]=pallot[i][1]+15; pallot[i][0]+=20;}
    if((pallot[i][3])==2) {pallot[i][1]=pallot[i][1]-15; pallot[i][0]-=10;}
    if((pallot[i][4])==1) {pallot[i][2]=pallot[i][2]+15; pallot[i][0]+=20;}
    if((pallot[i][4])==2) {pallot[i][2]=pallot[i][2]-15; pallot[i][0]-=10;}
}


for(i=0; i<4;i++){		 //piirrettävien pallojen määrä
    for(x = 0; x < 640; x++){    //näytön leveys
        for(y = 0; y < 480; y++){//näytön korkeus

	    //väriarvot taulukkoon
	    vari=( pallot[i][0] / ( ((pallot[i][1] - x)*(pallot[i][1] - x)) + ((pallot[i][2] - y)*(pallot[i][2]-y)) + 0.01));

	    //värien raja-arvot sekä muunto RGB:ksi
	    if(vari>1) { vari=1; }
	    if(vari<0.001) { vari=0.0; }
	    vari=((vari)*255);



	    piirto=(int)(vari);//muunto: double -> int

	    //sijoitus taulukkoon
	    taulukko[x][y]=((taulukko[x][y])+piirto);
	    if(taulukko[x][y]>255) { taulukko[x][y]=255; }



        }
    }
    for(x=0; x<640; x++){     //piirretään taulukko
	for(y=0; y<480; y++){
	    PiirraPikseli(naytto, x, y, 2, 2, taulukko[x][y]);
	    //saat pinnkejä palloja laittamalla red-väriksi taulukko[x][y] ;)
	    //taulukko[x][y]=0;//tyhjennetään taulukkoa samaa vauhtia piirtämisen kanssa
}}}

    SDL_Flip(naytto);//pyöräytetään näyttöpintaa


for(x=0; x<640; x++){//tyhjennetään taulukko
    for(y=0; y<480; y++){
	taulukko[x][y]=0;
}}





}

    SDL_Delay(3000);//venataan 3 sekuntia
    SDL_FreeSurface(naytto);//vapautetaan näyttöpinta
    SDL_Quit();//lopetetaan SDL
    return 0;//ja lopetetaan ohjelma
}



void PiirraPikseli(SDL_Surface *naytto, int x, int y, Uint8 R, Uint8 G, Uint8 B)    {//piirretään pikseli

    Uint32 color = SDL_MapRGB(naytto->format, R, G, B);
        {
            Uint32 *bufp;
            bufp = (Uint32 *)naytto->pixels + y*naytto->pitch/4 + x;
            *bufp = color;
        }


}

157 riviä koodia(notepadin mukaan)
pitäs olla kommentoitu ja kaikkee ;)

EDIT:: Tsatsatsaa, en saa pallojasi ajettua.. eli miten komentoriviltä laitetaan parametrit ohjelmalle(puhun ensimmäisestä versiosta..)

Legu [17.12.2007 18:52:53]

#

Vika, ettei toimi (tai käänny) on siinä, että tuolla yritetään staattisesti varata ei-const muuttujan osoittama tila.

Pallo pallot[PALLOJA];

Miksihän tuo muuten edes kääntyy gcc:llä (MinGW)?

g++ metapallot.cpp -o metapallot.exe -lmingw32 -lSDLmain -lSDL

VS 2005 express:n kääntäjä kertoi kylläkin, että tuolla kyseisellä rivillä on virhe.

Mitenhän TsaTsaTsaa olet saanut sen kääntymään ja vielä toimimaankin?

EDIT: Vaikka muuttaa PALLOJA:n constiksi ja poistaa tuon "PALLOJA = atoi(argv)":n niin sitten tuleepi: "Metapallot.exe has encountered a problem and needs to close. We are sorry for the inconvenience."

TsaTsaTsaa [17.12.2007 19:09:18]

#

Kääntyy kovasti ja toimiikin:

g++ -lSDL -lSDLmain main.cc -O3

Unohtui tuosta muutoksista muuten tuo piirto-taulukon alustus, eli rivi

int piirto[LEVEYS][KORKEUS] = { {0} };

Korvaus:

for (int i = 0; i < LEVEYS; ++i)
{
   for (int j = 0; j < KORKEUS; ++j)
   {
      piirto[i][j] = 0;
   }
}

Tai voi sen alustuksen vaan jättää poiskin (auts), ei pitäisi vahinkoa tapahtua.

Legu [17.12.2007 19:50:46]

#

Ahaa, että malloc/free ja new/delete ovat ihan turhia, kun joku velmu taikuri ilmeisesti taikonut tuollaisen staattisen varauksen, jossa varattua kokoa voi vaihtaa dynaamisesti? Ööh...

#include <iostream>

int KOKO;

int main()
{
    std::cin >> KOKO;
    int taulukko[KOKO];
    std::cin >> taulukko[KOKO-1];
    std::cout << taulukko[KOKO-1] << std::endl;
    return 0;
}

Online kääntäjä:

"ComeauTest.c", line 8: error: expression must have a constant value
      int taulukko[KOKO];

Visual Studion kääntäjä:

error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'taulukko' : unknown size

GCC:

legu@servu:~/koodaus/testaus$ g++ testi1.cpp -o testi1
legu@servu:~/koodaus/testaus$

GCC:ssä bugi? Vai onko asetukset/valitsimet jotenkin pielessä?

Metabolix [17.12.2007 20:09:19]

#

Legu kirjoitti:

GCC:ssä bugi? Vai onko asetukset/valitsimet jotenkin pielessä?

Ei vaan ilmeisesti muissa bugi. (C-koodi olisi muuten suotavaa kääntää gcc:llä eikä g++:lla.)

Eihän tuossakaan kokoa voi muuttaa, vaan kooksi tulee se, mitä KOKO sattuu olemaan tuon rivin kohdalla. Siksipä tuo onkin sikäli huono tapa, että aloittelija voi herkästi langeta kuvittelemaan, että taulukon koko muuttuisi vielä muuttamalla muuttujaa jäljempänä.

Vielä C:n standardista (C99) esimerkki aiheesta:

void copyt(int n)
{
      typedef int B[n];   // B is n ints, n evaluated now
      n += 1;
      B a;                // a is n ints, n without += 1
      int b[n];           // a and b are different sizes
      for (int i = 1; i < n; i++)
            a[i-1] = b[i];
}

Legu [17.12.2007 21:57:53]

#

Ahaa, niin päin. Hyvä tietää tuollainenkin juttu. Ilmeisesti tuon ohjelman kaatuaminen johtuikin sitten jostain muusta.

Metabolix kirjoitti:

(C-koodi olisi muuten suotavaa kääntää gcc:llä eikä g++:lla.)

Mikä C-koodi?

Hyvä open source \o/

Metabolix [18.12.2007 00:03:17]

#

Legu kirjoitti:

Mikä C-koodi?

Yleensä .c-pääte tarkoittaa C-koodia ja esimerkiksi .cc, .cpp ja .cxx sen sijaan C++:aa. Monet kääntäjät ja IDEt päättelevät tästä koodin kielen, jos sitä ei ole erikseen muualla määrätty. Ja kuten varmasti tiedät, C ja C++ ovat paikoin hieman erilaisia. Olisi kai pitänyt vilkaista itse koodiakin sen verran, että olisi osannut ilmaista asian toisin. Otetaanpa uusiksi: yleensä C++-koodin pääte on esimerkiksi .cpp eikä pelkästään .c. :)


Sivun alkuun

Vastaus

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

Tietoa sivustosta