距离上一篇博客已经很长时间了,升了大二,学了更多的东西,眼界更开阔了,回顾以前的寥寥几篇博客,相当的相当的矫情,总之现在还是坚持在学软件工程。这学期学了数据结构和Windows编程(C++可视化程序设计),很受启发,前段时间Windows要求完成一个吃豆人的小游戏,我贴一下自己的源代码。希望对正在学Windows的同学有用
//PacMan.cpp
#include<iostream>
#include "windows.h"
#include"resource.h"
#include<stdlib.h>
#include<time.h>
#include"atlstr.h"
#include"CString"
#include "mmsystem.h"//导入声音头文件
#pragma comment(lib,"winmm.lib")
using namespace std;
#define Max 100
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX WndClass;
HWND hWnd;
MSG msg;
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = 0;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
WndClass.lpszClassName = "WindowClass";
WndClass.hIconSm = LoadIcon(WndClass.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
if (!RegisterClassEx(&WndClass))
{
MessageBox(NULL, "窗口类注册失败!", "窗口注册", NULL);
return 1;
}
hWnd = CreateWindow(
"WindowClass",
"PacMan",
WS_OVERLAPPEDWINDOW,
0, 0,
1000, 650,
NULL,
NULL,
hInstance,
NULL
);
if (!hWnd)
{
MessageBox(NULL,"窗口创建失败!", "创建窗口 ", NULL);
return 1;
}
ShowWindow(hWnd, nCmdShow);
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)
{
HDC hdc;
PAINTSTRUCT ps;
HPEN hP;
HBRUSH hB;
TEXTMETRIC tm;
int t[Max];
CString d[Max];
for (int m = 0; m < Max; m++)
{
t[m] = m;
}
for (int m = 0; m < Max; m++)
{
d[m].Format("%d", t[m]);
}
static int score = 0;
static int a[80], b[80];
static int x3, y3;
static BOOL nRightKeyDown = FALSE, nLeftKeyDown = FALSE,
nUpKeyDown = FALSE, nDownKeyDown = FALSE;
static BOOL Begin = FALSE;
static BOOL Pause = FALSE;
static BOOL Continue = FALSE;
static BOOL Auto = FALSE;
static BOOL Opp = FALSE;
static int x1 = 0, x2 = 40, y1 = 0, y2 = 40;
static int ox1 = 900, oy1 = 520, ox2 = 930, oy2 = 550;
switch (message)
{
case WM_COMMAND:
switch (wParam)//(LOWORD(wParam))
{
case IDM_BEGIN:
Begin = TRUE;
InvalidateRect(hwnd, NULL, TRUE);
break;
case IDM_PAUSE:
Pause = TRUE;
InvalidateRect(hwnd, NULL, TRUE);
break;
case IDM_EXIT:
SendMessage(hwnd, WM_DESTROY, 0, 0);
break;
case IDM_CONTINUE:
Pause = FALSE;
InvalidateRect(hwnd, NULL, TRUE);
break;
case IDM_RBEGIN:
Pause = FALSE;
Begin = TRUE;
x1 = 0, x2 = 50, y1 = 0, y2 = 50;
srand(time(NULL));
for (int i = 0; i < 40; i++)
{
a[i] = rand() % 760;
b[i] = rand() % 570;
}
InvalidateRect(hwnd, NULL, TRUE);
break;
case ID_40007:
break;
case ID_40008:
ShellExecute(NULL, NULL, _T("https://msdn.microsoft.com/zh-cn"), NULL, NULL, SW_SHOWNORMAL);
break;
case IDM_AUTO:
Auto = TRUE;
InvalidateRect(hwnd, NULL, TRUE);
break;
}
break;
case WM_CREATE:
srand(time(NULL));
for (int i = 0; i < 80; i++)
{
a[i] = rand() % 960;
b[i] = rand() % 770;
}
SetTimer(hwnd, 1, 700, NULL);
break;
case WM_PAINT:
if (Begin == TRUE && Auto == FALSE)
{
hdc = BeginPaint(hwnd, &ps);
hP = (HPEN)GetStockObject(BLACK_PEN);
hB = CreateSolidBrush(RGB(127, 255, 0));
SelectObject(hdc, hP);
SelectObject(hdc, hB);
Ellipse(hdc, ox1, oy1, ox2, oy2);
GetTextMetrics(hdc, &tm);
SetTextColor(hdc, RGB(0, 0, 0));
TextOut(hdc, ox1-7, oy1-17, "Enemy", 5);
hP = (HPEN)GetStockObject(BLACK_PEN);
hB = CreateSolidBrush(RGB(160, 42, 42));
SelectObject(hdc, hP);
SelectObject(hdc, hB);
Ellipse(hdc, x1, y1, x2, y2);
for (int m = 0; m < 40; m++)
{
hB = CreateSolidBrush(RGB(255, 180, 185));
SelectObject(hdc, hB);
Ellipse(hdc, a[m], b[m], a[m] + 10, b[m] + 10);
}
GetTextMetrics(hdc, &tm);
SetTextColor(hdc, RGB(0, 0, 0));
TextOut(hdc, 1020, 30, "Score : ", 8);
if (score <= 9)
TextOut(hdc, 1100, 30, d[score], 1);
else
TextOut(hdc, 1100, 30, d[score], 2);
for (int j = 0; j < 40; j++)
{
if (((x1 - a[j] + 10)*(x1 - a[j] + 10) +
(y1 - b[j] + 10)*(y1 - b[j] + 10)) <= 680)
{
score++;
PlaySound(MAKEINTRESOURCE(IDR_EATING), (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), SND_RESOURCE | SND_ASYNC);//MAKEINTRESOURSE函数是根据资源的id号调用资源
a[j] = 0, b[j] = 0;
InvalidateRect(hwnd, NULL, TRUE);
a[j] = rand() % 960;
b[j] = rand() % 770;
Ellipse(hdc, a[j], b[j], a[j] + 10, b[j] + 10);
}
}
if (((x1 - ox1 + 15)*(x1 - ox2 + 15) +(y1 - oy1 + 15)*(y1 - oy2 + 15)) <= 680)
{
PlaySound(MAKEINTRESOURCE(IDR_GAMEOVER), (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), SND_RESOURCE | SND_ASYNC);
}
if (Opp == true)
{
//Ellipse(hdc, ox1, oy1, ox2, oy2);
//srand(time(NULL));
int direction =(int)(3 * rand() / (RAND_MAX + 1.0)) + 1;// rand() * 3 + 1; 生成1——4之间的随机数
if (direction == 1&&ox1<950 && oy1<=760 && ox2<950 && oy2 <= 760)
{
oy1 = oy1 + 30;
oy2 = oy2 + 30;
}
else
if (direction == 2 && ox1<950 && oy1 <= 760 && ox2<950 && oy2 <= 760)
{
oy1 = oy1 - 30;
oy2 = oy2 - 30;
}
else
if (direction == 3 && ox1<950 && oy1 <= 760 && ox2<950 && oy2 <= 760)
{
ox1 = ox1 - 30;
ox2 = ox2 - 30;
}
else
{
ox1 = ox1 + 30;
ox2 = ox2 + 30;
}
Opp = false;
}
}
else if(Auto==true)
{
hdc = BeginPaint(hwnd, &ps);
hP = (HPEN)GetStockObject(BLACK_PEN);
hB = CreateSolidBrush(RGB(25, 25, 112));//MidnightBlue
SelectObject(hdc, hP);
SelectObject(hdc, hB);
Ellipse(hdc, x1, y1, x2, y2);
GetTextMetrics(hdc, &tm);
SetTextColor(hdc, RGB(255, 0, 0));
TextOut(hdc, x1-9, y1-17, "automatic", 9);
TextOut(hdc, 820, 30, "You are under automatic mode, we won't count your score!", 56);
TextOut(hdc, 820, 50, "This mode is just for show", 26);
for (int m = 0; m < 80; m++)
{
hB = CreateSolidBrush(RGB(100, 149, 237));//CornflowerBlue
SelectObject(hdc, hB);
Ellipse(hdc, a[m], b[m], a[m] + 10, b[m] + 10);
}
for (int j = 0; j < 80; j++)
{
if (((x1 - a[j] + 10)*(x1 - a[j] + 10) +
(y1 - b[j] + 10)*(y1 - b[j] + 10)) <= 680)
{
score++;
PlaySound(MAKEINTRESOURCE(IDR_EATING), (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), SND_RESOURCE | SND_ASYNC);
a[j] = 0, b[j] = 0;
InvalidateRect(hwnd, NULL, TRUE);
a[j] = rand() % 960;
b[j] = rand() % 770;
Ellipse(hdc, a[j], b[j], a[j] + 10, b[j] + 10);
}
}
int direction2 = (int)(3 * rand() / (RAND_MAX + 1.0)) + 1;//生成1——4之间的随机数
if (direction2 == 1&&ox1<950 && oy1<=760 && ox2<950 && oy2 <= 760)
{
y1 = y1 + 30;
y2 = y2 + 30;
}
else
if (direction2 == 2&&ox1<950 && oy1<=760 && ox2<950 && oy2 <= 760)
{
y1 = y1 - 30;
y2 = y2 - 30;
}
else
if (direction2 == 3&&ox1<950 && oy1<=760 && ox2<950 && oy2 <= 760)
{
x1 = x1 - 30;
x2 = x2 - 30;
}
else
{
x1 = x1 + 30;
x2 = x2 + 30;
}
}
DeleteObject(hB);
DeleteObject(hP);
EndPaint(hwnd, &ps);
break;
case WM_TIMER:
Opp = true;
InvalidateRect(hwnd, NULL, TRUE);
break;
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_UP:
if ((y2 >= 50 && Pause == FALSE) || Continue == TRUE)
{
nUpKeyDown = TRUE;
x1 = x1;
x2 = x2;
y1 = y1 - 10;
y2 = y2 - 10;
}
else if ((y2< 50 || Pause == TRUE) && Continue == FALSE)
{
x1 = x1;
x2 = x2;
y1 = y1;
y2 = y2;
nUpKeyDown = FALSE;
}
//Opp = false;
InvalidateRect(hwnd, NULL, TRUE);
break;
case VK_DOWN:
if (y1 <= 760 && Pause == FALSE)
{
nDownKeyDown = TRUE;
x1 = x1;
x2 = x2;
y1 = y1 + 10;
y2 = y2 + 10;
}
else if (y1 > 760 || Pause == TRUE)
{
nDownKeyDown = FALSE;
x1 = x1;
x2 = x2;
y1 = y1;
y2 = y2;
}
InvalidateRect(hwnd, NULL, TRUE);
break;
case VK_LEFT:
if (x2 >= 50 && Pause == FALSE)
{
nLeftKeyDown = TRUE;
x1 = x1 - 10;
x2 = x2 - 10;
y1 = y1;
y2 = y2;
}
else if (x2 < 50 || Pause == TRUE)
{
nLeftKeyDown = FALSE;
x1 = x1;
x2 = x2;
y1 = y1;
y2 = y2;
}
InvalidateRect(hwnd, NULL, TRUE);
break;
case VK_RIGHT:
if (x1 <= 950 && Pause == FALSE)
{
nRightKeyDown = TRUE;
x1 = x1 + 10;
x2 = x2 + 10;
y1 = y1;
y2 = y2;
}
else if (x1 > 950 || Pause == TRUE)
{
nRightKeyDown = FALSE;
x1 = x1;
x2 = x2;
y1 = y1;
y2 = y2;
}
//Opp = false;
InvalidateRect(hwnd, NULL, TRUE);
break;
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
KillTimer(hwnd, 1);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
break;
}
return 0;
}
//resourse.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 PacMan.rc 使用
//
#define IDR_MENU1 101
#define IDR_EATING 104
#define IDR_GAMEOVER 105
#define ID_WENJIA_XFYH 40001
#define ID_WENJIA_GHG 40002
#define IDM_BEGIN 40005
#define IDM_EXIT 40006
#define ID_40007 40007
#define ID_40008 40008
#define ID_40009 40009
#define IDM_PAUSE 40010
#define ID_40011 40011
#define IDM_CONTINUE 40012
#define ID_40013 40013
#define IDM_RBEGIN 40014
#define IDM_AUTO 40015
#define ID_DIALOG 40016
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 107
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
//PacMan.rc
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// 中文(简体,中国) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENUEX
BEGIN
POPUP "游戏", 65535,MFT_STRING,MFS_ENABLED
BEGIN
MENUITEM "开始", IDM_BEGIN,MFT_STRING | MFT_RIGHTJUSTIFY,MFS_ENABLED
MENUITEM "退出", IDM_EXIT,MFT_STRING,MFS_ENABLED
END
MENUITEM "技术支持", ID_40008,MFT_STRING,MFS_ENABLED
MENUITEM "自动模式", IDM_AUTO,MFT_STRING,MFS_ENABLED
END
/////////////////////////////////////////////////////////////////////////////
//
// WAVE
//
IDR_EATING WAVE "wave4.bin"
IDR_GAMEOVER WAVE "wave1.bin"
#endif // 中文(简体,中国) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
在过程中,我遇到了一些问题:
1.添加wave文件时没有找到正确的添加方法,所以只能从网上找到了音频源代码,直接打开了C++编辑视图添加了进去;
2.时间原因,没有能在交作业之前添加更多关于敌人Opp的扩展功能,比如PacMan碰到Opp之后可以弹出一个对话框表示“Game Over”,且PacMan消失等;
3.如何添加更多的资源文件形成一个完整的游戏。
后续会继续完善这个作业