Alright, so there’s this pandora platforming competition, that i decided to bother with, seeing what the competition already has i’m not looking at prize money, but it’s something fun to do all the same.
project name: for now? pjump, which is bound to change once i design levels etc for it
progress: basic physics, collisions, jumping and gravity done, still limited to once screenful of level as i haven’t programmed the screen scrolling yet
Basic system:
A level is drawn as a bmp, no restrictions on size (apart from memory limits etc), and can look like anything that can be drawn in a bmp really
Along with each level is a level_map.bmp file, which specifies the map for the level, using different colours for solid objects, death traps, enemies and the like
Currently defined colours: 0xFF00FF : solid objects, ground etc
This map is then used for collisions with the solid objects, and starting placement of enemies etc, which will be specified as another colour in the map, so it can be scanned at load time and all the objects can be put into their respective linked lists/whathaveyous (therefore level loading might take a while, so this idea might have to go, and just use a config file for the other objects. this would make it a lot faster, but harder to get objects positioning right when creating a level)
collisions are handled simply by checking the row of pixels next to the player, although ignoring the first and last X pixels (X is defined differently for each direction), this is so the player can a: walk up slopes (without walking into the floor would be good aswell eventually), and doesn’t float in mid air when near the edge of a cliff.
The physics:
here’s a simplified version of the main game loop for basic player physics/clipping (in psuedo code, this won’t compile, and probably has mistakes anyway
)
(note: this is missing the screen scrolling, and clipping with the edges of the screen)
while(level is running)
{
get_input() //get the state of the input, and set pressed_* variable accordingly
//do some very basic physics to calculate where we want to be at the end of the frame
if(pressed_left)
if(x_delta>(0-X_DELTA_MAX))
x_delta--;
else
if(x_delta<0)
x_delta++; //slow the player down until stop
if(pressed_right)
if(x_delta<X_DELTA_MAX)
x_delta++;
else
if(x_delta>0)
x_delta--; //slow the player down until stop
//do the movement for this frame, for loops are used to generate smooth movement (a single flip at the end of the frame produces jerkyness
//in theory this actually does all the movement at the start of the frame, and have a delay afterwards, which would also make jerky movement, but it seems to work ok
if(x_delta<0)
if(can move left (i.e not solid to the left, or edge of screen etc)
for(i=0;i>x_delta;i++)
{
player->x--;
update_player();//redraw the player at the new location
}
else
x_delta=0; //player can't move, so stop the player moving
else if(x_delta>0)
else if(can move left)
for(i=0;i<x_delta;i++)
{
player->x++;
update_player();
}
else
x_delta=0;
//gravity
if(we can fall(i.e not colliding downwards))
if(gravity_t<GRAVITY)
gravity_t+=GRAVITY_DELTA; //if we're not at terminal velocity, increase velocity by GRAVITY_DELTA (acceleration)
for(i=0;i<gravity_t;i++) //smooth movement loop
{
if(we can fall) //need another check here as we are changing position
{
player->y++; //in SDL positive y is downwards
update_player();
}
}
else //we can't fall, so set things to not fall. and if we're on the ground we're obviously not jumping either
{
gravity_t=0;
jumping=0;
}
//jumping -- this is the most complicated, but is pretty simple once you think about it
if((we are on the ground) && pressed_jump && !jumping) //if we can jump, and have requested a jump
{
jumping=1; //we are now jumping
jump_orig_y=player->y; //store the start of our jump for use in calculating the jump height etc
}
if(jumping)
{
if(!touching the ceiling)
{
//as jump_t goes from 0 to 0.5, this will increase the jump height in a sin curve, to JUMP_HEIGHT
player->y=jump_orig_y-(JUMP_HEIGHT*sin(jump_t*PI);
jump_t+=JUMP_T_DELTA; //increase jump_t for the next frame in the jump
if(jump_t>0.5) //if we've reached the top of the jump, we're not jumping anymore
{
jump_t=0;
jumping=0;
pressed_jump=0;
}
}
else //we've hit the ceiling, cancel the jump
{
jump_t=0;
jumping=0;
pressed_jump=0;
}
}
draw stuff to the screen();
while(SDL_GetTicks()<last_frame+FRAME_TIME); //loop until we've waited long enough for this frame
last_frame=SDL_GetTicks(); //update the last_frame time
}
Like this:
Like Loading...