Posted: Thu Oct 07, 2004 7:36 am
Are vectors new or something? Because my books don't even mention them. At least I don't remember them mentioning it. *Checks*
The Next Generation of 2D Roleplaying Games
http://elysianshadows.com/phpBB3/
Code: Select all
#include <vector>
#include <string>
using namespace std;
class Thingy {
int someNumber;
string someString;
};
vector<Thingy*>thingiesVector; //vector of pointers to Thingy s
vector<Thingy>realThingies; //vector of copies of Thingy s
int main() {
Thingy* aThingy;
//add 5 pointers to Thingy s to thingiesVector
for (int i = 0;i < 5;i++) {
aThingy = NULL;
if (!(aThingy = new Thingy)) {
//error handle, probably exit.
}
thingiesVector.push_back(aThingy); //copies aThingy to thingies
//since aThingy is a pointer, that's all thats copied -- a pointer
//to an object, instead of making a copy of the whole object itself.
//which you can do, but the only problem is that when a vector
//has a new object or removes one then the whole thing might
//shift its place in memory -- and if you have a pointer to
//a vector object, it becomes no good, because that object
//has moved where it was and the pointer is no longer
//pointing to it.
//anyway -- back to the program
}
//then to iterate, you can do this....
//------------------------------------------------
//make an iterator (pointer to an object in a vector... has some nice
//properties. watch.)
vector<Thingy*>::iterator thingyIt;
for (thingyIt = thingiesVector.begin();thingyIt != thingiesVector.end();thingyIt++)
{
//isnt that incremental operator so convenient? :)
//i am unsure what happens if you remove an obj. and
//then increment a vector iterator, however. will have to look it up.
//since i dont know, i usually just be safe and go back to
//the beginning and reincrement. which is why there are two ways
//to iterate through a vector.
delete *thingyIt; //dereference the iterator, and you're left with
//a pointer to a Thingy. (since the vector is a vector of Thingy* s.)
}
//you can do this, then
thingyIt = thingiesVector.begin();
while (thingyIt != thingiesVector.end()) {
thingyVector.erase(thingyIt);
thingyIt = thingiesVector.begin();
};
//or this.
thingiesVector.clear(); //blankify the vector.
//--------------------------------------
// or you can do this
Thingy* theObj;
unsigned int theSize = thingiesVector.size();
//because repeated accesses to .size() is slower than necessary.
for (unsigned int i = 0;i < theSize;i++) {
//note: .size() is slower than it should be, due to
//standards compliance. that's why iterators are usually preferred.
//but this is easier to understand.
theObj = thingiesVector.at(i);
//you can also use thingiesVector[i], however, this can cause
//access violations. .at() is a bit slower but lots safer. if you do your
//own
//if (i >= thingiesVector.size()) { break; } and if (i < 0) { break; }
//checking, though, you dont need it. note .size() is still slow.
//access violation, btw, as in you access something past the vector.
//just like can happen with arrays
delete theObj;
}
thingiesVector.clear();
// ---------------------------------------
return 0;
}
Code: Select all
//Tile based collision by JS Lemming
//requires static linkage to:
//sdl.lib, sdlmain.lib
//requires dynamic linkage to:
//sdl.dll
//include SDL stuff
#include "sdl.h"
//include ability to exit program
#include <stdlib.h>
//include math functions
#include <math.h>
//These are the T/F flags that will be used to determine if a
//key is being held down by the user. If true, the key is down... false its not.
bool f_Up;
bool f_Down;
bool f_Left;
bool f_Right;
bool f_Space;
bool f_Escape;
//Function KeyDown(KeyFlag) - checks whether the arg passed to it is true,
//thus returning true. Why have this function at all? For consistancy sakes
//of the KeyHit function.
bool KeyDown(bool KeyFlag) {
return KeyFlag;
}
//Function KeyHit(KeyFlag) - checks whether the arg passed to it is true.
//Then setting the flag to false, and returning true.
bool KeyHit(bool& KeyFlag) {
if(KeyFlag == true)
{
KeyFlag = false;
return true;
}
return false;
}
//Classes
class Player
{
//private:
public:
float m_x, m_y; //maybe converting to float will fix a bug?
float m_xvel, m_yvel;
public:
Player()
{
m_x = 0;
m_y = 0;
m_xvel = 0;
m_yvel = 0;
}
int GetX() { return (int)m_x; }
int GetY() { return (int)m_y; }
float GetXvel() { return m_xvel; }
float GetYvel() { return m_yvel; }
void SetX( float p_newx ) { m_x = p_newx; }
void SetY( float p_newy ) { m_y = p_newy; }
void SetXvel( float p_newxvel ) { m_xvel = p_newxvel; }
void SetYvel( float p_newyvel ) { m_yvel = p_newyvel; }
};
//how much an object gets pulled down per frame
float Gravity = 0.38;
//screen dimensions
const int SCREEN_WIDTH=640;
const int SCREEN_HEIGHT=480;
//array holding map data (0 or 1 for now)
int map[20][15];
//---FUNCTIONS---
//MoveHorizontal() - moves thing based on velocity
//returns -1 if top left hits a solid
// 1 if right boundry hits a solid
// 0 if no collision detected in move
int MoveHorizontal(float& p_xvel, float& p_x, float& p_y, int p_left, int p_right, int p_top, int p_bottom)
{
for(int i=1; i<=abs( (int)p_xvel ); i++ )
{
//temporarily define the object's bounderies
int BoundLeft = ((int)p_x + p_left);
int BoundRight = ((int)p_x + p_right-1);
int BoundTop = ((int)p_y + p_top);
int BoundBottom = ((int)p_y + p_bottom-1);
//set temp Move = true? vars to false
bool MoveLeft = false;
bool MoveRight = false;
//loop from boundtop to boundbottom (replace loop with mar's idea!)
for(int Point=BoundTop; Point<=BoundBottom; Point++)
{
//if object going left
if(p_xvel < 0)
{
//if object's left bound minus 1 is in a solid tile
if(map[ (BoundLeft-1)/32 ][ (Point)/32 ] == 1)
{
//set the object's xvel to 0 and return with -1
p_xvel = 0;
return -1;
}
else
{
//set the MoveLeft var to true
MoveLeft = true;
}
}
//if object going right
if(p_xvel > 0)
{
//if object's right bound plus 1 is in a solid tile
if(map[ (BoundRight+1)/32 ][ (Point)/32 ] == 1)
{
//set the object's xvel to 0 and return with 1
p_xvel = 0;
return 1;
}
else
{
//set the MoveRight var to true
MoveRight = true;
}
}
}
//if the Move vars are now true, adjust the x values
if(MoveLeft == true) { p_x = p_x - 1; }
if(MoveRight == true) { p_x = p_x + 1; }
//if the object has gone out of array bounds, push it back on
if(p_x < 0) { p_x = 0; p_xvel = 0; }
if(p_x > 20*32) { p_x = 20*32; p_xvel = 0; } //replace 20*32 with map height var/function
}
//if no solids were hit at all, return 0
return 0;
}
//MoveVertical() - moves thing based on velocity
//returns -1 if top boundry hits a solid
// 1 if bottom boundry hits a solid
// 0 if no collision detected in move
int MoveVertical(float& p_yvel, float& p_x, float& p_y, int p_left, int p_right, int p_top, int p_bottom)
{
for(int i=1; i<=abs( (int)p_yvel ); i++ )
{
//temporarily define the object's bounderies
int BoundLeft = ((int)p_x + p_left);
int BoundRight = ((int)p_x + p_right-1);
int BoundTop = ((int)p_y + p_top);
int BoundBottom = ((int)p_y + p_bottom-1);
//set temp Move = true? vars to false
bool MoveUp = false;
bool MoveDown = false;
//loop from boundleft to boundright (replace loop with mar's idea!)
for(int Point=BoundLeft; Point<=BoundRight; Point++)
{
//if object going up
if(p_yvel < 0)
{
//if object's top bound minus 1 is in a solid tile
if(map[ (Point)/32 ][ (BoundTop-1)/32 ] == 1)
{
//set the object's yvel to 0 and return with -1
p_yvel = 0;
return -1;
}
else
{
//set the MoveUp var to true
MoveUp = true;
}
}
//if object going down
if(p_yvel > 0)
{
//if object's bottom bound plus 1 is in a solid tile
if(map[ (Point)/32 ][ (BoundBottom+1)/32 ] == 1)
{
//set the object's yvel to 0 and return with 1
p_yvel = 0;
return 1;
}
else
{
//set the MoveDown var to true
MoveDown = true;
}
}
}
//if the Move vars are now true, adjust the y values
if(MoveUp == true) { p_y = p_y - 1; }
if(MoveDown == true) { p_y = p_y + 1; }
//if the object has gone out of array bounds, push it back on
if(p_y < 0) { p_y = 0; p_yvel = 0; }
if(p_y > 15*32) { p_y = 15*32; p_yvel = 0; } //replace 15*32 with map height var/function
}
//if no solids were hit at all, return 0
return 0;
}
//display surface
SDL_Surface* g_pDisplaySurface;
//event structure
SDL_Event g_Event;
//rectangle
SDL_Rect g_Rect;
//color components
Uint8 g_Red, g_Green, g_Blue;
//color value
Uint32 g_Color;
//main function
int main(int argc, char* argv[])
{
//initialize SDL
if (SDL_Init(SDL_INIT_VIDEO)==-1)
{
//error initializing SDL
//report the error
fprintf(stderr,"Could not initialize SDL!\n");
//end the program
exit(1);
}
else
{
//SDL initialized
//report success
fprintf(stdout,"SDL initialized properly!\n");
//set up to uninitialize SDL at exit
atexit(SDL_Quit);
}
//hide mouse
SDL_ShowCursor(SDL_DISABLE);
//create windowed environment
g_pDisplaySurface = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,16,SDL_ANYFORMAT|SDL_FULLSCREEN|SDL_DOUBLEBUF);
//error check
if (g_pDisplaySurface == NULL)
{
//report error
fprintf(stderr,"Could not set up display surface!\n");
//exit the program
exit(1);
}
//Create instance of class player
Player dude;
dude.SetX(3*32);
dude.SetY(10*32);
//clear map array
for(int x=0; x<=19; x++)
{
for(int y=0; y<=14; y++)
{
map[x][y] = 0;
}
}
//put some solids into the map array
for(int x=0; x<=19; x++)
{
map[x][0] = 1;
map[x][1] = 1;
map[x][12] = 1;
map[x][13] = 1;
map[x][14] = 1;
}
//add some more solids yo
map[0][9] = 1;
map[0][10] = 1;
map[0][11] = 1;
map[12][6] = 1;
map[13][6] = 1;
map[14][6] = 1;
map[15][6] = 1;
map[16][6] = 1;
map[17][11] = 1;
map[18][11] = 1;
for(int y=0; y<15; y++)
{
map[19][y] = 1;
}
//take out some tiles yo
map[8][12] = 0;
map[9][12] = 0;
map[10][12] = 0;
map[11][12] = 0;
map[12][12] = 0;
//main game loop
while(1)
{
//look for an event
if(SDL_PollEvent( &g_Event ) == true)
{
//if user closes out of window, exit loop
if(g_Event.type==SDL_QUIT)
break;
//if ESC key
if(g_Event.key.keysym.sym == SDLK_ESCAPE )
{
// if ESC was pressed, quit the program.
SDL_Event quit;
quit.type = SDL_QUIT;
SDL_PushEvent( &quit );
}
//check key input
switch( g_Event.type )
{
//if a key is pressed
case SDL_KEYDOWN:
switch( g_Event.key.keysym.sym )
{
case SDLK_UP:
f_Up = true;
break;
case SDLK_DOWN:
f_Down = true;
break;
case SDLK_LEFT:
f_Left = true;
break;
case SDLK_RIGHT:
f_Right = true;
break;
case SDLK_SPACE:
f_Space = true;
break;
case SDLK_ESCAPE:
f_Escape = true;
break;
}
break;
//a key is released
case SDL_KEYUP:
switch( g_Event.key.keysym.sym )
{
case SDLK_UP:
f_Up = false;
break;
case SDLK_DOWN:
f_Down = false;
break;
case SDLK_LEFT:
f_Left = false;
break;
case SDLK_RIGHT:
f_Right = false;
break;
case SDLK_SPACE:
f_Space = false;
break;
case SDLK_ESCAPE:
f_Escape = false;
break;
}
break;
default:
break;
}
}
//clear the screen with black
SDL_FillRect(g_pDisplaySurface, NULL, SDL_MapRGB( g_pDisplaySurface->format, 0, 0, 0 ));
//draw the map
for(int x=0; x<=19; x++)
{
for(int y=0; y<=14; y++)
{
if(map[x][y] == 1)
{
//create a bright green rectangle
g_Rect.x = x*32;
g_Rect.y = y*32;
g_Rect.w = 32;
g_Rect.h = 32;
//set the color
g_Red = 0;
g_Green = 255;
g_Blue = 0;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
//create a darker green rectangle to go on top of the first
g_Rect.x = (x*32)+1;
g_Rect.y = (y*32)+1;
g_Rect.w = 30;
g_Rect.h = 30;
//set the color
g_Red = 0;
g_Green = 180;
g_Blue = 0;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
}
}
}
//simulate gravity (probably should be in jump function later)
dude.SetYvel(dude.GetYvel() + Gravity);
//simulate friction
if(dude.GetXvel() < 0) { dude.SetXvel(dude.GetXvel() + Gravity); }
if(dude.GetXvel() > 0) { dude.SetXvel(dude.GetXvel() - Gravity); }
//the below is not standard and should be implemented elsewhere (but this be just a demo yo.)
//keep dude from going left or right to fast
if( abs((int)dude.GetXvel()) > 3 )
{
//if velocity less then 0
if(dude.GetXvel() < 0)
{
dude.SetXvel(-3);
}
else
{
dude.SetXvel(3);
}
}
//keep dude from going up or down to fast
if( abs((int)dude.GetYvel()) > 6 )
{
//if velocity less then 0
if(dude.GetYvel() < 0)
{
dude.SetYvel(-6);
}
}
//update the box via user input
if( KeyDown(f_Up) )
dude.SetYvel(dude.GetYvel() - 1);
if( KeyDown(f_Down) )
dude.SetYvel(dude.GetYvel() + 1);
if( KeyDown(f_Left) )
dude.SetXvel(dude.GetXvel() - 1);
if( KeyDown(f_Right) )
dude.SetXvel(dude.GetXvel() + 1);
//MoveVertical(dude.GetYvel(),dude.GetX(),dude.GetY(),0,32,0,64);
MoveHorizontal(dude.m_xvel,dude.m_x,dude.m_y,0,32,0,64);
MoveVertical(dude.m_yvel,dude.m_x,dude.m_y,0,32,0,64);
//create a light blue rectangle
g_Rect.x = dude.GetX();
g_Rect.y = dude.GetY();
g_Rect.w = 32;
g_Rect.h = 64;
//set the color
g_Red = 0;
g_Green = 140;
g_Blue = 255;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
//create a dark blue rectangle on top the other
g_Rect.x = dude.GetX()+1;
g_Rect.y = dude.GetY()+1;
g_Rect.w = 30;
g_Rect.h = 62;
//set the color
g_Red = 0;
g_Green = 0;
g_Blue = 255;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
//update the screen
SDL_UpdateRect(g_pDisplaySurface,0,0,0,0);
//flip surface into view
SDL_Flip(g_pDisplaySurface);
//I heard someone say we should delay 10 millisecs to let the
//computer catch up and reduce lag. Is this true?
SDL_Delay(10);
}
//normal termination
fprintf(stdout,"Terminating normally.\n");
//return to OS
return(0);
}
Code: Select all
//Tile based collision by JS Lemming
//requires static linkage to:
//sdl.lib, sdlmain.lib
//requires dynamic linkage to:
//sdl.dll
//include SDL stuff
#include "sdl.h"
//include ability to exit program
#include <stdlib.h>
//include math functions
#include <math.h>
//These are the T/F flags that will be used to determine if a
//key is being held down by the user. If true, the key is down... false its not.
bool f_Up;
bool f_Down;
bool f_Left;
bool f_Right;
bool f_Space;
bool f_Escape;
//Function KeyDown(KeyFlag) - checks whether the arg passed to it is true,
//thus returning true. Why have this function at all? For consistancy sakes
//of the KeyHit function.
bool KeyDown(bool KeyFlag) {
return KeyFlag;
}
//Function KeyHit(KeyFlag) - checks whether the arg passed to it is true.
//Then setting the flag to false, and returning true.
bool KeyHit(bool& KeyFlag) {
if(KeyFlag == true)
{
KeyFlag = false;
return true;
}
return false;
}
//Classes
class Player
{
public:
//general movement
float m_x, m_y;
float m_xvel, m_yvel;
//jumping
bool m_jump;
bool m_letgo; //keeps track if the user is holding down space
float m_jumptimer;
//constructor
Player()
{
m_x = 0;
m_y = 0;
m_xvel = 0;
m_yvel = 0;
m_jump = false;
m_letgo = true;
m_jumptimer = 0;
}
};
//how much an object gets pulled down per frame
float Gravity = 0.38;
//screen dimensions
const int SCREEN_WIDTH=640;
const int SCREEN_HEIGHT=480;
//array holding map data (0 or 1 for now)
int map[20][15];
//---FUNCTIONS---
//MoveHorizontal() - moves thing based on velocity
//returns -1 if top left hits a solid
// 1 if right boundry hits a solid
// 0 if no collision detected in move
int MoveHorizontal(float& p_xvel, float& p_x, float& p_y, int p_left, int p_right, int p_top, int p_bottom)
{
for(int i=1; i<=abs( (int)p_xvel ); i++ )
{
//temporarily define the object's bounderies
int BoundLeft = ((int)p_x + p_left);
int BoundRight = ((int)p_x + p_right-1);
int BoundTop = ((int)p_y + p_top);
int BoundBottom = ((int)p_y + p_bottom-1);
//set temp Move = true? vars to false
bool MoveLeft = false;
bool MoveRight = false;
//loop from boundtop to boundbottom (replace loop with mar's idea!)
for(int Point=BoundTop; Point<=BoundBottom; Point++)
{
//if object going left
if(p_xvel < 0)
{
//if object's left bound minus 1 is in a solid tile
if(map[ (BoundLeft-1)/32 ][ (Point)/32 ] == 1)
{
//set the object's xvel to 0 and return with -1
p_xvel = 0;
return -1;
}
else
{
//set the MoveLeft var to true
MoveLeft = true;
}
}
//if object going right
if(p_xvel > 0)
{
//if object's right bound plus 1 is in a solid tile
if(map[ (BoundRight+1)/32 ][ (Point)/32 ] == 1)
{
//set the object's xvel to 0 and return with 1
p_xvel = 0;
return 1;
}
else
{
//set the MoveRight var to true
MoveRight = true;
}
}
}
//if the Move vars are now true, adjust the x values
if(MoveLeft == true) { p_x = p_x - 1; }
if(MoveRight == true) { p_x = p_x + 1; }
//if the object has gone out of array bounds, push it back on
if(p_x < 0) { p_x = 0; p_xvel = 0; }
if(p_x > 20*32) { p_x = 20*32; p_xvel = 0; } //replace 20*32 with map height var/function
}
//if no solids were hit at all, return 0
return 0;
}
//MoveVertical() - moves thing based on velocity
//returns -1 if top boundry hits a solid
// 1 if bottom boundry hits a solid
// 0 if no collision detected in move
int MoveVertical(float& p_yvel, float& p_x, float& p_y, int p_left, int p_right, int p_top, int p_bottom)
{
for(int i=1; i<=abs( (int)p_yvel ); i++ )
{
//temporarily define the object's bounderies
int BoundLeft = ((int)p_x + p_left);
int BoundRight = ((int)p_x + p_right-1);
int BoundTop = ((int)p_y + p_top);
int BoundBottom = ((int)p_y + p_bottom-1);
//set temp Move = true? vars to false
bool MoveUp = false;
bool MoveDown = false;
//loop from boundleft to boundright (replace loop with mar's idea!)
for(int Point=BoundLeft; Point<=BoundRight; Point++)
{
//if object going up
if(p_yvel < 0)
{
//if object's top bound minus 1 is in a solid tile
if(map[ (Point)/32 ][ (BoundTop-1)/32 ] == 1)
{
//set the object's yvel to 0 and return with -1
p_yvel = 0;
return -1;
}
else
{
//set the MoveUp var to true
MoveUp = true;
}
}
//if object going down
if(p_yvel > 0)
{
//if object's bottom bound plus 1 is in a solid tile
if(map[ (Point)/32 ][ (BoundBottom+1)/32 ] == 1)
{
//set the object's yvel to 0 and return with 1
p_yvel = 0;
return 1;
}
else
{
//set the MoveDown var to true
MoveDown = true;
}
}
}
//if the Move vars are now true, adjust the y values
if(MoveUp == true) { p_y = p_y - 1; }
if(MoveDown == true) { p_y = p_y + 1; }
//if the object has gone out of array bounds, push it back on
if(p_y < 0) { p_y = 0; p_yvel = 0; }
if(p_y > 15*32) { p_y = 15*32; p_yvel = 0; } //replace 15*32 with map height var/function
}
//if no solids were hit at all, return 0
return 0;
}
//display surface
SDL_Surface* g_pDisplaySurface;
//event structure
SDL_Event g_Event;
//rectangle
SDL_Rect g_Rect;
//color components
Uint8 g_Red, g_Green, g_Blue;
//color value
Uint32 g_Color;
//main function
int main(int argc, char* argv[])
{
//initialize SDL
if (SDL_Init(SDL_INIT_VIDEO)==-1)
{
//error initializing SDL
//report the error
fprintf(stderr,"Could not initialize SDL!\n");
//end the program
exit(1);
}
else
{
//SDL initialized
//report success
fprintf(stdout,"SDL initialized properly!\n");
//set up to uninitialize SDL at exit
atexit(SDL_Quit);
}
//hide mouse
SDL_ShowCursor(SDL_DISABLE);
//create windowed environment
g_pDisplaySurface = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,16,SDL_ANYFORMAT|SDL_DOUBLEBUF|SDL_FULLSCREEN);
//error check
if (g_pDisplaySurface == NULL)
{
//report error
fprintf(stderr,"Could not set up display surface!\n");
//exit the program
exit(1);
}
//Create instance of class player
Player dude;
dude.m_x = (3*32);
dude.m_y = (10*32);
//clear map array
for(int x=0; x<=19; x++)
{
for(int y=0; y<=14; y++)
{
map[x][y] = 0;
}
}
//put some solids into the map array
for(int x=0; x<=19; x++)
{
map[x][0] = 1;
map[x][1] = 1;
map[x][12] = 1;
map[x][13] = 1;
map[x][14] = 1;
}
//add some more solids yo
map[0][9] = 1;
map[0][10] = 1;
map[0][11] = 1;
map[12][6] = 1;
map[13][6] = 1;
map[14][6] = 1;
map[15][6] = 1;
map[16][6] = 1;
map[17][11] = 1;
map[18][11] = 1;
for(int y=0; y<15; y++)
{
map[19][y] = 1;
}
//take out some tiles yo
map[8][12] = 0;
map[9][12] = 0;
map[10][12] = 0;
map[11][12] = 0;
map[12][12] = 0;
//main game loop
while(1)
{
//look for an event
if(SDL_PollEvent( &g_Event ) == true)
{
//if user closes out of window, exit loop
if(g_Event.type==SDL_QUIT)
break;
//if ESC key
if(g_Event.key.keysym.sym == SDLK_ESCAPE )
{
// if ESC was pressed, quit the program.
SDL_Event quit;
quit.type = SDL_QUIT;
SDL_PushEvent( &quit );
}
//check key input
switch( g_Event.type )
{
//if a key is pressed
case SDL_KEYDOWN:
switch( g_Event.key.keysym.sym )
{
case SDLK_UP:
f_Up = true;
break;
case SDLK_DOWN:
f_Down = true;
break;
case SDLK_LEFT:
f_Left = true;
break;
case SDLK_RIGHT:
f_Right = true;
break;
case SDLK_SPACE:
f_Space = true;
break;
case SDLK_ESCAPE:
f_Escape = true;
break;
}
break;
//a key is released
case SDL_KEYUP:
switch( g_Event.key.keysym.sym )
{
case SDLK_UP:
f_Up = false;
break;
case SDLK_DOWN:
f_Down = false;
break;
case SDLK_LEFT:
f_Left = false;
break;
case SDLK_RIGHT:
f_Right = false;
break;
case SDLK_SPACE:
f_Space = false;
break;
case SDLK_ESCAPE:
f_Escape = false;
break;
}
break;
default:
break;
}
}
//clear the screen with black
SDL_FillRect(g_pDisplaySurface, NULL, SDL_MapRGB( g_pDisplaySurface->format, 0, 0, 0 ));
//draw the map
for(int x=0; x<=19; x++)
{
for(int y=0; y<=14; y++)
{
if(map[x][y] == 1)
{
//create a bright green rectangle
g_Rect.x = x*32;
g_Rect.y = y*32;
g_Rect.w = 32;
g_Rect.h = 32;
//set the color
g_Red = 0;
g_Green = 255;
g_Blue = 0;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
//create a darker green rectangle to go on top of the first
g_Rect.x = (x*32)+1;
g_Rect.y = (y*32)+1;
g_Rect.w = 30;
g_Rect.h = 30;
//set the color
g_Red = 0;
g_Green = 180;
g_Blue = 0;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
}
}
}
//move dude in persective of velocities
MoveHorizontal(dude.m_xvel,dude.m_x,dude.m_y,0,32,0,64);
if(MoveVertical(dude.m_yvel,dude.m_x,dude.m_y,0,32,0,64) == 1)
{ dude.m_jump = false; }
//simulate gravity (probably should be in jump function later)
dude.m_yvel = (dude.m_yvel + Gravity);
//simulate friction
if(dude.m_xvel < 0) { dude.m_xvel = (dude.m_xvel + Gravity); }
if(dude.m_xvel > 0) { dude.m_xvel = (dude.m_xvel - Gravity); }
//sorry, can't jump while falling :D
if(dude.m_yvel > 1) { dude.m_jump = true; }
//attempt to activate jump
if( KeyDown(f_Space) )
{
//if we are not currently jumping, and spacebar wasn't held
if((dude.m_jump == false) && (dude.m_letgo == true))
{
//set some vars
dude.m_letgo = false;
dude.m_jump = true;
//at this point, we could put in an if statement to see if dude
//is moving fast enough to jump higer.. but not right now.
dude.m_jumptimer = 8;
//make dude bounce into action
dude.m_yvel = -4.5;
}
}
else
{
//if dude isn't going up or down, reset letgo to true
if(abs((int)dude.m_yvel) < 1) { dude.m_letgo = true; }
//reset the jumptimer to 0
dude.m_jumptimer = 0;
}
//if we are currently jumping
if((dude.m_jump == true) && (dude.m_jumptimer > 0))
{
//adjust velocity for life
dude.m_yvel = dude.m_yvel - 1;
//decrease the jump timer
dude.m_jumptimer--;
}
//the below is not standard and should be implemented elsewhere (but this be just a demo yo.)
//keep dude from going left or right to fast
if( abs((int)dude.m_xvel) > 3 )
{
//if velocity less then 0
if(dude.m_xvel < 0)
{
dude.m_xvel = (-3);
}
else
{
dude.m_xvel = (3);
}
}
/*
//keep dude from going up or down to fast
if( abs((int)dude.m_yvel) > 6 )
{
//if velocity less then 0
if(dude.m_yvel < 0)
{
dude.m_yvel = (-6);
}
}
*/
//update the box via user input
if( KeyDown(f_Left) )
dude.m_xvel = (dude.m_xvel - 1);
if( KeyDown(f_Right) )
dude.m_xvel = (dude.m_xvel + 1);
//create a light blue rectangle
g_Rect.x = (int)dude.m_x;
g_Rect.y = (int)dude.m_y;
g_Rect.w = 32;
g_Rect.h = 64;
//set the color
g_Red = 0;
g_Green = 140;
g_Blue = 255;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
//create a dark blue rectangle on top the other
g_Rect.x = (int)dude.m_x+1;
g_Rect.y = (int)dude.m_y+1;
g_Rect.w = 30;
g_Rect.h = 62;
//set the color
g_Red = 0;
g_Green = 0;
g_Blue = 255;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
//update the screen
SDL_UpdateRect(g_pDisplaySurface,0,0,0,0);
//flip surface into view
SDL_Flip(g_pDisplaySurface);
//I heard someone say we should delay 10 millisecs to let the
//computer catch up and reduce lag. Is this true?
SDL_Delay(10);
}
//normal termination
fprintf(stdout,"Terminating normally.\n");
//return to OS
return(0);
}
Code: Select all
//clear map array
for(int x=0; x<=19; x++)
{
for(int y=0; y<=14; y++)
{
map[x][y] = 0;
}
}
//put some solids into the map array
for(int x=0; x<=19; x++)
{
map[x][0] = 1;
map[x][1] = 1;
map[x][12] = 1;
map[x][13] = 1;
map[x][14] = 1;
}
I could have sworn that when you intialize a var in a loop statement that it is only local to the loop. If not, you can simply take out the initializers and put them up before the loops.SS wrote:Did Dev-C++ seriously let you compile that? Notice that you're reinitializing x in the second for() loop? Wow, MSVC++ tried to murder me when I tried to compile. Don't worry, though, I fixed it.
Code: Select all
/*
Tile based collision and jumping by JS Lemming (Travis Stuart)
Random shooting and tile destruction by Super Sonic (Falco Jaenisch)
Helluva special thanks to Tvspelsfreak on Super Sonic's behalf
requires static linkage to:
sdl.lib, sdlmain.lib
requires dynamic linkage to:
sdl.dll
*/
//include SDL stuff
#include "sdl.h"
//include ability to exit program
#include <stdlib.h>
//include math functions
#include <cmath>
//Classes
class Player
{
public:
//general movement
float m_x, m_y;
float m_xvel, m_yvel;
//jumping
bool m_jump;
bool m_letgo; //keeps track if the user is holding down space
bool m_dir;
float m_jumptimer;
//constructor
Player()
{
m_x = 0;
m_y = 0;
m_xvel = 0;
m_yvel = 0;
m_jump = false;
m_letgo = true;
m_jumptimer = 0;
}
};
class Bullet {
public:
int x;
int y;
bool active;
int direction;
};
bool KeyDown(bool KeyFlag);
bool KeyHit(bool &KeyFlag);
int MoveHorizontal(float& p_xvel, float& p_x, float& p_y, int p_left, int p_right, int p_top, int p_bottom);
int MoveVertical(float& p_yvel, float& p_x, float& p_y, int p_left, int p_right, int p_top, int p_bottom);
void Shoot(int x, int y, bool dir);
void UpdateBullets();
//These are the T/F flags that will be used to determine if a
//key is being held down by the user. If true, the key is down... false its not.
bool f_Up;
bool f_Down;
bool f_Left;
bool f_Right;
bool f_X;
bool f_C;
bool f_Escape;
//Create 3 bullets that may be shot
Bullet bullet[3];
//how much an object gets pulled down per frame
float Gravity = 0.38;
//screen dimensions
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
//array holding map data (0 or 1 for now)
int map[20][15];
//display surface
SDL_Surface* g_pDisplaySurface;
//event structure
SDL_Event g_Event;
//rectangle
SDL_Rect g_Rect;
//color components
Uint8 g_Red, g_Green, g_Blue;
//color value
Uint32 g_Color;
//main function
int main(int argc, char* argv[])
{
//initialize SDL
if (SDL_Init(SDL_INIT_VIDEO)==-1)
{
//error initializing SDL
//report the error
fprintf(stderr,"Could not initialize SDL!\n");
//end the program
exit(1);
}
else
{
//SDL initialized
//report success
fprintf(stdout,"SDL initialized properly!\n");
//set up to uninitialize SDL at exit
atexit(SDL_Quit);
}
//hide mouse
SDL_ShowCursor(SDL_DISABLE);
//create windowed environment
g_pDisplaySurface = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,16,SDL_ANYFORMAT|SDL_DOUBLEBUF);
//error check
if (g_pDisplaySurface == NULL)
{
//report error
fprintf(stderr,"Could not set up display surface!\n");
//exit the program
exit(1);
}
//Create instance of class player
Player dude;
dude.m_x = (3*32);
dude.m_y = (10*32);
dude.m_dir = 1;
//clear map array
for(int x=0; x<=19; x++)
{
for(int y=0; y<=14; y++)
{
map[x][y] = 0;
}
}
//put some solids into the map array
for(x=0; x<=19; x++)
{
map[x][0] = 1;
map[x][1] = 1;
map[x][12] = 1;
map[x][13] = 1;
map[x][14] = 1;
}
//add some more solids yo
map[0][9] = 1;
map[0][10] = 1;
map[0][11] = 1;
map[12][6] = 1;
map[13][6] = 1;
map[14][6] = 1;
map[15][6] = 1;
map[16][6] = 1;
/*map[5][6] = 1;
map[6][6] = 1;
map[7][6] = 1;
map[8][6] = 1;*/
map[16][6] = 1;
map[17][11] = 1;
map[18][11] = 1;
for(int y=0; y<15; y++)
{
map[19][y] = 1;
}
//take out some tiles yo
map[8][12] = 0;
map[9][12] = 0;
map[10][12] = 0;
map[11][12] = 0;
map[12][12] = 0;
//main game loop
while(1)
{
//look for an event
if(SDL_PollEvent(&g_Event) == true)
{
//if user closes out of window, exit loop
if(g_Event.type == SDL_QUIT)
break;
//if ESC key
if(g_Event.key.keysym.sym == SDLK_ESCAPE)
{
// if ESC was pressed, quit the program.
SDL_Event quit;
quit.type = SDL_QUIT;
SDL_PushEvent(&quit);
}
//check key input
switch( g_Event.type )
{
//if a key is pressed
case SDL_KEYDOWN:
switch( g_Event.key.keysym.sym )
{
case SDLK_UP:
f_Up = true;
break;
case SDLK_DOWN:
f_Down = true;
break;
case SDLK_LEFT:
f_Left = true;
break;
case SDLK_RIGHT:
f_Right = true;
break;
case SDLK_x:
f_X = true;
break;
case SDLK_c:
f_C = true;
break;
case SDLK_ESCAPE:
f_Escape = true;
break;
}
break;
//a key is released
case SDL_KEYUP:
switch( g_Event.key.keysym.sym )
{
case SDLK_UP:
f_Up = false;
break;
case SDLK_DOWN:
f_Down = false;
break;
case SDLK_LEFT:
f_Left = false;
break;
case SDLK_RIGHT:
f_Right = false;
break;
case SDLK_x:
f_X = false;
break;
case SDLK_c:
f_C = false;
break;
case SDLK_ESCAPE:
f_Escape = false;
break;
}
break;
default:
break;
}
}
//clear the screen with black
SDL_FillRect(g_pDisplaySurface, NULL, SDL_MapRGB( g_pDisplaySurface->format, 0, 0, 0 ));
//draw the map
for(int x=0; x<=19; x++)
{
for(int y=0; y<=14; y++)
{
if(map[x][y] == 1)
{
//create a bright green rectangle
g_Rect.x = x*32;
g_Rect.y = y*32;
g_Rect.w = 32;
g_Rect.h = 32;
//set the color
g_Red = 0;
g_Green = 255;
g_Blue = 0;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
//create a darker green rectangle to go on top of the first
g_Rect.x = (x*32)+1;
g_Rect.y = (y*32)+1;
g_Rect.w = 30;
g_Rect.h = 30;
//set the color
g_Red = 0;
g_Green = 180;
g_Blue = 0;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
}
}
}
//move dude in persective of velocities
MoveHorizontal(dude.m_xvel,dude.m_x,dude.m_y,0,32,0,64);
if(MoveVertical(dude.m_yvel,dude.m_x,dude.m_y,0,32,0,64) == 1)
{ dude.m_jump = false; }
//simulate gravity (probably should be in jump function later)
dude.m_yvel = (dude.m_yvel + Gravity);
//simulate friction
if(dude.m_xvel < 0) { dude.m_xvel = (dude.m_xvel + Gravity); }
if(dude.m_xvel > 0) { dude.m_xvel = (dude.m_xvel - Gravity); }
//sorry, can't jump while falling :D
if(dude.m_yvel > 1) { dude.m_jump = true; }
//attempt to activate jump
if( KeyDown(f_X) )
{
//if we are not currently jumping, and spacebar wasn't held
if((dude.m_jump == false) && (dude.m_letgo == true))
{
//set some vars
dude.m_letgo = false;
dude.m_jump = true;
//at this point, we could put in an if statement to see if dude
//is moving fast enough to jump higer.. but not right now.
dude.m_jumptimer = 8;
//make dude bounce into action
dude.m_yvel = -4.5;
}
}
else
{
//if dude isn't going up or down, reset letgo to true
if(abs((int)dude.m_yvel) < 1) { dude.m_letgo = true; }
//reset the jumptimer to 0
dude.m_jumptimer = 0;
}
//if we are currently jumping
if((dude.m_jump == true) && (dude.m_jumptimer > 0))
{
//adjust velocity for life
dude.m_yvel = dude.m_yvel - 1;
//decrease the jump timer
dude.m_jumptimer--;
}
//the below is not standard and should be implemented elsewhere (but this be just a demo yo.)
//keep dude from going left or right to fast
if( abs((int)dude.m_xvel) > 3 )
{
//if velocity less then 0
if(dude.m_xvel < 0)
{
dude.m_xvel = (-3);
}
else
{
dude.m_xvel = (3);
}
}
/*
//keep dude from going up or down to fast
if( abs((int)dude.m_yvel) > 6 )
{
//if velocity less then 0
if(dude.m_yvel < 0)
{
dude.m_yvel = (-6);
}
}
*/
//update all onscreen bullets
UpdateBullets();
//update the box via user input
if( KeyDown(f_Left) ) {
dude.m_xvel = (dude.m_xvel - 1);
dude.m_dir = 0;
}
if( KeyDown(f_Right) ) {
dude.m_xvel = (dude.m_xvel + 1);
dude.m_dir = 1;
}
if( KeyDown(f_C) )
Shoot(dude.m_x, dude.m_y, dude.m_dir);
//create a light blue rectangle
g_Rect.x = (int)dude.m_x;
g_Rect.y = (int)dude.m_y;
g_Rect.w = 32;
g_Rect.h = 64;
//set the color
g_Red = 0;
g_Green = 140;
g_Blue = 255;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
//create a dark blue rectangle on top the other
g_Rect.x = (int)dude.m_x+1;
g_Rect.y = (int)dude.m_y+1;
g_Rect.w = 30;
g_Rect.h = 62;
//set the color
g_Red = 0;
g_Green = 0;
g_Blue = 255;
g_Color=SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
//update the screen
SDL_UpdateRect(g_pDisplaySurface,0,0,0,0);
//flip surface into view
SDL_Flip(g_pDisplaySurface);
//I heard someone say we should delay 10 millisecs to let the
//computer catch up and reduce lag. Is this true?
SDL_Delay(10);
}
//normal termination
fprintf(stdout,"Terminating normally.\n");
//return to OS
return(0);
}
//Function KeyDown(KeyFlag) - checks whether the arg passed to it is true,
//thus returning true. Why have this function at all? For consistancy sakes
//of the KeyHit function.
bool KeyDown(bool KeyFlag) {
return KeyFlag;
}
//Function KeyHit(KeyFlag) - checks whether the arg passed to it is true.
//Then setting the flag to false, and returning true.
bool KeyHit(bool &KeyFlag) {
if(KeyFlag == true)
{
KeyFlag = false;
return true;
}
return false;
}
//---FUNCTIONS---
//MoveHorizontal() - moves thing based on velocity
//returns -1 if top left hits a solid
// 1 if right boundry hits a solid
// 0 if no collision detected in move
int MoveHorizontal(float& p_xvel, float& p_x, float& p_y, int p_left, int p_right, int p_top, int p_bottom)
{
for(int i=1; i<=abs( (int)p_xvel ); i++ )
{
//temporarily define the object's bounderies
int BoundLeft = ((int)p_x + p_left);
int BoundRight = ((int)p_x + p_right-1);
int BoundTop = ((int)p_y + p_top);
int BoundBottom = ((int)p_y + p_bottom-1);
//set temp Move = true? vars to false
bool MoveLeft = false;
bool MoveRight = false;
//loop from boundtop to boundbottom (replace loop with mar's idea!)
for(int Point=BoundTop; Point<=BoundBottom; Point++)
{
//if object going left
if(p_xvel < 0)
{
//if object's left bound minus 1 is in a solid tile
if(map[ (BoundLeft-1)/32 ][ (Point)/32 ] == 1)
{
//set the object's xvel to 0 and return with -1
p_xvel = 0;
return -1;
}
else
{
//set the MoveLeft var to true
MoveLeft = true;
}
}
//if object going right
if(p_xvel > 0)
{
//if object's right bound plus 1 is in a solid tile
if(map[ (BoundRight+1)/32 ][ (Point)/32 ] == 1)
{
//set the object's xvel to 0 and return with 1
p_xvel = 0;
return 1;
}
else
{
//set the MoveRight var to true
MoveRight = true;
}
}
}
//if the Move vars are now true, adjust the x values
if(MoveLeft == true) { p_x = p_x - 1; }
if(MoveRight == true) { p_x = p_x + 1; }
//if the object has gone out of array bounds, push it back on
if(p_x < 0) { p_x = 0; p_xvel = 0; }
if(p_x > 640) { p_x = 640; p_xvel = 0; } //replace 20*32 with map height var/function
}
//if no solids were hit at all, return 0
return 0;
}
//MoveVertical() - moves thing based on velocity
//returns -1 if top boundry hits a solid
// 1 if bottom boundry hits a solid
// 0 if no collision detected in move
int MoveVertical(float& p_yvel, float& p_x, float& p_y, int p_left, int p_right, int p_top, int p_bottom)
{
for(int i=1; i<=abs( (int)p_yvel ); i++ )
{
//temporarily define the object's bounderies
int BoundLeft = ((int)p_x + p_left);
int BoundRight = ((int)p_x + p_right-1);
int BoundTop = ((int)p_y + p_top);
int BoundBottom = ((int)p_y + p_bottom-1);
//set temp Move = true? vars to false
bool MoveUp = false;
bool MoveDown = false;
//loop from boundleft to boundright (replace loop with mar's idea!)
for(int Point=BoundLeft; Point<=BoundRight; Point++)
{
//if object going up
if(p_yvel < 0)
{
//if object's top bound minus 1 is in a solid tile
if(map[ (Point)/32 ][ (BoundTop-1)/32 ] == 1)
{
//set the object's yvel to 0 and return with -1
p_yvel = 0;
return -1;
}
else
{
//set the MoveUp var to true
MoveUp = true;
}
}
//if object going down
if(p_yvel > 0)
{
//if object's bottom bound plus 1 is in a solid tile
if(map[ (Point)/32 ][ (BoundBottom+1)/32 ] == 1)
{
//set the object's yvel to 0 and return with 1
p_yvel = 0;
return 1;
}
else
{
//set the MoveDown var to true
MoveDown = true;
}
}
}
//if the Move vars are now true, adjust the y values
if(MoveUp == true) { p_y = p_y - 1; }
if(MoveDown == true) { p_y = p_y + 1; }
//if the object has gone out of array bounds, push it back on
if(p_y < 0) { p_y = 0; p_yvel = 0; }
if(p_y > 15*32) { p_y = 15*32; p_yvel = 0; } //replace 15*32 with map height var/function
}
//if no solids were hit at all, return 0
return 0;
}
void Shoot(int x, int y, bool dir) {
for(int i=0; i<1; i++) {
if(bullet[i].active == false) {
bullet[i].active = true;
bullet[i].x = x;
bullet[i].y = y + 20;
bullet[i].direction = dir;
break;
}
}
}
void UpdateBullets() {
for(int a=0; a<1; a++) {
if(bullet[a].active) {
if(bullet[a].direction == 0) bullet[a].x -= 14; // Left
if(bullet[a].direction == 1) bullet[a].x += 14; // Right
//create a red rectangle
g_Rect.x = bullet[a].x;
g_Rect.y = bullet[a].y;
g_Rect.w = 4;
g_Rect.h = 4;
//set the color
g_Red = 255;
g_Green = 0;
g_Blue = 0;
g_Color = SDL_MapRGB(g_pDisplaySurface->format,g_Red,g_Green,g_Blue);
//fill the rectangle
SDL_FillRect(g_pDisplaySurface,&g_Rect,g_Color);
if(bullet[a].x < 0 || bullet[a].x > 640 || bullet[a].y < 0 || bullet[a].y > 480) {
bullet[a].active = false;
}
else{
for(int Point = bullet[a].y; Point < bullet[a].y+4; Point++){
if(map[ (bullet[a].x)/32 ][ (Point)/32 ] == 1) {
map[ (bullet[a].x)/32 ][ (Point)/32 ] = 0;
bullet[a].active = false;
}
}
}
}
}
}