2D tile map scrolling and collision

2D tile map scrolling and collision

Postby Pix3l » 01 Jul 2011, 20:15

Hello there!
I have try to wrote my first 2D tile based game, i read some tutorials found around the web and i was able only to make scrolling working a little, but not collisions...
Is there anyone who knew about a good and complete tutorial about 2D tile based games?

I put here my work, i don't fully understand how scrolling works with collisions.
from loserjuegos.
Thanks for help :] :think:

{l Code}: {l Select All Code}
    //gcc -o scrolling scrolling.c -lSDL

    #include <stdio.h>
    #include <stdlib.h>
    #include <SDL/SDL.h>
    #include <time.h>

    #define SCREEN_WIDTH 320
    #define SCREEN_HEIGHT 320
    #define TILESIZE 32
    #define ROWS 15
    #define COLUMNS 40
    #define PLAYER_W 10
    #define PLAYER_H 10

        //Global variables
        int t, tl = 0, frequency = 1000 / 100, temp, t2; //StopBall variables
        int repeat, i, quit=0, paused=0, shoot=0;
        SDL_Event event;
        SDL_Surface *screen;
        SDL_Rect rect; //Main drawing surface
        Uint8 *keystate; // keyboard state

int playfield[ROWS][COLUMNS] =
{
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1,0,0,1,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
  0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,
  1,1,0,1,0,0,0,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,
  0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,
  1,0,0,1,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,
  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,
  0,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
  1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
}; 

    struct _Player
    {
        int w, h, onGround;
        int x, y, jump, lockjump;
        float dirX, dirY;
    } Player;
   
    struct _Game{
       int mapx;
   } Game;
   
   struct _Camera
   {
      int x, y;
   } Camera;

    void DrawRect(int x, int y, int width, int height, int color)
    {
            rect.x = x;
            rect.y = y;
            rect.w = width;
            rect.h = height;
            SDL_FillRect(screen, &rect, color);
    }

    void drawbackground()
    {
   int i;
   int j;
   int row = Camera.y / TILESIZE;
   int column = Camera.x / TILESIZE;
   int shiftX = Camera.x % TILESIZE;
   int shiftY = Camera.y % TILESIZE;
   
   for (i = 0; i < ROWS; i ++)
    {
       for (j = 0; j < COLUMNS; j ++)
       {
         if(playfield[row + i][column + j]==0)
             DrawRect(j * TILESIZE - shiftX, i * TILESIZE - shiftY, TILESIZE, TILESIZE, 0x000000);
       }
    }
    }

    void Draw()
    {
       drawbackground();
       DrawRect(Player.x - Camera.x + (SCREEN_WIDTH/2), Player.y - Camera.y + (SCREEN_HEIGHT/2), PLAYER_W, PLAYER_H, 0xff0000);
       //printf("Player.x %d Camera.x %d X %d\n", (int)Player.x, (int)Camera.x, (int)Player.x - (int)Camera.x + (SCREEN_WIDTH/2));
       //printf("Player.y %d Camera.y %d Y %d\n", (int)Player.y, (int)Camera.y, (int)Player.y - (int)Camera.y + (SCREEN_WIDTH/2));
       DrawRect(Camera.x, Camera.y, PLAYER_W, PLAYER_H, 0xffffff);
    }

    void doCamera()
    {
       //Converte da coordinata a tiles???
       int limitX = COLUMNS * TILESIZE - SCREEN_WIDTH;
       int limitY = ROWS * TILESIZE - SCREEN_HEIGHT;
       
       /* se acerca a la posición del tanque de manera gradual */
       Camera.x +=  Player.x - Camera.x;
       Camera.y +=  Player.y - Camera.y;
       
       /* detiene el desplazamiento en los límites */
       if (Camera.x < 0)
        Camera.x = 0;
       
       if (Camera.y < 0)
        Camera.y = 0;
       
       if (Camera.x > limitX)
        Camera.x = limitX;
       
       if (Camera.y > limitY)
        Camera.y = limitY;
    }

int tileCollision(int x, int y, int w, int h)
{
    int i, j;
    int minx, miny, maxx, maxy;
    // Return a collision if the rectangle is outside of the map.
    if (x < 0 || (x + w) > TILESIZE * COLUMNS ||
        y < 0 || (y + h) > TILESIZE * ROWS)
        return 1;
    // The passed coordinates are in pixels so convert them to tiles.
    minx = x / TILESIZE;
    miny = y / TILESIZE;
    printf("minx %d\n", minx);
   
    maxx = (x + w - 1) / TILESIZE;
    maxy = (y + h - 1) / TILESIZE;

    // Return a collision if the rectangle intersects with a tile.   
    for (i = minx; i <= maxx ; i++)
    {
        for (j = miny ; j <= maxy ; j++)
        {
            if (playfield[j][i])
                return 1;
        }
    }
    // No collision otherwise.
    return 0;
}

