IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 2D游戏引擎开发入门(一) -> 正文阅读

[游戏开发]2D游戏引擎开发入门(一)

创建Windows窗口

创建一个空项目

使用VS创建一个空项目。我这里使用的是Visual Studio 2022。具体方法不再描述。

右键属性,将C++语言标准升到C++20.

创建声明部分

添加头文件:

#include <windows.h>
#include <iostream>

声明WindowProc函数:

LRESULT CALLBACK WindowProc(
	HWND hwnd,
	UINT uMsg,
	WPARAM wParam,
	LPARAM lParam
);

该函数是一个应用程序定义的函数。它处理发送给窗口的消息。

编写主体部分

编写main函数:

int wmain(int argc, wchar_t* argv[])
{

wmain()是unicode版本的的main() 。

设置控制台的显示中文,否则无法使用宽字符来输出中文:

setlocale(LC_ALL, "chs");

定义窗口类属性:

int width = 1024;
int height = 720;
HINSTANCE hInstance;
hInstance = GetModuleHandle(NULL);
WNDCLASS wndClass{};
// 设置应用图标
wndClass.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndClass.lpfnWndProc = WindowProc;
// 设置类名字
wndClass.lpszClassName = L"SGE";
wndClass.hInstance = hInstance;
// 指定唯一一个style
wndClass.style = CS_OWNDC;

注册窗口类:

RegisterClass(&wndClass);

根据之前的窗口类,创建一个Windows窗口:

HWND hwnd = CreateWindow(
		L"SGE",							// 类名
		L"The Seed Game Engine",		// 窗口名
		WS_OVERLAPPED | WS_SYSMENU  | WS_MINIMIZEBOX  | WS_VISIBLE,
		38,
		20,
		width,
		height,
		NULL,
		NULL,
		hInstance,
		NULL);

其中第三个参数为窗口样式:WS_OVERLAPPED表示该窗口拥有标题栏和窗口边框;WS_SYSMENU表示该窗口拥有窗口系统控制按钮;WS_MINIMIZEBOX表示窗口拥有最小化按钮;WS_VISIBLE表示窗口初始可视。

判断窗体时候创建成功:

if (FAILED(hwnd))
{
    std::wcout << L"创建窗口出错!" << std::endl;
    throw;
    return  0;
}

由于窗口存在标题栏和边框,需要修改窗口大小,保证绘图区域为固定的分辨率:

RECT rc;
GetClientRect(hwnd, &rc);
MoveWindow(hwnd, 0, 0, width + width - rc.right, height + height - rc.bottom, true);

创建消息循环:

	MSG msg;
	while (true)
	{
		MSG msg;
		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
				return 0;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		Sleep(300);
	}

消息循环是很重要的一部分。主逻辑每隔一段时间就清空所有的Windows消息队列中的消息,对其中的消息进行转发和处理,然后休眠一段时间,继续循环。

最后,就剩下补充WindowProc函数实现:

LRESULT CALLBACK WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

最终效果

image-20220123135500549

完整代码

#include <windows.h>
#include <iostream>

LRESULT CALLBACK WindowProc(
	HWND hwnd,
	UINT uMsg,
	WPARAM wParam,
	LPARAM lParam
);
int wmain(int argc, wchar_t* argv[])
{
	// 设置控制台的中文显示
	setlocale(LC_ALL, "chs");

	int width = 1024;
	int height = 720;
	HINSTANCE hInstance;
	hInstance = GetModuleHandle(NULL);
	WNDCLASS wndClass{};
	// 设置应用图标
	wndClass.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
	wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wndClass.lpfnWndProc = WindowProc;
	// 设置类名字
	wndClass.lpszClassName = L"SGE";
	wndClass.hInstance = hInstance;
	// 指定唯一一个style
	wndClass.style = CS_OWNDC;

	// 注册
	RegisterClass(&wndClass);

	HWND hwnd = CreateWindow(
		L"SGE",							// 类名
		L"The Seed Game Engine",		// 窗口名
		WS_OVERLAPPED  | WS_SYSMENU  | WS_MINIMIZEBOX  | WS_VISIBLE,
		38,
		20,
		width,
		height,
		NULL,
		NULL,
		hInstance,
		NULL);

	if (FAILED(hwnd))
	{
		std::wcout << L"创建窗口出错!" << std::endl;
		throw;
		return  0;
	}
    
    RECT rc;
    GetClientRect(hwnd, &rc);
    MoveWindow(hwnd, 0, 0, width + width - rc.right, height + height - rc.bottom, true);
    
	MSG msg;
	while (true)
	{
		MSG msg;
		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
				return 0;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		Sleep(300);
	}

	return 0;
}

LRESULT CALLBACK WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

本节项目链接地址:https://github.com/nayaku/SGE/tree/dev_1

总结

这一章节,我们实现了一个简单的Window窗口的创建。然而,窗体内容还是空的。下一章节,将会开始搭建引擎的框架来一步步实现一个完整的游戏引擎。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-01-25 10:54:26  更:2022-01-25 10:56:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 18:46:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码