From a3e3f43a51e4a8137dff779f38b358b5b8608e4e Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Wed, 28 Oct 2015 08:48:56 -0400 Subject: [PATCH] bug fixes --- Changelog | 10 +++ assets/mountain.png | Bin 2125 -> 2197 bytes include/entities.h | 6 +- main.cpp | 10 +-- src/entities.cpp | 14 ++-- src/gameplay.cpp | 6 +- src/world.cpp | 155 ++++++++++++++++++++++++++++++++++---------- xcf/mountain.xcf | Bin 209841 -> 12475 bytes 8 files changed, 153 insertions(+), 48 deletions(-) diff --git a/Changelog b/Changelog index 4c4d823..4af9d0c 100644 --- a/Changelog +++ b/Changelog @@ -182,3 +182,13 @@ - gained knowledge on sprite creation - created tree and mountain sprites - created a decent bird AI + +10/28/2015: +=========== + + - fixed world drawing bug + - fixed segfault with entering buildings + - found bug with npc quest preloading + - documented more of world.cpp + - improved background textures/parallax stuff + - diff --git a/assets/mountain.png b/assets/mountain.png index 12c0f64000c912aa6456ac2ead339796ddc93371..7039174f7350359fc4ff72070e3915c1855eb738 100644 GIT binary patch delta 2182 zcmV;12zmF-5S0;IiBL{Q4GJ0x0000DNk~Le0001A0000~2nGNE0OX77HUIzs24YJ` zL;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2j2=D3n&yc5n<|) zTPT11NklDf1vX@J=Gima}wuIXKckRwNq96562$dMyQjvP61$&zdpR*a!{a;M`82r`+9%(Su7Tt^NX_$9n%t%nO~FTpFS_b@rxhK z^CwS72Q>qB;m;rL6?AEFK@!%SAVJ3@r10tu6O6Z zfA@Bi>wy#a#bUAf_I5Ck z6kVB6R5SWcK+!euvcO8lTflmYt~YRvryw_5ufLu5Fw4g;Fa)TI7 zT3ki%x#QvY(UK_l_a#4_f?w5I#xy>5pO}>O<^78;B`0Mj8*@NaM~Vi1AJX%rE8u_m z`9Whfj~^?RTrOh3dmItz{pm>vAFsCGwaWw)Z39oB^Z50T?ef#-1+{*YMnr#8Og}x@ zKmPHmyAjY!Kc5ov=Jm_n_T=ekmy8g?4j?2|G%~EjagariKg_2g+^x3fJ)1nN|7SE` zW4#qLB6x!MK0Z<`xBotpKkZ@XWe;Ec42uR6vxqUp*?}tE@pli(kvhMD8mwmCGO9wBch}EdjUMqj{Aqy~Q&c^}IdlDVqd7#f1={7TDHxlIe)`h~cOhYs{xaw3UFeN$HRbwTdKSzIIQK&D3N? zvR+F7fliF4&(UbWvO}zwR#3890<1A#I-i)c@i?5=I%m0Dr)Y!yWmBx@ER_WkO_(%5 zwd0l)NyhUfXT3bGNe+K8UfRwP9tmo{Py6veQC}A;siI~pyJ;r<_J$&D*=L2E>coa7C>Ap>r%-8fhwP0)4do`W! zv;4hWwyFKKnJ?MRKQb{M(9wA@#!CmoS&zU*%qM*(ttZCcvTJ|u*W1sattN6dUe}^E z)-1+rx~~;kOY^zS{C9-&(cXV=ha^XvBq89@EHAvIdhXXDELZh= zK1Chi5wkrBsT$TqNjv6gDaZ*{EJ%9lCZJ3O-Xj$n@Y+Pn8?ueSrA7iQt)adLy~DmU2_FV*zdX zb~(wiq{eEl@dOa-n{qs5isbNz(rt(AOrk!HbT_f<(1a>hT)Fgc;Au3xm{gaZG8K?# zlWxG5?O^Rmlr|b-NkCxBQ6P1m1J8?YtIVg&qKV603-W(rbt|=pBHHyS-%lolYdx15 zzD~Mdh5c^k%UA2T-d0Tj>cMMTuK_O^US(ujk|W(sue}}Zhga#PTOi86CzFgM$1{7C zInS~wGoRWFN1a0nZfrl27sPy7Y`q$7g|%<-qbrdr16sVjmVBHv>MABd6;oW3WHMrSmAA`Md-EFGt;A@L z8uysbUkpOJS+_-;(uHphRP~#d-v~cj8r|VS&K1hO`|1nj=B?K+?ez z?oDK@m~v;M$&CiGrtKW`nC2ttDQKtX4O|HxDsww|vshn;@v=LqJq$r^hW1I;%f!eDSV|P*QP|Xd@7$7;D%Yl5 zkGha`->;GEN6hEjDWhVK`P!3t@5~bY2cH}zvC-h^!&}x-_TOXAU8R3VvslD@Yt*F9 zdP`Z5yo`xC98Est`t2%NGu3r+GnyjCdmjNJR>vk&RURq+1G2%8?X0E3c>n+a07*qo IM6N<$f*!Om`v3p{ delta 2109 zcmV-D2*UT35zP==iBL{Q4GJ0x0000DNk~Le000180000+2nGNE0Ipz|n*aa+24YJ` zL;wH)0002_L%V+f000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2j2=C3?wqrF@-0Q zTPT0ENkla|I5WVk-XB01>5up_zd6A8~K*;=r{__3=swz>M4U0-3wT_jL zg%L5rUAW^6<1-)kecB>dvYy{3&Y5%1oSAn?>0vyKA7K=S_Jc=NTBGB4tHb+S4g%~^ zmDXRst+t=}e7-)vI9t;>Eg%m}ugU5UALoDR_}Ne9_2b9YL9o8qcd(aVR^Oewyu3_5 zpZuZ*fPmj;@E`3X*b?aL#ZCJ6>L2w!9*E_a)%N=Xuu<`gn&#bg#dq_ zPN&=JQ%Y$%oo>&)ee-&7;EN#vfA{Cv77z|>1YFMOlu{^gob^KjU+fFu$f-ntk4Ve) z;%4VLLjpe-=*Sl40$gW?ko^2mpmV^l7dK&P;0%r=QyEB<6NUo5=o@gEI3>d^K%>bt z8qn*-O?vh6dGEj%eF7e}hB@Fi9YcRu$zljuL5wD?t)u7M!SLs3!IQ`PmYH5buWJ!K z4fmeoNmk$9z35X~aw<>H(bSz88t8pW%%i>l|Lxa%4b?olmjt;icz{P74(a*nNlNdp zHovtG;ES#SC$RbW{jbgT!^b(bV6$dGTg*N^***XMs(Z!{(od&Ayn6Y3yFY(^Ty2Ap zQrZH8B#CB%6)+C2=&`5SB&FNs=DH{2`|k&@=^D$eK{J2{h9BcIgT`!<(jR~0Yi5(p zF@FB^#0R=-wio*XIMnuKO2^~-?*tx!DF+8vvN@&AJ^?PbeF9%}0XS!BU65%%rOh!J zfas_zBL@e16P9zJWiU_>Pym03!PYU2<)2q69aY@|Uv}lk>i|uF5}5or`mQmagULa? zUGDD7aa3)9Z~8a&#`HF{97&ADdQDOgt0mBuDn_Rc2ScL$#M;N0-G34pQCCI<%L)-EuCbs1Xg3Z zbTXb(i8vPTJ7=~0PNPk>mu<0}vr;BLROo0xYUeGan0+OYY#FoW5%kbGJ%qv8>;dDVhL|m>da2-C-3t+PO&SFAF1Yki^sl zzRU$YA_*GcT7eWDvfSsAB7v0_(JKA9Cr5=5*Ydm7j^wO61)VHnq+5spjkpny>2j-q z$@Scl9O=gq@S1;?KO5JZv7NPc+maUxV9R&Q;>ePeNPBlw-Lt%@gDG>Qg}?0WddN;8 z>a$3<;@yV|AunliiQ#|~`=5>TC8o>;;>oxl&}Cazd-J2Q-vb|kELksgoCD62X(vpl zNTPz{wgVZlx`*1!2<`ry-zNjXwVX=||4zD|!}c)K zOIoB`8Kn23{lRs5*%o;6-;=>b(h{jQrH*SaDUg)3c zlW0`KHK!6Og0y|o^TjeRp_Wk@(5AW7`-oV$h+d;-Xm9i*9mI&V5UVB2dE)HEr;n<% zM$3t<{)d0Iib^Zlb6u15p3`EuloYG4!nIt2FM%eO=dituXgC5fw+R)w7O_5>Gjft7 zDvYFt(-sv%8r!4xvGi=BHl3rc#d04gI9k&RIg|*~5zDQBaKOF9DK$N6AIqps^wyF@ zX9BtoU2m;lxm|7mv-&9#RPT)tD)Y5+pTMre@^F75)fz{Ld6Aib-d$Qnm$uL|m)&ix zVId8dEN>()GJ$G9Ye0F`qSY-#Qlsrhe7MJQt<={v9I>2(A8Gk!7e|PR$XQq#Y`sFW z81C6YX30k|WyB)#Mya4-la!d33xVq}euk&ih{t@|eZ)CJdL|LhU64awl|5vRnp47EW1_ zQH-jzZo2N;l8rj|=G>3Ef=$<_NVX%U^ZlGzuw}aTraM{*qW_U5XNAZ9NFUs?fU^JX nz1Nif8&#c%>DDZXR;m91(3fuplpj)x00000NkvXXu0mjf>pTJk diff --git a/include/entities.h b/include/entities.h index 94febcf..a9375c3 100644 --- a/include/entities.h +++ b/include/entities.h @@ -69,7 +69,7 @@ public: void spawn(float, float); void draw(void); - virtual void wander(int, vec2*){} + virtual void wander(int){} void getName(); virtual void interact(){} int ticksToUse; //The variable for deciding how long an entity should do a certain task @@ -89,14 +89,16 @@ public: NPC(); void addAIFunc(int (*func)(NPC *),bool preload); void interact(); - void wander(int, vec2*); + void wander(int); }; + class Structures : public Entity{ public: void *inside; Structures(); unsigned int spawn(_TYPE, float, float); }; + class Mob : public Entity{ public: float init_y; diff --git a/main.cpp b/main.cpp index 002fc83..4fb5a00 100644 --- a/main.cpp +++ b/main.cpp @@ -62,7 +62,7 @@ static GLuint bgImage, bgTreesFirst; * */ -bool gameRunning = true; +bool gameRunning; /* * currentWorld - This is a pointer to the current world that the player @@ -173,6 +173,7 @@ unsigned int millis(void){ * MAIN ************************************************************************ *******************************************************************************/ int main(int argc, char *argv[]){ + gameRunning=false; /* * (Attempt to) Initialize SDL libraries so that we can use SDL facilities and eventually @@ -383,6 +384,7 @@ int main(int argc, char *argv[]){ **** GAMELOOP **** **************************/ + gameRunning=true; while(gameRunning){ mainLoop(); } @@ -558,7 +560,7 @@ void render(){ glTexCoord2i(0,0);glVertex2i(-SCREEN_WIDTH*2,SCREEN_HEIGHT); glEnd(); - int base = 50 - (int)worldGetYBase(currentWorld); + int base = 40 - (int)worldGetYBase(currentWorld); glBindTexture(GL_TEXTURE_2D, bgTreesFirst); @@ -729,9 +731,9 @@ void logic(){ * that the NPC doesn't move when it talks to the player. * */ - + if(entity[i]->canMove) - NPCp(entity[i])->wander((rand() % 120 + 30), &entity[i]->vel); + NPCp(entity[i])->wander((rand() % 120 + 30)); /* * Don't bother handling the NPC if another has already been handled. diff --git a/src/entities.cpp b/src/entities.cpp index 0479d5e..acc45bd 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -227,28 +227,32 @@ void Player::interact(){ //the function that will cause the player to search for * the memory address passed to it is directly modified. */ -void NPC::wander(int timeRun, vec2 *v){ //this makes the entites wander about +void NPC::wander(int timeRun){ + /* * Direction is the variable that decides what direction the entity will travel in * the value is either -1, 0, or 1. -1 being left, 0 means that the npc will stay still * and a value of 1 makes the entity move to the right */ - static int direction; //variable to decide what direction the entity moves + + static int direction; + /* * Ticks to use is a variable in the entity class that counts the total ticks that need to be used * * This loop only runs when ticksToUse is 0, this means that the speed, direction, etc... Will be * calculated only after the npc has finished his current walking state */ + if(ticksToUse == 0){ ticksToUse = timeRun; - v->x = .008*HLINE; //sets the inital velocity of the entity + vel.x = .008*HLINE; //sets the inital velocity of the entity 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 + vel.x *= direction; //changes the velocity based off of the direction } - ticksToUse--; //removes one off of the entities timer + ticksToUse--; //removes one off of the entities timer } std::vector AIpreload; // A dynamic array of AI functions that are being preloaded diff --git a/src/gameplay.cpp b/src/gameplay.cpp index d3cc4f4..9e0cc99 100644 --- a/src/gameplay.cpp +++ b/src/gameplay.cpp @@ -20,9 +20,10 @@ int compTestQuest(NPC *speaker){ } int giveTestQuest(NPC *speaker){ + unsigned int i; ui::dialogBox(speaker->name,"Here, have a quest!"); player->qh.assign("Test"); - NPCp(entity[2])->addAIFunc(compTestQuest,true); + npc[1]->addAIFunc(compTestQuest,true); return 0; } @@ -41,7 +42,6 @@ void initEverything(void){ */ test->addLayer(400); - //test->addLayer(100); test->addPlatform(150,100,100,10); @@ -91,7 +91,7 @@ void initEverything(void){ /* * Link all the entities that were just created to the initial world, and setup a test AI function. */ - NPCp(entity[1])->addAIFunc(giveTestQuest,false); + npc[0]->addAIFunc(giveTestQuest,false); for(i=0;iinWorld=currentWorld; diff --git a/src/world.cpp b/src/world.cpp index e1d05ab..168ac4c 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -15,7 +15,8 @@ #define INDOOR_FLOOR_HEIGHT 100 // Defines how high the base floor of an IndoorWorld should be -extern std::vectorentity; +extern std::vector entity; +extern std::vector build; void safeSetColor(int r,int g,int b){ // safeSetColor() is an alternative to directly using glColor3ub() to set if(r>255)r=255; // the color for OpenGL drawing. safeSetColor() checks for values that are @@ -79,8 +80,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 > 90)line[i].y = 90; // Maximum bound + if(line[i].y < 40)line[i].y = 40; // Minimum bound + else if(line[i].y > 70)line[i].y = 70; // Maximum bound } @@ -198,14 +199,16 @@ LOOP2: * the 'for' loop below that draws the layer. */ - v_offset=(p->loc.x - current->x_start) / HLINE; + v_offset=(p->loc.x + p->width / 2 - current->x_start) / HLINE; // is -> i start - is=v_offset - SCREEN_WIDTH / (yoff / (DRAW_Y_OFFSET / 2)); + is=v_offset - (SCREEN_WIDTH / 2 / HLINE) - GEN_INC; if(is<0)is=0; // Minimum bound - - ie=v_offset + SCREEN_WIDTH / (yoff / (DRAW_Y_OFFSET / 2)); + + // ie -> i end + + ie=v_offset + (SCREEN_WIDTH / 2 / HLINE) + GEN_INC; if(ie>current->lineCount)ie=current->lineCount; // Maximum bound /* @@ -222,12 +225,13 @@ LOOP2: //shade*=-1; /* - * Draw entities in the current layer if we're on the one we started at. + * Draw structures in the current layer if we're on the one we started at. We draw + * structures behind the dirt/grass so that the buildings corners don't stick out. */ if(current==this){ for(i=0;iinWorld==this) + if(entity[i]->inWorld==this && entity[i]->type == STRUCTURET) entity[i]->draw(); } } @@ -248,48 +252,133 @@ LOOP2: } glEnd(); + /* + * If we're drawing the closest/last world, handle and draw the player and entities in + * the world. + */ + if(current==this){ - int ph; - ph=(p->loc.x+p->width/2-x_start)/HLINE; // Calculate what line the player is currently on - for(i=0;iground==1&&iph-6)cline[i].gs=false; - else cline[i].gs=true; + + /* + * Calculate the line that the player is on + */ + + int ph = (p->loc.x + p->width / 2 - x_start) / HLINE; + + /* + * If the player is on the ground, flatten the grass where the player is standing + * by setting line.gs to false. + */ + + if(p->ground){ + for(i=0;i ph - 6 ) + cline[i].gs=false; + else cline[i].gs=true; + } } + + /* + * Draw the player. + */ + p->draw(); + + /* + * Draw non-structure entities. + */ + + if(current==this){ + for(i=0;iinWorld==this && entity[i]->type != STRUCTURET) + entity[i]->draw(); + } + } } + + /* + * Draw grass on every line. + */ + float cgh[2]; glBegin(GL_QUADS); for(i=is;iplatform.size();i++){ - glRectf(current->platform[i].p1.x,current->platform[i].p1.y+yoff-DRAW_Y_OFFSET, - current->platform[i].p2.x,current->platform[i].p2.y+yoff-DRAW_Y_OFFSET); + glRectf(current->platform[i].p1.x, current->platform[i].p1.y + yoff - DRAW_Y_OFFSET, + current->platform[i].p2.x, current->platform[i].p2.y + yoff - DRAW_Y_OFFSET); } - if(current->infront){ // If there's a world in front of the one that was just drawn - yoff-=DRAW_Y_OFFSET; // draw it as well. - shade-=DRAW_SHADE; + + /* + * Draw the next closest world if it exists. + */ + + if(current->infront){ + yoff -= DRAW_Y_OFFSET; + shade -= DRAW_SHADE; + current=current->infront; goto LOOP2; - }else{ // Otherwise reset static values and return + + }else{ + + /* + * If finished, reset the yoff and shade variables for the next call. + */ + yoff=DRAW_Y_OFFSET; shade=0; } @@ -470,17 +559,16 @@ void World::addPlatform(float x,float y,float w,float h){ World *World::goInsideStructure(Player *p){ unsigned int i; - for(i=0;itype==-1){ - if(entity[i]->inWorld==this){ - if(p->loc.x>entity[i]->loc.x&&p->loc.x+p->widthloc.x+entity[i]->width){ - return (World *)((Structures *)entity[i])->inside; - } - }else if(((Structures *)entity[i])->inside==this){ - p->loc.x=entity[i]->loc.x+entity[i]->width/2-p->width/2; - p->loc.y=entity[i]->loc.y+HLINE; - return (World *)entity[i]->inWorld; + for(i=0;iinWorld==this){ + if(p->loc.x > build[i]->loc.x && + p->loc.x + p->width < build[i]->loc.x + build[i]->width){ + return (World *)build[i]->inside; } + }else if(build[i]->inside==this){ + p->loc.x=build[i]->loc.x + build[i]->width / 2 - p->width / 2; + p->loc.y=build[i]->loc.y + HLINE; + return (World *)build[i]->inWorld; } } return this; @@ -493,8 +581,6 @@ void World::addHole(unsigned int start,unsigned int end){ } } - - IndoorWorld::IndoorWorld(void){ } @@ -519,6 +605,7 @@ void IndoorWorld::generate(unsigned int width){ // Generates a flat area of wid void IndoorWorld::draw(Player *p){ int i,ie,v_offset; + v_offset=(p->loc.x-x_start)/HLINE; // Calculate the player's offset in the array 'line' using the player's location 'vec' i=v_offset-SCREEN_WIDTH/2; // um if(i<0)i=0; // If the player is past the start of that world 'i' should start at the beginning @@ -535,7 +622,7 @@ void IndoorWorld::draw(Player *p){ glVertex2i(x_start+i*HLINE ,line[i].y-50); } glEnd(); - for(i=0;iinWorld==this) entity[i]->draw(); } diff --git a/xcf/mountain.xcf b/xcf/mountain.xcf index 5ef311ee1e0e1c69fc513d8ee33a762cdb7a694a..32fd5b1f43c1f855291870a1985fa15f4b638ab2 100644 GIT binary patch delta 2684 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