Advertisement

project help please!

Started by May 29, 2003 04:16 AM
1 comment, last by lisaG 21 years, 9 months ago
Hi everyone, I''m in need of some help for a Uni project. I have to create a version of Boulderdash using openGL. So far I have done the levels, which you can interactively select and load in, but I''m having problems with the movement of my character. I can get him to move around the screen, but I''m having problems with him digging the dirt, etc. i.e, I need to be able to stop him moving through boulders and walls, and for the dirt to disappear when he passes over it. I wondered if anyone could look at my source code and tell me why my move function isn''t doing this - logically I think it should..... I haven''t written out the whole function, but what is there should do what I want - but it doesn''t. Any advice much appreciated (sorry this is long winded!!!) :0) /*********************************************************************************************** LISA GONZALEZ BOULDERDASH COMPUTER PROGRAMMING 2 PROJECT a1490273 *********** MAY 2003 Some source code was obtained from http:\\programming.swordfighter.co.uk. Other websites looked at/used for research: www.nehe.gamedev.net, www.openGL.org A HUGE thanks to Eike Anderson for much needed help! ************************************************************************************************/ #include <GL/glut.h> #include <stdio.h> #include <stdlib.h> #include "image.h" #define windowWidth 600 /* Parameters for window size */ #define windowHeight 650 /* Alter these to suit need */ #define topx 225 #define topy 50 int pressedq = 0; /* global variables to store key pressed information */ int presseda = 0; int pressedz = 0; int pressedx = 0; /*********************************************************************************************** I have created a structure to easily keep track of the objects that are in the game. The variables used are ''movex'' and ''movey'', and they will store the current positions of the objects. This structure can be used for all game objects, such as the player (Rockford), the boulders, the diamonds, enemies and special items. I have created a new structure underneath called player, which will hold the player (Rockford) information. This way it is easy to keep track of object positions, and access the variables easily. ***********************************************************************************************/ struct object { int movex; int movey; }; struct object player; int move(int, int); /* ''move'' function prototype */ image boulder; /* Initialise boulder texture */ image diamond; /* Initialise diamond texture */ image dirt; /* Initialise dirt texture */ image exit_open; /* Initialise exit open texture */ image wall; /* Initialise wall texture */ image rockford; /* Initialise rockford texture */ GLuint boulder_texture, diamond_texture, dirt_texture, exit_open_texture, wall_texture, rockford_texture; /*********************************************************************************************** These are dynamic arrays that will read in the characters that make up the cave levels. These are stored as text files (currently in my ''boulderdash'' directory). Using a dynamic array is better performance wise than a static one, as it saves memory. The ''cave'' text files are opened using fopen, then the width and height of the cave level is read in using fscanf. The for loops then fill the array with the character string using dynamic memory allocation. Finally, the text file is closed. ***********************************************************************************************/ char **cave_array; /* Pointers for ''cave_array'' */ FILE *cave; int height = 0, width = 0; /* Variables to store height and width */ /* of ''cave_array'' */ void init(void) { int i, j; int level = 0; char filename[100]; glClearColor(0.3, 0.2, 0.1, 0.0); /* Clear window to black */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,20,0,22.5,-1,1); /* Ortho projection */ printf(" BOULDERDASH PLAYING INSTRUCTIONS \n"); printf("**********************************\n\n"); printf("OBJECT OF THE GAME:\n\n"); printf("To move your character (rockford) around the cave collecting all of the\n"); printf("diamonds and avoiding the falling boulders. Dig through the dirt to collect\n"); printf("the diamonds. Boulders can fall through dirt that has been digged - watch out!\n"); printf("The exit will open once all diamonds on the level have been collected.\n\n"); printf("CONTROLS:\n\n"); printf("z = move Rockford left\n"); printf("x = move Rockford right\n"); printf("q = move Rockford up\n"); printf("a = move Rockford down\n\n"); printf("Please select which level you wish to play (1 - 3): "); scanf("%d", &level); sprintf(filename, "C:\\Documents and Settings\\LisaG\\Desktop\\boulderdash\\cave%d.txt", level); cave = fopen(filename, "r"); if (cave != NULL) { fscanf(cave, "%d%d", &width, &height); /* Open ''cave?'' text file, */ /* and scan characters into */ cave_array = (char**) malloc (height*sizeof(char*)); /* dynamic array ''cave_array'' */ if (cave_array != NULL) { for (i=0;i = (char*) calloc (width, sizeof(char)); } } for (i=height-1;i>=0;i--) /* For loops to fill ''cave_array'' with */ for (j=0;j[j] = fgetc(cave); fclose(cave); /* Close ''cave1'' text file */ } /*********************************************************************************************** The following code will attempt to load in all necessary texture files from the specified directories. An error message will be displayed if loading the textures fails. ***********************************************************************************************/ if (!loadImage("C:\\Documents and Settings\\LisaG\\Desktop\\boulderdash\\boulder.bmp", &boulder)) { printf("Unable to load image!\n"); exit(EXIT_FAILURE); } if (!loadImage("C:\\Documents and Settings\\LisaG\\Desktop\\boulderdash\\diamond.bmp", &diamond)) { printf("Unable to load image!\n"); exit(EXIT_FAILURE); } if (!loadImage("C:\\Documents and Settings\\LisaG\\Desktop\\boulderdash\\dirt.bmp", &dirt)) { printf("Unable to load image!\n"); exit(EXIT_FAILURE); } if (!loadImage("C:\\Documents and Settings\\LisaG\\Desktop\\boulderdash\\exit_open.bmp", &exit_open)) { printf("Unable to load image!\n"); exit(EXIT_FAILURE); } if (!loadImage("C:\\Documents and Settings\\LisaG\\Desktop\\boulderdash\\wall.bmp", &wall)) { printf("Unable to load image!\n"); exit(EXIT_FAILURE); } if (!loadImage("C:\\Documents and Settings\\LisaG\\Desktop\\boulderdash\\rockford.bmp", &rockford)) { printf("Unable to load image!\n"); exit(EXIT_FAILURE); } makeTexture(&boulder_texture, &boulder); makeTexture(&diamond_texture, &diamond); makeTexture(&dirt_texture, &dirt); makeTexture(&exit_open_texture, &exit_open); makeTexture(&wall_texture, &wall); makeTexture(&rockford_texture, &rockford); glShadeModel(GL_FLAT); } /************************************************************************************************ The drawing is done here! The cave level is drawn using two for loops and a huge switch statement. The two for loops run through each element stored in ''cave_array''. The inner for loop increments the x coords for each element, and the outer for loop increments the y coords. The switch statement uses ''cave_array'' as its controlling expression, evaluating each case (+,$,O,X, and E) and drawing the appropriate level object. ************************************************************************************************/ void display_level(void) { float x1 = 1; float x2 = 0; /* Variables for co - ords used */ float y1 = 1; /* to draw objects in level */ float y2 = 0; float x3 = 1.25; float x4 = 0.25; float y3 = 1.25; float y4 = 0.25; int i, j; glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); /* Enable texturing */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, 0.0); /* Move back to origin */ glLineWidth(1.5); for (i=0; i<height; i++) /* For loops to run through ''cave_array'', */ { for (j=0; j<width; j++) { switch(cave_array[j]) /* Switch statement to determine what */ { /* objects need to be drawn for each */ /* character read in by ''cave_array''. */ case ''$'': glBindTexture(GL_TEXTURE_2D,dirt_texture); glColor3f(1.0, 0.5, 0.0); /* If case ''$'' a dirt object will */ glBegin(GL_POLYGON); /* be drawn */ glTexCoord2f(0.0, 0.0); glVertex3f(x1, y1, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(x2, y1, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(x2, y2, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(x1, y2, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(x1, y1, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x2, y2, 0.0); glVertex3f(x1, y2, 0.0); glEnd(); glColor3f(0.3, 0.2, 0.1); glBegin(GL_POLYGON); glVertex3f(x3, y3, 0.0); glVertex3f(x4, y3, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x3, y3, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x1, y2, 0.0); glVertex3f(x3, y4, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(x3, y3, 0.0); glVertex3f(x4, y3, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x3, y3, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x1, y2, 0.0); glVertex3f(x3, y4, 0.0); glEnd(); break; case ''+'': /* If case ''+'' then a wall object */ /* is drawn */ glBindTexture(GL_TEXTURE_2D,wall_texture); glColor3f(0.0, 1.0, 1.0); glBegin(GL_POLYGON); glTexCoord2f(0.0, 0.0); glVertex3f(x1, y1, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(x2, y1, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(x2, y2, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(x1, y2, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(x1, y1, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x2, y2, 0.0); glVertex3f(x1, y2, 0.0); glEnd(); glColor3f(0.0, 1.0, 0.5); glBegin(GL_POLYGON); glVertex3f(x3, y3, 0.0); glVertex3f(x4, y3, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x3, y3, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x1, y2, 0.0); glVertex3f(x3, y4, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(x3, y3, 0.0); glVertex3f(x4, y3, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x3, y3, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x1, y2, 0.0); glVertex3f(x3, y4, 0.0); glEnd(); break; case ''E'': /* If case ''E'', then the end square */ /* is drawn */ glBindTexture(GL_TEXTURE_2D,exit_open_texture); glColor3f(0.0, 1.0, 0.0); glBegin(GL_POLYGON); glTexCoord2f(0.0, 0.0); glVertex3f(x1, y1, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(x2, y1, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(x2, y2, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(x1, y2, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(x1, y1, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x2, y2, 0.0); glVertex3f(x1, y2, 0.0); glEnd(); glColor3f(0.0, 0.3, 0.0); glBegin(GL_POLYGON); glVertex3f(x3, y3, 0.0); glVertex3f(x4, y3, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x3, y3, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x1, y2, 0.0); glVertex3f(x3, y4, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(x3, y3, 0.0); glVertex3f(x4, y3, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x3, y3, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x1, y2, 0.0); glVertex3f(x3, y4, 0.0); glEnd(); break; case ''X'': /* If case ''X'', a diamond is drawn */ glBindTexture(GL_TEXTURE_2D,diamond_texture); glColor3f(0.7, 0.0, 0.3); glBegin(GL_POLYGON); glTexCoord2f(0.0, 0.0); glVertex3f(x1, y1, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(x2, y1, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(x2, y2, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(x1, y2, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(x1, y1, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x2, y2, 0.0); glVertex3f(x1, y2, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex3f(x3, y3, 0.0); glVertex3f(x4, y3, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x3, y3, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x1, y2, 0.0); glVertex3f(x3, y4, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(x3, y3, 0.0); glVertex3f(x4, y3, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x3, y3, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x1, y2, 0.0); glVertex3f(x3, y4, 0.0); glEnd(); break; case ''O'': /* If case ''O'', a boulder is drawn */ glBindTexture(GL_TEXTURE_2D,boulder_texture); glLoadIdentity(); glColor3f(1.0, 1.0, 1.0); glBegin(GL_POLYGON); glTexCoord2f(0.0, 0.0); glVertex3f(x1, y1, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(x2, y1, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(x2, y2, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(x1, y2, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(x1, y1, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x2, y2, 0.0); glVertex3f(x1, y2, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex3f(x3, y3, 0.0); glVertex3f(x4, y3, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x3, y3, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x1, y2, 0.0); glVertex3f(x3, y4, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(x3, y3, 0.0); glVertex3f(x4, y3, 0.0); glVertex3f(x2, y1, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x3, y3, 0.0); glVertex3f(x1, y1, 0.0); glVertex3f(x1, y2, 0.0); glVertex3f(x3, y4, 0.0); glEnd(); break; } x1++; /* Increments the x coords for each loop */ x2++; x3++; x4++; } y1++; y2++; /* Increments the y coords for each loop */ y3++; y4++; x1 = 1; x2 = 0; /* Resets the x coords to their original */ x3 = 1.25; /* value, ready for the next pass through */ x4 = 0.25; /* the for loops */ } glDisable(GL_TEXTURE_2D); /* Disable textures */ glColor3f(0.0, 0.0, 0.0); /* Draw title panel at top of screen */ glBegin(GL_POLYGON); /* Level info will go here (eventually!) */ glVertex3f(20.0, 22.5, 0.0); glVertex3f(0.0, 22.5, 0.0); glVertex3f(0.0, 20.0, 0.0); glVertex3f(20.0, 20.0, 0.0); glEnd(); glColor3f(0.7, 0.7, 0.7); glBegin(GL_POLYGON); glVertex3f(19.75, 22.25, 0.0); glVertex3f(0.25, 22.25, 0.0); glVertex3f(0.25, 20.25, 0.0); glVertex3f(19.75, 20.25, 0.0); glEnd(); glEnable(GL_TEXTURE_2D); /* Enable textures again */ glBindTexture(GL_TEXTURE_2D,rockford_texture); /* Draw Rockford character */ glTranslatef(player.movex + 1.0, player.movey + 18.0, 0.0); glColor3f(1.0, 1.0, 1.0); glBegin(GL_POLYGON); glTexCoord2f(1.0, 1.0); glVertex3f(1.0, 1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(0.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glEnd(); glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3f(1.0, 1.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glEnd(); glFlush(); glutSwapBuffers(); glutPostRedisplay(); } /************************************************************************************************ Get keyboard input. Use keys z,x,q and a to move rockford around the screen. glutKeyboardFunc and a switch statement handle the keys being pressed. ************************************************************************************************/ void keyboard(unsigned char key, int x, int y) { switch(key) { case ''z'': case ''Z'': pressedz++; player.movex–; break; case ''x'': case ''X'': pressedx++; move(1,0); break; case ''q'': case ''Q'': pressedq++; player.movey++; break; case ''a'': case ''A'': presseda++; player.movey–; break; } } int move(int xdir, int ydir) { if (cave_array[player.movey + ydir][player.movex + xdir] == ''O'') return 0; else player.movex += xdir; player.movey += ydir; return 1; } void idle() { if (pressedq != 0) { pressedq = 0; } if (presseda != 0) { presseda = 0; } if (pressedz != 0) { pressedz = 0; } if (pressedx != 0) { pressedx = 0; } } void main(int argc,char *argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutInitWindowSize(windowWidth,windowHeight); glutInitWindowPosition(topx,topy); glutCreateWindow("Lisa''s version of Boulderdash!"); init(); glutDisplayFunc(display_level); glutKeyboardFunc(keyboard); glutIdleFunc(idle); glutMainLoop(); } </i>
Hi Lisa,

