Beispiel #1
0
game_status state_in_game(SDL_Renderer* renderer, game* p_game)
{
  bool done=false;
  
  //the return code is always GAME_OVER, the player try to beat his hi-score
  //until his demise
  game_status ret_code = GAME_OVER;
  long timelastcall=SDL_GetTicks();

  //initialize the states of completed lines to 0
  memset(p_game->state,
	 0,
	 STATE_NUM * sizeof(int));
  p_game->score = 0;

  int level_cur = 0;
  int level_max = 10;

  level_init();
  
  //declare two shapes, one controled by the player, the other to indicates
  //the type of the next shape
  shape o_falling_shape, o_preview_shape;

  //set the falling shape type randomly
  shape_set(&o_falling_shape, rand() % SHAPE_NB);
  shape_default_coord(&o_falling_shape);

  shape_type next_shape_type = rand() % SHAPE_NB;
  shape_set(&o_preview_shape, next_shape_type);

  //put the preview shape on the side of the board
  o_preview_shape.x = LEVEL_WIDTH + 1;
  o_preview_shape.y = o_preview_shape.len - SHAPE_SIZE / 2 + 2;
  
  while (!done){
    //drawing
    SDL_SetRenderDrawColor(renderer, 0, 42, 0, 255);
    SDL_RenderClear(renderer);
    //draw the falling shape
    shape_draw(&o_falling_shape, p_game->p_fontmap, renderer);

    //draw the next shape as a preview
    shape_draw(&o_preview_shape, p_game->p_fontmap, renderer);

    //draw the level (empty blocks and alderly placed shapes)
    level_draw(renderer, &o_falling_shape, p_game->p_fontmap);
    
    int game_speed = level_max * 100 - level_cur * 100;
    
    int total=0;
    for(int i=0;i<3;i++)total += p_game->state[i];

    //draw a line between the board and the score / next shape area
    SDL_SetRenderDrawColor( renderer, 0x00, 0x00, 0xFF, 0xFF );
    SDL_RenderDrawLine(renderer,
		       TILE_SIZE * 12,
		       0,
		       TILE_SIZE * 12,
		       SCREEN_HEIGHT);
      
    //draw the score
    fontmap_printf(p_game->p_fontmap,
		   SCREEN_WIDTH - 7*5,
		   SCREEN_HEIGHT - 120,
		   renderer,
		   "%d",
		   p_game->score);

    SDL_Event event;
    while (SDL_PollEvent(&event)){

      if((event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_RETURN)||
	 (event.type == SDL_JOYBUTTONDOWN && event.jbutton.button == 5)){
	ret_code = state_paused(renderer);
	if(ret_code!=STAY){
	  done = 1;
	}
	      
      }

      if(event.type ==  SDL_QUIT){
	exit(EXIT_SUCCESS);
      }

      switch ( event.type )
	{
	case SDL_KEYDOWN:
	  switch (event.key.keysym.sym)
	    {
	    case SDLK_RIGHT:
	      if(shape_move(&o_falling_shape, 1, 0))o_falling_shape.x++;
	      break;
	    case SDLK_LEFT:
	      if(shape_move(&o_falling_shape, -1, 0))o_falling_shape.x--;
	      break;
	    case SDLK_DOWN:
	      if(shape_move(&o_falling_shape, 0, 1)) timelastcall=SDL_GetTicks()+game_speed;
	      break;
	    case SDLK_SPACE:
	      while(shape_move(&o_falling_shape, 0, 1)) o_falling_shape.y++;
	      timelastcall=SDL_GetTicks()+game_speed;
	      break;
	    case SDLK_f:
	      shape_rotate(&o_falling_shape, 0);
	      break;
	    case SDLK_d:
	      shape_rotate(&o_falling_shape, 1);
	      break;
	    case SDLK_q:
	      exit(EXIT_SUCCESS);
	      break;	      
	    default:
	      break;
	    }
	  break;
	case SDL_JOYBUTTONDOWN:
	  switch(event.jbutton.button)
	    {
	    case 0:
	      while(shape_move(&o_falling_shape, 0, 1)) o_falling_shape.y++;
	      timelastcall=SDL_GetTicks()+game_speed;
	      break;
	    case 2:
	      shape_rotate(&o_falling_shape, 1);
	      break;
	    case 3:
	      shape_rotate(&o_falling_shape, 0);
	      break;
	    case 6:
	      done=true;
	      ret_code = QUIT;
	      break;
	    case 19:
	      done=true;
	      ret_code = QUIT;
	      break;
	    default:
	      break;
	    }
	  break;
	}
    }
    
    if(SDL_GetTicks() - timelastcall > game_speed) {
      //check if the falling shape can move
      if(shape_move(&o_falling_shape, 0, 1)){
	//update coord
	o_falling_shape.y++;
      }else{
	//the shape can not move
	int i;
	level_add_shape(&o_falling_shape);

	int lines_in_a_row=0;
	//tab of line index to remove
	int rem_tab[SHAPE_SIZE];
	int line_nb = level_check_line(rem_tab);

	for(i=1;i<line_nb;i++){
	  if(rem_tab[i] == rem_tab[i-1]+1)lines_in_a_row++;
	  else lines_in_a_row = 0;
	}

	if(line_nb){
	  //blink completed line(s)
	  blink(renderer, rem_tab, line_nb, p_game->p_fontmap);

	  for(i=0;i<line_nb;i++)level_remove_line(rem_tab[i]);    //remove completed line(s)
	  p_game->score +=  line_nb * (lines_in_a_row + 1);       //update score
	  p_game->state[lines_in_a_row]++;                        //update game states
	  if(line_nb == 2 && lines_in_a_row == 0)p_game->state[0]++;

	  level_cur = p_game->score / 1000;                      //eventually update level number
	  if(level_cur >= level_max)level_cur = level_max;
	}

	if(level_check_game_over()){
	  done = 1;
	  ret_code = GAME_OVER;
	}
	else{
	  //"create" a new falling block by chaning the falling shape type
	  //to the next shape and reseting the coords
	  shape_set(&o_falling_shape, next_shape_type);
	  shape_default_coord(&o_falling_shape);

	  //pick a next shape type randomly for the preview and the next falling
	  //block
	  next_shape_type = rand() % SHAPE_NB;
	  shape_set(&o_preview_shape, next_shape_type);
	}
      }

      //update timer
      timelastcall=SDL_GetTicks();
    }
    
    SDL_RenderPresent(renderer);
  }
 
    return ret_code;
}
Beispiel #2
0
static int tetris(int argc, char ** argv)
{
	struct console * con = get_console_stdout();
	u32_t x, y, shape;
	u32_t newx, newy, newshape;
	bool_t fell = FALSE;
	bool_t try_again = FALSE;
	u32_t code;

	if(!con)
		return -1;

	console_setcursor(con, FALSE);
	console_cls(con);

	srand(jiffies + rand());

	do {
		screen_init();

		y = 3;
		x = GAME_AREA_WIDTH / 2;
		shape = rand() % ARRAY_SIZE(shapes);
        shape_draw(x, y, shape);
        refresh();

        while(1)
        {
            newx = x;
            newy = y;
            newshape = shape;

            if(console_stdin_getcode_with_timeout(&code, 250))
            {
    			switch(code)
    			{
    			case 0x10:	/* up */
    				newshape = shapes[shape].plus90;
    				fell = FALSE;
    				break;

    			case 0xe:	/* down */
                    if(y < GAME_AREA_HEIGHT - 1)
                        newy = y + 1;
                    fell = TRUE;
    				break;

    			case 0x2:	/* left */
    				if(x > 0)
    					newx = x - 1;
    				fell = FALSE;
    				break;

    			case 0x6:	/* right */
    				if(x < GAME_AREA_WIDTH - 1)
    					newx = x + 1;
    				fell = FALSE;
    				break;

    			default:
    				newy++;
    				fell = TRUE;
    				break;
    			}

            }
            else
            {
				newy++;
				fell = TRUE;
            }

	        if((newx == x) && (newy == y) && (newshape == shape))
	            continue;

	        shape_erase(x, y, shape);
	        if(shape_hit(newx, newy, newshape) == FALSE)
	        {
				x = newx;
	            y = newy;
	            shape = newshape;
	        }
	        else if(fell == TRUE)
	        {
	            shape_draw(x, y, shape);

	    		y = 3;
	    		x = GAME_AREA_WIDTH / 2;
	    		shape = rand() % ARRAY_SIZE(shapes);
	    		collapse();

	            if(shape_hit(x, y, shape))
	            {
	            	try_again = FALSE;
	            	break;
	            }
	        }

	        shape_draw(x, y, shape);
	        refresh();
        }
	}while(try_again);

	console_setcursor(con, TRUE);
	console_setcolor(con, TCOLOR_WHITE, TCOLOR_BLACK);
	console_cls(con);

	return 0;
}