/ Published in: C
Expand |
Embed | Plain Text
#include "SDL/SDL.h" #include "SDL/SDL_opengl.h" #include <math.h> #include <string.h> #include <stdio.h> #define TICK_INTERVAL 30 #define TRUE 1 #define true TRUE #define FALSE 0 #define false FALSE int SCREEN_WIDTH = 300; int SCREEN_HEIGHT = 600; int SCREEN_BPP = 32; /*#undef main*/ /* allows write straight to console */ SDL_Surface *surface; int VIDEO_FLAGS; /* Flags to pass to SDL_SetVideoMode */ int DONE = 0; /* Main loop variable. (val 1 = QUIT*/ #define PIECE_SIZE 5 int PIECE[PIECE_SIZE][PIECE_SIZE] = {0}; #define MAP_HEIGHT 20 #define MAP_WIDTH 10 int MAP[MAP_HEIGHT][MAP_WIDTH] = {0}; int IS_ROTATEBLE = 0; /* can piece be rotated? */ int PIECE_X = 0, PIECE_Y = 0; /* position on MAP */ void quit (int return_code) { SDL_Quit(); /* clean up the window */ exit(return_code); /* and exit appropriately */ } void resize_window (int width, int height) { SCREEN_WIDTH = width; SCREEN_HEIGHT = height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, width, 0, height, - 1, 1); /* Make sure we're chaning the model view and not the projection */ glMatrixMode(GL_MODELVIEW); /* just to make sure */ glLoadIdentity(); /* glPointSize((width + height) / 50); */ } void clear_piece() { int i, j; for(i = 0; i < PIECE_SIZE; i++){ for(j = 0; j < PIECE_SIZE; j++){ PIECE[i][j] = 0; } } } void clear_map() { int i, j; for(i = 0; i < MAP_HEIGHT; i++){ for(j = 0; j < MAP_WIDTH; j++){ MAP[i][j] = 0; } } } void rotate_piece() { int i, j; int old_piece[PIECE_SIZE][PIECE_SIZE]; if(IS_ROTATEBLE){ /*copy piece*/ for(i = 0; i < PIECE_SIZE; i++){ for(j = 0; j < PIECE_SIZE; j++){ old_piece[i][j] = PIECE[i][j]; } } /*rotate*/ for(i = 0; i < PIECE_SIZE; i++){ for(j = 0; j < PIECE_SIZE; j++){ PIECE[4-i][j] = old_piece[j][i]; } } } } void store_piece() { int px, py; /*piece*/ int mX, mY; /*map*/ for(py = 0; py < PIECE_SIZE; py++){ for(px = 0; px < PIECE_SIZE; px++){ if(PIECE[py][px] != 0){ mX = PIECE_X + px; mY = PIECE_Y + py; if((mX >= 0) && (mX < MAP_WIDTH) && (mY >= 0) && (mY < MAP_HEIGHT)){ MAP[mY][mX] = PIECE[py][px]; } } } } } int is_possible_movement() { int px, py; /*piece*/ int mX, mY; /*map*/ for(mX = PIECE_X, px = 0; mX < (PIECE_X + PIECE_SIZE); mX++, px++){ for(mY = PIECE_Y, py = 0; mY < (PIECE_Y + PIECE_SIZE); mY++, py++){ if(PIECE[py][px] != 0){ /*The piece is outside the limits of the board*/ if((mX < 0) || (mX >= MAP_WIDTH) || (mY >= MAP_HEIGHT)){ return 0; } /*The piece have collisioned with a block already stored in the map*/ if((mY >= 0) && (MAP[mY][mX] != 0)){ return 0; } } } } return 1; } void delete_line(int mY) { int x, y; // Moves all the upper lines one row down for(y = mY; y > 0; y--){ for(x = 0; x < MAP_WIDTH; x++){ MAP[x][y] = MAP[x][y-1]; } } } void delete_possible_lines() { int x, y; for(y = 0; y < MAP_HEIGHT; y++){ x = 0; while(x < MAP_WIDTH){ if(MAP[x][y] == 0) break; x++; } if (x == MAP_WIDTH) delete_line(y); } } void load_O() { clear_piece(); PIECE[2][2] = 3; PIECE[3][2] = 2; PIECE[3][3] = 2; PIECE[2][3] = 2; IS_ROTATEBLE = 0; PIECE_X = 2; PIECE_Y = -2; } void load_L() { clear_piece(); PIECE[1][2] = 2; PIECE[2][2] = 3; PIECE[3][2] = 2; PIECE[3][3] = 2; IS_ROTATEBLE = 1; PIECE_X = 2; PIECE_Y = -2; } int is_game_over() { int i; for(i = 0; i < MAP_WIDTH; i++){ if(MAP[0][i] != 0){ return 1; } } return 0; } void draw_map() { int y, x; glBegin(GL_POINTS); for(y = 0; y < MAP_HEIGHT; y++){ for(x = 0; x < MAP_WIDTH; x++){ if(MAP[y][x] != 0){ glColor3f(1, 1, 1); }else{ glColor3f(0.1, 0.1, 0.1); } glVertex2d(SCREEN_WIDTH/MAP_WIDTH * x + 20, SCREEN_HEIGHT/MAP_HEIGHT * y + 20); } } glEnd(); } void draw_piece(int pX, int pY) { int I, J; float x, y; glColor3f(1, 0, 0); glBegin(GL_POINTS); for(I = 0; I < PIECE_SIZE; I++){ for(J = 0; J < PIECE_SIZE; J++){ if(PIECE[I][J] != 0){ x = SCREEN_WIDTH/MAP_WIDTH * (J + pX); y = SCREEN_HEIGHT/MAP_HEIGHT * (I + pY); glVertex2d(x + 20, y + 20); } } } glEnd(); } void draw() { glClear(GL_COLOR_BUFFER_BIT); draw_map(); draw_piece(PIECE_X, PIECE_Y); SDL_GL_SwapBuffers(); } void hanlde_events (SDL_Event event) { switch(event.type){ default: /* puts ("unknown event!"); */ break; case SDL_VIDEORESIZE: surface = SDL_SetVideoMode(event.resize.w, event.resize.h, 32, SDL_OPENGL); if(!surface){ fprintf(stderr, "no surface after resize: %s\n", SDL_GetError()); quit(1); } resize_window(event.resize.w, event.resize.h); break; case SDL_KEYDOWN: switch(event.key.keysym.sym){ default: break; case SDLK_q: case SDLK_ESCAPE: DONE = 1; quit(0); break; case SDLK_F1: SDL_WM_ToggleFullScreen(surface); break; case SDLK_s: case SDLK_DOWN: while(is_possible_movement()){ PIECE_Y++; } PIECE_Y--; store_piece(); delete_possible_lines(); load_L(); if(!is_possible_movement()){ DONE = 1; quit(0); } break; case SDLK_w: case SDLK_UP: rotate_piece(); if(!is_possible_movement()){ rotate_piece(); rotate_piece(); rotate_piece(); } break; case SDLK_a: case SDLK_LEFT: PIECE_X--; if(!is_possible_movement()){ PIECE_X++; } break; case SDLK_d: case SDLK_RIGHT: PIECE_X++; if(!is_possible_movement()){ PIECE_X--; } break; } break; case SDL_QUIT: DONE = 1; break; } } void init () { SDL_Init(SDL_INIT_EVERYTHING); SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_OPENGL); glClearColor(0, 0, 0, 1); glClearDepth(1); glPointSize(8); /*glLineWidth(4);*/ resize_window(SCREEN_WIDTH, SCREEN_HEIGHT); } int main(int argc, char **argv) { SDL_Event event; /* used to collect events */ Uint32 next_time; Uint32 vertical_move; init(); load_L(); next_time = SDL_GetTicks() + TICK_INTERVAL; vertical_move = SDL_GetTicks(); while(!DONE){ while(SDL_PollEvent(&event)) hanlde_events(event); draw(); if(vertical_move + 750 < SDL_GetTicks()){ PIECE_Y++; if(!is_possible_movement()){ PIECE_Y--; store_piece(); delete_possible_lines(); load_L(); if(!is_possible_movement()){ DONE = 1; quit(0); } } vertical_move = SDL_GetTicks(); } SDL_Delay(next_time - SDL_GetTicks()); next_time += TICK_INTERVAL; } quit(0); return 0; }
You need to login to post a comment.
