// Code begins ///////////////////////////////////
#include "SDL.h"
using namespace std;
// The attributes of the window
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
// The surface for screen
SDL_Surface *screen;
// 'color' will define the color wich is used in SDL_FillRect()
Uint32 color;
// Initialize SDL, images and so on...
void InitializeAll();
// Handle movement
void Movement();
// CLASSES ///////////////////////////////////////
// Information about players spaceship
class Player
{
private:
// Temporary surface to images
SDL_Surface *Temp;
public:
// Main surfaces for images
SDL_Surface *Ship;
SDL_Surface *LFlame;
SDL_Surface *RFlame;
SDL_Surface *DFlame;
// Coordinates of ship and flame images, contain place.x and place.y
SDL_Rect ShipPlace;
SDL_Rect LFlamePlace;
SDL_Rect RFLmaePlace;
SDL_Rect DFlamePlace;
// Initialize all Ships images
void InitShipImages();
// Initialize ship images places
void InitShipPlaces();
};
// Set up class
Player player;
void Player::InitShipImages()
{
// Load the images to temporary surfaces and convert it to DisplayFormat and delete temp
Temp = SDL_LoadBMP("Images/Ship/ship.bmp"); // Ship
Ship = SDL_DisplayFormat(Temp);
SDL_FreeSurface(Temp);
Temp = SDL_LoadBMP("Images/Ship/flameleft.bmp"); // Flame Left
LFlame = SDL_DisplayFormat(Temp);
SDL_FreeSurface(Temp);
Temp= SDL_LoadBMP("Images/Ship/flameright.bmp"); // Flame Right
RFlame = SDL_DisplayFormat(Temp);
SDL_FreeSurface(Temp);
Temp = SDL_LoadBMP("Images/Ship/flamedown.bmp"); // Flame Down
DFlame = SDL_DisplayFormat(Temp);
SDL_FreeSurface(Temp);
}
void Player::InitShipPlaces()
{
// Where the ship is (center of screen)
ShipPlace.x = 302;
ShipPlace.y = 231;
// Where the Left Flame is
LFlamePlace.x = ShipPlace.x-11;
LFlamePlace.y = ShipPlace.x+5;
// Right Flame
RFLmaePlace.x = ShipPlace.x+35;
RFLmaePlace.y = ShipPlace.y+5;
// And Flame Down
DFlamePlace.x = ShipPlace.x+11;
DFlamePlace.y = ShipPlace.y+17;
}
class Level
{
private:
// Temporary surface for Level 1
SDL_Surface *Temp_Level1;
public:
// Main surface for Level 1
SDL_Surface *Level1;
// Coordinates to Level 1 in screen, includes x and y.
SDL_Rect PlaceLevel1;
// Coordinates to pick target part of Level 1, includes x, y, w and h.
SDL_Rect PartOfLevel1;
// Initialize images of maps
void InitLevelImages();
// Initialize coordinates of maps
void InitLevelPlaces();
};
// Set up class
Level level;
void Level::InitLevelImages()
{
// Load the map image to temporary surface
Temp_Level1 = SDL_LoadBMP("Images/Levels/Taso3.11.bmp");
// Load temporary surface to main surface and delete temporary
Level1 = SDL_DisplayFormat(Temp_Level1);
SDL_FreeSurface(Temp_Level1);
}
void Level::InitLevelPlaces()
{
// Place of map on the screen (left upper corner)
PlaceLevel1.x = 0;
PlaceLevel1.y = 0;
// What place we blit to screen (works like starting place)
PartOfLevel1.x = 200;
PartOfLevel1.y = 200;
PartOfLevel1.w = 640;
PartOfLevel1.h = 480;
}
class TimeMovement
{
private:
// Key states
Uint8 *Keystate;
// Time handling
float Timerdiff; // Used to determine the time elapsed
float SecsPerFrame; // Used to hold the value for how many seconds have elapsed between frames
// Movement
struct DesiredDistance // Desired distance to move in a second, includes ships and levels x and y
{
// Ships
float sx;
float sy;
// Levels
float lx;
float ly;
};
struct MovementValue // Value to move by each frame for Ship and Level, includes x and y
{
// Ship
float sx;
float sy;
// Level
float lx;
float ly;
};
// Set up classes
DesiredDistance ddistance;
MovementValue movementv;
public:
float Timer; // Used to check the current time
// Key to game loop
bool IsRunning;
// Init DesiredDistance
void InitDDistance();
// Handles moving
void Movement();
};
// Set up class
TimeMovement timo;
void TimeMovement::InitDDistance()
{
// Init DesiredDistances
ddistance.sx = 0;
ddistance.sy = 0;
ddistance.lx = 0;
ddistance.ly = 0;
movementv.sx = 0;
movementv.sy = 0;
}
void TimeMovement::Movement()
{
// Check if user quits
SDL_Event event;
while(SDL_PollEvent(&event))
{
// If Quit
if (event.type == SDL_QUIT)
timo.IsRunning = false;
switch(event.type)
{
case SDL_KEYDOWN:
{
if(event.key.keysym.sym == SDLK_ESCAPE)
IsRunning = false;
}
break;
}
}
// Here begins movement code
// Get key states
Keystate = SDL_GetKeyState(NULL);
// If the pressed key is UP
if(Keystate[SDLK_UP])
{
timo.ddistance.sy -= 15.57;
}
// If the pressed key is DOWN
if(Keystate[SDLK_DOWN])
{
timo.ddistance.sy += 15.57;
}
// If the key was LEFT
if(Keystate[SDLK_LEFT])
{
timo.ddistance.sx -= 8.2;
}
// If the key was RIGHT
if(Keystate[SDLK_RIGHT])
{
timo.ddistance.sx += 8.2;
}
// This code will use Time based moving
// Determine how many seconds elapset, GetTime() -> Now
Timerdiff = SDL_GetTicks() - Timer;
/* Function uses milliseconds so convert to seconds
by dividing 1000 */
SecsPerFrame = (float)(Timerdiff/1000.0);
// Compute the movement value to Ship and Level, x and y
movementv.sx = (float) (ddistance.sx*SecsPerFrame); // Ships x
movementv.sy = (float) (ddistance.sy*SecsPerFrame); // Ships y
movementv.lx = (float) (ddistance.lx*SecsPerFrame); // Levels x
movementv.ly = (float) (ddistance.ly*SecsPerFrame); // Levels y
// Now add MovementValue to original coordinations, Ship&Level
player.ShipPlace.x += (Sint16) movementv.sx; // Ship x
player.ShipPlace.y += (Sint16) movementv.sy; // Ship y
level.PartOfLevel1.x += (Sint16) movementv.lx; // Level x
level.PartOfLevel1.y += (Sint16) movementv.ly; // Level y
}
// END OF CLASSES ////////////////////////////////
// MAIN PROGRAM BEGINS ///////////////////////////
int main(int argc, char *argv[])
{
// Initialize game
InitializeAll();
// Give a moment
SDL_Delay(500);
// Game loop starts here
while(timo.IsRunning == true)
{
// Get time
timo.Timer = SDL_GetTicks();
// Clear the screen
SDL_FillRect(screen, NULL, color);
// Draw player to screen surface
SDL_BlitSurface(player.Ship, NULL, screen, &player.ShipPlace);
// Flip to screen
SDL_Flip(screen);
// Check movement
timo.Movement();
}
return 0;
}
// OTHER PROGRAMS ////////////////////////////////
void InitializeAll()
{
// Initialize SDL (Video and Timer)
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) == -1)
{
fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
}
// Initialize screen with HWSURFACE and DOUBLEBUF
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_HWSURFACE|SDL_DOUBLEBUF);
//Set the window caption
SDL_WM_SetCaption( "Battle Lander", NULL );
//Initialize images and places
player.InitShipImages();
player.InitShipPlaces();
level.InitLevelImages();
level.InitLevelPlaces();
// Define the SDL_FIllRect color (black)
color = SDL_MapRGB(screen->format, 0, 0, 0);
// Set game on
timo.IsRunning = true;
}
Laggy movement (SDL) [SOLVED]
I have been working out my new game but now I found a wierd problem. When I run program all is fine, but when the animation should move, it moves a 'little' laggy. I have other older code wich has been a base to this new and the old works fine. I can't figure out what the problem is even these two program sould work same way... I'm using 'time based moving' and the animation looks laggy and it won't respond to all movement controls instantly.
Here is my code. It's a little big and the problem would be hard to find. All help is welcome!
BTW, I think that in 'Timerdiff = SDL_GetTicks() - Timer;' function 'Timer' will made this laggy... I'm not sure about that.
[Edited by - Zakkeus on December 20, 2005 3:27:13 PM]
When you say 'laggy' what do you mean? Jerky movemnt? When you press a key to move it takes a couple frames to respond? What happens if you make in non-frame-rate-independent? Does the 'laggyness' go away then?
Also, it might be easier if you provide less code in the future. We probrablly don't need to see your functions that initiate values.
Also, it might be easier if you provide less code in the future. We probrablly don't need to see your functions that initiate values.
Yeah, I think jerky would be the best word. It just moves slow, then faster and sometimes jumps around. It doesn't move smoothy.
It takes a while when it respond to the key pressing. Maybe a couble of frames. It stays still or keeps going to the way where it was going while pressing couple of seconds. And it doesn't slow it's speed smoothly (it should!) but stops suddenly and then change direction.
The jerky moving disappear if I put it to no_time_based_moving.
Oh, sorry about that ammount of code. I promise that I will reduce the code in future!
[Edited by - Zakkeus on December 17, 2005 6:55:50 PM]
It takes a while when it respond to the key pressing. Maybe a couble of frames. It stays still or keeps going to the way where it was going while pressing couple of seconds. And it doesn't slow it's speed smoothly (it should!) but stops suddenly and then change direction.
The jerky moving disappear if I put it to no_time_based_moving.
Oh, sorry about that ammount of code. I promise that I will reduce the code in future!
[Edited by - Zakkeus on December 17, 2005 6:55:50 PM]
Zakk, I tried to compile your code (and I created dummy images) and I only get a window blinked up and stderr.txt says there was a seg-fault. That aside I'd like to guess as to what the problem is. Your code goes something like this:
(Distance = speed*time)
speed = speed + SPEED_X (that is, timo.ddistance.sx += 8.2;)
Distance to move = DeltaTime * speed
So I guess what I'm saying is you're mixing up your speed and your distance...as far as I can make out, the further you are from the original point on the map, the faster you'll move because you're multiplying your delta time by how far you've moved instead of a constant speed.
This could probably be fixed by using constant speeds.
I might be totally off the mark though; just a suggestion!
(Distance = speed*time)
speed = speed + SPEED_X (that is, timo.ddistance.sx += 8.2;)
Distance to move = DeltaTime * speed
So I guess what I'm saying is you're mixing up your speed and your distance...as far as I can make out, the further you are from the original point on the map, the faster you'll move because you're multiplying your delta time by how far you've moved instead of a constant speed.
This could probably be fixed by using constant speeds.
const int SPEED_X = 8.2 // this will probably be WAY WAY WAY too fast..maybe divide by 100if(Keystate[SDLK_RIGHT]){ timo.ddistance.sx += SPEED_X * Timerdiff;}if(Keystate[SDLK_LEFT]){ timo.ddistance.sx -= SPEED_X * Timerdiff;}// then your code that moves the ship
I might be totally off the mark though; just a suggestion!
Thx, Frequency but that didn't help...
I think I haven't mixed up time and distance. Here is a web page where I get this idea. I hope it will help a little.
Movement
I think I haven't mixed up time and distance. Here is a web page where I get this idea. I hope it will help a little.
Movement
Heh, I found my mistake. The thing wich solved my problem was that I used this code:
But 'the right way' was something like this:
I don't know the reason why is should be like this, but this helped me...
// Now add MovementValue to original coordinations, Ship&Level player.ShipPlace.x += (Sint16) movementv.sx; // Ship x player.ShipPlace.y += (Sint16) movementv.sy; // Ship y
But 'the right way' was something like this:
// Now add MovementValue to original coordinations, Ship&Level x += (Sint16) movementv.sx; // Ship x y += (Sint16) movementv.sy; // Ship y player.ShipPlace.x = (Sint16) x; player.ShipPlace.y = (Sint16) y;
I don't know the reason why is should be like this, but this helped me...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement