Beispiel #1
0
// 游戏控制的一个主要流程。
// 当计时器发生时进行的处理逻辑。
void OnTimer(HWND hwnd)
{
	// 计时器到时以后,蛇移动一步。
	// 根据以后以后的状态,进行后续处理。
	switch (SnakeMove())
	{
	// 如果蛇已经死了
	case SNAKE_DEAD:
		// 首先关闭计时器,避免在计时器的驱动下再次调用本函数
		KillTimer(hwnd, TIMER_ID);
		// 然后通知玩家,Game Over了,退出进程。
		MessageBox(0, "Game Over", "Game Over", 0);
		ExitProcess(0);
		break;
	// 如果蛇吃到了食物
	case SNAKE_EATEN_FOOD:
		// 计分;
		score++;
		// 创建新的食物。食物是一个全局唯一变量。
		CreateFood();
		// 蛇进行生长,然后判断蛇生长以后的状态,进行后续处理。
		switch (SnakeGorwup())
		{
			// 玩家赢了,停止计时器。
		case SNAKE_COMPLETE:		
			KillTimer(hwnd, TIMER_ID);
			// 通知玩家,退出进程,结束游戏。
			MessageBox(0, "You Win!", "You Win", 0);
			ExitProcess(0);
			break;
			// 发生错误,停止计时器,并退出。
		case SNAKE_ERROR:
			KillTimer(hwnd, TIMER_ID);
			MessageBox(hwnd, "Error!!", "Error!1", MB_OK);
			ExitProcess(0);
			break;
			// 没有结束,也没有错误,正常吃到食物。
		case SNAKE_GROWUP:
			// 判断计分,是否升级。
			if (IS_SPEEDUP(score))
			{
				level++;
				SpeedUp(hwnd);
			}
			break;
		} //switch (SnakeGorwup()) 结束
		break;
	case SNAKE_MOVED:
		break;
	}
	return;

}
Beispiel #2
0
//改变方向
void CSnakeGame::ChangeDirection(int iDirection)
{
	//如果是相同方向或者游戏不是运行中状态,则返回
	if (m_enGameState != GAMESTATE_RUNNING || m_iSnakeDirection == iDirection)
	{
		return;
	}

	//按钮音效
	PLAY_EFFECT(EFFECT_CHANGE2);

	//设置方向
	int nOldDirection = m_iSnakeDirection;
	m_iSnakeDirection = iDirection;

	//如果是反方向
	if (iDirection == OPPSITE_DIRECTION[nOldDirection])
	{
		//转换
		int iNodeCount = m_mapSnakeNodes.size();
		for (int i = 0; i < iNodeCount / 2; ++i)
		{
			POSITION stTempPos = m_mapSnakeNodes[i];
			m_mapSnakeNodes[i] = m_mapSnakeNodes[iNodeCount - 1 - i];
			m_mapSnakeNodes[iNodeCount - 1 - i] = stTempPos;
		}

		//获取下一个位置
		POSITION stHeaderPos = m_mapSnakeNodes[0];
		GetNextPos(stHeaderPos);

		//是否可以按照反方向移动,不能则恢复之前的方向
		if (CheckGameOver(stHeaderPos))
		{
			m_iSnakeDirection = nOldDirection;
		}
	}
	
	//移动
	SnakeMove();

	//重置时间
	m_fWaitRefreshTime = 0;
}
Beispiel #3
0
LRESULT CALLBACK  windProc(HWND	hwnd,UINT		Message,WPARAM		wParam,LPARAM		lParam)
{
	int i;
	static HDC	hdc;
	static HDC hdcDes;
	static HBITMAP hBitMap[BMPS];
	static BITMAP bitMap;
	static HINSTANCE hInstance;
	static HBRUSH hBrush;
	static RECT rectStartButton;//开始游戏按钮区
	static PAINTSTRUCT ps;
	static POINT mouseLocation;
	static int x,y;
	
	hBrush = CreateSolidBrush(RGB(255,255,255));
	switch (Message)
	{
	case WM_CREATE:		
		hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
		hBitMap[0] = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BRICK));//墙
		hBitMap[1] = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_NUMERS));//分数
		hBitMap[2] = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_SCORE));//得分字样
		hBitMap[3] = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_GAMELEVEL));//游戏等级字样
		hBitMap[4] = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_ANIMATE));//开机动画的贴图
		hBitMap[5] = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_GAMESTART));//游戏开始按钮
		hBitMap[6] = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_WORDSNAKE));//snake四个英文字母
		hBitMap[7] = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_SNAKE));//蛇的身体以及食物
		hBitMap[8] = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_STARTCHANGE));//鼠标放在开始按钮上时改变颜色
		hBitMap[9] = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_GAMEOVER));//GAMEOVER四个字母
		srand((unsigned)time(NULL));
		SetClientRect(hwnd,704,576);
		
		return 0;

	case WM_SIZE:
		GetClientRect(hwnd,&rectClient);
		rectSnake.left = rectClient.left+32;
		rectSnake.top = rectClient.top+32;
		rectSnake.bottom = rectClient.bottom-32;
		rectSnake.right = rectClient.left+17*32;

		rectStartButton.left = rectSnake.left+150;
		rectStartButton.right = rectStartButton.left+236;
		rectStartButton.top = rectSnake.bottom-100;
		rectStartButton.bottom = rectStartButton.top+79;
		return 0;
	case WM_KEYDOWN:
		switch (wParam)
		{
		case VK_SPACE:
			Pause = !Pause;
			if(Pause)
			{
				if(GameState != 1)
				{
					GameLevel = 1;
					GameState = 1;
					SnakeLength = 1;
					GameSpeed = 200;
					Snake[0].x = rectSnake.left+160;//初始化蛇头坐标信息
					Snake[0].y = rectSnake.left+160;
					x = Snake[0].x;
					y = Snake[0].y;
				}
				SetTimer(hwnd,GAMETIMER,GameSpeed,NULL);//设置时间计时器
			}
			else KillTimer(hwnd,GAMETIMER);
			break;
		case VK_ESCAPE:
			int result;
			result = MessageBox(NULL,TEXT("你确定要退出游戏吗?"),TEXT("Warning!"),MB_YESNO|MB_ICONWARNING);
			switch (result)
			{
			case IDYES:
				DestroyWindow(hwnd);
				break;
			case IDNO:
				break;
			default: break;
			}
			break;
		case VK_LEFT:
		    if(MoveDirection != 2)
			MoveDirection = 1;
			return 0;
		case VK_RIGHT:
		    if(MoveDirection != 1)
			MoveDirection = 2;
			return 0;
		case VK_UP:
		    if(MoveDirection != 4)
			MoveDirection = 3;
			return 0;
		case VK_DOWN:
		    if(MoveDirection != 3)
			MoveDirection = 4;
			return 0;
		}
		return 0;
	
	
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case ID_ABOUT:
			DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIABOUT),NULL,AboutProc);
			break;
		case ID_GAMESTART://点击菜单中的开始游戏按钮开始游戏
			GameLevel = 1;
			GameState = 1;
			SnakeLength = 1;
			GameSpeed = 200;
			SetTimer(hwnd,GAMETIMER,GameSpeed,NULL);//设置时间计时器
			Snake[0].x = rectSnake.left+160;//初始化蛇头坐标信息
			Snake[0].y = rectSnake.left+160;
			x = Snake[0].x;
			y = Snake[0].y;
			Pause = TRUE;
			break;
		case ID_GAMEQUIT:
			KillTimer(hwnd,GAMETIMER);
			ReleaseDC(hwnd,hdc);
			DestroyWindow(hwnd);
			exit(0);
			break ;
		}	
		return 0;
	
	case	 WM_PAINT:
		
		hdc = GetDC(hwnd);
		hdc = BeginPaint(hwnd, &ps);
		GetClientRect(hwnd,&rectClient);
		hdcDes = CreateCompatibleDC(hdc);
		Draw(hwnd,hdc,hBitMap,rectClient);	
		if(GameState == 0)
		{
			DrawAnimate(hwnd,hdc,hBitMap,rectSnake);//开机动画
		}
		else if(GameState == 1)
		{	
			FillRect(hdc,&rectSnake,hBrush);
			SelectObject(hdcDes,hBitMap[7]);
			GetObject(hBitMap[7],sizeof(BITMAP),&bitMap);
			if(!food.state)
				BitBlt(hdc, food.foodLocation.x, food.foodLocation.y, bitMap.bmWidth, bitMap.bmHeight/2,hdcDes,0,16,SRCCOPY);
			for(i =0;i<SnakeLength;i++)
			{
				BitBlt(hdc, Snake[i].x, Snake[i].y, bitMap.bmWidth, bitMap.bmHeight/2,hdcDes,0,0,SRCCOPY);
			}
		}
		else if(GameState == 2)
		{
			DrawGameOver(hwnd,hdc,hBitMap,9);
			KillTimer(hwnd,GAMETIMER);
		}
		DeleteDC(hdcDes);
		EndPaint(hwnd,&ps);
		Flag = FALSE;
		return 0;
	case WM_TIMER:
		if(GameState == 1)
		{
			if(MoveDirection == 4)
			{
				x= x;
				y = y +16;
			}
			else if(MoveDirection == 3)
			{
				x = x;
				y = y - 16;
			}
			else if(MoveDirection == 2)
			{
				x = x+16;
				y = y;
			}
			else if(MoveDirection == 1)
			{
				x = x -16;
				y = y;
			}
			SnakeMove(x,y);
			InvalidateRect(hwnd,&rectSnake,FALSE);
		}
		
		return 0;
	case WM_LBUTTONDOWN:
		mouseLocation.x = LOWORD(lParam);
		mouseLocation.y = HIWORD(lParam);
		if(GameState == 0)
		{
			if(PtInRect(&rectStartButton,mouseLocation))//点击开始游戏按钮开始游戏
			{
				GameLevel = 1;
				GameState = 1;
				SnakeLength = 1;
				GameSpeed = 200;
				SetTimer(hwnd,GAMETIMER,GameSpeed,NULL);//设置时间计时器
				Snake[0].x = rectSnake.left+160;//初始化蛇头坐标信息
				Snake[0].y = rectSnake.left+160;
				x = Snake[0].x;
				y = Snake[0].y;
				Pause = TRUE;
			}
		}
		return 0;

		//按钮效果实现
	case WM_MOUSEMOVE:
		TRACKMOUSEEVENT TrackME;
		mouseLocation.x = LOWORD(lParam);
		mouseLocation.y = HIWORD(lParam);
		TrackME.cbSize = sizeof(TrackME);  
		TrackME.dwFlags = TME_LEAVE | TME_HOVER;  
		TrackME.hwndTrack = hwnd;  
		TrackME.dwHoverTime = 1;//持续多长算HOVER  
		TrackMouseEvent(&TrackME);  
		if(GameState == 0)
		{
			if(PtInRect(&rectStartButton,mouseLocation))
			{
				FillRect(hdc,&rectStartButton,hBrush);
				SetCursor(LoadCursor(NULL,IDC_HAND));
				DrawButton(hwnd,hdc,hBitMap,rectStartButton,8);
			}
			else 
			{
				FillRect(hdc,&rectStartButton,hBrush);
				DrawButton(hwnd,hdc,hBitMap,rectStartButton,5);
			}
		}		
		return 0;
	
	case WM_DESTROY:	
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd,Message,wParam,lParam);
}
Beispiel #4
0
//更新
void CSnakeGame::Play(float dt)
{
	if (m_enGameState == GAMESTATE_RUNNING)
	{
		//刷新标记
		bool bNeedRefreshFlag = false;

		m_fWaitRefreshTime += dt;
		float fMaxTime = m_bImproveSpeed ? 50 : (SNAKE_MOVE_INTERVAL - 30 * m_iSpeed);
		if (m_fWaitRefreshTime >= fMaxTime)
		{
			m_fWaitRefreshTime = 0;
			SnakeMove();
			bNeedRefreshFlag = true;
		}

		m_fAppleShowTime += dt;
		if (m_fAppleShowTime >= APPLE_REFRESH_INTERVAL)
		{
			m_fAppleShowTime = 0;
			m_bAppleState = !m_bAppleState;
			bNeedRefreshFlag = true;
		}

		//是否需要刷新界面
		if (!bNeedRefreshFlag)
		{
			return;
		}
	}
	else if (m_enGameState == GAMESTATE_PASS)
	{
		//时间更新
		m_fWaitRefreshTime += dt;
		if (m_fWaitRefreshTime < GAMEPASS_REFRESH_INTERVAL)
		{
			return;
		}
		m_fWaitRefreshTime = 0;

		if (m_iAddScoreCount < GAMEPASS_ADDCOUNT)
		{
			++m_iAddScoreCount;
			m_iScore += GAMEPASS_ADDSCORE;
			m_pGameScene->UpdateScore(m_iScore);
			return;
		}
		else
		{
			//更新速度和等级
			if (++m_iSpeed > 10)
			{
				m_iSpeed = 0;
				if (++m_iLevel > 10)
				{
					m_iLevel = 0;
				}
			}

			//更新显示
			m_pGameScene->UpdateLevel(m_iLevel);
			m_pGameScene->UpdateSpeed(m_iSpeed);

			//重置数据
			InitData();
		}
	}
	else if (m_enGameState == GAMESTATE_OVER)
	{
		//时间更新
		m_fWaitRefreshTime += dt;
		if (m_fWaitRefreshTime < BOOM_REFRESH_INTERVAL)
		{
			return;
		}
		m_fWaitRefreshTime = 0;

		if (m_iShowBoomCount < BOOM_SHOWCOUNT)
		{
			m_bShowBoom = !m_bShowBoom;
			++m_iShowBoomCount;
		}
		else
		{
			//设置剩余生命
			--m_iLife;
			m_pGameScene->UpdateSmallBricks();

			//检查是否有剩余生命,没有则返回游戏结束界面
			if (m_iLife <= 0)
			{
				m_pGameScene->RunScene(SCENE_GAMEOVER);
				return;
			}

			//重置数据
			InitData();
		}
	}

	m_pGameScene->UpdateBricks();
}