\r
#include <common.h>\r
\r
+// Total amount of entities that can be bound to a layer\r
#define MAX_ENTITIES 8\r
\r
+// Easy shortcuts used in UIClass\r
#define goWorldLeft(w) if(w->toLeft){w=w->toLeft;}\r
#define goWorldRight(w) if(w->toRight){w=w->toRight;}\r
\r
class World {\r
private:\r
struct line_t {\r
- // x = 2.0 (window width) / HLINES\r
- double start; // Where to change to dirt, going down (y)\r
+ double start; // Where land begins, going down (i.e. y)\r
} __attribute__ ((packed)) *line;\r
- unsigned int lineCount;\r
- unsigned int entCount;\r
+ unsigned int lineCount; // Size of line array, calculated in the constructor\r
+ unsigned int entCount; // Count of currently bound entities\r
void *entity[MAX_ENTITIES];\r
public:\r
- World *behind,*infront;\r
- World *toLeft,*toRight;\r
- World(void);\r
- World(const float width,World *l,World *r);\r
- void draw(void);\r
- void detect(vec2 *v,vec2 *vel,const float width);\r
- float getWidth(void);\r
- void saveToFile(FILE *f,World *parent);\r
- void loadFromFile(FILE *f,World *parent);\r
- void addLayer(const float width);\r
- void addEntity(void *e);\r
+ World *behind,*infront; // As in layers\r
+ World *toLeft,*toRight; // 'new' worlds (off screen)\r
+ World(void); // Creates an empty world\r
+ World(const float width,World *l,World *r); // Creates a legit world\r
+ void draw(void); // Draws the world as well as any bound entities\r
+ void detect(vec2 *v,vec2 *vel,const float width); // Object / gravity detection\r
+ float getWidth(void); // Get coordinate width of world\r
+ void saveToFile(FILE *f,World *parent); // WIP: Save the world (seed) to a file?\r
+ void loadFromFile(FILE *f,World *parent); // No\r
+ void addLayer(const float width); // Creates a layer of said width behind the current one\r
+ void addEntity(void *e); // Adds (binds) an entity to the world\r
};\r
\r
#endif // WORLD_H
#include <World.h>\r
#include <cstdio>\r
\r
+// Layer modulation in draw()\r
static float drawOffsetX=0,\r
drawOffsetY=0;\r
\r
+// Generates a blank world\r
World::World(void){\r
line=NULL;\r
lineCount=entCount=0;\r
toLeft=toRight=behind=infront=NULL;\r
}\r
+// Generates a legit world\r
World::World(const float width,World *l,World *r){\r
unsigned int i;\r
double f;\r
- lineCount=width/HLINE+11;\r
- if((line=(struct line_t *)calloc(lineCount,sizeof(struct line_t)))==NULL){\r
+ lineCount=width/HLINE+11; // Last 10 lines won't be drawn\r
+ if((line=(struct line_t *)calloc(lineCount,sizeof(struct line_t)))==NULL){ // Allocate buffer for lines\r
std::cout<<"Failed to allocate memory!"<<std::endl;\r
abort();\r
}\r
- toLeft=l;\r
+ toLeft=l; // Set other variables\r
toRight=r;\r
behind=infront=NULL;\r
entCount=0;\r
- if(toLeft){\r
+ if(toLeft){ // Make sure linked worlds link back\r
if(toLeft->toRight){\r
std::cout<<"There's already a world to the left!"<<std::endl;\r
abort();\r
- }else{\r
- toLeft->toRight=this;\r
- }\r
+ }else toLeft->toRight=this;\r
}\r
if(toRight){\r
if(toRight->toLeft){\r
std::cout<<"There's already a world to the right!"<<std::endl;\r
abort();\r
- }else{\r
- toRight->toLeft=this;\r
- }\r
+ }else toRight->toLeft=this;\r
}\r
- line[0].start=(grand()%100)/100.0f-0.8f; // lazy\r
- if(line[0].start>-0.5f)line[0].start=-0.7f;\r
- for(i=10;i<lineCount;i+=10){ \r
+ line[0].start=(grand()%100)/100.0f-0.8f; // Set .start of first line\r
+ if(line[0].start>-0.5f)line[0].start=-0.7f; // Don't let the ground take up too much of the window\r
+ for(i=10;i<lineCount;i+=10){ // Set heights for every 10 lines\r
line[i].start=((double)((grand()%50)+400))/1000.0f-1;\r
}\r
- for(i=0;i<lineCount;i++){\r
+ for(i=0;i<lineCount;i++){ // Set heights for other lines based on those\r
if(!(i%10)||!i){\r
- f=line[i+10].start-line[i].start;\r
+ f=line[i+10].start-line[i].start; // 1/10th of difference between the two heights\r
f/=10.0f;\r
}else{\r
line[i].start=line[i-1].start+f;\r
}\r
}\r
}\r
+// Set RGB color with potentially not 8-bit values\r
void safeSetColor(int r,int g,int b){\r
if(r>255)r=255;else if(r<0)r=0;\r
if(g>255)g=255;else if(g<0)g=0;\r
void World::draw(void){\r
unsigned int i;\r
float x,y,hline=HLINE;\r
- static World *root,*cur;\r
+ World *root,*cur;\r
int shade;\r
root=cur=this;\r
LOOP:\r
- if(cur->behind){\r
- drawOffsetX+=(cur->getWidth()-cur->behind->getWidth())/2;\r
- drawOffsetY+=.3;\r
+ if(cur->behind){ // If there's a layer behind us,\r
+ drawOffsetX+=(cur->getWidth()-cur->behind->getWidth())/2; // set drawOffsetX so that it will be centered behind this one\r
+ drawOffsetY+=.3; // Push it back a bit for depth-feel\r
//hline/=2;\r
- cur=cur->behind;\r
- goto LOOP;\r
- //behind->draw();\r
+ cur=cur->behind; // Go back one\r
+ goto LOOP; // loop\r
}\r
-LOOP2:\r
- shade=30*(drawOffsetY/.3);\r
+LOOP2: // Should be in furthest back layer once this is first reached\r
+ shade=30*(drawOffsetY/.3); // Trash shaders\r
glBegin(GL_QUADS);\r
- for(i=0;i<cur->lineCount-10;i++){\r
- x=(hline*i)-1+drawOffsetX;\r
- y=cur->line[i].start+drawOffsetY;\r
- safeSetColor(0,200+shade,0);\r
- glVertex2f(x ,y);\r
+ for(i=0;i<cur->lineCount-10;i++){ // Draw the layer\r
+ x=(hline*i)-1+drawOffsetX; // Pre-calculate x for 'optimization'\r
+ y=cur->line[i].start+drawOffsetY; // same, but y\r
+ safeSetColor(0,200+shade,0); // Set shaded green for grass\r
+ glVertex2f(x ,y); // Doodle\r
glVertex2f(x+hline,y);\r
- y-=hline*2;\r
+ y-=hline*2; // 'optimization'\r
glVertex2f(x+hline,y);\r
glVertex2f(x ,y);\r
- safeSetColor(150+shade,100+shade,50+shade);\r
+ safeSetColor(150+shade,100+shade,50+shade); // Set shaded brown for dirt\r
glVertex2f(x ,y);\r
glVertex2f(x+hline,y);\r
glVertex2f(x+hline,-1);\r
glVertex2f(x ,-1);\r
}\r
glEnd();\r
- if(root!=cur){\r
- cur=cur->infront;\r
- drawOffsetX-=(cur->getWidth()-cur->behind->getWidth())/2;\r
- drawOffsetY-=.3;\r
+ if(root!=cur){ // If we're still in one of the behinds\r
+ cur=cur->infront; // Move one closer\r
+ drawOffsetX-=(cur->getWidth()-cur->behind->getWidth())/2; // Take off last layer's centering\r
+ drawOffsetY-=.3; // And back-pushing\r
//hline*=2;\r
- goto LOOP2;\r
+ goto LOOP2; // Loop the draw\r
}else{\r
- drawOffsetX=drawOffsetY=0;\r
- for(i=0;i<entCount;i++){\r
+ drawOffsetX=drawOffsetY=0; // Reset for next draw() call\r
+ for(i=0;i<entCount;i++){ // Draw any bound entities\r
((Entity **)entity)[i]->draw();\r
}\r
}\r
}\r
void World::detect(vec2 *v,vec2 *vel,const float width){\r
unsigned int i;\r
- // hey\r
- // oh hai\r
- for(i=0;i<lineCount-10;i++){\r
- if(v->y<line[i].start){\r
- if(v->x>(HLINE*i)-1&&v->x<(HLINE*i)-1+HLINE){\r
- if(v->y<line[i].start){vel->y=0;v->y=line[i].start+HLINE;}\r
- return;\r
- }else if(v->x+width>(HLINE*i)-1&&v->x+width<(HLINE*i)-1+HLINE){\r
- if(v->y<line[i].start){vel->y=0;v->y=line[i].start+HLINE;}\r
- return;\r
+ for(i=0;i<lineCount-10;i++){ // For every line in world\r
+ if(v->y<line[i].start){ // If we're inside the line\r
+ if(v->x>(HLINE*i)-1&&v->x<(HLINE*i)-1+HLINE){ // And we're inside it ;)\r
+ vel->y=0;v->y=line[i].start+HLINE; // Correct\r
+ return; // :/\r
+ }else if(v->x+width>(HLINE*i)-1&&v->x+width<(HLINE*i)-1+HLINE){ // Same as above, but coming from right side instead of left\r
+ vel->y=0;v->y=line[i].start+HLINE;\r
+ return; // ;)\r
}\r
- }else if(v->y>line[i].start+HLINE){\r
+ }else if(v->y>line[i].start+HLINE){ // Trashy gravity handling\r
vel->y-=.00000001;\r
}\r
}\r
}\r
+// Calculate the world's width in coordinates\r
float World::getWidth(void){\r
return (lineCount-11)*HLINE;\r
}\r
+// no\r
void World::saveToFile(FILE *f,World *parent){\r
fwrite(&lineCount,sizeof(unsigned int) ,1 ,f);\r
fwrite(&line ,sizeof(struct line_t),lineCount,f);\r
toRight->saveToFile(f,toRight);\r
}\r
}\r
+// no\r
void World::loadFromFile(FILE *f,World *parent){\r
fread(&lineCount,sizeof(unsigned int) ,1 ,f);\r
line=(struct line_t *)malloc(lineCount*sizeof(struct line_t *));\r
}\r
}\r
void World::addLayer(const float width){\r
- if(behind){\r
- behind->addLayer(width);\r
+ if(behind){ // If there's already a layer behind us\r
+ behind->addLayer(width); // Add it back there\r
}else{\r
- behind=new World(width,NULL,NULL);\r
+ behind=new World(width,NULL,NULL); // Otherwise add it directly behind us\r
behind->infront=this;\r
}\r
}\r
void World::addEntity(void *e){\r
- entity[entCount++]=e;\r
+ entity[entCount++]=e; // duh\r
}\r