C++语言学习笔记3:超级小玛丽

C++语言学习笔记3:超级小玛丽

WinMain.cpp

//WinMain.cpp
// window 应用程序,多字符集
#include<windows.h>
#include "Mali.h"

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HINSTANCE hIns = 0;  //全局变量,程序实例句柄

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nShowCmd)
{
	//-----------------------------------------------------
	HWND hwnd = 0;
	MSG msg;       //  装消息的结构体
	WNDCLASSEX wndclass;
	//-----------------------------------------------------

	hIns = hInstance;
	LPCSTR lClassName = "yue"; //窗口类名
	int nx = 0;                  //窗口位置X
	int ny = 0;                  //窗口位置Y
	int nwidth = 0;              //窗口宽度
	int nheigh = 0;              //窗口高度
	const CHAR* strTitle = "yue";         //窗口标题名
	int pos_x = nx;
	if (pos_x < 0) {
		pos_x = 0;
	}
	int pos_y = ny;
	if (pos_y < 0) {
		pos_y = 0;
	}
	int nWidth = nwidth;
	if (nWidth <= 0) {
		nWidth = 500;
	}
	int nHeight = nheigh;
	if (nHeight <= 0) {
		nHeight = 500;
	}

	//----------------------创建窗口过程-----------------------------------
	//  1. 设计
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.cbSize = sizeof(wndclass);
	wndclass.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wndclass.hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW));
	wndclass.hIcon = 0;
	wndclass.hIconSm = 0;
	wndclass.hInstance = hInstance;
	wndclass.lpfnWndProc = WindowProc;
	wndclass.lpszClassName = lClassName;
	wndclass.lpszMenuName = 0;
	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	// 2.  注册
	if (RegisterClassEx(&wndclass) == FALSE)
	{
		MessageBox(0, "注册失败", "提示", MB_OK);
		return 0;
	}
	//  3.  创建
	hwnd = CreateWindow(lClassName, strTitle, WS_OVERLAPPEDWINDOW, pos_x, pos_y, nWidth, nHeight, 0, 0, hInstance, 0);
	if (hwnd == 0)
	{
		MessageBox(0, "创建失败", "提示", MB_OK);
		return 0;
	}
	//  4.  显示窗口
	ShowWindow(hwnd, SW_SHOW);
	//---------------------------创建窗口过程------------------------------------------------

	//----------------------------消息循环-------------------------------------------
	while (GetMessage(&msg, 0, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	//----------------------------消息循环-------------------------------------------

	return 0;
}

CMali* pMali = NULL;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CREATE: //窗口创建消息
	{
		if (pMali == NULL) {
			pMali = new CMali;
			pMali->InitPeople(hIns);
		}
	}
	break;
	case WM_PAINT:  //重绘消息
	{
		PAINTSTRUCT ps = { 0 };
		HDC hdc = ::BeginPaint(hwnd, &ps);
		//——————————————————————————————————————————
		if (pMali != NULL) 
		{
			pMali->ShowPeople(hdc);
		}
		//——————————————————————————————————————————
		::EndPaint(hwnd, &ps);
	}
	break;
	//case WM_TIMER:   //定时器,需要我们在子类中手动添加定时器并设置触发间隔
	//{

	//}
	//break;
	case WM_KEYDOWN:  //键盘按下触发消息
	{
		if (pMali != NULL)
		{
			pMali->MovePeople(wParam);
		}
		RECT rect = { 0,0,500,500 };//整个窗口都需要刷新,所以大小是整个窗口
		::InvalidateRect(hwnd,&rect,TRUE);//无效区(刷新窗口)
										  //FALSE会留下轨迹,不擦除上一位置的位图  TRUE移动会擦除上一位置
	}
	break;
	//case WM_KEYUP:  //键盘抬起触发消息
	//{

	//}
	//break;
	//case WM_LBUTTONDOWN: //鼠标左键按下触发消息
	//{

	//}
	//break;
	//case WM_LBUTTONUP: //鼠标左键抬起触发消息
	//{

	//}
	//break;
	//case WM_MOUSEMOVE:  //鼠标移动
	//{

	//}
	//break;
	case WM_CLOSE:
	{
		int res = ::MessageBox(NULL, "[WM_CLOSE] 是否确定退出", "提示", MB_OKCANCEL);
		if (res == IDOK) { //点击 【确定】按钮

		}
		else if (res == IDCANCEL) {//点击【取消】按钮,不调用默认的消息处理 DefWindowProc 

			return 0;
		}
		else {
			return 0;
		}
	}
	break;
	case WM_DESTROY:
	{
		//::MessageBox(NULL, "WM_DESTROY", "提示", MB_OK);
		//释放游戏资源
		if (pMali) 
		{
			delete pMali;
			pMali = NULL;
		}
		PostQuitMessage(0);
	}
	break;
	case WM_QUIT:
	{
		::MessageBox(NULL, "WM_QUIT", "提示", MB_OK);
	}
	break;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);

}

