十周的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;
}