int main(void) { //Initialize SDL if(SDL_Init(SDL_INIT_VIDEO) < 0) { return 1; } //Create the window, OpenGL context SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_Window* window = SDL_CreateWindow("TestSDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_OPENGL); if(!window) { SDL_Quit(); return 1; } SDL_GL_CreateContext(window); //Make sure we have a recent version of OpenGL GLenum glewError = glewInit(); if(glewError != GLEW_OK) { SDL_Quit(); return 1; } if(!GLEW_VERSION_1_5) { SDL_Quit(); return 1; } int tileW = 64; int tileH = 64; GLuint empty = glTexImageTGAFile("t3.tga", &tileW, &tileH ); GLuint cube = glTexImageTGAFile("t2.tga", &tileW, &tileW); GLuint ch1 = glTexImageTGAFile("char1.tga", &tileW, &tileH ); GLuint ch2 = glTexImageTGAFile("char2.tga", &tileW, &tileH ); GLuint ch3 = glTexImageTGAFile("char3.tga", &tileW, &tileH ); GLuint ch4 = glTexImageTGAFile("char4.tga", &tileW, &tileH ); GLuint ch5 = glTexImageTGAFile("char5.tga", &tileW, &tileH ); GLuint ch6 = glTexImageTGAFile("char6.tga", &tileW, &tileH ); GLuint ch7 = glTexImageTGAFile("char7.tga", &tileW, &tileH ); GLuint ch8 = glTexImageTGAFile("char8.tga", &tileW, &tileH ); //initialize player struct entity player; player.xPos = 0; player.yPos = 0; //struct coords crd; struct polygon pg; //bounding box for player pg.p1.xComp = 33.0; pg.p1.yComp = 1.0; pg.p2.xComp = 28.0; pg.p2.yComp = 0.0; pg.p3.xComp = 37.0; pg.p3.yComp = 0.0; pg.p4.xComp = 30.0; pg.p4.yComp = -1.0; player.pol = assemblePolygon(pg); player.zpos = 0; player.zVel = 0; player.isJumping = 0; player.stack = 0; player.image = &ch1; /*int tileMap[12][12] = {{1,1,1,1,1,2,2,1,1,1,1,1}, {1,1,1,1,1,2,2,1,1,1,1,1}, {1,1,1,1,1,2,2,1,1,1,1,1}, {1,1,1,1,1,2,2,1,1,1,1,1}, {1,1,1,1,1,2,2,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,2,2,1,1,1,1,1}, {1,1,1,1,1,2,2,1,1,1,1,1}, {1,1,1,1,1,2,2,1,1,1,1,1}, {1,1,1,1,1,2,2,1,1,1,1,1}}; int tileMapHeight[12][12] = {{2,2,2,2,3,1,1,4,3,2,2,2}, {2,1,1,1,2,1,1,2,1,1,1,2}, {2,1,1,1,2,1,1,2,1,1,1,2}, {2,1,1,1,2,1,1,2,1,1,1,2}, {2,1,1,1,2,1,1,2,1,1,1,2}, {2,1,1,1,2,2,2,2,1,1,1,2}, {2,1,1,1,1,1,1,1,1,1,1,2}, {2,1,1,1,2,2,2,2,1,1,1,2}, {2,1,1,1,2,1,1,2,1,1,1,2}, {2,1,1,1,2,1,1,2,1,1,1,2}, {2,1,1,1,2,1,1,2,1,1,1,2}, {2,2,2,2,2,1,1,2,2,2,2,2}}; */ struct chunk map = generateChunk(); int **tileMap = map.chunkBase; int **tileMapHeight = map.chunkBlocks; int mapHeight = 100; //sizeof(tileMap)/sizeof(tileMap[0]); int mapWidth = 100; // sizeof(tileMap[0])/sizeof(tileMap[0][0]); struct Tile tiles[(mapWidth * mapHeight)]; // may need to be 2d array int tileType; int tileHeight; int count =0; for(int i = 0; i< mapHeight; i++) { for(int j = mapWidth-1; j>= 0; j--) { tileType = tileMap[i][j]; tileHeight = tileMapHeight[i][j]; struct Tile t; t.stack = tileHeight; t.num = tileType; float xp = (j * tileXScaleCalc / 2) + (i * tileXScaleCalc / 2); float yp = (i * tileYScaleCalc / 2) - (j * tileYScaleCalc / 2); t.xPos = xp; t.yPos = yp; struct polygon pg; pg.p1.xComp = xp + 32.0; pg.p1.yComp = yp - 16.0; pg.p2.xComp = xp; pg.p2.yComp = yp - 32.0; pg.p3.xComp = xp + 30.0; pg.p3.yComp = yp - 48.0; pg.p4.xComp = xp + 62.0; pg.p4.yComp = yp - 32.0; t.pol = assemblePolygon(pg); if(tileType == 0) { t.image = ∅ t.xScale = tileXScale; t.yScale = tileYScale; } else if(tileType == 1) { t.image = &cube; t.xScale = tileXScale; t.yScale = tileXScale; } tiles[count] = t; count++; } } unsigned char kbPrevState[SDL_NUM_SCANCODES] = {0}; //The current frame's keyboard state const unsigned char* kbState = NULL; //Keep a pointer to SDL's internal keyboard state kbState = SDL_GetKeyboardState(NULL); glViewport( 0, 0, 800, 600 ); glMatrixMode(GL_PROJECTION); glOrtho( 0, 800, 600, 0, 0, 1 ); glEnable( GL_TEXTURE_2D ); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //lighting //glEnable(GL_LIGHTING); int shouldExit = 0; //change to int float xoffset = 0; float yoffset = 0; //int x; //int y; //start position. if player is colliding with a tile, move him till he doest updateCoords(350, -10, &player); int colindex = 0; while(checkCollision(player.pol, tiles,(mapWidth * mapHeight) , &colindex)) { updateCoords(1.5, 0, &player); xoffset += 1.5; } int ticksPerFrame = 1000 / 60; int prevTick = SDL_GetTicks(); int ticksPerPhysics = 1000 / 100; int prevPhysicsTick = prevTick; int mx, my; //testing, move to outside of loop int castEnable = 0; int shaddow; while(!shouldExit) { //kbState is updated by the message pump. Copy over the old state before the pump! memcpy(kbPrevState, kbState, sizeof(kbPrevState)); //Handle OS message pump SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: return 0; } } int tick = SDL_GetTicks(); do { SDL_Delay((int) fmax( 0, ticksPerFrame - (tick - prevTick) )); tick = SDL_GetTicks(); } while( ticksPerFrame - (tick - prevTick) > 0 ); prevTick = tick; const unsigned char* keys = SDL_GetKeyboardState(NULL); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); while( tick > prevPhysicsTick + ticksPerPhysics ) { SDL_GetMouseState(&mx, &my); mx -= player.pol.p1.xComp - xoffset; my -= player.pol.p1.yComp - player.zpos + screenScale - yoffset + 50; double angle = -(atan2(my, mx) * 180 * 3.14159265)/10; if(angle < 0) { angle += 360; } if(angle < 25) { player.image = &ch2; } else if(angle < 55) { player.image = &ch8; } else if(angle < 120) { player.image = &ch1; } else if(angle < 170) { player.image = &ch7; } else if(angle < 195) { player.image = &ch3; } else if(angle < 230) { player.image = &ch6; } else if(angle < 300) { player.image = &ch4; } else { player.image = &ch5; } //printf("mouse x = %i mouse y = %i angle = %f \n", mx, my, angle); // Update physics if(!checkCollision(player.pol, tiles,(mapWidth * mapHeight), &colindex) ) { player.stack = 0; colindex = 0; } if(keys[SDL_SCANCODE_SPACE] ) { playerJump(&player); //printf("jump"); //player.image = &ch3; } if(keys[SDL_SCANCODE_O] ) { castEnable = 1; } if(keys[SDL_SCANCODE_P] ) { castEnable = 0; } if(keys[SDL_SCANCODE_K] ) { shaddow = 1; } if(keys[SDL_SCANCODE_L] ) { shaddow = 0; } if(keys[SDL_SCANCODE_A] ) { xoffset -= 1.5; updateCoords(-1.5, 0, &player); if(checkCollision(player.pol, tiles,(mapWidth * mapHeight), &colindex) ) { if(player.zpos > tiles[colindex].stack * 10) { player.stack = tiles[colindex].stack; } else if(player.stack < tiles[colindex].stack) { //player.stack = 0; updateCoords(1.5, 0, &player); xoffset += 1.5; } } } if(keys[SDL_SCANCODE_D] ) { xoffset += 1.5; updateCoords(1.5, 0, &player); if(checkCollision(player.pol, tiles, (mapWidth * mapHeight), &colindex) ) { if(player.zpos > tiles[colindex].stack * 10) { player.stack = tiles[colindex].stack; } else if(player.stack < tiles[colindex].stack) { //player.stack = 0; updateCoords(-1.5, 0, &player); xoffset -= 1.5; } } } if(keys[SDL_SCANCODE_W] ) { yoffset -= 1.5 ; updateCoords(0, -1.5, &player); if(checkCollision(player.pol, tiles, (mapWidth * mapHeight), &colindex) ) { if(player.zpos > tiles[colindex].stack * 10) { player.stack = tiles[colindex].stack; } else if(player.stack < tiles[colindex].stack) { //player.stack = 0; yoffset += 1.5 ; updateCoords(0, 1.5, &player); //player.isColliding = 0; } } } if(keys[SDL_SCANCODE_S] ) { yoffset += 1.5; updateCoords(0, 1.5, &player); if(checkCollision(player.pol, tiles, (mapWidth * mapHeight), &colindex) ) { if(player.zpos > tiles[colindex].stack * 10) { player.stack = tiles[colindex].stack; } else if(player.stack < tiles[colindex].stack) { //player.stack = 0; updateCoords(0, -1.5, &player); yoffset -= 1.5; } } } playerTick(&player); prevPhysicsTick += ticksPerPhysics; } //draw base layer for(int z = 0; z < (mapWidth * mapHeight); z++) { if( tiles[z].xPos > xoffset && tiles[z].xPos < xoffset +750 && tiles[z].yPos > yoffset -250 && tiles[z].yPos < yoffset +270) { glDrawSprite(*tiles[z].image, tiles[z].xPos - xoffset, tiles[z].yPos+screenScale - yoffset, tiles[z].xScale, tiles[z].yScale ); } } //cast rays; optimise when to recalculate //This is debug code glLineWidth(.1); glColor3f(1.0f, 0.0f, 0.0f); if(castEnable) { for(int z = 0; z < (mapWidth * mapHeight); z++) { if(tiles[z].stack > 1) { if( tiles[z].xPos > xoffset && tiles[z].xPos < xoffset +750 && tiles[z].yPos > yoffset -250 && tiles[z].yPos < yoffset +270) { glBegin(GL_LINES); glVertex2f(player.pol.p1.xComp - xoffset, player.pol.p1.yComp - yoffset + screenScale + 64 - player.zpos) ; glVertex2f(tiles[z].pol.p1.xComp - xoffset, tiles[z].pol.p1.yComp +screenScale - yoffset + 64); glVertex2f(player.pol.p1.xComp - xoffset, player.pol.p1.yComp - yoffset + screenScale + 64 - player.zpos) ; glVertex2f(tiles[z].pol.p2.xComp - xoffset, tiles[z].pol.p2.yComp +screenScale - yoffset + 64); glVertex2f(player.pol.p1.xComp - xoffset, player.pol.p1.yComp - yoffset + screenScale + 64 - player.zpos) ; glVertex2f(tiles[z].pol.p3.xComp - xoffset, tiles[z].pol.p3.yComp +screenScale - yoffset + 64); glVertex2f(player.pol.p1.xComp - xoffset, player.pol.p1.yComp - yoffset + screenScale + 64 - player.zpos) ; glVertex2f(tiles[z].pol.p4.xComp - xoffset, tiles[z].pol.p4.yComp +screenScale - yoffset + 64); glEnd(); } } } } //cast shaddows //This is debug code if(shaddow) { int z = 999; while(tiles[z].stack <= 2) { z--; } glShadeModel(GL_SMOOTH); glBegin(GL_TRIANGLES); glColor4f(0.1, 0.2, 0.3, .0); glVertex3f(tiles[z].pol.p1.xComp - xoffset, tiles[z].pol.p1.yComp +screenScale - yoffset + 64, 0); glColor4f(0.4, 0.5, 0.6, .0); glVertex3f(tiles[z].pol.p2.xComp - xoffset, tiles[z].pol.p2.yComp +screenScale - yoffset + 64, 0); glColor4f(0.7, 0.8, 0.9, 1); glVertex3f(player.pol.p1.xComp - xoffset, player.pol.p1.yComp - yoffset + screenScale + 64 - player.zpos, 0); glEnd(); for(z = 0; z < (mapWidth * mapHeight); z++) { if(tiles[z].stack > 1) { if( tiles[z].xPos > xoffset && tiles[z].xPos < xoffset +750 && tiles[z].yPos > yoffset -250 && tiles[z].yPos < yoffset +270) { glShadeModel(GL_SMOOTH); //glBegin(GL_TRIANGLES); glBegin( GL_TRIANGLE_STRIP ); glColor4f(0.4, 0.5, 0.6, .0); glVertex3f(tiles[z].pol.p1.xComp - xoffset, tiles[z].pol.p1.yComp +screenScale - yoffset + 64, 0); glColor4f(0.4, 0.5, 0.6, .0); glVertex3f(tiles[z].pol.p2.xComp - xoffset, tiles[z].pol.p2.yComp +screenScale - yoffset + 64, 0); glColor4f(0.7, 0.8, 0.9, .6); glVertex3f(player.pol.p1.xComp - xoffset, player.pol.p1.yComp - yoffset + screenScale + 64 - player.zpos, 0); glColor4f(0.4, 0.5, 0.6, .0); glVertex3f(tiles[z].pol.p2.xComp - xoffset, tiles[z].pol.p2.yComp +screenScale - yoffset + 64, 0); glColor4f(0.4, 0.5, 0.6, .0); glVertex3f(tiles[z].pol.p3.xComp - xoffset, tiles[z].pol.p3.yComp +screenScale - yoffset + 64, 0); glColor4f(0.7, 0.8, 0.9, .6); glVertex3f(player.pol.p1.xComp - xoffset, player.pol.p1.yComp - yoffset + screenScale + 64 - player.zpos, 0); glColor4f(0.4, 0.5, 0.6, .0); glVertex3f(tiles[z].pol.p3.xComp - xoffset, tiles[z].pol.p3.yComp +screenScale - yoffset + 64, 0); glColor4f(0.4, 0.5, 0.6, .0); glVertex3f(tiles[z].pol.p4.xComp - xoffset, tiles[z].pol.p4.yComp +screenScale - yoffset + 64, 0); glColor4f(0.7, 0.8, 0.9, .6); glVertex3f(player.pol.p1.xComp - xoffset, player.pol.p1.yComp - yoffset + screenScale + 64 - player.zpos, 0); glColor4f(0.4, 0.5, 0.6, .0); glVertex3f(tiles[z].pol.p1.xComp - xoffset, tiles[z].pol.p1.yComp +screenScale - yoffset + 64, 0); glColor4f(0.4, 0.5, 0.6, .0); glVertex3f(tiles[z].pol.p2.xComp - xoffset, tiles[z].pol.p2.yComp +screenScale - yoffset + 64, 0); glColor4f(0.7, 0.8, 0.9, .6); glVertex3f(player.pol.p1.xComp - xoffset, player.pol.p1.yComp - yoffset + screenScale + 64 - player.zpos, 0); glEnd(); } } } } //############################################################################## here be dragons. //draw things behind and under player. for(int z = 0; z < (mapWidth * mapHeight); z++) { if(tiles[z].stack > 1) { if(player.pol.p1.yComp <= tiles[z].yPos - 16 - 14) { //do nothing } else { for(int ix = 1; ix < tiles[z].stack; ix++) { if( tiles[z].xPos > xoffset && tiles[z].xPos < xoffset +750 && tiles[z].yPos > yoffset -250 && tiles[z].yPos < yoffset +270 ) { glDrawSprite(*tiles[z].image, tiles[z].xPos - xoffset , tiles[z].yPos+screenScale -(ix * 16) - yoffset, tiles[z].xScale, tiles[z].yScale ); } } } if(player.stack >= tiles[z].stack -2) { for(int ix = 1; ix < tiles[z].stack; ix++) { if( tiles[z].xPos > xoffset && tiles[z].xPos < xoffset +750 && tiles[z].yPos > yoffset -250 && tiles[z].yPos < yoffset +270 ) { glDrawSprite(*tiles[z].image, tiles[z].xPos - xoffset , tiles[z].yPos+screenScale -(ix * 16) - yoffset, tiles[z].xScale, tiles[z].yScale ); } } } } } //draw player glDrawSprite(*player.image, player.pol.p1.xComp -30 - xoffset, player.pol.p1.yComp - player.zpos + screenScale - yoffset, 64, 64 ); //draw things in front of player for(int z = 0; z < (mapWidth * mapHeight); z++) { if(tiles[z].stack > 1) { if(player.pol.p1.yComp <= tiles[z].yPos - 16 - 14 ) { for(int ix = 1; ix < tiles[z].stack; ix++) { if( tiles[z].xPos > xoffset && tiles[z].xPos < xoffset +750 && tiles[z].yPos > yoffset -250 && tiles[z].yPos < yoffset +270 ) { if(tiles[z].stack > player.stack && ix >= player.stack) { glDrawSprite(*tiles[z].image, tiles[z].xPos - xoffset , tiles[z].yPos+screenScale -(ix * 16) - yoffset, tiles[z].xScale, tiles[z].yScale ); } } } if(z == colindex && tiles[z].stack == player.stack) { glDrawSprite(*player.image, player.pol.p1.xComp -30 - xoffset, player.pol.p1.yComp - player.zpos + screenScale - yoffset, 64, 64 ); } } } } //############################################################################## /* glLineWidth(2.5); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_LINES); glVertex2f(10, 10); glVertex2f(20, 20); glEnd(); */ SDL_GL_SwapWindow(window); //glFlush(); } SDL_Quit(); return 0; }
int main(void) { // Initialize SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { return 1; } // Create the window, OpenGL context SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_Window* window = SDL_CreateWindow( "Press the Arrow Keys to make things happen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL); if (!window) { fprintf(stderr, "Could not create window. Error Code = %s\n", SDL_GetError()); SDL_Quit(); return 1; } SDL_GL_CreateContext(window); // Make sure we have a recent version of OpenGL GLenum glewError = glewInit(); if (glewError != GLEW_OK) { fprintf(stderr, "Could not initialize glew. Error Code = %s\n", glewGetErrorString(glewError)); SDL_Quit(); } if (!GLEW_VERSION_3_0) { fprintf(stderr, "OpenGL max supported version is too low now.\n"); SDL_Quit(); return 1; } // Setup OpenGL state glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); glMatrixMode(GL_PROJECTION); glOrtho(0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, 100); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Create the background texture array. Going to load // everything at the same time for now. Maybe there // is a more efficient way to load this later GLuint lambda = glTexImageTGAFile("lambda.tga", NULL, NULL); GLuint aperture = glTexImageTGAFile("aperture.tga", NULL, NULL); int ryuWidth, ryuHeight; GLuint ryu = glTexImageTGAFile("ryu.tga", &ryuWidth, &ryuHeight); // Logic to keep track of keyboard pushes unsigned char kbPrevState[SDL_NUM_SCANCODES] = {0}; const unsigned char* kbState = NULL; kbState = SDL_GetKeyboardState(NULL); // Need to keep track of when to redraw frames Uint32 lastFrameMs = 0; Uint32 currentFrameMs = SDL_GetTicks(); // Some initialization for the background int background[40][40]; for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { // Generate random tiles for now background[i][j] = (rand() % 2 == 0) ? 0 : 1; } } // Set options for camera coordinates to draw background int camX = 0; int camY = 0; // Set options for the player coordinates int playerX = 320; int playerY = 240; // The game loop char shouldExit = 0; while (!shouldExit) { // kbState is updated by the message pump. Copy over the old state before the pump! lastFrameMs = currentFrameMs; memcpy(kbPrevState, kbState, sizeof(kbPrevState)); // Handle OS message pump SDL_Event event; while (SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: shouldExit = 1; } } // Going to handle keyboard events here kbState = SDL_GetKeyboardState(NULL); if (kbState[SDL_SCANCODE_RIGHT]) { camX = (camX < 640) ? camX += 4 : camX; playerX = (playerX < 640) ? playerX += 1 : playerX; } if (kbState[SDL_SCANCODE_LEFT]) { camX = (camX > 0) ? camX -= 4 : camX; playerX = (playerX > 0) ? playerX -= 1 : playerX; } if (kbState[SDL_SCANCODE_UP]) { camY = (camY > 0) ? camY -= 4: camY; playerY = (playerY > 0) ? playerY -= 1: playerY; } if (kbState[SDL_SCANCODE_DOWN]) { camY = (camY < 640) ? camY += 4 : camY; playerY = (playerY < 640) ? playerY += 1 : playerY; } // Calculating frame updates currentFrameMs = SDL_GetTicks(); float deltaTime = (currentFrameMs - lastFrameMs) / 1000.0f; glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT); // This draws the background. for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { int tempCamX = camX / 40; int tempCamY = camY / 40; if (background[i][j] == 0) { glDrawSprite(aperture, (j * 40) - tempCamX, (i * 40) - tempCamY, 40, 40); } else { glDrawSprite(lambda, (j * 40) - tempCamX, (i * 40) - tempCamY, 40, 40); } } } glDrawSprite(ryu, playerX, playerY, 60, 60); SDL_GL_SwapWindow(window); } SDL_Quit(); return 0; }
int main(void) { // Initialize SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { return 1; } // Create the window, OpenGL context SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_Window* window = SDL_CreateWindow( "Press the Arrow Keys to make things happen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL); if (!window) { fprintf(stderr, "Could not create window. Error Code = %s\n", SDL_GetError()); SDL_Quit(); return 1; } SDL_GL_CreateContext(window); // Make sure we have a recent version of OpenGL GLenum glewError = glewInit(); if (glewError != GLEW_OK) { fprintf(stderr, "Could not initialize glew. Error Code = %s\n", glewGetErrorString(glewError)); SDL_Quit(); } if (!GLEW_VERSION_3_0) { fprintf(stderr, "OpenGL max supported version is too low now.\n"); SDL_Quit(); return 1; } // Setup OpenGL state glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); glMatrixMode(GL_PROJECTION); glOrtho(0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, 100); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Create the background texture array. Going to load // everything at the same time for now. Maybe there // is a more efficient way to load this later GLuint lambda = glTexImageTGAFile("lambda.tga", NULL, NULL); GLuint aperture = glTexImageTGAFile("aperture.tga", NULL, NULL); textures[0] = glTexImageTGAFile("ryu_walk_1.tga", NULL, NULL); textures[1] = glTexImageTGAFile("ryu_walk_2.tga", NULL, NULL); textures[2] = glTexImageTGAFile("ryu_walk_3.tga", NULL, NULL); textures[3] = glTexImageTGAFile("ryu_walk_4.tga", NULL, NULL); textures[4] = glTexImageTGAFile("mushroom_1.tga", NULL, NULL); textures[5] = glTexImageTGAFile("mushroom_2.tga", NULL, NULL); textures[6] = glTexImageTGAFile("mushroom_3.tga", NULL, NULL); textures[7] = glTexImageTGAFile("mushroom_4.tga", NULL, NULL); // Logic to keep track of keyboard pushes unsigned char kbPrevState[SDL_NUM_SCANCODES] = {0}; const unsigned char* kbState = NULL; kbState = SDL_GetKeyboardState(NULL); // Need to keep track of when to redraw frames Uint32 lastFrameMs = 0; Uint32 currentFrameMs = SDL_GetTicks(); // Some initialization for the background BackgroundTile background[40][40]; AABB backgroundBox; for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { BackgroundTile tile; tile.spriteId = ((i % 2 == 0) || (j % 2 == 0)) ? 0 : 1; tile.collision = (tile.spriteId == 1) ? true : false; tile.box.x = j * 40; tile.box.y = i * 40; tile.box.w = 40; tile.box.h = 40; background[i][j] = tile; } } // Set options for camera coordinates to draw background Camera camera; camera.posX = 0; camera.posY = 0; camera.box.x = 0; camera.box.y = 0; camera.box.w = 640; camera.box.h = 480; // Set options for the player coordinates Player player; player.posX = 321; player.posY = 241; player.box.x = 321; player.box.y = 241; player.box.w = 30; player.box.h = 30; player.nearMissTries = 5; int playerPrevX = 321; int playerPrevY = 241; AnimData playerAnimData; AnimDef playerAnimDef; playerAnimData.curFrame = 0; playerAnimData.timeToNextFrame = 0.1; playerAnimData.isPlaying = true; playerAnimDef.name = "ryu"; playerAnimDef.numFrames = 4; playerAnimDef.frames[0].frameNum = 0; playerAnimDef.frames[0].frameTime = 0.1; playerAnimDef.frames[1].frameNum = 1; playerAnimDef.frames[1].frameTime = 0.1; playerAnimDef.frames[2].frameNum = 2; playerAnimDef.frames[2].frameTime = 0.1; playerAnimDef.frames[3].frameNum = 3; playerAnimDef.frames[3].frameTime = 0.1; playerAnimData.def = &playerAnimDef; // Initializing other objects Mushroom m1; m1.captured = false; m1.posX = 160; m1.posY = 40; m1.box.x = 160; m1.box.y = 40; m1.box.w = 40; m1.box.h = 40; AnimData m1AnimData; AnimDef m1AnimDef; m1AnimData.curFrame = 0; m1AnimData.timeToNextFrame = 0.1; m1AnimData.isPlaying = true; m1AnimDef.name = "mushroom"; m1AnimDef.numFrames = 4; m1AnimDef.frames[0].frameNum = 4; m1AnimDef.frames[0].frameTime = 0.1; m1AnimDef.frames[1].frameNum = 5; m1AnimDef.frames[1].frameTime = 0.1; m1AnimDef.frames[2].frameNum = 6; m1AnimDef.frames[2].frameTime = 0.1; m1AnimDef.frames[3].frameNum = 7; m1AnimDef.frames[3].frameTime = 0.1; m1AnimData.def = &m1AnimDef; Mushroom m2; m2.captured = false; m2.posX = 80; m2.posY = 160; m2.box.x = 80; m2.box.y = 160; m2.box.w = 40; m2.box.h = 40; AnimData m2AnimData; AnimDef m2AnimDef; m2AnimData.curFrame = 0; m2AnimData.timeToNextFrame = 0.1; m2AnimData.isPlaying = true; m2AnimDef.name = "mushroom"; m2AnimDef.numFrames = 4; m2AnimDef.frames[0].frameNum = 4; m2AnimDef.frames[0].frameTime = 0.1; m2AnimDef.frames[1].frameNum = 5; m2AnimDef.frames[1].frameTime = 0.1; m2AnimDef.frames[2].frameNum = 6; m2AnimDef.frames[2].frameTime = 0.1; m2AnimDef.frames[3].frameNum = 7; m2AnimDef.frames[3].frameTime = 0.1; m2AnimData.def = &m2AnimDef; Mushroom m3; m3.captured = false; m3.posX = 240; m3.posY = 200; m3.box.x = 240; m3.box.y = 200; m3.box.w = 40; m3.box.h = 40; AnimData m3AnimData; AnimDef m3AnimDef; m3AnimData.curFrame = 0; m3AnimData.timeToNextFrame = 0.1; m3AnimData.isPlaying = true; m3AnimDef.name = "mushroom"; m3AnimDef.numFrames = 4; m3AnimDef.frames[0].frameNum = 4; m3AnimDef.frames[0].frameTime = 0.1; m3AnimDef.frames[1].frameNum = 5; m3AnimDef.frames[1].frameTime = 0.1; m3AnimDef.frames[2].frameNum = 6; m3AnimDef.frames[2].frameTime = 0.1; m3AnimDef.frames[3].frameNum = 7; m3AnimDef.frames[3].frameTime = 0.1; m3AnimData.def = &m2AnimDef; // The game loop char shouldExit = 0; while(!shouldExit) { // kbState is updated by the message pump. Copy over the old state before the pump! lastFrameMs = currentFrameMs; playerPrevX = player.posX; playerPrevY = player.posY; memcpy(kbPrevState, kbState, sizeof(kbPrevState)); // Handle OS message pump SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: shouldExit = 1; } } // Going to handle keyboard events to move the camera or player kbState = SDL_GetKeyboardState(NULL); if (kbState[SDL_SCANCODE_RIGHT]) { player.posX = (player.posX < 640) ? player.posX += 1 : player.posX; player.box.x = (player.box.x < 640) ? player.box.x += 1 : player.box.x; } if (kbState[SDL_SCANCODE_LEFT]) { player.posX = (player.posX > 0) ? player.posX -= 1 : player.posX; player.box.x = (player.box.x > 0) ? player.box.x -= 1 : player.box.x; } if (kbState[SDL_SCANCODE_UP]) { player.posY = (player.posY > 0) ? player.posY -= 1: player.posY; player.box.y = (player.box.y > 0) ? player.box.y -= 1 : player.box.y; } if (kbState[SDL_SCANCODE_DOWN]) { player.posY = (player.posY < 640) ? player.posY += 1 : player.posY; player.box.y = (player.box.y < 640) ? player.box.y += 1 : player.box.y; } if (kbState[SDL_SCANCODE_D]) { camera.posX = (camera.posX < 640) ? camera.posX += 4 : camera.posX; camera.box.x = (camera.box.x < 640) ? camera.box.x += 4 : camera.box.x; } if (kbState[SDL_SCANCODE_A]) { camera.posX = (camera.posX > 0) ? camera.posX -= 4 : camera.posX; camera.box.x = (camera.box.x > 0) ? camera.box.x -= 4 : camera.box.x; } if (kbState[SDL_SCANCODE_W]) { camera.posY = (camera.posY > 0) ? camera.posY -= 4: camera.posY; camera.box.y = (camera.box.y > 0) ? camera.box.y -= 4: camera.box.y; } if (kbState[SDL_SCANCODE_S]) { camera.posY = (camera.posY < 640) ? camera.posY += 4 : camera.posY; camera.box.y = (camera.box.y < 640) ? camera.box.y += 4 : camera.box.y; } // Calculating frame updates currentFrameMs = SDL_GetTicks(); float deltaTime = (currentFrameMs - lastFrameMs) / 1000.0f; glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT); // Update player if (playerAnimData.curFrame == 3) { animReset(&playerAnimData); } else { animTick(&playerAnimData, deltaTime); } // Update Objects if (m1AnimData.curFrame == 3) { animReset(&m1AnimData); } else { animTick(&m1AnimData, deltaTime); } if (m2AnimData.curFrame == 3) { animReset(&m2AnimData); } else { animTick(&m2AnimData, deltaTime); } if (m3AnimData.curFrame == 3) { animReset(&m3AnimData); } else { animTick(&m3AnimData, deltaTime); } // Check for mushroom collisions and update if (AABBIntersect(&player.box, &m1.box)) { m1.captured = true; } if (AABBIntersect(&player.box, &m2.box)) { m2.captured = true; } if (AABBIntersect(&player.box, &m3.box)) { m3.captured = true; } // Check for wall collisions and update for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { if (AABBIntersect(&camera.box, &background[i][j].box)) { // If a player collides with wall reset position if (AABBIntersect(&player.box, &background[i][j].box) && background[i][j].collision) { player.posX = playerPrevX; player.box.x = playerPrevX; player.posY = playerPrevY; player.box.y = playerPrevY; } } } } playerPrevX = player.posX; playerPrevY = player.posY; // This draws the background. for (int i = 0; i < 40; i++) { for (int j = 0; j < 40; j++) { if (AABBIntersect(&camera.box, &background[i][j].box)) { if (background[i][j].spriteId == 0) { glDrawSprite(aperture, (j * 40) - camera.posX, (i * 40) - camera.posY, 40, 40); } else { glDrawSprite(lambda, (j * 40) - camera.posX, (i * 40) - camera.posY, 40, 40); } } } } // This draws the other objects if (AABBIntersect(&camera.box, &m1.box) && !m1.captured) { animDraw(&m1AnimData, m1.posX - camera.posX, m1.posY - camera.posY, 40, 40); } if (AABBIntersect(&camera.box, &m2.box) && !m2.captured) { animDraw(&m2AnimData, m2.posX - camera.posX, m2.posY - camera.posY, 40, 40); } if (AABBIntersect(&camera.box, &m3.box) && !m3.captured) { animDraw(&m2AnimData, m3.posX - camera.posX, m3.posY - camera.posY, 40, 40); } // This draws the player animDraw(&playerAnimData, player.posX - camera.posX, player.posY - camera.posY, 40, 40); SDL_GL_SwapWindow(window); } SDL_Quit(); return 0; }
int main(void) { /*** Ia. Initialize SDL */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("Unable to initialize graphics library!\n"); return 1; } /*** Ib. Create the window, OpenGL context */ SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_Window* window = SDL_CreateWindow( WINDOW_TITLE, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL); if (!window) { fprintf(stderr, "Could not create window.ErrorCode = %s\n", SDL_GetError()); SDL_Quit(); return 1; } SDL_GL_CreateContext(window); /*** II. Make sure we have a recent version of OpenGL */ GLenum glewError = glewInit(); if (glewError != GLEW_OK) { fprintf(stderr, "Colud not initialize glew.ErrorCode = %s\n", glewGetErrorString(glewError)); SDL_Quit(); return 1; } if (!GL_VERSION_3_0) { fprintf(stderr, "OpenGL max supported version is too low.\n"); return 1; } /*** III. Setup OpenGL state */ glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); //What portion of the screen will be displayed glMatrixMode(GL_PROJECTION);// 2D rendering glOrtho(0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, 100); // right to bottom glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /*** IV. The game loop - the main loop */ kbState = SDL_GetKeyboardState(NULL); //Keep a pointer to SDL's internal keyboard state while (!shouldExit)// including HANDLING INPUT (or EVENTs), LOGIC, RENDERING { /* a. HANDLING INPUT */ /* kbState is updated by the message pump. Copy over the old state before the pump! */ memcpy(kbPrevState, kbState, sizeof(kbPrevState)); /* b. EVENTS */ /* Handle OS message pump! */ SDL_Event event; while (SDL_PollEvent(&event)) { /* IV.1. Save last frame's values (was just keyboard update)*/ /* IV.2. Handle OS message pump */ switch (event.type) { case SDL_QUIT: // when the window is closed shouldExit = 1; break; } //logic that should happen for a certain event }// end of inner while /* VI.3. Timing update */ /* IV.4. LOGIC: Game logic goes here - Update + draw game */ if (kbState[SDL_SCANCODE_LEFT]) /// if the left arrow is pressed { imgX -= 2; if (imgX <= 0)imgX = 0; } if (kbState[SDL_SCANCODE_UP]) /// if the left arrow is pressed { imgY -= 2; if (imgY <= 0)imgY = 0; } if (kbState[SDL_SCANCODE_DOWN]) /// if the left arrow is pressed { imgY += 2; if (imgY >= 480 - imgH)imgY = 480 - imgH; } if (kbState[SDL_SCANCODE_RIGHT]) /// if the left arrow is pressed { imgX += 2; if (imgX >= 640 - imgW)imgX = 640 - imgW; } /* c. RENDERING: */ /* IV.5.1. Rendering: */ glClearColor(0, 0, 0, 1); // specific the clear color glClear(GL_COLOR_BUFFER_BIT); //rendering the screen /* IV.5.2. load the textures - load all your images before the game loop */ sonicTex = glTexImageTGAFile("sonic.tga", NULL, NULL); glDrawSprite(sonicTex, imgX, imgY, imgW, imgH); /* IV.5.3. update a window with OpenGL rendering */ SDL_GL_SwapWindow(window); }// END of outer while SDL_Quit(); return 0; }