It kind of hard to figure out what exactly the problem is just by looking at code that I can''t compile and step through, but after skimming it I have a couple thoughts that might be related to your problems.

First, you talk about needing dirt to disappear. It looks like your level is stored in cave_array, which is drawn in your draw_level function. But I don''t see anywhere else in the code where the cave_array is manipulated, ie. dirt removed, so that the dirt isn''t drawn the next time draw_level is called.

About moving through boulders and walls, it looks like you''re only calling the move() function if x is pressed, but not for q, a, or z. So only x is getting checked for collision with boulders, the others are just moving the player regardless.

I recommend running your app in a window (or running on a second machine, through remote debugging if possible) so your game and your debugger are not overlapping, and step through your code. It will really help you identify problem spots in the code.
Brianmiserere nostri Domine miserere nostri
Advertisement
i'm a bit perplexed with the way you allocate your cave_array

if (cave != NULL)
{
fscanf(cave, "%d%d", &width, &height); /* Open 'cave?' text file, */
/* and scan characters into */
cave_array = (char**) malloc (height*sizeof(char*)); /* dynamic array 'cave_array' */
if (cave_array != NULL)
{
for (i=0;i {
cave_array = (char*) calloc (width, sizeof(char));
}
}

shouldn't the last bit be

*cave_array = (char*) calloc (width, sizeof(char));<br><br>as all you are doing it replacing the first allocation with the second allocation ??<br><br>when you do you switch/case then you have remember that cave_array is a pointer to a pointer.. just using cave_array[ j ] won't work.<br><br>might be best if you just allocate a fixed sized array (for the maximum map size) and load it into that.<br><br>http://members.iinet.net.au/~cleathley/<br><br><SPAN CLASS=editedby>[edited by - jumpman &#111;n May 29, 2003 12:03:55 AM]</SPAN>

This topic is closed to new replies.

Advertisement