int getInput()
{
   int x, y;
    x = Player.x;
    y = Player.y;
   
    printf("player X %d\n", Player.x);
   
    while(SDL_PollEvent(&event))
        {
            if (event.type == SDL_QUIT ||
            (event.type == SDL_KEYDOWN &&
            event.key.keysym.sym == SDLK_ESCAPE)) quit = 1;        /* Window closed */
        }
       
        // Grab a keystate snapshot
        keystate = SDL_GetKeyState( NULL );
        /* Handle key presses */

        if (keystate[SDLK_LEFT])
         {
            if((int)Player.x - (int)Camera.x + (SCREEN_WIDTH/2) != 0)
             if(!tileCollision(x-1, y, TILESIZE, TILESIZE))
              Player.x -= 1;
         }
       
        if (keystate[SDLK_RIGHT])
         {
            
             if(!tileCollision(x+1, y, TILESIZE, TILESIZE))
              Player.x += 1;
         }
         
        if (keystate[SDLK_UP])
         if((int)Player.y - (int)Camera.y + (SCREEN_HEIGHT/2) != 0 )
          if(!tileCollision(x, y-1, TILESIZE, TILESIZE))
           Player.y-=1;
         
        if (keystate[SDLK_DOWN])
         if((int)Player.y - (int)Camera.y + (SCREEN_HEIGHT/2) != 320 - PLAYER_H )
          if(!tileCollision(x, y+1, TILESIZE, TILESIZE))
           Player.y+=1;
}

    int fps_sync ()
    {
        t = SDL_GetTicks ();
        //printf("tl: %d t: %d\n", tl, t);
        if (t - tl >= frequency)
        {
            temp = (t - tl) / frequency; //delta time
            tl += temp * frequency;
            //printf("temp: %d tl: %d \n", t, tl);
            return temp;
        }
        else
        {
            SDL_Delay (frequency - (t - tl));
            tl += frequency;
            return 1;
        }
    }

    void logicLoop()
    {
       getInput();
    }

    int mainLoop()
    {
      //main game loop
      while(!quit)
       {
        repeat = fps_sync ();
            for (i = 0; i < repeat; i ++)
             {
                logicLoop();
                doCamera();
                //Debug purpose
                //int x = (int)Player.x/TILESIZE;
                //int y = (int)Player.y/TILESIZE;
                //printf("Player tile %d %d\n", x, y);
             }
             
            //clear the screen
            SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 128, 128, 128));
            //draw to the screen
            Draw();
            //update the screen
            SDL_Flip(screen);
       }
    }

    int main(int argc, char *argv[])
    {
      // init video stuff
       // init screen
        screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_SWSURFACE);
        if(screen == NULL)
        {
            fprintf(stderr, "Can't initialize SDL: %s\n", SDL_GetError());
            exit(-1);
        }

        SDL_WM_SetCaption("Scrolling", "Scrolling");
       
       
        Player.x = 32; //-SCREEN_WIDTH/2 + TILESIZE;
        Player.y = 32; //36 middle
       
        //main game loop
        mainLoop();
           SDL_Quit();
        return 0;
    }
http://www.pix3lworkshop.altervista.org/ - Your 8bit choice since 2006!
User avatar
Pix3l
 
Posts: 55
Joined: 10 Sep 2010, 21:00
Location: Italy

Re: 2D tile map scrolling and collision

Postby ghoulsblade » 02 Jul 2011, 12:28

User avatar
ghoulsblade
Global Moderator
 
Posts: 138
Joined: 08 Nov 2009, 22:47

Re: 2D tile map scrolling and collision

Postby Pix3l » 03 Jul 2011, 20:09

It's not exactly what i need :]
I can perform collisions on tile based maps, but when i try to implement scrolling, collisions doesn't works right...
I need to figure out how scrolling works and make collisions working with it
http://www.pix3lworkshop.altervista.org/ - Your 8bit choice since 2006!
User avatar
Pix3l
 
Posts: 55
Joined: 10 Sep 2010, 21:00
Location: Italy

Re: 2D tile map scrolling and collision

Postby Edward_Lii » 05 Jul 2011, 07:35

Hello Pix3l,

Pix3l {l Wrote}:I can perform collisions on tile based maps, but when i try to implement scrolling, collisions doesn't works right...
I need to figure out how scrolling works and make collisions working with it

I haven't looked at your code, but what has collision to do with scrolling?

Scrolling only determines what to draw, it shouldn't influence collision.
First get collision to work than implement scrolling, if collision is broken, then it is a rendering problem.

Best of luck! ;)
From,
Edward_Lii
User avatar
Edward_Lii
MnMS Moderator
 
Posts: 777
Joined: 20 Dec 2010, 16:46

Re: 2D tile map scrolling and collision

Postby Pix3l » 06 Jul 2011, 19:10

I have tested collision in a simple static tile based map without scrolling, and it works.
My problem is make tile based collision and scrolling working togheter, anyway i will try to read other tutorials and hope to makes it works.
Thanks anyway :]
http://www.pix3lworkshop.altervista.org/ - Your 8bit choice since 2006!
User avatar
Pix3l
 
Posts: 55
Joined: 10 Sep 2010, 21:00
Location: Italy

Who is online

Users browsing this forum: No registered users and 1 guest