]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
bug fixes
authorClyne Sullivan <tullivan99@gmail.com>
Mon, 26 Oct 2015 12:49:10 +0000 (08:49 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Mon, 26 Oct 2015 12:49:10 +0000 (08:49 -0400)
Changelog
Makefile
include/entities.h
main.cpp
src/Makefile
src/entities.cpp
src/gameplay.cpp
src/world.cpp

index ad5f1b6597d7d31435930e2856cfd888440bc12d..c1426fdf5fc14a8c1286a9e8452250379c6ee405 100644 (file)
--- a/Changelog
+++ b/Changelog
 
        - fixed entity initialization
        - added multiple mobs
-       - improved texture handling
\ No newline at end of file
+       - improved texture handling
+       
+10/26/2015:
+===========
+
+       - removed windows build commands
+       - fixed bug with spawning 'dead' NPCs
+       - entities are now drawn behind the current world as well as the grass
+       - player can now only highlight one NPC at a time
+       - fixed GLEW shader initialization segfault
+       - began working on bird mob
+       - improved world scenery
index a362803df2d19bb32747a505496d8f4da6f27e83..8ac3b3d95fcd12591536b5ecda185b0e81ec559a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,6 @@
-LIBS = -lGL\r
-WIN_LIBS = -lopengl32 -lmingw32\r
+LIBS = -lGL -lGLEW -lSDL2main -lSDL2 -lfreetype -lSDL2_image -lSDL2_mixer\r
 \r
-FLAGS = -std=c++11 -Iinclude -Iinclude/freetype2 -lGL -lGLEW -lSDL2 -lfreetype -lSDL2_image -lSDL2_mixer\r
+FLAGS = -m32 -std=c++11 -Iinclude -Iinclude/freetype2\r
 \r
 all:\r
        @rm -f out/*.o\r
@@ -9,9 +8,6 @@ all:
        @echo "  CXX  main.cpp"\r
        @g++ $(FLAGS) -o main main.cpp out/*.o $(LIBS)\r
 \r
-win32:\r
-       @g++ $(FLAGS) -o main main.cpp src/*.cpp $(WIN_LIBS)\r
-\r
 clean:\r
        @echo "  RM main"\r
        @-rm -f main\r
index 47f7f55b4eef3c49e1d41a51e97dab693715c45a..c111ea7020dc237b2006ac706edc2fae023c136e 100644 (file)
@@ -16,9 +16,9 @@
 
 enum _TYPE { //these are the main types of entities
        STRUCTURET = -1,
-       PLAYERT    = 0,
-       NPCT       = 1,
-       MOBT       = 2
+       PLAYERT,
+       NPCT,
+       MOBT
 };
 
 enum GENDER{
@@ -27,6 +27,11 @@ enum GENDER{
        NONE 
 };
 
+enum MOB_SUB {
+       MS_RABBIT = 1,
+       MS_BIRD
+};
+
 class Entity{
 public:
        Inventory *inv;
@@ -94,8 +99,9 @@ public:
 };
 class Mob : public Entity{
 public:
+       float init_y;
        Mob(int);
-       void wander(int, vec2*);
+       void wander(int);
 };
 
 #endif // ENTITIES_H
index e43029aa5bf89f7a8a1f6fc230935f9141234d31..8e67d8e1fdf5a90925b86f7ac11a584230e13b0d 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -173,16 +173,6 @@ unsigned int millis(void){
  * MAIN ************************************************************************
  *******************************************************************************/
 int main(int argc, char *argv[]){
-       /*
-        *      Initialize GLEW libraries, and exit if there was an error.
-        *      Not sure what they're for yet.
-        * 
-       */
-       
-       if(glewInit() < 0){
-               std::cout << "GLEW was not able to initialize! Error: " << std::endl;
-               return -1;
-       }
        
        /*
         *      (Attempt to) Initialize SDL libraries so that we can use SDL facilities and eventually
@@ -267,6 +257,19 @@ int main(int argc, char *argv[]){
         return -1;
     }
        
+       /*
+        *      Initialize GLEW libraries, and exit if there was an error.
+        *      Not sure what they're for yet.
+        * 
+       */
+       
+       GLenum err;
+       glewExperimental = GL_TRUE;
+       if((err=glewInit()) != GLEW_OK){
+               std::cout << "GLEW was not able to initialize! Error: " << glewGetErrorString(err) << std::endl;
+               return -1;
+       }
+       
        /*
         *      Initialize the FreeType libraries and select what font to use using functions from the ui
         *      namespace, defined in include/ui.h and src/ui.cpp. These functions should abort with errors
@@ -303,22 +306,21 @@ int main(int argc, char *argv[]){
        SDL_ShowCursor(SDL_DISABLE);
 
        /*
-        *      TODO - Initialize shaders n' stuff
+        *      Initializes our shaders so that the game has shadows.
        */
 
-       /*
-       
-       GLuint fragShader;
+       /*GLuint fragShader;
        GLuint shaderProgram;
 
        const GLchar *shaderSource = "shader.frag";
-       GLint bufferln = GL_FALSE;
+       GLint bufferln = GL_FALSE;      
 
-       shaderProgram = glCreateProgram();
        fragShader = glCreateShader(GL_FRAGMENT_SHADER);
-       
        glShaderSource(fragShader, 1, &shaderSource, NULL);
        glCompileShader(fragShader);
+
+       shaderProgram = glCreateProgram();
+       
        glGetShaderiv(fragShader, GL_COMPILE_STATUS, &bufferln);
        
        if(bufferln == GL_TRUE){
@@ -329,10 +331,8 @@ int main(int argc, char *argv[]){
        glLinkProgram(shaderProgram);
        glValidateProgram(shaderProgram);
 
-       //glEnable(GL_DEPTH_TEST);
-       //glEnable(GL_MULTISAMPLE);
-       
-       */
+       glEnable(GL_DEPTH_TEST);
+       glEnable(GL_MULTISAMPLE);*/
 
        /*
         *      Open the names file containing potential names for NPCs and store it in the names file
@@ -628,6 +628,14 @@ void render(){
 }
 
 void logic(){
+       
+       /*
+        *      NPCSelected is used to insure that only one NPC is made interactable with the mouse
+        *      if, for example, multiple entities are occupying one space.
+       */
+       
+       static bool NPCSelected = false;
+       
        /*
         *      Handle user input (keyboard & mouse).
        */
@@ -647,10 +655,11 @@ void logic(){
         *      click detection is done as well for NPC/player interaction.
         * 
        */
-        //std::cout << "Game Loop: "<< loops << std::endl;
        
        for(unsigned int i=0;i<entity.size();i++){
                
+               if(!entity[i]->alive)std::cout<<"Entity "<<i<<" is not alive!"<<std::endl;
+               
                /*
                 *      Check if the entity is in this world and is alive.
                */
@@ -676,6 +685,15 @@ void logic(){
                                if(entity[i]->canMove)
                                        NPCp(entity[i])->wander((rand() % 120 + 30), &entity[i]->vel);
                                
+                               /*
+                                *      Don't bother handling the NPC if another has already been handled.
+                               */
+                               
+                               if(NPCSelected){
+                                       entity[i]->near=false;
+                                       break;
+                               }
+                               
                                /*
                                 *      Check if the NPC is under the mouse.
                                */
@@ -698,10 +716,12 @@ void logic(){
                                        if(pow((entity[i]->loc.x - player->loc.x),2) + pow((entity[i]->loc.y - player->loc.y),2) <= pow(40*HLINE,2)){
                                                
                                                /*
-                                                *      Set Entity->near so that this NPC's name is drawn under them.
+                                                *      Set Entity->near so that this NPC's name is drawn under them, and toggle NPCSelected
+                                                *      so this NPC is the only one that's clickable.
                                                */
                                                
                                                entity[i]->near=true;
+                                               NPCSelected=true;
                                                
                                                /*
                                                 *      Check for a right click, and allow the NPC to interact with the
@@ -729,8 +749,13 @@ void logic(){
                                /*
                                 *      Run the Mob's AI function.
                                */
-                               
-                               Mobp(entity[i])->wander((rand()%240 + 15),&entity[i]->vel);     // Make the mob wander
+                       
+                               switch(entity[i]->subtype){
+                               case MS_RABBIT:
+                               case MS_BIRD:
+                                       Mobp(entity[i])->wander((rand()%240 + 15));     // Make the mob wander
+                                       break;
+                               }
                                
                                break;  // End case MOBT
                                
@@ -745,4 +770,5 @@ void logic(){
        */
        
        loops++;
+       NPCSelected=false;
 }
index 8021f42c48fd63422c968dd09b92f3fc689a0719..a243846937aa25fecec9f36a614d74e0dbd303ec 100644 (file)
@@ -1,6 +1,6 @@
-LIBS = -lGL -lSDL2_image -lSDL2_mixer
+LIBS = -lGL -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -lfreetype
 
-FLAGS = -std=c++11 -I../include -I../include/freetype2 -lSDL2main -lSDL2 -lfreetype
+FLAGS = -m32 -std=c++11 -I../include -I../include/freetype2
 
 OUT = `echo "" $$(ls -c $(wildcard *.cpp)) | sed s/.cpp/.o/g | sed 's/ / ..\/out\//g'`
 
index ae8b4c862d235dca967a05dbc456705a1851d0ec..8100a4c083c4c1f8be0125d211a0a16ac27a6d8d 100644 (file)
@@ -26,6 +26,9 @@ void Entity::spawn(float x, float y){ //spawns the entity you pass to it based o
        
        if(!maxHealth)health = maxHealth = 1;
        
+       if(type==MOBT)
+               Mobp(this)->init_y=loc.y;
+       
        name = (char*)malloc(16);
        getName();
 }
@@ -49,6 +52,8 @@ NPC::NPC(){   //sets all of the NPC specific traits on object creation
        type    = NPCT; //sets type to npc
        subtype = 0;
        
+       maxHealth = health = 100;
+       
        tex = new Texturec(1,"assets/NPC.png");
        inv = new Inventory(NPC_INV_SIZE);
 }
@@ -63,15 +68,20 @@ Structures::Structures(){ //sets the structure type
 }
 
 Mob::Mob(int sub){
-       width = HLINE * 10;
+       width  = HLINE * 10;
        height = HLINE * 8;
-       type = MOBT; //sets type to MOB
-       subtype = sub; //SKIRL
-       if(subtype == 1){//RABBIT
+       type   = MOBT;
+       
+       maxHealth = health = 50;
+       
+       switch((subtype = sub)){
+       case MS_RABBIT:
                tex = new Texturec(2, "assets/rabbit.png", "assets/rabbit1.png");
-       }else if(subtype == 2){//BIRD
-               //add bird textures and bird things
+               break;
+       case MS_BIRD:
+               break;
        }
+       
        inv = new Inventory(NPC_INV_SIZE);
 }
 
@@ -287,8 +297,8 @@ unsigned int Structures::spawn(_TYPE t, float x, float y){ //spawns a structure
                for(int i=0;i<tempN;i++){
                        
                        /*
-                        *                              This is where the entities actually spawn.
-                        *              A new entity is created with type NPC so polymorphism can be used
+                        *      This is where the entities actually spawn. A new entity is created
+                        *      with type NPC by using polymorphism.
                        */
                        
                        npc.push_back(new NPC());
@@ -305,27 +315,32 @@ unsigned int Structures::spawn(_TYPE t, float x, float y){ //spawns a structure
 /*
  *     Mob::wander this is the function that makes the mobs wander around
  *
- *     See NPC::wander for the explaination of the arguments variables
+ *     See NPC::wander for the explaination of the argument's variable
 */
-void Mob::wander(int timeRun, vec2* v){
+
+void Mob::wander(int timeRun){
+       static int direction;   //variable to decide what direction the entity moves
        switch(subtype){
-               case 1: //SKIRL
-                       static int direction;   //variable to decide what direction the entity moves
-                       if(ticksToUse == 0){
-                               ticksToUse = timeRun;
-                               direction = (getRand() % 3 - 1);        //sets the direction to either -1, 0, 1
-                                                                                                       //this lets the entity move left, right, or stay still
-                               if(direction==0)ticksToUse/=2;
-                               v->x *= direction;      //changes the velocity based off of the direction
-                       }
-                       if(ground && direction != 0){
-                               v->y=.15;
-                               loc.y+=HLINE*.25;
-                               ground=false;
-                               v->x = (.07*HLINE)*direction;   //sets the inital velocity of the entity
-                       }
-                       ticksToUse--; //removes one off of the entities timer
+       case MS_RABBIT:
+               if(!ticksToUse){
+                       ticksToUse = timeRun;
+                       direction = (getRand() % 3 - 1);        //sets the direction to either -1, 0, 1
+                                                                                               //this lets the entity move left, right, or stay still
+                       if(direction==0)ticksToUse/=2;
+                       vel.x *= direction;     //changes the velocity based off of the direction
+               }
+               if(ground && direction){
+                       vel.y=.15;
+                       loc.y+=HLINE*.25;
+                       ground=false;
+                       vel.x = (.07*HLINE)*direction;  //sets the inital velocity of the entity
+               }
+               ticksToUse--; //removes one off of the entities timer
+               break;
+       case MS_BIRD:
+               if(loc.y<=init_y-.2)vel.y+=.005*deltaTime;      // TODO handle direction
+               break;
+       default:
                break;
-               default:break;
        }
 }
index 1f4b3fee7ad12f4aee96e84f3b7656512291191e..77d00212be60121ab31b21d3c15da1d7d8fd369a 100644 (file)
@@ -78,8 +78,9 @@ void initEverything(void){
 
        /*
         *      Spawn a mob. 
-       */      
-       mob.push_back(new Mob(1));
+       */
+       
+       mob.push_back(new Mob(MS_RABBIT));
        entity.push_back(mob.back());
        mob.back()->spawn(200,100);
        
index a05c155d6704e52ccc1d41fdaf30490459d12bf8..9f18180c6fcef30dd954367b736096df1a5ae7bb 100644 (file)
@@ -3,11 +3,11 @@
 #define getWidth(w) ((w->lineCount-GEN_INC)*HLINE)     // Calculates the width of world 'w'
 
 #define GEN_INC 10             // Defines at what interval y values should be calculated for the array 'line'.
-                               // As explained in World(), the last few lines in the array 'line' are incorrectly calculated
-                               // or not calculated at all, so GEN_INC is also used to decrease 'lineCount' in functions like draw()
-                               // and detect().
+                                               // As explained in World(), the last few lines in the array 'line' are incorrectly calculated
+                                               // or not calculated at all, so GEN_INC is also used to decrease 'lineCount' in functions like draw()
+                                               // and detect().
 
-#define GRASS_HEIGHT 4         // Defines how long the grass layer of a line should be in multiples of HLINE.
+#define GRASS_HEIGHT 4 // Defines how long the grass layer of a line should be in multiples of HLINE.
 
 
 #define DRAW_Y_OFFSET 50       // Defines how many pixels each layer should be offset from each other on the y axis when drawn.
@@ -31,8 +31,8 @@ World::World(void){
 }
 
 void World::generate(unsigned int width){      // Generates the world and sets all variables contained in the World class.
-       unsigned int i;                         // Used for 'for' loops 
-       float inc;                              // See line 40
+       unsigned int i;
+       float inc;
        
        /*
         *      Calculate the world's real width. The current form of generation fails to generate
@@ -69,8 +69,8 @@ void World::generate(unsigned int width){     // Generates the world and sets all va
                */
                
                line[i].y=rand() % 8 - 4 + line[i-GEN_INC].y;   // Add +/- 4 to the previous line
-                        if(line[i].y <  60)line[i].y =  60;            // Minimum bound
-               else if(line[i].y > 110)line[i].y = 110;                // Maximum bound
+                        if(line[i].y < 60)line[i].y =  60;                     // Minimum bound
+               else if(line[i].y > 90)line[i].y =  90;                 // Maximum bound
                
        }
        
@@ -145,36 +145,99 @@ void World::draw(Player *p){
        static World *current;
        int i,is,ie,v_offset,cx_start;
        struct line_t *cline;
-       current=this;   // yeah
        glClearColor(.1,.3,.6,0);
-LOOP1:                                                         // Check for worlds behind the current one and set 'current' to them if they exist
-       if(current->behind){                    // so that once LOOP1 is exited 'current' contains the furthest back world.
+       
+       /*
+        *      World drawing is done recursively, meaning that this function jumps
+        *      back as many 'layers' as it can and then draws, eventually coming
+        *      back to the initial or 'root' layer. LOOP1 does the recursion back
+        *      to the furthest behind layer, modifying shade and y offsets as it
+        *      does.
+        * 
+       */
+       
+       current=this;
+       
+LOOP1:
+
+       if(current->behind){
+               
+               /*
+                *      Add to the y offset and shade values (explained further below)
+                *      and recurse.
+                * 
+               */
+               
                yoff+=DRAW_Y_OFFSET;
                shade+=DRAW_SHADE;
                current=current->behind;
                goto LOOP1;
        }
-LOOP2:                                                                                                 // Draw each world
-       v_offset=(p->loc.x-current->x_start)/HLINE;                     // Calculate the player's offset in the array 'line' using the player's location 'vec'
-       is=v_offset-SCREEN_WIDTH/(yoff/(DRAW_Y_OFFSET/2));      // Set 'i' to that somehow
-       if(is<0)is=0;                                                                           // If the player is past the start of that world 'i' should start at the beginning
-                                                                                                               // of the world
-       ie=v_offset+SCREEN_WIDTH/(yoff/(DRAW_Y_OFFSET/2));      // Set how many lines should be drawn (the drawing for loop loops from 'i' to 'ie')
-       if(ie>current->lineCount)ie=current->lineCount;         // If the player is past the end of that world 'ie' should contain the end of that world
-       cline=current->line;                                                            // 'cline' and 'cx_start' only exist to make the for loop clear (and maybe make it faster)
+       
+       /*
+        *      Here is where the actual world drawing begins. A goto is made to
+        *      LOOP2 once the current layer is drawn and the function shifts to
+        *      draw the next closest layer.
+       */
+       
+LOOP2:
+
+       /*
+        *      Calculate the offset in the line array that the player is (or would)
+        *      currently be on. This function then calculates reasonable values for
+        *      the 'for' loop below that draws the layer.
+       */
+
+       v_offset=(p->loc.x - current->x_start) / HLINE;
+       
+       // is -> i start
+       
+       is=v_offset - SCREEN_WIDTH / (yoff / (DRAW_Y_OFFSET / 2));
+       if(is<0)is=0;                                                                                           // Minimum bound
+
+       ie=v_offset + SCREEN_WIDTH / (yoff / (DRAW_Y_OFFSET / 2));
+       if(ie>current->lineCount)ie=current->lineCount;                         // Maximum bound
+       
+       /*
+        *      Make more direct variables for quicker referencing.
+       */
+       
+       cline   =current->line;
        cx_start=current->x_start;
+       
+       /*
+        *      Invert shading if desired.
+       */
+       
        //shade*=-1;
+       
+       /*
+        *      Draw entities in the current layer if we're on the one we started at.
+       */
+       
+       if(current==this){
+               for(i=0;i<entity.size();i++){
+                       if(entity[i]->inWorld==this)
+                               entity[i]->draw();
+               }
+       }
+       
+       /*
+        *      Draw the layer up until the grass portion, which is done later.
+       */
+       
        glBegin(GL_QUADS);
-               for(i=is;i<ie-GEN_INC;i++){                                                                     // For lines in array 'line' from 'i' to 'ie'
-                       cline[i].y+=(yoff-DRAW_Y_OFFSET);                                       // 'yoff' is always one incrementation ahead of what it should be
-                       safeSetColor(cline[i].color+shade,cline[i].color-50+shade,cline[i].color-100+shade);    // Set the shaded dirt color (safely)
+               for(i=is;i<ie-GEN_INC;i++){
+                       cline[i].y+=(yoff-DRAW_Y_OFFSET);                                                                                                               // Add the y offset
+                       safeSetColor(cline[i].color+shade,cline[i].color-50+shade,cline[i].color-100+shade);    // Set the shaded dirt color
                        glVertex2i(cx_start+i*HLINE      ,cline[i].y-GRASS_HEIGHT);
                        glVertex2i(cx_start+i*HLINE+HLINE,cline[i].y-GRASS_HEIGHT);
                        glVertex2i(cx_start+i*HLINE+HLINE,0);
                        glVertex2i(cx_start+i*HLINE              ,0);
-                       cline[i].y-=(yoff-DRAW_Y_OFFSET); // Reset 'cline[i]'`s y to what it was
+                       cline[i].y-=(yoff-DRAW_Y_OFFSET);                                                                                                               // Restore the line's y value
                }
        glEnd();
+       
        if(current==this){
                int ph;
                ph=(p->loc.x+p->width/2-x_start)/HLINE; // Calculate what line the player is currently on
@@ -182,11 +245,6 @@ LOOP2:                                                                                                     // Draw each world
                        if(p->ground==1&&i<ph+6&&i>ph-6)cline[i].gs=false;
                        else cline[i].gs=true;
                }
-               for(i=0;i<entity.size();i++){
-                       if(entity[i]->inWorld==this){
-                               entity[i]->draw();
-                       }
-               }
                p->draw();
        }
        float cgh[2];
@@ -234,9 +292,11 @@ void World::singleDetect(Entity *e){
         *      Kill any dead entities.
        */
        
-       if(e->health<=0){
+       if(e->alive&&e->health<=0){
          
                e->alive=false;
+               std::cout<<"Killing entity..."<<std::endl;
+               return;
                
        }