NEStix: Programming (C++/SDL)

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

User avatar
JS Lemming
Game Developer
Game Developer
Posts: 2383
Joined: Fri May 21, 2004 4:09 pm
Location: C:\CON\CON

Post by JS Lemming »

Are vectors new or something? Because my books don't even mention them. At least I don't remember them mentioning it. *Checks*
Small girl at the harbor wrote:Look Brandon, that crab's got ham!
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Post by Falco Girgis »

It really makes me sad. I read the intro sentence to Vectors in my book. I knew, those are the answer to my prayers.

Alas, I can't learn them. Learning Vectors requires knowledge of templates. Then learning templates (in my book) requires advanced object oriented topics.

I'm going to have to go back all the way and read from straight page 100 to 666 to learn all of the irrelevancies in the endless chain to learn vectorz.

I'm sad.

Maybe Mar could teach me?? :?
User avatar
JS Lemming
Game Developer
Game Developer
Posts: 2383
Joined: Fri May 21, 2004 4:09 pm
Location: C:\CON\CON

Post by JS Lemming »

Templates aren't that difficult. I would teach you myself, but I'm no master my self.

Hey Mar, maybe you could make us a cheap little text based console thingy showing how to add, delete, and iterate through a vector. And how to set it up and such. :mrgreen:
Small girl at the harbor wrote:Look Brandon, that crab's got ham!
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Post by MarauderIIC »

Easy money.

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;
}
Last edited by MarauderIIC on Thu Oct 07, 2004 8:33 pm, edited 1 time in total.
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
Don Pwnious
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 833
Joined: Tue Jun 15, 2004 5:32 pm
Location: on the streets wit my j23
Contact:

Post by Don Pwnious »

Ummm... i didn't know where to post this but i just ordered the focus on SDL book. Lemming i will let you see it when ever i get it.
1/8th time- 14secs
1/8th speed - 110mph
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Post by MarauderIIC »

Did it help any? Still confused? Where?
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
JS Lemming
Game Developer
Game Developer
Posts: 2383
Joined: Fri May 21, 2004 4:09 pm
Location: C:\CON\CON

Post by JS Lemming »

Woot Woot! Mar, just caught sight of your examplage. Nice!

*reads in more detail*
Small girl at the harbor wrote:Look Brandon, that crab's got ham!
User avatar
JS Lemming
Game Developer
Game Developer
Posts: 2383
Joined: Fri May 21, 2004 4:09 pm
Location: C:\CON\CON

Post by JS Lemming »

I don't have very much time so here. This is a demo of my Tile Based collison thingy.

Controlls:
arrows: move
esc key: quit

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);
}
As you can see, i first planned to use accesor methods for changing the x,y,xvel, and yvel, but the function I made astually changes the things passed to it. So that didn't work (that's why there are 2 publics, it used to be private). Any comments on that?
Small girl at the harbor wrote:Look Brandon, that crab's got ham!
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Post by Falco Girgis »

Sorry, JSL, I haven't been on the forums for a while. i've been off swinging on vines deep in the jungle and playing Poke'mon. I have yet to test your creation, but I am going to now. Niceness.
User avatar
JS Lemming
Game Developer
Game Developer
Posts: 2383
Joined: Fri May 21, 2004 4:09 pm
Location: C:\CON\CON

Post by JS Lemming »

I cleaned up the code a little and added a jump ability. Super Sonic, if you still want to add a gun and explodeable tiles to the demo (very cool idea) then use this one:

space: jump

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);
}
Last edited by JS Lemming on Sun Oct 17, 2004 1:19 pm, edited 1 time in total.
Small girl at the harbor wrote:Look Brandon, that crab's got ham!
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Post by Falco Girgis »

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;
    } 
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.

Dear god, do you realize rhis post took me like 10 minutes to type? I can only use one hand, and my festering blisters have fully taken over my right arm...

BTW, I'm still reading the source. The MoveVertical() and MoveHorizontal() functions are all new to me so I'm trying to make sure that I devour all of it--Goodness.
User avatar
Don Pwnious
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 833
Joined: Tue Jun 15, 2004 5:32 pm
Location: on the streets wit my j23
Contact:

Post by Don Pwnious »

well i will compile your code whenever i get home.
Did the vines hurt you that bad?
i got 5 vines in my backyard but i dont know they are either too thick or too dry.
1/8th time- 14secs
1/8th speed - 110mph
User avatar
JS Lemming
Game Developer
Game Developer
Posts: 2383
Joined: Fri May 21, 2004 4:09 pm
Location: C:\CON\CON

Post by JS Lemming »

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.
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.
Small girl at the harbor wrote:Look Brandon, that crab's got ham!
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Post by Falco Girgis »

Whilest sitting at home from school due to my distasteful case of poison ivy/oak, I finally decided to try to work on the tile thing. It wasn't easy. It took all day to do what shouldn't of taken that long. So here, you can shoot, and destroy tiles.

I got VERY bored though, so you can download it compiled and the source here:
http://thechaosrift.com/pc/sdl/Tile.zip

If you're too lazy, or if your computer can't handle downloading it from your closet *cough*JSL*cough* :rofl:

here's the source:

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;
					}
				}
			}
        } 
    }
}
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Post by Falco Girgis »

There's a REALLY wierd glitch I've found. If you increase the bullets the play can shoot to 3 (you have to recompile, because the .exe that you download only allows 1 because of this glitch) then something wierd will happen.

The only time I've found is if you're standing at the VERY bottom on the level shooting towards the right. Every now and again, 1 of the 3 bullets will randomly bounce off the wall in the opposite direction.

Also, no matter what I do, you can always go through the wall to the right after shooting down the tiles. The left doesn't do that, but the right does. Then, when you go offscreen after shooting them, bad stuff happens. >_<

What do you guys think?
Post Reply