I want to make a simple platform game with a player can jump around, but i have some problems in making the player jump correctly and with collision between player and platfroms.
I don't found any good tutorial about platform game in C, only this one http://www.parallelrealities.co.uk/tutorials/intermediate/tutorial14.php that i try to rewrote by my self.
The code is below, maybe there is some junkies around... I hope someone can help me to fix this.
- {l Code}: {l Select All Code}
//gcc -o jumpfix jumpfix.c -lSDL
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <time.h>
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 320
#define MAP_W 10
#define MAP_H 10
#define BLANK_TILE 0
#define TILESIZE 32
#define PLAYER_SPEED 1
#define FRICTION 0.99f
#define GRAVITY_SPEED 1
#define TIME_STOP 2000
#define MAX_FALL_SPEED 20
//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, *textSurface;
SDL_Rect rect; //Main drawing surface
Uint8 *keystate; // keyboard state
float increment, incrementY;
int playfield[10][10] =
{
1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,1,1,1,0,0,0,1,
1,0,0,0,0,0,0,1,0,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,1,1,
1,0,0,0,0,1,1,0,0,1,
1,0,0,0,1,1,1,0,0,1,
1,1,1,1,1,1,1,1,1,1,
};
void Move();
struct _Player
{
int w, h, onGround;
int thinkTime, jump;
int x, y, dirX, dirY, maxjump;
} Player;
struct _Character {
int x,y;
int dir;
int delay;
} Character;
struct _Game
{
int status;
} Game;
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, j;
for (i = 0; i < 10; i++)
{
for (j = 0; j < 10; j++)
{
if(playfield[j][i]==0)
DrawRect(i * TILESIZE, j * TILESIZE, TILESIZE, TILESIZE, 0xffffff);
}
}
}
void Draw()
{
//Draw Maze
drawbackground();
//Draw Player
DrawRect(Player.x, Player.y, TILESIZE, TILESIZE, 0xff0000);
}
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 * MAP_W ||
y < 0 || (y + h) > TILESIZE * MAP_H)
return 1;
// The passed coordinates are in pixels so convert them to tiles.
minx = x / TILESIZE;
miny = y / TILESIZE;
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()
{
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 */
//The paddles can move only if there's nothing on their way
if (keystate[SDLK_LEFT])
{
Player.dirX = -1;
}
if (keystate[SDLK_RIGHT])
{
Player.dirX = 1;
}
if (!keystate[SDLK_LEFT] && !keystate[SDLK_RIGHT])
{
Player.dirX=0;
increment-=0.1;
}
/*
if (!keystate[SDLK_LEFT] && !keystate[SDLK_RIGHT] && increment<0)
{
Player.dirX=0;
increment+=0.1;
}
*/
if (keystate[SDLK_UP] && Player.onGround == 1)
{
//Player.maxjump = 13;
Player.dirY = -11;
//printf("assing power\n");
}
}
void Move()
{
// Check our playground before move
if(Player.x >=0 || Player.x + TILESIZE <= MAP_W ||
Player.y >=0 || Player.y + TILESIZE <= MAP_H)
{
if(!tileCollision(Player.x+Player.dirX, Player.y, TILESIZE, TILESIZE))
{
Player.x+=Player.dirX; // Increment/Drecrement coordinates
//Player.dirY=1;
}
Player.dirY += GRAVITY_SPEED;
if (Player.dirY >= MAX_FALL_SPEED)
{
Player.dirY = MAX_FALL_SPEED;
}
if (Player.dirY > 0)
{
/* Trying to move down */
if(tileCollision(Player.x, Player.y, TILESIZE, TILESIZE+Player.dirY))
{
/* Place the player as close to the solid tile as possible */
//printf("on ground!\n");
Player.onGround = 1;
Player.dirY = 0;
}
}
else if (Player.dirY < 0)
{
/* Trying to move up */
if(tileCollision(Player.x, Player.y-1, TILESIZE, TILESIZE+Player.dirY))
{
/* Place the player as close to the solid tile as possible */
Player.y += Player.dirY;
Player.dirY = 0;
}
}
Player.y+=Player.dirY;
}
printf("dirY %d\n", Player.dirY);
}
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()
{
if(!paused)
getInput();
}
int mainLoop()
{
//main game loop
while(!quit)
{
SDL_PollEvent(&event);
repeat = fps_sync ();
for (i = 0; i < repeat; i ++)
{
if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE))
quit = 1; /* Window closed */
switch(Game.status)
{
case 0: //Menu
logicLoop();
Move();
break;
}
}
//clear the screen
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
//draw to the screen
Draw();
//update the screen
SDL_Flip(screen);
}
}
int main()
{
// 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("Maze", "Maze");
Player.x = 64;
Player.y = 64;
//main game loop
mainLoop();
printf("Thanks for playing!\n");
SDL_Quit();
return 0;
}