/***************** (C) COPYRIGHT 2016 Panda_Xiao ************************
* File Name : play.cpp
* Author : Panda_Xiao
* Date First Issued : 2016/07/02
* Description : 游戏的进行的整体逻辑
*
*************************************************************************
* History:
************************************************************************/
/* Includes -----------------------------------------------------------*/
#include "head.h"
/* Variables ----------------------------------------------------------*/
extern char g_gameBoard[][X_ROCK_SQUARE_NUM] ;
extern int g_rockNum ;
extern RockLocation_t rockArray[1000] ;
extern int g_grade ;
extern int g_score ;
/* Function prototypes ------------------------------------------------*/
void InitProc(void);
void SetOccupy(void);
void MovetoUp(void);
void MovetoDown(void);
void MovetoLeft(void);
void MovetoRight(void);
void IsGameover(void);
/************************************************************************
* Function Name : PlayGame
* Create Date : 2016/07/02
* Author : Panda_Xiao
* Description : 游戏进行的主要流程
* Param : None
* Return Code : None
* Global Variable : rockArray[]
g_gameBoard[][]
g_rockNum
g_score
* File Static Variable : backGameBoard[][]
* Function Static Variable : None
************************************************************************/
void PlayGame(void)
{
int userHitChar ; //从键盘获取的字符
FoodLocation_t food ; //食物的信息
RockLocation_t backrockArray[1000] ; //蛇身移动之前的方块信息
DWORD oldtime = 0 ;
int i ;
int j ;
//初始化前3个方块的位置和方向
rockArray[0].left = X_GUI_PIX/2 ;
rockArray[0].top = Y_GUI_PIX/2 ;
rockArray[0].direction = DIRECT_RIGHT ;
rockArray[1].left = X_GUI_PIX/2-ROCK_SQUARE_WIDTH ;
rockArray[1].top = Y_GUI_PIX/2 ;
rockArray[1].direction = DIRECT_RIGHT ;
rockArray[2].left = X_GUI_PIX/2-2*ROCK_SQUARE_WIDTH ;
rockArray[2].top = Y_GUI_PIX/2 ;
rockArray[2].direction = DIRECT_RIGHT ;
g_rockNum = 3 ;
InitProc() ; //设置游戏墙的占位信息
SetOccupy() ; //设置蛇身的占位信息
//随机生成食物的位置
srand(time(NULL)) ;
food.left = (rand()%(X_ROCK_SQUARE_NUM-2)+1) ;
food.top = (rand()%(Y_ROCK_SQUARE_NUM-2)+1) ;
//当食物出现的位置在蛇身上,重新生成食物的位置
while(g_gameBoard[food.top][food.left] == 1)
{
food.left = (rand()%(X_ROCK_SQUARE_NUM-2)+1) ;
food.top = (rand()%(Y_ROCK_SQUARE_NUM-2)+1) ;
}
food.left *= ROCK_SQUARE_WIDTH ;
food.top *= ROCK_SQUARE_WIDTH ;
//游戏进行
while(1)
{
BeginBatchDraw() ;
//画出蛇头,蛇身、蛇尾和食物
DrawHeadRock(&rockArray[0] , TRUE ) ;
for(i=1;i<g_rockNum-1;i++)
{
DrawRock(&rockArray[i] , TRUE ) ;
}
DrawTailRock(&rockArray[g_rockNum-1] , TRUE ) ;
DrawFood(&food , TRUE) ;
//蛇头在接近食物之前头变大
switch(rockArray[0].direction)
{
case DIRECT_UP :
if((rockArray[0].left == food.left) && (rockArray[0].top-10 == food.top))
{
DrawHeadRock(&rockArray[0], FALSE) ;
DrawBigHeadRock(&rockArray[0], TRUE) ;
}
break;
case DIRECT_DOWN :
if((rockArray[0].left == food.left) && (rockArray[0].top+10 == food.top))
{
DrawHeadRock(&rockArray[0], FALSE) ;
DrawBigHeadRock(&rockArray[0], TRUE) ;
}
break;
case DIRECT_LEFT :
if((rockArray[0].left-10 == food.left) && (rockArray[0].top == food.top))
{
DrawHeadRock(&rockArray[0], FALSE) ;
DrawBigHeadRock(&rockArray[0], TRUE) ;
}
break;
case DIRECT_RIGHT :
if((rockArray[0].left+10 == food.left) && (rockArray[0].top == food.top))
{
DrawHeadRock(&rockArray[0], FALSE) ;
DrawBigHeadRock(&rockArray[0], TRUE) ;
}
break;
default : break ;
}
//当蛇头吃到食物的时候
if((rockArray[0].left == food.left) && (rockArray[0].top == food.top))
{
DrawFood(&food , FALSE) ; //食物消失
g_score += 10 ; //得分加10
DrawScore() ; //更新得分显示
rockArray[g_rockNum] = rockArray[g_rockNum-1] ;
DrawTailRock(&rockArray[g_rockNum-1] , FALSE ) ; //原蛇尾消失
//生成新蛇尾的位置和方向
switch(rockArray[g_rockNum-1].direction)
{
case DIRECT_UP : rockArray[g_rockNum].top += ROCK_SQUARE_WIDTH ; break ;
case DIRECT_DOWN : rockArray[g_rockNum].top -= ROCK_SQUARE_WIDTH ; break ;
case DIRECT_LEFT : rockArray[g_rockNum].left += ROCK_SQUARE_WIDTH ; break ;
case DIRECT_RIGHT : rockArray[g_rockNum].left -= ROCK_SQUARE_WIDTH ; break ;
default : break ;
}
DrawRock(&rockArray[g_rockNum-1] , TRUE ) ; //新增一蛇身
DrawTailRock(&rockArray[g_rockNum] , TRUE ) ; //显示新蛇尾
g_rockNum ++ ; //蛇身方块数量加一
//重新设置占位信息
for(i=0;i<X_ROCK_SQUARE_NUM;i++)
{
for(j=0;j<Y_ROCK_SQUARE_NUM;j++)
{
g_gameBoard[j][i] = 0 ;
}
}
InitProc() ;
SetOccupy() ;
//重新生成食物的位置
srand(time(NULL)) ;
food.left = (rand()%(X_ROCK_SQUARE_NUM-2)+1) ;
food.top = (rand()%(Y_ROCK_SQUARE_NUM-2)+1) ;
while(g_gameBoard[food.top][food.left] == 1)
{
food.left = (rand()%(X_ROCK_SQUARE_NUM-2)+1) ;
food.top = (rand()%(Y_ROCK_SQUARE_NUM-2)+1) ;
}
food.left *= ROCK_SQUARE_WIDTH ;
food.top *= ROCK_SQUARE_WIDTH ;
DrawFood(&food , TRUE ) ;
}
//在蛇身改变位置之前,储存其位置和方向信息
for(i=0;i<g_rockNum;i++)
{
backrockArray[i] = rockArray[i] ;
}
//时间到了,蛇身自动往蛇头移动方向前进一格
DWORD newtime = GetTickCount() ;
if(newtime - oldtime >= (unsigned int)(240-40*g_grade))
{
oldtime = newtime ;
//根据蛇头移动的方向向该方向移动一格
switch(rockArray[0].direction)
{
case DIRECT_UP : MovetoUp() ; break ;
case DIRECT_DOWN : MovetoDown() ; break ;
case DIRECT_LEFT : MovetoLeft() ; break ;
case DIRECT_RIGHT : MovetoRight() ; break ;
default : break ;
}
}
//检测有无键盘输入
if(kbhit())
{
//从键盘获取一个字符
userHitChar = getch() ;
//除了不能后退以外,根据键盘输入字符蛇身可向三个方向移动
switch(userHitChar)
{
case 'w' :
if(rockArray[0].direction != DIRECT_DOWN)
MovetoUp() ;
break ;
case 's' :
if(rockArray[0].direction != DIRECT_UP)
MovetoDown() ;
break ;
case 'a' :
if(rockArray[0].direction != DIRECT_RIGHT)
MovetoLeft() ;
break ;
case 'd' :
if(rockArray[0].direction != DIRECT_LEFT)
MovetoRight() ;
break ;
// 按q暂停和开始
case 'q' :
while(1)
{
if(getch()=='q')
break;
}
break ;
default : break ;
}
}
//更新占位信息
for(i=0;i<X_ROCK_SQUARE_NUM;i++)
{
for(j=0;j<Y_ROCK_SQUARE_NUM;j++)
{
g_gameBoard[j][i] = 0 ;
}
}
InitProc() ;
SetOccupy() ;
//批量画图,避免闪烁
FlushBatchDraw();
//原蛇身消失
DrawBigHeadRock(&backrockArray[0], FALSE) ;
DrawHeadRock(&backrockArray[0] , FALSE ) ;
for(i=1;i<g_rockNum-1;i++)
{
DrawRock(&backrockArray[i] , FALSE) ;
}
DrawTailRock(&backrockArray[g_rockNum-1] , FALSE) ;
}
}
/************************************************************************
* Function Name : InitProc
* Create Date : 2016/07/02
* Author : Panda_Xiao
* Description : 设置围墙的占位信息
* Param : None
* Return Code : None
* Global Variable : g_gameBoard[][]
* File Static Variable : None
* Function Static Variable : None
************************************************************************/
void InitProc(void)
{
int i ;
//设置上下墙的占位
for(i=0;i<X_ROCK_SQUARE_NUM;i++)
{
g_gameBoard[0][i] = 1