Пример #1
0
// 蛇生长
int SnakeGorwup()
{
	// 给新的节点分配内存
	PGAME_COORD pNewTail;
	PGAME_COORD pTail;		// 倒数第一节点
	PGAME_COORD pLastButOne;	// 倒数第二节点
	int size = GetSnakeSize();

	if (size >= boundary.x*boundary.y-1) //长到最长了,游戏结束!~
		return SNAKE_COMPLETE;

	if (size == 0) // 没有头,不知从何生长,返回错误。
		return SNAKE_ERROR;

	pNewTail = (PGAME_COORD)malloc(sizeof(GAME_COORD));
	if (size == 1) // 只有一个节点,按照当前的移动方向生长。
	{
		
		pTail = (PGAME_COORD)GetSnakeTail();
		switch (snake_dir)
		{
		case SNAKE_LEFT:
			pNewTail->x = pTail->x + 1;
			pNewTail->y = pTail->y;
			break;
		case SNAKE_RIGHT:
			pNewTail->x = pTail->x - 1;
			pNewTail->y = pTail->y;
			break;
		case SNAKE_UP:
			pNewTail->x = pTail->x ;
			pNewTail->y = pTail->y + 1;
			break;
		case SNAKE_DOWN:
			pNewTail->x = pTail->x;
			pNewTail->y = pTail->y - 1;
			break;
		}

	}
	else // 有两个以上节点,取倒数第一和倒数第二计算生长方向。
	{
		pTail = (PGAME_COORD)GetSnakeTail();
		pLastButOne = (PGAME_COORD)GetSnakeAt(size - 2);
		// 沿着倒数第二->倒数第一的方向,添加一个新的节点。
		pNewTail->x = pTail->x + (pTail->x - pLastButOne->x);
		pNewTail->y = pTail->y + (pTail->y - pLastButOne->y);

	}

	// 新节点放入到蛇尾的位置
	ListPushBack(snake_list, pNewTail);
	return SNAKE_GROWUP;

}
Пример #2
0
void GamePaint(HWND hwnd)
{
	/*******************************************************************************
	* ##########   关于 GDI    ##########
	*
	* GDI的全称是Graphics Device Interface,图形设备接口。
	* GDI是Windows系统中最基础的图形图像接口,我们在这里演示的是GDI中最基础的部分,
	* 但是对于编写贪吃蛇这样的小游戏已经足够用了。
	*
	* 来看GDI最基础的三个概念:
	* 1、DC:DC的全称是Device Context,绘制操作在此进行。可以类比理解为一块画布,对应屏幕的一个区域。
	*      GDI的绘制操作必须在一个DC上进行,因此第一步就是得到DC的句柄,BeginPaint或者GetDC函数。
	* 2、GDI对象:包括PEN、BRUSH、FONT等,每一种绘制操作都会使用到一个或者多个GDI对象,
	*      所以,在绘制操作之前必须的一个操作是将绘制所用的GDI对象放入DC中,使用SelectObject函数完成。
	* 3、绘制操作:即在DC上使用被选择如DC中的GDI对象绘制图形、线条、文字等。
	*      如LineTo画出线条、Ellipse画出(椭)圆、Rectangle画出矩形、TextOut输出文字
	*
	* 使用GDI输出各类图像有其特定的流程,如下:
	*******************************************************************************/

	HPEN hpen;
	//HBRUSH hbrush;
	HDC hdc, hdcmem;
	HBITMAP hbmMem;

	HPEN hPenBoundary;
	HPEN hOldPen;

	HBRUSH hbrushFood;
	HBRUSH hBrushSnake;
	HBRUSH hOldBrush;

	HFONT hFont, hOldFont;

	RECT rect;

	PGAME_COORD pSnakeBody;
	PGAME_COORD lpFood;
	int i, snake_size;

	GetClientRect(hwnd, &rect);

	hdc = GetDC(hwnd);

	// 注意 CreateCompatibleDC 中的这一段话:
	// Before an application can use a memory DC for drawing operations, 
	// it must select a bitmap of the correct width and height into the DC. 
	// To select a bitmap into a DC, use the CreateCompatibleBitmap function
	// 注意:
	// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183488(v=vs.85).aspx
	hdcmem = CreateCompatibleDC(hdc);
	hbmMem = CreateCompatibleBitmap(hdc,
		rect.right - rect.left, rect.bottom - rect.top);

	SelectObject(hdcmem, hbmMem);

	// 创建需要用到的PEN和BRUSH
	hbrushFood = CreateSolidBrush(COLOR_FOOD); // RGB颜色,实心BRUSH
	hpen = CreatePen(PS_NULL, 0, RGB(0, 0, 0));  // PEN, PS_NULL表示不可见
	hBrushSnake = CreateSolidBrush(COLOR_SNAKE);
	hPenBoundary = CreatePen(0, 3, COLOR_BOUNDARY);


	/*******************************************************************************
	* #############  画背景  ################
	*
	*******************************************************************************/
	FillRect(hdcmem, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));

	/*******************************************************************************
	* #############  画食物  ################
	*
	*******************************************************************************/

	// 将画图需要用的PEN和BRUSH选择到DC中
	hOldBrush = (HBRUSH)SelectObject(hdcmem, hbrushFood);
	hOldPen = (HPEN)SelectObject(hdcmem, hpen);

	lpFood = GetFood();

	// (椭)圆形,使用上面选择的PEN勾勒边框,BRUSH填充
	Rectangle(hdcmem,
		lpFood->x * CELL_PIXEL + rectBoundary.left,
		lpFood->y * CELL_PIXEL + rectBoundary.top,
		(lpFood->x + 1)*CELL_PIXEL + rectBoundary.left,
		(lpFood->y + 1)*CELL_PIXEL + rectBoundary.top);

	/*******************************************************************************
	* #############  画蛇  ################
	*
	*******************************************************************************/

	SelectObject(hdcmem, hBrushSnake);

	snake_size = GetSnakeSize();

	for (i = 0; i < snake_size; i++)
	{
		pSnakeBody = (PGAME_COORD)GetSnakeAt(i);
		Rectangle(hdcmem,
			pSnakeBody->x * CELL_PIXEL + rectBoundary.left,
			pSnakeBody->y * CELL_PIXEL + rectBoundary.top,
			(pSnakeBody->x + 1)*CELL_PIXEL + rectBoundary.left,
			(pSnakeBody->y + 1)*CELL_PIXEL + rectBoundary.top);
	}

	/*******************************************************************************
	* #############  画墙  ################
	*
	*******************************************************************************/

	SelectObject(hdcmem, hPenBoundary);

	// 将PEN移动到需要绘制的方框的左上角
	MoveToEx(hdcmem, rectBoundary.left, rectBoundary.top, NULL);
	// 画了一个方框。演示LineTo函数
	LineTo(hdcmem, rectBoundary.left, rectBoundary.bottom);
	LineTo(hdcmem, rectBoundary.right, rectBoundary.bottom);
	LineTo(hdcmem, rectBoundary.right, rectBoundary.top);
	LineTo(hdcmem, rectBoundary.left, rectBoundary.top);

	/*******************************************************************************
	* #############  写一行字  ################
	*
	*******************************************************************************/

	// 创建了一个字体对象
	hFont = CreateFont(48, 0, 0, 0, FW_DONTCARE, 0, 1, 0, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
		CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Consolas"));

	// 将这个FONT对象放入DC中
	if (hOldFont = (HFONT)SelectObject(hdcmem, hFont))
	{
		CHAR szSourceInfo[1024];
		wsprintf(szSourceInfo, "score %d level %d", GetScore(), GetLevel());
		// 设置输出颜色
		SetTextColor(hdcmem, COLOR_TEXT);
		// 输出字符串。
		TextOut(hdcmem, rectBoundary.left + 3, rectBoundary.bottom + 3,
			szSourceInfo, lstrlen(szSourceInfo));
		// 输出完成,将原来的字体对象放回DC中
		SelectObject(hdcmem, hOldFont);
	}

	// 在内存DC中画完,一次输出的窗口DC上。
	BitBlt(hdc,
		0, 0, rect.right - rect.left, rect.bottom - rect.top,
		hdcmem, 0, 0, SRCCOPY);

	/*******************************************************************************
	* #############  回收和释放资源  ################
	*
	*******************************************************************************/
	// 回收资源
	// DeleteObject 释放GDI对象
	DeleteObject(hbmMem);
	DeleteObject(hdcmem);
	DeleteObject(hbrushFood);
	DeleteObject(hBrushSnake);
	DeleteObject(hpen);
	DeleteObject(hPenBoundary);
	DeleteObject(hFont);
	/*******************************************************************************
	* #############  ReleaseDC 函数  ################
	* 释放占用的DC等系统资源。
	*******************************************************************************/
	ReleaseDC(hwnd, hdc);
}