|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| ||||||||||||||||||||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Space Invaders SDL - timing issue
I'm having issues with the movement of the ship in this invaders game. The movement is smooth, but I want it to begin slowly during the inititial stages of movement, then gradually increase in speed.
I was using time.h functions to keep time before, but then I realized that using a simple int counter would work since it would only increase by about 200 every second; I think this might be because the SDL update screen command is very slow, so the main while loop isn't iterating that often. It's odd because the complex bounds checking algorithms are lightning fast it seems. Adding more aliens to the screen has no effect on the game speed. Having 1 alien is no different to having 96, in terms of speed. Save the following as functions.cpp: Code:
#include <SDL/SDL.h>
#define SWAP(x, y) (x ^= y ^= x ^= y)
bool keysHeld[323] = {false};
char shiftkeys[323] = { 0 };
SDL_Surface* screen;
SDL_Event ev;
int keypoll()
{
if (SDL_PollEvent(&ev))
{
if (ev.type == SDL_QUIT)
{
}
if (ev.type == SDL_KEYDOWN)
{
keysHeld[ev.key.keysym.sym] = true;
return ev.key.keysym.sym;
}
if (ev.type == SDL_KEYUP)
{
keysHeld[ev.key.keysym.sym] = false;
return 0;
}
}
return 0;
}
int keywait()
{
int key;
while (1)
{
key=keypoll();
if (key != 0) return key;
}
}
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
void dispixel(int y,int x,int r,int g,int b)
{
Uint16 pixel = SDL_MapRGB(screen->format,r,g,b);
putpixel(screen,x,y,pixel);
}
void start_display()
{
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
}
void end_display()
{
SDL_Quit();
}
void clear_screen()
{
SDL_FillRect( screen, NULL, 0 );
}
void update_screen()
{
// When you draw pixels to the SDL_Surface structure the screen isn't changed until you call this function
// Wait until you've done all the changes etc before you call the function to keep a snappy feel to the program
SDL_Flip(screen);
}
void line(int x0, int y0, int x1, int y1, int r, int g, int b)
{
int Dx = x1 - x0;
int Dy = y1 - y0;
int steep = (abs(Dy) >= abs(Dx));
if (steep) {
SWAP(x0, y0);
SWAP(x1, y1);
// recompute Dx, Dy after swap
Dx = x1 - x0;
Dy = y1 - y0;
}
int xstep = 1;
if (Dx < 0) {
xstep = -1;
Dx = -Dx;
}
int ystep = 1;
if (Dy < 0) {
ystep = -1;
Dy = -Dy;
}
int TwoDy = 2*Dy;
int TwoDyTwoDx = TwoDy - 2*Dx; // 2*Dy - 2*Dx
int E = TwoDy - Dx; //2*Dy - Dx
int y = y0;
int xDraw, yDraw;
for (int x = x0; x != x1; x += xstep) {
if (steep) {
xDraw = y;
yDraw = x;
} else {
xDraw = x;
yDraw = y;
}
// plot
dispixel(xDraw, yDraw, r, g, b);
// next
if (E > 0) {
E += TwoDyTwoDx; //E += 2*Dy - 2*Dx;
y = y + ystep;
} else {
E += TwoDy; //E += 2*Dy;
}
}
}
int left_key_down()
{
return keysHeld[SDLK_LEFT];
}
int right_key_down()
{
return keysHeld[SDLK_RIGHT];
}
int f_key_down()
{
return keysHeld[SDLK_f];
}
Save following as global.cpp Code:
bool global_ship_icon[18][42] =
{
{ 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 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, 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 },
{ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1 }};
bool global_alien_icon[15][14] = {
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0},
{0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0},
{0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0},
{0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0},
{0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 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, 1, 0},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} };
bool global_alien_icon2[15][14] = {
{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, 1, 0},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0},
{0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0},
{0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0},
{0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0},
{0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0} };
Save following as functions.h: Code:
int keypoll(); int keywait(); void clear_screen(); void start_display(); void end_display(); void update_screen(); void dispixel(int,int,int,int,int); void line(int, int, int, int, int, int, int); int ramdom_number(int); int left_key_down(); int right_key_down(); int f_key_down(); Save following as objects.h: Code:
class WeaponBolt
{
public:
int y_pos;
int x_pos;
WeaponBolt();
};
class Alien
{
public:
int y_pos;
int x_pos;
int v_range;
int h_range;
Alien();
};
Save following as objects.cpp: Code:
#include "objects.h"
WeaponBolt::WeaponBolt()
{
y_pos=0;
x_pos=0;
}
Alien::Alien()
{
y_pos = 0;
x_pos = 0;
v_range = 15;
h_range = 14;
}
Save the following as main.cpp Code:
#include "functions.h"
#include "objects.h"
#include <time.h>
#include <vector>
extern bool global_ship_icon[18][42];
extern bool global_alien_icon[15][14];
extern bool global_alien_icon2[15][14];
int main()
{
start_display();
std::vector<WeaponBolt> array_of_bolts;
std::vector<WeaponBolt>::iterator it_array_of_bolts;
std::vector<Alien> array_of_aliens;
std::vector<Alien>::iterator it_array_of_aliens;
WeaponBolt newbolt;
Alien newalien;
newalien.y_pos = 5;
newalien.x_pos = 40;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 12; j++)
{
newalien.x_pos +=39;
array_of_aliens.push_back(newalien);
}
newalien.x_pos = 40;
newalien.y_pos +=21;
}
int smooth_move = 50;
int dec = 1;
int alieni = 0;
int limit = 0;
int limit2 = 0;
int delay = 0;
int ypos = 450;
int xpos = 0;
int key;
int interval = 0;
int interval2 = 0;
int interval3 = 0;
clock_t first;
clock_t second = clock();
while (1)
{
//first = clock();
interval++;
interval2++;
interval3++;
limit = array_of_bolts.size();
limit2 = array_of_aliens.size();
/* move all bolts and destroy them if necessary */
for (int i = 0; i < limit; i++)
{
array_of_bolts[i].y_pos--;
/* ckeck to see if this bolt has entered the range of this alien */
for (int a = 0; a < limit2; a++)
{
if (
(array_of_bolts[i].y_pos >= array_of_aliens[a].y_pos && array_of_bolts[i].y_pos <= array_of_aliens[a].y_pos+array_of_aliens[a].v_range) &&
(array_of_bolts[i].x_pos >= array_of_aliens[a].x_pos && array_of_bolts[i].x_pos <= array_of_aliens[a].x_pos+array_of_aliens[a].h_range))
{
it_array_of_bolts = array_of_bolts.begin(); it_array_of_bolts+=i;
it_array_of_aliens = array_of_aliens.begin(); it_array_of_aliens+=a;
array_of_bolts.erase(it_array_of_bolts);
array_of_aliens.erase(it_array_of_aliens);
}
}
if (array_of_bolts[i].y_pos<=0)
{
it_array_of_bolts = array_of_bolts.begin(); it_array_of_bolts+=i;
array_of_bolts.erase(it_array_of_bolts);
}
}
/* respond to key presses and act if keys are still held down */
key = keypoll();
if (key=='q') break;
else if (key == 'f' || f_key_down())
{
if (delay == 0)
{
delay = 1;
newbolt.y_pos = ypos-6;
newbolt.x_pos = xpos+20;
array_of_bolts.push_back(newbolt);
}
}
if (interval2 >= 100)
{
interval2 = 0;
if (alieni == 0) { alieni = 1; }
else alieni = 0;
}
if (interval >= 100)
{
interval = 0;
delay = 0;
}
if ( left_key_down() )
{
if (smooth_move > 0)
{
if (interval3 >= smooth_move)
{
interval3 = 0;
xpos--;
}
smooth_move-=dec;
dec = dec * 2;
}
else
xpos--;
}
else if ( right_key_down() )
{
if (smooth_move > 0)
{
if (interval3 >= smooth_move)
{
interval3 = 0;
xpos++;
}
smooth_move-=dec;
dec = dec * 2;
}
else
xpos++;
}
else
{
smooth_move = 1000;
dec = 1;
}
/* draw all the objects to the buffer surface */
clear_screen();
limit = array_of_aliens.size();
for (int i = 0; i < limit; i++)
{
for (int ii = 0; ii < 15; ii++)
{
for (int jj = 0; jj < 14; jj++)
{
if (alieni==0)
{
if (global_alien_icon[ii][jj])
{
dispixel(array_of_aliens[i].y_pos+ii,array_of_aliens[i].x_pos+jj,0,255,0);
}
}
else
{
if (global_alien_icon2[ii][jj])
{
dispixel(array_of_aliens[i].y_pos+ii,array_of_aliens[i].x_pos+jj,0,255,0);
}
}
}
}
}
for (int i = 0; i < 18; i++)
{
for (int j = 0; j < 42; j++)
{
if (global_ship_icon[i][j])
{
dispixel(ypos+i,xpos+j,255,255,255);
}
}
}
limit = array_of_bolts.size();
for (int i = 0; i < limit; i++)
{
for (int ii = 0; ii < 4; ii++)
{
for (int jj = 0; jj < 2; jj++)
{
dispixel(array_of_bolts[i].y_pos+ii,array_of_bolts[i].x_pos+jj,255,255,255);
}
}
}
/* copy the buffer surface to hardware video memory (update screen) */
update_screen();
}
//keywait();
end_display();
}
|
|
#2
|
||||
|
||||
|
Was there a question in there, or are you issuing instructions to an employee via the forum?
__________________
Write no code whose complexity leaves you wondering what the hell you did. Politically Incorrect DaWei on Pointers Grumpy on Exceptions |
|
#3
|
|||
|
|||
|
Quote:
Sizablegrin, bearing in mind the conversation we had when I posted last, you should know by now that I don't have any employees, nor am I employed in the game programming industry. As I said before, I do this for fun, not for profit. If you would like to take a look at the program and see what the problem is, I'd be grateful. |
|
#4
|
||||
|
||||
|
You still haven't bothered to tell us what you think we should be looking for. I don't see a question in there anywhere.
__________________
My worst nightmare was a pointless infinite loop. Work in progress; don't poke the curmudgeon! http://www.odonahue.com/ |
|
#5
|
||||
|
||||
|
Prototype something small in a single source file which demonstrates the essence of the problem.
This does 3 things: a) we're more likely to look at something small, rather than something large. b) you might discover something about the problem in the process. c) you'll be able to ask a more direct question about the issue. It's a basic rule. If you're stuck then prototype something which is easy to edit, and allows you to get down to the real problem quickly. Oh, and FWIW, your SWAP macro sucks. It's a dumb 1980's hack.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut. |
|
#6
|
|||
|
|||
|
Quote:
Stuck? No, my dear, I'm not. If you don't want to look at the code or compile it, then don't. Please don't whine about it. |
|
#7
|
|||
|
|||
|
Quote:
I'll take your word for it. I got the line drawing code from Wikipedia. Since you seem to know so much about the subject, perhaps you would like to go there and correct the error? http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm |
|
#8
|
|||
|
|||
|
http://id.mind.net/~zona/mstm/physics/mechanics/kinematics/EquationsForAcceleratedMotion/Origins/Velocity/Origin.htm
http://id.mind.net/~zona/mstm/physics/mechanics/kinematics/EquationsForAcceleratedMotion/EquationsForAcceleratedMotion.htm http://library.thinkquest.org/27948/accel.html |
|
#9
|
|||
|
|||
|
Quote:
Code:
x ^= y ^= x ^= y ). You should never modify a variable more than once between sequence points. The following, however, is fine: Code:
x ^= y, y ^= x, x ^= y Last edited by Lux Perpetua : July 6th, 2009 at 02:22 PM. |
|
#10
|
||||
|
||||
|
What exactly is SDL anyway? Would it be Simple DirectMediay Layer by any chance? Posters should never assume that their favorite non-standard library is going to be well known and if want any meaningful assistance around here, you shouldn't expect us to do much work beyond thinking about helping you with your particular problem.
Quote:
You've told us how you want the ship to behave and that you are "having trouble" with it. But you have been very vague. A quick visual scan of the code you posted doesn't turn up anything that looks like a ship. Your comments don't reference your code in any meaningful way that would indicate to us how we can help you. You seem to expect us to download, compile, test and read your mind in an effort to assist you. Your experience to date should inform you that's not a good plan. Quote:
You should always assume that loop execution time will vary substantially from one machine to the next and even from one test pass to the next; unless you introduce some timing mechanism. I suspect the crux of your difficulty revolves around keeping time and synchronizing something in your code to that time. Is that the case? I normally don't bother looking at a poster's code if they haven't stated their problem well enough for me to figure out what I should look for, but looking at your main() function, I see that it's way too complex for even an expert software engineer to review without committing a substantial block of time. You should break it up into smaller functions. Perhaps if you had had something like a calculateShipsNextPosition( currentPos, velocity, direction ) we could have zeroed in the the code in question? The solution to your problem might just reveal itself after you refactor your current code set. |
![]() |
| Viewing: Dev Shed Forums > Programming Languages > C Programming > Space Invaders SDL - timing issue |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|
|