#include "stdafx.h"
#include "MyGameFrame.h"
#include <stdio.h>
//恐龙结构体
struct dragon
{
int x, y;//恐龙窗口
int dir;//方向
};
//全局变量
HWND hWnd;
HINSTANCE hInst;
HDC hdc, mdc, bufdc;
HBITMAP bg, draPic[4];
int picNum;
DWORD tPre, tNow;
BOOL bPause = FALSE;
const int draNum = 10;
dragon dra[draNum];
int i;
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitWindow(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
VOID CartoonPaint(HDC hdc);
void Sort(int n);
int APIENTRY WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 初始化全局字符串
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitWindow(hInstance, nCmdShow))//初始化窗口
{
return FALSE;//如果不成功则返回FALSE,并退出程序
}
MSG msg; //创建消息类对象
// TODO: 在此放置运行代码。
//定义局部变量
HBITMAP bmp;
//建立内存DC和窗口DC
hdc = GetDC(hWnd);
mdc = CreateCompatibleDC(hdc);
bufdc = CreateCompatibleDC(hdc);
//建立适用位图
bmp = CreateCompatibleBitmap(hdc, 640, 480);
SelectObject(mdc, bmp);
//加载图片
bg = (HBITMAP)LoadImage(NULL, "bg.bmp", IMAGE_BITMAP, 640, 480, LR_LOADFROMFILE);
draPic[0] = (HBITMAP)LoadImage(NULL, "dra0.bmp", IMAGE_BITMAP, 528, 188, LR_LOADFROMFILE);
draPic[1] = (HBITMAP)LoadImage(NULL, "dra1.bmp", IMAGE_BITMAP, 544, 164, LR_LOADFROMFILE);
draPic[2] = (HBITMAP)LoadImage(NULL, "dra2.bmp", IMAGE_BITMAP, 760, 198, LR_LOADFROMFILE);
draPic[3] = (HBITMAP)LoadImage(NULL, "dra3.bmp", IMAGE_BITMAP, 760, 198, LR_LOADFROMFILE);
//定义恐龙初始方向和位置
for (i = 0; i<draNum; i++)
{
dra[i].dir = 3;
dra[i].x = 200;
dra[i].y = 200;
}
//绘制恐龙
CartoonPaint(hdc);
// 主消息循环:
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);//赋初值
while (msg.message != WM_QUIT) //进入游戏消息循环:
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg); //获得游戏玩家输入的消息;
DispatchMessage(&msg);//分配玩家消息并响应用户消息。
}
else
{
tNow = GetTickCount();
if (tNow - tPre >= 100)
if (bPause)
CartoonPaint(hdc);
}
}
return (int)msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 注册Windows类,一款游戏有且仅有一个主窗口,与游戏程序唯一对应。创建游戏窗口前要填写窗口类结构体WNDCLASSEX
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex =
{
wcex.cbSize = sizeof(WNDCLASSEX),
CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
WndProc,0,0,
hInstance,
LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYGAMEFRAME)),
LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1),NULL,
_T("GameFrame"),
LoadIcon(NULL,MAKEINTRESOURCE(IDI_SMALL))
};
return RegisterClassEx(&wcex);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitWindow(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow
(
_T("GameFrame"),
_T("游戏框架"),
WS_OVERLAPPEDWINDOW^WS_THICKFRAME^WS_MAXIMIZEBOX,//普通样式,不能改变大小,不能最大化
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, nullptr, nullptr, hInstance, nullptr
);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
PAINTSTRUCT ps; //用于WM_PAINT
HDC hdc; //设备场景句柄
switch (msg) //判断消息
{
case WM_CREATE:
//执行初始化代码
return(0);
break;
//键盘控制龙运动或静止
case WM_CHAR:
bPause = !bPause;
break;
case WM_PAINT:
//确定窗口是否有效
hdc = BeginPaint(hwnd, &ps);
//TODO:添加执行绘制代码
//结束代码
EndPaint(hwnd, &ps);
return(0);
break;
case WM_DESTROY:
//关闭程序,发送WM_QUIT消息
PostQuitMessage(0);
return(0);
break;
default:
break;
}
return (DefWindowProc(hwnd, msg, wparam, lparam));
}
void CartoonPaint(HDC hdc)
{
//图片大小
int w, h;
//动作循环
if (picNum == 8)
picNum = 0;
//绘制背景
SelectObject(bufdc, bg);
BitBlt(mdc, 0, 0, 640, 480, bufdc, 0, 0, SRCCOPY);
Sort(draNum); //以Y 轴坐标进行排序
for (i = 0; i < draNum; i++)
{
SelectObject(bufdc, draPic[dra[i].dir]);
//对窗口中跑动的恐龙进行贴图
switch (dra[i].dir)
{
//前
case 0:
w = 66;
h = 94;
break;
//后
case 1:
w = 68;
h = 82;
break;
//左
case 2:
w = 95;
h = 99;
break;
//右
case 3:
w = 95;
h = 99;
break;
}
//半透明处理
BitBlt(mdc, dra[i].x, dra[i].y, w, h, bufdc, picNum*w, h, SRCAND);
BitBlt(mdc, dra[i].x, dra[i].y, w, h, bufdc, picNum*w, 0, SRCPAINT);
}
BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY);
tPre = GetTickCount();
picNum++;
for (i = 0; i < draNum; i++)
{
// 计算移动过的绘图坐标,同时进行误差的校正
int nDir = rand() % 4;
//改变随机转换方向的几率
if (rand() % 3 != 0)
nDir = dra[i].dir;
switch (nDir) {
//由前变为
case 0: //上
switch (dra[i].dir) {
case 0:
dra[i].y -= 20;
break;
case 1:
dra[i].x += 2;
dra[i].y -= 31;
break;
case 2:
dra[i].x += 14;
dra[i].y -= 20;
break;
case 3:
dra[i].x += 14;
dra[i].y -= 20;
break;
}
if (dra[i].y < 0)
dra[i].y = 0;
dra[i].dir = 0;
break;
//由后变为
case 1: //下
switch (dra[i].dir)
{
case 0:
dra[i].x -= 2;
dra[i].y += 31;
break;
case 1:
dra[i].y += 20;
break;
case 2:
dra[i].x += 15;
dra[i].y += 29;
break;
case 3:
dra[i].x += 15;
dra[i].y += 29;
break;
}
if (dra[i].y > 370) dra[i].y = 370;
dra[i].dir = 1;
break;
//由左变为
case 2: //左
switch (dra[i].dir)
{
case 0:
dra[i].x -= 34;
break;
case 1:
dra[i].x -= 34;
dra[i].y -= 9;
break;
case 2:
dra[i].x -= 20;
break;
case 3:
dra[i].x -= 20;
break;
}
if (dra[i].x < 0) dra[i].x = 0;
dra[i].dir = 2;
break;
//由右变为
case 3: //右
switch (dra[i].dir) {
case 0:
dra[i].x += 6;
break;
case 1:
dra[i].x += 6;
dra[i].y -= 10;
break; case 2:
dra[i].x += 20;
break;
case 3:
dra[i].x += 20;
break;
}
if (dra[i].x > 535)
dra[i].x = 535;
dra[i].dir = 3;
break;
}
}
}
//对小恐龙们进行视觉上的排序,使其看起来自然
void Sort(int n) {
int i, j;
bool f;
dragon tmp;
for (i = 0; i<n - 1; i++)
{
f = false;
for (j = 0; j<n - i - 1; j++)
{
if (dra[j + 1].y < dra[j].y)
{
tmp = dra[j + 1];
dra[j + 1] = dra[j];
dra[j] = tmp;
f = true;
}
}
if (!f)
break;
}
}