Mali.h

#pragma once
#include <windows.h>
#include "resource.h"


class CMali
{
public:
	int m_nx;
	int m_ny;
	int m_nDirection;//方向

	HBITMAP m_hUp;
	HBITMAP m_hDown;
	HBITMAP m_hRight;
	HBITMAP m_hLeft;

	CMali() {
		m_nx = 0;
		m_ny = 0;
		m_nDirection = VK_LEFT;

		m_hUp = NULL;
		m_hDown = NULL;
		m_hRight = NULL;
		m_hLeft = NULL;
	}

	~CMali() {
		::DeleteObject(m_hUp);
		m_hUp = NULL;
		::DeleteObject(m_hDown);
		m_hDown = NULL;		
		::DeleteObject(m_hLeft);
		m_hLeft = NULL;
		::DeleteObject(m_hRight);
		m_hRight = NULL;
	}

	void InitPeople(HINSTANCE hIns) {		//初始化
		m_nx = 200;
		m_ny = 200;
		m_hUp = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_Up));
		m_hDown = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_Down));
		m_hRight = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_Right));
		m_hLeft = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_Left));
	}

	void ShowPeople(HDC hdc) {		//显示
		//1.获取窗口DC
		//2.创建兼容性DC
		HDC compDc = ::CreateCompatibleDC(hdc);
		//3.句柄选入到兼容性DC中(选入相应的位图)
		if (m_nDirection == VK_LEFT) 
		{
			::SelectObject(compDc, m_hLeft);
		}else if (m_nDirection == VK_RIGHT)
		{
			::SelectObject(compDc, m_hRight);
			}
		else if (m_nDirection == VK_UP)
		{
			::SelectObject(compDc, m_hUp);
		}
		else if (m_nDirection == VK_DOWN)
		{
			::SelectObject(compDc, m_hDown);
		}
		//4.兼容性DC里的图贴到窗口上(贴图)
		::BitBlt(hdc, m_nx, m_ny, 60, 60, compDc, 0, 0, SRCAND);//SRCAAND与操作,可以将位图的白色部分消除,只显示非白色部分
		//5.删除创建的兼容性DC
		::DeleteDC(compDc);
		compDc = NULL;
		//6.释放获取的窗口DC
	}

	void MovePeople(int direct, int step = 4) {		//移动 
		switch (direct) {
		case VK_LEFT:
		{
			if (m_nx - step <= 0) 
			{
				m_nx = 0;
			}
			else {
				m_nx -= step;
			}
			m_nDirection = VK_LEFT;
		}
		break;
		case VK_RIGHT:
		{
			if (m_nx + step >= 440)
			{
				m_nx = 440;
			}
			else {
				m_nx += step;
			}
			m_nDirection = VK_RIGHT;
		}
		break;
		case VK_UP:
		{
			if (m_ny - step <= 0)
			{
				m_ny = 0;
			}
			else {
				m_ny -= step;
			}
			m_nDirection = VK_UP;
		}
		break;
		case VK_DOWN:
		{
			if (m_ny + step >= 440) 
			{
				m_ny = 440;
			}
			else {
				m_ny += step;
			}
			m_nDirection = VK_DOWN;
		}
		break;
		}
	}

protected:
private:
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

97Marcus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值