aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/world.h56
-rw-r--r--src/world.cpp133
2 files changed, 115 insertions, 74 deletions
diff --git a/include/world.h b/include/world.h
index c89ced7..00b7a7f 100644
--- a/include/world.h
+++ b/include/world.h
@@ -1,30 +1,58 @@
#ifndef WORLD_H
#define WORLD_H
-#include <common.h>
+#include <common.h> // For HLINE, vec2, OpenGL utilities, etc.
+/*
+ * World - creates and handles an area of land
+*/
class World {
private:
+ /*
+ * struct line_t
+ *
+ * The world is stored in an array of lines. Example:
+ *
+ * ||
+ * ||| || |
+ * |||||||||
+ * line no. 123456789...
+ *
+ */
struct line_t {
float y;
unsigned char color;
} __attribute__ ((packed)) *line;
- unsigned int lineCount;
- int x_start;
- World *behind,*infront;
+ unsigned int lineCount; // Size of the array 'line' (aka the width of the world)
+ int x_start; // Worlds are centered on the x axis (0,n), this contains
+ // where to start drawing the world to have it centered properly.
+ World *behind,*infront; // Pointers to other areas of land that are behind or in front of this one, respectively.
public:
- World *toLeft,*toRight;
- World(unsigned int width);
- ~World(void);
+ World *toLeft,*toRight; // Pointers to areas to the left and right of this world. These are made public
+ // so that they can easily be set without a function.
+
+ World(unsigned int width); // Generates a world of width 'width'.
+ ~World(void); // Frees the 'line' array.
- void addLayer(unsigned int width);
- void draw(vec2 *vec);
- void detect(vec2 *v,vec2 *vel,const float width);
+ void addLayer(unsigned int width); // Generates a new world and makes 'behind' point to it. If 'behind'
+ // already points to a world, the new world will be set to be behind 'behind'.
+
+ void draw(vec2 *vec); // Draws the world around the coordinates 'vec'
- World *goWorldLeft(vec2 *loc,const float width);
- World *goWorldRight(vec2 *loc,const float width);
- World *goWorldBack(vec2 *loc,const float width);
- World *goWorldFront(vec2 *loc,const float width);
+ void detect(vec2 *v,vec2 *vel,const float width); // Insures objects/entities at location 'v' with a width of 'width' and a
+ // velocity of 'vel' stay outside of the ground (defined by array 'line'),
+ // and handles gravity for that object/entity by modifying it's velocity ('vel')
+
+ World *goWorldLeft(vec2 *loc,const float width); // Returns the world to the left of this one if it exists and the player at
+ // location 'loc' with width 'width' is at the left edge of this world.
+ World *goWorldRight(vec2 *loc,const float width); // Functions the same as goWorldLeft(), but checks/returns the world to the right
+ // of the player.
+
+ World *goWorldBack(vec2 *loc,const float width); // Returns the address of the world behind this one if it exists and the player
+ // at location 'loc' with width 'width' is within the area of it (i.e., when this
+ // world is drawn the world has to appear directly behind the player)
+ World *goWorldFront(vec2 *loc,const float width); // Functions the same as goWorldBack(), but checks/returns the world in front of
+ // this one.
};
#endif // WORLD_H
diff --git a/src/world.cpp b/src/world.cpp
index d05d5c1..891c8cd 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -1,13 +1,20 @@
#include <world.h>
-#define getWidth(w) ((w->lineCount-GEN_INC)*HLINE)
+#define getWidth(w) ((w->lineCount-GEN_INC)*HLINE) // Calculates the width of world 'w'
-#define GEN_INC 10
-#define GRASS_HEIGHT 4
+#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().
+#define GRASS_HEIGHT 4 // Defines how long the grass layer of a line should be in multiples of HLINE.
-void safeSetColor(int r,int g,int b){
- if(r>255)r=255;
- if(g>255)g=255;
+
+#define DRAW_Y_OFFSET 50 // Defines how many pixels each layer should be offset from each other on the y axis when drawn.
+#define DRAW_SHADE 40 // Defines a shade increment for draw()
+
+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
+ if(g>255)g=255; // outside the range of an unsigned character and sets them to a safer value.
if(b>255)b=255;
if(r<0)r=0;
if(g<0)g=0;
@@ -15,96 +22,98 @@ void safeSetColor(int r,int g,int b){
glColor3ub(r,g,b);
}
-World::World(unsigned int width){
- unsigned int i;
- float inc;
- lineCount=width+GEN_INC;
- line=(struct line_t *)calloc(lineCount,sizeof(struct line_t)); // allocate space for the array of lines
- line[0].y=80;
- for(i=GEN_INC;i<lineCount;i+=GEN_INC){
- line[i].y=rand()%8-4+line[i-GEN_INC].y;
- if(line[i].y<60)line[i].y=60;
- if(line[i].y>110)line[i].y=110;
+World::World(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 37
+ lineCount=width+GEN_INC; // Sets line count to the desired width plus GEN_INC to remove incorrect line calculations.
+
+ line=(struct line_t *)calloc(lineCount,sizeof(struct line_t)); // Allocate memory for the array 'line'
+
+ line[0].y=80; // Sets a starting value for the world generation to be based off of
+ for(i=GEN_INC;i<lineCount;i+=GEN_INC){ // For every GEN_INCth line in the array 'line'
+ line[i].y=rand()%8-4+line[i-GEN_INC].y; // Generate a y value for it, and correct it if it is too high or low.
+ if(line[i].y<60)line[i].y=60; // y value minimum
+ if(line[i].y>110)line[i].y=110; // y value maximum
}
- for(i=0;i<lineCount-GEN_INC;i++){
- if(!i||!(i%GEN_INC)){
- inc=(line[i+GEN_INC].y-line[i].y)/(float)GEN_INC;
- }else{
- line[i].y=line[i-1].y+inc;
+ for(i=0;i<lineCount-GEN_INC;i++){ // Calculate the rest of the lines as well as set color values for them.
+ if(!i||!(i%GEN_INC)){ // If this is one of the GEN_INCth lines that are already calculated
+ inc=(line[i+GEN_INC].y-line[i].y)/(float)GEN_INC; // Calculate the slope between this line and the line ahead of it, then
+ // divide it by the number of lines inbetween the two.
+ }else{ // If this line's y hasn't been set yet
+ line[i].y=line[i-1].y+inc; // Set it by incrementing the previous line's y by 'inc'.
}
- line[i].color=rand()%20+130;
+ line[i].color=rand()%20+130; // Generate a color for the dirt area of this line. This value will be used
+ // in the form (where n represents the color) glColor3ub(n,n-50,n-100)
}
- x_start=0-getWidth(this)/2+GEN_INC/2*HLINE;
- behind=infront=NULL;
- toLeft=toRight=NULL;
+ x_start=0-getWidth(this)/2+GEN_INC/2*HLINE; // Calculate x_start (explained in world.h)
+ behind=infront=NULL; // Set pointers to other worlds to NULL
+ toLeft=toRight=NULL; // to avoid accidental calls to goWorld... functions
}
World::~World(void){
- free(line);
+ free(line); // Free (de-allocate) the array 'line'
}
void World::draw(vec2 *vec){
- static float yoff=50;
+ static float yoff=DRAW_Y_OFFSET; // Initialize stuff
static int shade=0;
- static World *root,*current;
+ static World *current;
int i,ie,v_offset,cx_start;
struct line_t *cline;
- root=current=this;
-LOOP1:
- if(current->behind){
- yoff+=50;
- shade+=40;
+ current=this; // yeah
+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.
+ yoff+=DRAW_Y_OFFSET;
+ shade+=DRAW_SHADE;
current=current->behind;
goto LOOP1;
}
-LOOP2:
- v_offset=(vec->x-current->x_start)/HLINE;
- i=v_offset-SCREEN_WIDTH/(yoff/25);
- if(i<0)i=0;
- ie=v_offset+SCREEN_WIDTH/(yoff/25);
- if(ie>current->lineCount)ie=current->lineCount;
- //std::cout<<v_offset<<" "<<i<<" "<<ie<<yoff<<std::endl;
- cline=current->line;
+LOOP2: // Draw each world
+ v_offset=(vec->x-current->x_start)/HLINE; // Calculate the player's offset in the array 'line' using the player's location 'vec'
+ i=v_offset-SCREEN_WIDTH/(yoff/(DRAW_Y_OFFSET/2)); // Set 'i' to that somehow
+ if(i<0)i=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)
cx_start=current->x_start;
glBegin(GL_QUADS);
- for(i=i;i<ie-GEN_INC;i++){
- cline[i].y+=(yoff-50);
- safeSetColor(shade,200+shade,shade);
- glVertex2i(cx_start+i*HLINE ,cline[i].y);
+ for(i=i;i<ie;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(shade,200+shade,shade); // Safely set the grass color
+ glVertex2i(cx_start+i*HLINE ,cline[i].y); // Draw the grass area of the line
glVertex2i(cx_start+i*HLINE+HLINE,cline[i].y);
glVertex2i(cx_start+i*HLINE+HLINE,cline[i].y-GRASS_HEIGHT);
glVertex2i(cx_start+i*HLINE ,cline[i].y-GRASS_HEIGHT);
- safeSetColor(cline[i].color+shade,cline[i].color-50+shade,cline[i].color-100+shade);
- glVertex2i(cx_start+i*HLINE ,cline[i].y-GRASS_HEIGHT);
+ safeSetColor(cline[i].color+shade,cline[i].color-50+shade,cline[i].color-100+shade); // Set the shaded dirt color (safely)
+ glVertex2i(cx_start+i*HLINE ,cline[i].y-GRASS_HEIGHT); // Draw the dirt area of the line
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-50);
+ cline[i].y-=(yoff-DRAW_Y_OFFSET); // Reset 'cline[i]'`s y to what it was
}
glEnd();
- if(current->infront){
- yoff-=50;
- shade-=40;
+ 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;
current=current->infront;
goto LOOP2;
- }else{
- yoff=50;
- shade=40;
+ }else{ // Otherwise reset static values and return
+ yoff=DRAW_Y_OFFSET;
+ shade=0;
}
}
void World::detect(vec2 *v,vec2 *vel,const float width){
unsigned int i;
- // Vertical checks
- i=(v->x+width/2-x_start)/HLINE;
- if(v->y<=line[i].y){
+ i=(v->x+width/2-x_start)/HLINE; // Calculate what line the player is currently on
+ if(v->y<=line[i].y){ // Snap the player to the top of that line if the player is inside it
vel->y=0;
v->y=line[i].y+HLINE/2;
- }else{
+ }else{ // If the player is above the ground do some gravity stuff
vel->y-=.01;
}
- // Horizontal checks
- if(v->x<x_start){
+ if(v->x<x_start){ // Keep the player inside world bounds (ui.cpp handles world jumping)
vel->x=0;
v->x=x_start+HLINE/2;
}else if(v->x+width+HLINE>x_start+getWidth(this)){
@@ -113,6 +122,10 @@ void World::detect(vec2 *v,vec2 *vel,const float width){
}
}
+/*
+ * The rest of these functions are explained well enough in world.h ;)
+*/
+
void World::addLayer(unsigned int width){
if(behind){
behind->addLayer(width);