简体   繁体   中英

Leaving a trail on screen using SDL2/C++

I am making an ant simulation program using SDL2 and C++ using http://www.openprocessing.org/sketch/15109 as my reference.The link is a Processing sketch.

I have figured out how to do everything in C++/SDL2 except the part where the ants leave trails on the screen which evaporate over time. Now the trails are integral to the algorithm itself but at the same time having them on the screen increases the beauty of the program :D. I managed to get the algorithm part working. Now I just need to see the trails.

The relevant code (in Processing) is:

void draw() {

  loadPixels();
  for (int i=0; i<pherHome.length; i++) {
    color pixelColor;
    if (food.getValue(i)) {
      // Draw food
      pixelColor = FOOD_COLOR;
    } 
    else {
      // Draw pheromones

      float pixelAlpha = pherHome.getPercentage(i);
      int pixel_r = int(HOME_R * pixelAlpha + DIRT_R * (1-pixelAlpha));
      int pixel_g = int(HOME_G * pixelAlpha + DIRT_G * (1-pixelAlpha));
      int pixel_b = int(HOME_B * pixelAlpha + DIRT_B * (1-pixelAlpha));

      pixelAlpha = pherFood.getPercentage(i);
      pixel_r = int(FOOD_R * pixelAlpha + pixel_r * (1-pixelAlpha));
      pixel_g = int(FOOD_G * pixelAlpha + pixel_g * (1-pixelAlpha));
      pixel_b = int(FOOD_B * pixelAlpha + pixel_b * (1-pixelAlpha));

      // Using bitwise color math instead of color() on the following line
      // upped the framerate from 43 to 58 on my computer
      //pixelColor = color(pixel_r, pixel_g, pixel_b);
      pixelColor = pixel_r << 16 | pixel_g << 8 | pixel_b;
    }
    // Set
    pixels[i] = pixelColor;
  }
  updatePixels();

  // Draw ants and do other stuff}

Please suggest some way in which I can achieve the same effect.

My SDL2 code :

/* draw loop**********************************************************************************************************************************/

bool quit = false;

while (!quit)

{   
    SDL_Event e;

    while ( SDL_PollEvent(&e) != 0)
    {
        if (e.type == SDL_QUIT)
        {
            quit = true;
        }
    }
    int mousex,mousey;
    SDL_GetMouseState(&mousex,&mousey);
    if ( e.type == SDL_MOUSEBUTTONDOWN )
    {
        food.addFood(mousex,mousey);
    }

    SDL_BlitSurface (background, NULL, gsurface, NULL);
    // displaying food
    for(int i =0 ; i < width; i ++)
    {
        for(int j = 0; j < height ; j++)
        {
            if (food.getValue(i,j))
            {
                SDL_Rect pos;
                pos.x = i;
                pos.y = j;

                SDL_BlitSurface (food_source_image, NULL, gsurface, &pos);
            }
        }
    }



    for (int i = 0; i < col.ants.size(); i++) 
    {
      col.ants[i].step();
      int thisXi = col.ants[i].intX;// position in int
      int thisYi = col.ants[i].intY;

      float thisXf = col.ants[i].x;// position in float
      float thisYf = col.ants[i].y;

      if (col.ants[i].hasFood) 
      {
        if (thisXi>col.x-10 && thisXi<col.x+10 && thisYi>col.y-10 && thisYi<col.y+10) 
        {
          // Close enough to home
          cout << "dropped" << endl;
          col.ants[i].hasFood = false;
          col.ants[i].homePher = 100;
        }
      }
      else if(food.getValue(thisXi, thisYi)) 
      {
        cout << "found " << endl;
        col.ants[i].hasFood = true;
        col.ants[i].foodPher = 100;
        food.bite(thisXi, thisYi);
      }

      SDL_Rect pos; pos.x = thisXi; pos.y = thisYi;
      SDL_BlitSurface (human_image, NULL, gsurface, &pos);

    }

    // Evaporate
    pherHome.step();
    pherFood.step();

    SDL_UpdateWindowSurface(gwindow);
    SDL_Delay(1);
}

I'm not really sure but in terms of textures, let me make an example.

You wanted an image on the screen lighten and disappear over time so-

SDL_Texture* image = IMG_LoadTexture(putRendererHere, FilePath.c_str());

FilePath.c_str() should be replaced by the address of your file example : "Resources/Intro/15.png"

SDL_Rect rect;

rect.x = x; //x coordinate

rect.y = y; //y coordinate

rect.w = w; //width

rect.h = h; //height

The rect is responsible for handling the position and size of the image.

The next part would be the one responsible for your "Fade-out" effects.

int elapsedTime = xx; //xx should be your in-game time. You can use SDL_GetTicks()

int alpha1 = 250; //In alpha terms, 250 is Opaque while 0 is invisible

int alpha2 = 250;

SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);//This sets the texture in blendmode

if (alpha1 > 0) { //This checks if the image is not yet invisible

  alpha2 -= xf * elapsedTime; // change x into any float alpha1 = alpha2; //so alpha1 starts to slowly decrease. (Fading Out) 

}

if (alpha1 <= 0) { //This code will repeat in the while loop above, once it hits 0 or below 0 then all looping stops and this loop sets the image to a state where it can't be seen.

  alpha1 = 0; alpha2 = 0; 

}

SDL_SetTextureAlphaMod(texture, alpha);

SDL_RenderCopy(renderer, texture, NULL, &rect);

Those are the basics, but since you're making 'trails' then I'm assuming that you'd be making millions of these, you should make a function responsible for creating the image, drawing, and changing the alpha of the texture.

After that, you should be able to replicate these with just a line.

In the last if statement, you can tweak the contents to make the program forget about the image, thus, releasing all the memory it took to generate the images.

Happy Coding :)

//I can't to open your link so I'm not sure if this was what you accurately needed but as a tip-

  • Create a an int that handles the general time in you game

  • Create a bunch of other int that handles the time per footprint and once it's done, it could handle another footprint.

  • Do some Math with the above int(s) and you should get footprint-like results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM