last day on windows programming

十周的win编课,感觉学了不少,最后做出成品其实只有不到400行,可能比一个数据结构题目的类定义还要少,但是第一次看到图形界面简直哭了

最后代码,内容是一个射箭的小游戏。本来想做天上很多太阳,随便射,后来发现图片消失太难做,放弃了。最后做成了这种屏幕上同一时刻只能有一个太阳的情况



最后闪烁问题也没有解决好,总之是个比较lame的作品啦...

/* Demonstrate a bitmap */
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include "resource.h"
#include <iostream>
#include <cstring>
#include <string>
#include <ctime>
#define sunnum 9
using namespace std;

#define ID_TIMER1  1000
#define ID_TIMER2  1001
#define ID_TIMER3  1002

static int hitcount = 0;

LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DialogFunc(HWND, UINT, WPARAM, LPARAM);

char szWinName[] = "MyWin"; 

HBITMAP hOpen;
HBITMAP hstartup, hmstartup, hstartdown,hmstartdown; 
HBITMAP hbk, hsun, hmsun,hboom,hmboom,hwhite;
HBITMAP harrow, hmarrow, hbow, hmbow;
HINSTANCE hInst; //实例代号

void PutBit(HWND hwnd, HBITMAP hBit, int X, int Y, int Width, int Height, DWORD dwHow)
{
	HDC DC, memDC;
	HGDIOBJ hOldBit;
	DC = GetDC(hwnd); /* get device context */
	memDC = CreateCompatibleDC(DC);  /* create compatible DC */
	SelectObject(memDC, hBit);
	BitBlt(DC, X, Y, X+Width, Y+Height, memDC, 0, 0, dwHow);  /* display image */
	ReleaseDC(hwnd, DC);
	//SelectObject(memDC, hOldBit);
	DeleteDC(memDC); /* free the memory context */
}

