zoukankan      html  css  js  c++  java
  • 学习游戏基础编程1:Win32自定义控件

    第一次写博客,感觉怪怪的。

    我想学习游戏编程,之前也写过简单的2D类型的类似超级玛丽游戏,但是感觉除了在设计思想方面和GUI基本毫无收获,于是准备从头开始,去认识游戏是怎么编成的,虽然我很菜,但是我有信心。

    我认为一个游戏首先要具备的就是素材,幸好之前就有好多存货,这次准备的是依然2D的,当然3D的从现在搞有点难度,不过这次的图片是斜45度类型的,相当于2.5D的吧,刚好符合2D->2.5D->3D的路线,废话不多说开始吧。

    开始研究Win32的GUI,当然有好多成熟的GUI库,好多是跨平台的,可视化的,不过对于喜欢钻牛角尖的我来说,单纯的组织数据来编写游戏满足不了我,我要从里到外把它摸一遍。直接用Win32API编写界面,嗯,不得不说这个决定是很愚蠢的,因为这相当于要自己砍木做房子,而不是用别人造好的家具。

    接下来我看了Directx2D,不兼容XP及更低的OS,无所谓,反正是学习,不过GDI+也不错,看看后面的实际情况吧,如果有严格性能要求的就用D2D。

    接下来就是数据的事情了,嗯,首先就是xml文件的操作,感觉xml格式的数据来驱动游戏是个好方法。C中没有xml的标准库,网上搜之发现tinyxml口碑不错,试了下,果然简单实用。学习之。

    接下来开始规划,基本的技术要求都有了解,接下来会使细化的具体实现,那才是最难过的时间,要马不停蹄的各种查资料。好吧,问题已经来了,想了好多哦,头疼,先从最简单的开始做起,抛弃那些不断浮现的想法,因为这是不切实际,一口吃不成胖子。我需要一个地图编辑器,参观了war3的地图编辑器,果然牛逼,暴雪品质不是吹出来的,这个地图编辑器只有一个大窗口,左边是地图编辑区,右边有地图缩略图,一个下拉框列表框显示图片组,下面是要选择的图片,菜单栏有文件和帮助,文件包括打开,新建,保存,退出,工具栏和状态栏暂略。

    开始了,我的地图编辑器之旅。

    好吧,问题接踵而至,我需要显示图片,使用控件,但是Win32没有现成的,只能自定义,额额额,痛苦,期间学习到了不少Win32的控件的知识,感觉自己牛逼了好多。

    看了好多文章,也写了几个简单的例子,都感觉不太完美,其实和一个简单windows窗口一样,需要你指定注册窗口类和窗口过程函数。需要注意的是指定WS_CHILD样式。

    第一步:注册窗口类

     WNDCLASSEX wc;

      
        wc.cbSize         = sizeof(wc);
        wc.lpszClassName  = szClassName;
        wc.hInstance      = GetModuleHandle(0);
        wc.lpfnWndProc    = CustWndProc;
        wc.hCursor        = LoadCursor (NULL, IDC_ARROW);
        wc.hIcon          = 0;
        wc.lpszMenuName   = 0;
        wc.hbrBackground  = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE);
        wc.style          = 0;
        wc.cbClsExtra     = 0;
        wc.cbWndExtra     = 0;
        wc.hIconSm        = 0;
        RegisterClassEx(&wc);
    第二步:定义窗口过程函数:
    LRESULT CALLBACK CustWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch(msg)
        {
        default:
            break;
        }
     
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    第三步:创建窗口:
    HWND hwndCtrl;
      
        hwndCtrl = CreateWindowEx(
                     WS_EX_CLIENTEDGE, // give it a standard border
                     szClassName
                     _T("A custom control"),
                     WS_VISIBLE | WS_CHILD,
                     0, 0, 100, 100,
                     hwndParent,
                     NULL, GetModuleHandle(0), NULL
                   );
    关键的地方红色标出来了,一个是注册自定义窗口的类名,第二个是指定窗口样式为子窗口。
    接下来该怎么做呢?
    我需要的编辑地图,因此我要将我选中的地图贴到指定地方,即控件,因此我需要几个变量能让我实现这个控件显示我要的图片。
    你可以用C的方式声明一个结构体或者C++的方式定义一个类。
    typedef struct
    {
      HWND hwnd;
      定义变量用以帮助显示图片
    }MyCtrl;
    class MyCtrl
    {
      定义函数绘制图片
    }
    关于自定义控件的知识我推荐这篇博文,非常棒!http://www.catch22.net/tuts/custom-controls
    又过了几天,总结一下:窗口子类化的知识。
    如果是C风格的 可以建一个结构体:里面呢 放上你需要的各种资源如窗口句柄、字体颜色、位图等。另外最好是有注册窗口类、创建窗口、自定义窗口过程、方法,注册窗口类在程序开始时就加上去,免得忘记,创建窗口则是方便提供一个整齐直观的接口对外调用,也不用到处CreateWindow()了,自定义窗口过程是最重要的,因为这是你自己最主要的实现。当然C风格的不如C++那样不容易扩展,适合底层次的封装。当然随手做的小程序可以不用顾忌,反而更容易理解。
    如果是C++风格的 就可以用类了,依然里面几个重要的方法必须是静态的。其它倒是差不多,不过可以方便扩展。可以写一个基类,可以用模板来更好的扩展。
    里面有个难点:就是如何把窗口句柄和结构体或者类对象关联起来,根据我搜集到的知识来看,最好的方法之一就是:WNDCLASS里的cbWndExtra来存储,另外一种通过GWL_USERDATA来存储,两者都可以SetWindowLong和GetWindowLong来操作,不过前者适合自定义的控件。之后可以在窗口过程函数里操作,CreateWindow()里的最后一个LPVOID lpParam参数,在WM_NCCREATE或者WM_CREATE下的lParam参数,强制转换成LPCREATESTRUCT结构体,这个结构体里的lpCreateParams成员就是之前LPVOID lpParam的值,可以把它放在GWL_USERDATA里,随时启用,如http://bbs.csdn.net/topics/390152857这个例子。也可以在创建窗口的时候就去关联例如这个例子http://blog.csdn.net/fishion/article/details/8985414。当然效率最高的是thunk技术了,不过有兴趣的朋友可以去仔细看下。
    方法有很多种,最后的目的都是一样的。学东西要深入浅出,莫钻牛角尖。
  • 相关阅读:
    Echarts实现区级行政区划地图
    webpack4.x开发环境配置
    说说说vue.js中的组
    原生JS实现购物车功能详解
    面向对象的一些重要的基本概念
    Lucene教程
    开启事务时mybatis返回主键id
    生成二维码的方法,基于zxing
    mysql判断一条记录是否存在,如果存在,则更新此语句,如果不存在,则插入
    一:验证微信的Token
  • 原文地址:https://www.cnblogs.com/gameNote/p/3517042.html
Copyright © 2011-2022 走看看