自写小游戏 ——Retro Snaker 开启我的博客之旅

博主受到华哥和高鑫的鼓励,决定通过写博客记录学习过程,分享自己编写小游戏Retro Snaker的经验。他认识到实践编程的重要性,希望通过这个过程发现并解决课本上找不到的问题,同时期待与读者交流和学习。代码附在博客中,期待大家的指导。
摘要由CSDN通过智能技术生成

华哥和高鑫告诉我。要多写一下博客。记录下自己的学习问题及感想。这样就能更好的向大家学习交流。自己也能从中找到更大的学习乐趣和广泛的知识。

昨天。醒哥说我学了那么久自己也可以试一下先写些简单的小程序练习一下。这样就能从实践中学习和发现一些从课本上找不到的问题。以便向大家请教。是的,自己在一个自闭的角落是学习。真的进步很慢。所以。我会以后自己多写博客。多问问题。希望大家能多多的指教。谢谢大家。

昨天就先试写了一个贪吃蛇。因为自己早在两个星期前就看过高鑫的源码。所以对于它的思路也非常清楚了。

但还是从写的过程中发现了很多细节的问题。先附上代码

//贪吃蛇
#include <windows.h>
#include <stdlib.h>
#include <time.h>


int NUM=5;
#define ID_TIMER  1  
int i ,BTN =  4 ;


LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
struct Snake  
{
	int left;
	int top;
	int right;
	int button;
}s[500];
struct food 
{
	int x;
	int y;
}f;


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
	PSTR szCmdLine, int iCmdShow) 
{
	static TCHAR szAppName[] = TEXT ("Retro Snaker " ) ;
	HWND         hwnd ;  
	MSG          msg ;  
	WNDCLASS     wndclass ; 


	wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc   = WndProc ;
	wndclass.cbClsExtra    = 0 ;
	wndclass.cbWndExtra    = 0 ;
	wndclass.hInstance     = hInstance ;
	wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName  = NULL ;
	wndclass.lpszClassName = szAppName ;


	if (!RegisterClass (&wndclass))  
	{
		MessageBox (NULL, TEXT ( "This program requires Windows NT!" ),
			szAppName, MB_ICONERROR) ; 
		return 0 ;
	}


	hwnd = CreateWindow (szAppName,                  // window class name
		TEXT ( "Retro Snaker  __Crazw"), // window caption
		WS_OVERLAPPEDWINDOW,        // window style
		CW_USEDEFAULT,              // initial x position
		CW_USEDEFAULT,              // initial y position
		CW_USEDEFAULT,              // initial x size
		CW_USEDEFAULT,              // initial y size
		NULL,                       // parent window handle
		NULL,                       // window menu handle
		hInstance,                  // program instance handle
		NULL) ;                     // creation parameters


	ShowWindow (hwnd, iCmdShow) ;
	UpdateWindow (hwnd) ; 


	while (GetMessage (&msg, NULL, 0, 0)) 
	{
		TranslateMessage (&msg) ; 
		DispatchMessage (&msg) ;  
	} 
	return msg.wParam ;
}


LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HDC hdcScreen;
	HDC         hdc ;
	PAINTSTRUCT ps ;
	RECT        rect ;
	static int cxClient,cyClient;
	// int i ,BTN =  3 ;                       //   wsm不能在这定义?????????????????????????


	switch (message)
	{
	case WM_CREATE:
		SetTimer (hwnd, ID_TIMER, 200, NULL) ;
		return 0 ;
	case WM_SIZE:
		cxClient = LOWORD(lParam);
		cyClient = HIWORD(lParam);   //cxclient 和 cyclient   GetClientRect  区别有吗?????????

		s[0].left = 100;
		s[0].top = 100;
		s[0].right = 120;
		s[0].button = 120;
		for(i = 1;i < NUM ;i++)
		{
			s[i].left = s[i - 1].left + 20;
			s[i].top = s[0].top ;
			s[i].right = s[i - 1].right+ 20;
			s[i].button = s[0].button;
		}


		srand(time(0));
		f.x = (rand() % cxClient) / 20 * 20 ;                //确保能与蛇头相容;从高鑫那才想到这一点。
		f.y = (rand() % cyClient) / 20 * 20;
		//InvalidateRect(hwnd,NULL,true);
		return 0;
	case WM_TIMER:
		//响应按键
		if(BTN == 1)
		{
			for(i = 0;i < NUM - 1;i++)
			{
				s[i].left = s[i + 1].left;
				s[i].top = s[i + 1].top;
				s[i].right = s[i + 1].right;
				s[i].button = s[i + 1].button;
			}
			s[NUM - 1].top -= 20;
			s[NUM - 1].button -= 20;
			
		}
		else if(BTN == 2)
		{
			for(i = 0;i < NUM - 1;i++)
			{
				s[i].left = s[i + 1].left;
				s[i].top = s[i + 1].top;
				s[i].right = s[i + 1].right;
				s[i].button = s[i + 1].button;
			}
			s[NUM - 1].top += 20;
			s[NUM - 1].button += 20;
		}
		else if(BTN == 3)
		{
			for(i = 0;i < NUM - 1;i++)
			{
				s[i].left = s[i + 1].left;
				s[i].top = s[i + 1].top;
				s[i].right = s[i + 1].right;
				s[i].button = s[i + 1].button;
			}
			s[NUM - 1].right -= 20;
			s[NUM - 1].left -= 20;
		}
		else if(BTN == 4)
		{
			for(i = 0;i < NUM - 1;i++)
			{
				s[i].left = s[i + 1].left;
				s[i].top = s[i + 1].top;
				s[i].right = s[i + 1].right;
				s[i].button = s[i + 1].button;
			}
			s[NUM - 1].right += 20;
			s[NUM - 1].left += 20;


		}
		//怎么死
		if(s[NUM - 1].right > cxClient || s[NUM - 1].left < 0 || s[NUM - 1].top < 0 ||s[NUM - 1].button > cyClient +20)  //触边死   
		{
			KillTimer(hwnd,ID_TIMER);
			MessageBox(hwnd,TEXT("Sorry,You lost!"),TEXT("Result"),MB_OK|MB_ICONERROR);
			exit(0);
		}
		for(i = 0;i < NUM - 1;i ++)
		{
			if(s[NUM - 1].left ==s[i].left&&s[NUM - 1].right == s[i].right && s[NUM - 1].top == s[i].top && s[NUM - 1].button == s[i].button)  
			{
				KillTimer(hwnd,ID_TIMER);
				MessageBox(hwnd,TEXT("Sorry,You lost!"),TEXT("Result"),MB_OK|MB_ICONERROR);
				exit(0);
			}
		}
		//增长
		switch(BTN)
		{
		case 1:
			if(s[NUM - 1].top == f.y + 20 && s[NUM - 1].left == f.x)
			{
				NUM ++;
				s[NUM - 1].top = f.y;
				s[NUM - 1].left = f.x;
				s[NUM - 1].right = f.x + 20;
				s[NUM - 1].button = f.y + 20;
				f.x = (rand() % cxClient) / 20 * 20 ;               
				f.y = (rand() % cyClient) / 20 * 20;
				break ;
			}
		case 2:
			if(s[NUM - 1].top == f.y && s[NUM - 1].left == f.x)
			{
				NUM ++;
				s[NUM - 1].top = f.y;
				s[NUM - 1].left = f.x;
				s[NUM - 1].right = f.x + 20;
				s[NUM - 1].button = f.y + 20;
				f.x = (rand() % cxClient) / 20 * 20 ;               
				f.y = (rand() % cyClient) / 20 * 20;
				break ;
			}
		case 3:
			if(s[NUM - 1].top == f.y && s[NUM - 1].left == f.x)
			{
				NUM ++;
				s[NUM - 1].top = f.y;
				s[NUM - 1].left = f.x;
				s[NUM - 1].right = f.x + 20;
				s[NUM - 1].button = f.y + 20;
				f.x = (rand() % cxClient) / 20 * 20 ;                
				f.y = (rand() % cyClient) / 20 * 20;
				break ;
			}
		case 4:
			if(s[NUM - 1].top == f.y && s[NUM - 1].left == f.x)
			{
				NUM ++;
				s[NUM - 1].top = f.y;
				s[NUM - 1].left = f.x;
				s[NUM - 1].right = f.x + 20;
				s[NUM - 1].button = f.y + 20;
				f.x = (rand() % cxClient) / 20 * 20 ;                
				f.y = (rand() % cyClient) / 20 * 20;
				break ;
			}
		default:
			break;
		}
		InvalidateRect(hwnd, NULL, TRUE);  
		return 0;
	
	case WM_KEYDOWN:
		switch(wParam)
		{
		case VK_UP:
			BTN = 1;
			break;
		case VK_DOWN:
			BTN = 2;
			break;
		case VK_LEFT:
			BTN = 3;
			break;
		case VK_RIGHT:
			BTN = 4;
			break;
		}
		return 0;
	case WM_PAINT:
		hdc = BeginPaint (hwnd, &ps) ; 


		for(i = 0;i < NUM - 1;i++)
		{
			Rectangle(hdc,s[i].left,s[i].top,s[i].right,s[i].button);
		}
		SelectObject(hdc,(HBRUSH)GetStockObject(GRAY_BRUSH));
		Rectangle(hdc,s[NUM - 1].left,s[NUM - 1].top,s[NUM - 1].right,s[NUM - 1].button);
		Ellipse(hdc,f.x,f.y,f.x + 20,f.y + 20);
		
		EndPaint (hwnd, &ps) ; 
		return 0 ;


	case WM_DESTROY:
		KillTimer(hwnd,ID_TIMER);
		PostQuitMessage (0) ; 
		return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ; 
}









大致实现了贪吃蛇的基本功能。但是还有很多可以改进的地方。所以。希望大家能给于指点和意见。万分感谢。
补充:在处理碰框死亡时。高鑫说可以改进。在创建窗口时可以初始化窗口的大小和位置。做好全局安排蛇和食物的大小和位置。
           又学习了一点。







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值