int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
	HWND hwnd;
	MSG msg;
	WNDCLASSEX wcl;
	HACCEL hAccel;
	wcl.cbSize = sizeof(WNDCLASSEX);
	wcl.hInstance = hThisInst; 
	wcl.lpszClassName = szWinName; 
	wcl.lpfnWndProc = WindowFunc; /* window function */
	wcl.style = 0; /* default style */

	wcl.hIcon = LoadIcon(hThisInst, MAKEINTRESOURCE(127)); /* standard icon */
	wcl.hIconSm = NULL; /* SMALL ICON */
	wcl.hCursor = LoadCursor(hThisInst, MAKEINTRESOURCE(130)); /* cursor style */

	/* Specify name of menu resource. This will be overridden. */
	wcl.lpszMenuName = MAKEINTRESOURCE(128); /* main menu */
	wcl.cbClsExtra = 0; /* no extra information needed */
	wcl.cbWndExtra = 0;	/* no extra information needed */

	/* Make the windows backgraoud white */
	wcl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

	/* Register the window class. */
	if (!RegisterClassEx(&wcl))
		return 0;

	hInst = hThisInst;
	/* Now that a window class has been registered, a window can be created. */
	hwnd = CreateWindow(
		szWinName,	/* name of window class */
		"后羿射日", /* title */
		WS_OVERLAPPEDWINDOW, /* window style - normal */
		CW_USEDEFAULT,	/* X coordinate - let Winodws decide */
		CW_USEDEFAULT,	/* Y coordinate - let Windows decide */
		800,	/* width - let Windows decide */
		450,	/* height - let Windows decide */
		HWND_DESKTOP, /* no parent window */
		NULL,  /*  no menu */
		hThisInst, /* handle of this instance of the program */
		NULL /* no additional arguments */
		);

	/* Load accelerators. */
	hAccel = LoadAccelerators(hThisInst, MAKEINTRESOURCE(135));
	/* Display the windows. */
	ShowWindow(hwnd, nWinMode);
	UpdateWindow(hwnd);

	/* Createthe message loop. */
	while (GetMessage(&msg, NULL, 0, 0))	{
		if (!TranslateAccelerator(hwnd, hAccel, &msg))//对加速键的处理
		{
			TranslateMessage(&msg); /* translate keyboard messages */
			DispatchMessage(&msg); /* return control to Windows 98 */
		}
	}
	return msg.wParam;
}

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HMENU hMenu;
	HDC hdc;
	//static HINSTANCE hInstance;
	PAINTSTRUCT ps;
	SIZE size;
	BITMAP bitmap;
	static RECT rect;
	static POINT mouse;
	static POINT sunp[1200];
	static bool start = false;
	static bool arrowup = false;
	static int seed, i = 0;
	seed = time_t(NULL);
	static int time = 3000;//timer1间隔
	static int count = 0;
	
	static int timeleft = sunnum;//太阳个数
	static int flag = 0;
	static int bowx = 350;
	static int arrowx = 400, arrowy = 350;
	static bool hit[1200] = { false };
	static int response;
	char ctimes[100], ctimeleft[100];
	switch (message) {
	case WM_CREATE:
		hOpen = LoadBitmap(hInst, MAKEINTRESOURCE(101));
		hstartup = LoadBitmap(hInst, MAKEINTRESOURCE(103));
		hmstartup = LoadBitmap(hInst, MAKEINTRESOURCE(104));
		hstartdown = LoadBitmap(hInst, MAKEINTRESOURCE(105));
		hbk = LoadBitmap(hInst, MAKEINTRESOURCE(109));
		hsun = LoadBitmap(hInst, MAKEINTRESOURCE(113));
		hmsun = LoadBitmap(hInst, MAKEINTRESOURCE(114));
		hboom = LoadBitmap(hInst, MAKEINTRESOURCE(115));
		hmboom = LoadBitmap(hInst, MAKEINTRESOURCE(116));
		harrow = LoadBitmap(hInst, MAKEINTRESOURCE(120));
		hmarrow = LoadBitmap(hInst, MAKEINTRESOURCE(121));
		hbow = LoadBitmap(hInst, MAKEINTRESOURCE(122));
		hmbow = LoadBitmap(hInst, MAKEINTRESOURCE(123));

		SetTimer(hwnd, ID_TIMER1, time, NULL);//太阳
		SetTimer(hwnd, ID_TIMER2, 5, NULL);//判断箭是否射中太阳
		SetTimer(hwnd, ID_TIMER3, 5, NULL);//箭上移

		srand(seed);
		seed = rand();
		srand(seed);
		for (int j = 0; j < 1200; j++)
		{
			sunp[j].x = rand() % 730;
			sunp[j].y = rand() % 100;
		}

		return 0;
	case WM_LBUTTONDOWN:
		mouse.x = LOWORD(lParam);
		mouse.y = HIWORD(lParam);
		if (mouse.x > 540 && mouse.x<764 && mouse.y>150 && mouse.y < 224)
		{
			flag = 1;
		}
		return 0;
	case WM_LBUTTONUP:
		if (flag == 1)
			start = true;
		InvalidateRect(hwnd, NULL, false);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
		if (start == false)
		{
			PutBit(hwnd, hOpen, 0, 0, 800, 450, SRCCOPY);
			PutBit(hwnd, hstartup, 540, 150, 224, 74, SRCINVERT);
			PutBit(hwnd, hmstartup, 540, 150, 224, 74, SRCAND);
			PutBit(hwnd, hstartup, 540, 150, 224, 74, SRCINVERT);
		}

		//太阳和背景
		else
		{
			PutBit(hwnd, hbk, 0, 0, 800, 450, SRCCOPY);
			if (hit[i] == true)
			{
				PutBit(hwnd, hboom, sunp[i].x - 5, sunp[i].y - 5, 70, 70, SRCINVERT);
				PutBit(hwnd, hmboom, sunp[i].x - 5, sunp[i].y - 5, 70, 70, SRCAND);
				PutBit(hwnd, hboom, sunp[i].x - 5, sunp[i].y - 5, 70, 70, SRCINVERT);
			}
			else
			{
				PutBit(hwnd, hsun, sunp[i].x, sunp[i].y, 60, 60, SRCINVERT);
				PutBit(hwnd, hmsun, sunp[i].x, sunp[i].y, 60, 60, SRCAND);
				PutBit(hwnd, hsun, sunp[i].x, sunp[i].y, 60, 60, SRCINVERT);
			}

			PutBit(hwnd, hbow, bowx, 350, 100, 71, SRCINVERT);
			PutBit(hwnd, hmbow, bowx, 350, 100, 71, SRCAND);
			PutBit(hwnd, hbow, bowx, 350, 100, 71, SRCINVERT);

			PutBit(hwnd, harrow, arrowx, arrowy, 4, 71, SRCINVERT);
			PutBit(hwnd, hmarrow, arrowx, arrowy, 4, 71, SRCAND);
			PutBit(hwnd, harrow, arrowx, arrowy, 4, 71, SRCINVERT);

			TextOut(hdc, 0, 0, TEXT("得分:"), 6);
			TextOut(hdc, 62, 0, TEXT("剩余太阳:"),10);
			sprintf_s(ctimes, "%i", hitcount);
			sprintf_s(ctimeleft, "%i", timeleft);
			if (hitcount>=10)
				TextOut(hdc, 45, 0, ctimes, 2);
			else 
				TextOut(hdc, 45, 0, ctimes, 1);
			if (timeleft<10)
				TextOut(hdc, 132, 0, ctimeleft, 1);
			else
				TextOut(hdc, 132, 0, ctimeleft, 2);

		}
		EndPaint(hwnd, &ps);
		break;
		
	case WM_KEYDOWN:
		switch (wParam)
		{
		case VK_LEFT:
			if (bowx >= 50)
			{
				bowx = bowx - 50;
				
				if (arrowup == false)
					arrowx = bowx + 50;
			}
			flag = 0;
			InvalidateRect(hwnd, NULL, false);
			break;
		case VK_RIGHT:
			if (bowx <= 650)
			{
				bowx = bowx + 50;
				if (arrowup == false)
					arrowx = bowx + 50;
			}
			flag = 0;
			InvalidateRect(hwnd, NULL, false);
			break;
		case VK_SPACE:
			if (arrowup==false)
				arrowup = true;
		    break;
		}
		
	case WM_TIMER:
		switch (wParam)
		{
		case ID_TIMER1://出现太阳
			if (start == true)
			{
				timeleft --;//用来输出剩余太阳个数
				count++;//用来结束计时器
				i++;//用来画太阳

				InvalidateRect(hwnd, NULL, false);
			}

			if (count == sunnum+1)//太阳个数
			{
				KillTimer(hwnd, ID_TIMER1);
				
				DialogBox(hInst, MAKEINTRESOURCE(132), hwnd, (DLGPROC)DialogFunc);
				if (time>1000)
					SetTimer(hwnd, ID_TIMER1, time - 1000, NULL);//太阳
				else 
					SetTimer(hwnd, ID_TIMER1, time, NULL);
				hitcount = 0;
				count = 0;
				timeleft = sunnum;
				start = false;
				//sprintf_s(ctimes, "你射中了%i个太阳", hitcount);
				//MessageBox(NULL, ctimes, TEXT("Game over"), 0);
				//start = false;
				//PostQuitMessage(0);
			}
			break;
		case ID_TIMER3://箭上移
			if (start == true)
			{
				if (arrowup == false)
					arrowx = bowx+50;
				else
				{
					if (arrowy < -71)
					{
						arrowy = 350;
						arrowx = bowx + 50;
						arrowup = false;
						InvalidateRect(hwnd, NULL, false);
					}
						
					else
					{
						arrowy = arrowy - 5;
						InvalidateRect(hwnd, NULL, false);
					}					
				}
			}
			break;
			
		case ID_TIMER2:
			if (start == true) 
			{
				if (sunp[i].x <= arrowx&&arrowx <= sunp[i].x + 60 && sunp[i].y <= arrowy&&arrowy <= sunp[i].y + 30)
				{
					hit[i] = true;
					hitcount++;
					arrowy = 350;
					arrowx = bowx+50;
					arrowup = false;
					InvalidateRect(hwnd, NULL, false);
				}
			}
			break;
		}
		return 0;

	case WM_COMMAND:
		hMenu = GetMenu(hwnd);
		switch (LOWORD(wParam)) {
		case IDM_START:
			if (start==false)
				start = true;
			return 0;
		case IDM_EXIT:
			response = MessageBox(hwnd, "真的退出游戏?", "退出游戏", MB_YESNO);
			if (response == IDYES)
				PostQuitMessage(0);
			return 0;
		case IDM_ABOUT:
			MessageBox(hwnd, "开发者\n12122558 彭素素\n12122563 李玉玮\n12122571 徐泉华\n上海大学计算机工程与科学学院\n联系方式:li.yuwei@outlook.com", "关于我们", MB_OK);
			return 0;
		case IDM_HELP:
			MessageBox(hwnd, "键盘左右键移动弓箭,空格射箭,射下8个太阳", "帮助", MB_OK);
			return 0;
		}
		return 0;
	case WM_DESTROY:
		DeleteObject(hOpen);
		DeleteObject(hstartup);
		DeleteObject(hmstartup);
		DeleteObject(hstartdown);
		DeleteObject(hbk);
		DeleteObject(hmsun);
		DeleteObject(hsun);
		DeleteObject(hboom);
		DeleteObject(harrow);
		DeleteObject(hmarrow);
		DeleteObject(hbow);
		DeleteObject(hmbow);
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}
BOOL CALLBACK DialogFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	char str[100], name[50];
	switch (message) {
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDOK:
			GetDlgItemText(hwnd, IDC_EDIT1, name, 80);
			if (hitcount<8)
				sprintf_s(str, "%s, 你射中了%i个太阳,剩余太阳多于一个,你被热死了\n点击鼠标再来一局,键盘左右键回到开始界面", name,hitcount);
			else if (hitcount=9)
				sprintf_s(str, "%s, 你射中了%i个太阳,已经没有剩余太阳了,你被冷死了\n点击鼠标再来一局,键盘左右键回到开始界面", name, hitcount);
			else
				sprintf_s(str, "%s, 你射中了%i个太阳,你成为了新一代后羿!\n点击鼠标再来一局,键盘左右键回到开始界面", name, hitcount);
			MessageBox(hwnd, str, "游戏结束", MB_OK);
			EndDialog(hwnd, 0);
			return 1;
		}
		break;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值