diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2015-10-26 08:49:10 -0400 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2015-10-26 08:49:10 -0400 |
commit | e017c5cbc9f1cf357ca82593e5d2829dd7f729ce (patch) | |
tree | a65b9516a4e6a2ff6f9c292da97d5f6f6f84b3bd | |
parent | 99c8a41cde3e5ec74f35660c8701de4326ffcd21 (diff) |
bug fixes
-rw-r--r-- | Changelog | 13 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | include/entities.h | 14 | ||||
-rw-r--r-- | main.cpp | 76 | ||||
-rw-r--r-- | src/Makefile | 4 | ||||
-rw-r--r-- | src/entities.cpp | 69 | ||||
-rw-r--r-- | src/gameplay.cpp | 5 | ||||
-rw-r--r-- | src/world.cpp | 118 |
8 files changed, 211 insertions, 96 deletions
@@ -162,4 +162,15 @@ - 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 @@ -1,7 +1,6 @@ -LIBS = -lGL
-WIN_LIBS = -lopengl32 -lmingw32
+LIBS = -lGL -lGLEW -lSDL2main -lSDL2 -lfreetype -lSDL2_image -lSDL2_mixer
-FLAGS = -std=c++11 -Iinclude -Iinclude/freetype2 -lGL -lGLEW -lSDL2 -lfreetype -lSDL2_image -lSDL2_mixer
+FLAGS = -m32 -std=c++11 -Iinclude -Iinclude/freetype2
all:
@rm -f out/*.o
@@ -9,9 +8,6 @@ all: @echo " CXX main.cpp"
@g++ $(FLAGS) -o main main.cpp out/*.o $(LIBS)
-win32:
- @g++ $(FLAGS) -o main main.cpp src/*.cpp $(WIN_LIBS)
-
clean:
@echo " RM main"
@-rm -f main
diff --git a/include/entities.h b/include/entities.h index 47f7f55..c111ea7 100644 --- a/include/entities.h +++ b/include/entities.h @@ -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 @@ -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 @@ -268,6 +258,19 @@ int main(int argc, char *argv[]){ } /* + * 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 * if they have error. @@ -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. */ @@ -677,6 +686,15 @@ void logic(){ 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; } diff --git a/src/Makefile b/src/Makefile index 8021f42..a243846 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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'` diff --git a/src/entities.cpp b/src/entities.cpp index ae8b4c8..8100a4c 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -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; } } diff --git a/src/gameplay.cpp b/src/gameplay.cpp index 1f4b3fe..77d0021 100644 --- a/src/gameplay.cpp +++ b/src/gameplay.cpp @@ -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); diff --git a/src/world.cpp b/src/world.cpp index a05c155..9f18180 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -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; } |