同时执行两个或更多功能的方法

我留意到群里和贴吧有不少人都在问怎样同时执行两个过程,比如:

  1. 贪吃蛇游戏,怎样实现双人对抗?就是控制两条蛇移动。
  2. 俄罗斯方块游戏,要加一个时钟,怎样使时钟和游戏同时进行?
  3. 打砖块游戏,怎样实现一边让小球自由移动、一边实现玩家控制木板?

有些人会想到用多线程来解决。我这里首先要说:这个问题不要用多线程,多线程要解决是另一种问题,这里不再详述,本文只讲一下怎样实现前面说的问题。(当然不用多线程解决)

先说一个简单的程序要求:有一个变量 a,初值为 0,每秒钟增加 2,按任意键停止;还有一个变量 b,初值为 0,每秒钟增加 3。现在要求将这两个功能同时执行,该怎么做?

我相信很多人都能写出来这个简单的程序:

#include <stdio.h>
#include <conio.h>
#include <graphics.h>

void main()
{
	// 
...

禁用 EasyX 绘图窗口关闭按钮的方法(控制程序流程)

目前,点 EasyX 绘图窗口的“关闭”,会直接退出整个程序。有时候,程序需要执行完整的流程,因此,禁止关闭按钮就是一个很需要的方法。

可以通过 initgraph 函数的第三个参数禁用关闭按钮,确保程序按实际流程完整执行。

以下代码禁用关闭按钮(VC6 / VC2010 编译通过):

#include <graphics.h>
#include <conio.h>

void main()
{
	initgraph(640, 480, NOCLOSE);

	circle(320, 240, 100);
	
	_getch();
	closegraph();
}

修改 VC 生成的 EXE 文件的图标

默认 VC 生成的 EXE 文件的图标很大众,可以根据以下办法修改 exe 的图标。

以 Visual C++ 6.0 为例:

1. 创建项目,添加代码,并且保证项目可以正常编译。

2. 为项目增加资源文件:

  1. 点菜单:File -> New...,选择 Files 中的 Resource Script,并在右侧 File 中写入名称 myapp,点 OK 添加到项目中。VC 会默认打开 myapp.rc 文件,先关闭它,我们可以 FileView 找到新添加的 myapp.rc 文件。
  2. 双击 myapp.rc,会在 Workspace 区中打开 ResourceView 视图,这里就是资源列表,起初是空的。

3. 在资源文件中导入图标

  1. 为了整齐,我们在项目路径下建立 res 文件夹,并将图标放入该文件夹内,例如取名 app.ico。
  2. 切换到 ResourceView 视图,右击 myapp resources,选择 I
...

在游戏中使用 midi 音乐文件

关于什么是 midi 音乐文件,请参考百度百科:http://baike.baidu.com/view/7969.htm 。

这里简单说一说:

midi 是一种音乐文件,通常扩展名为 mid。不同于 mp3 的地方是:mp3 保存的是声音的波形数据,而 mid 保存的是乐器、音符、音调等。所以从文件体积上来说,mp3 的体积是 mid 体积的几十倍甚至上百倍。

鉴于 midi 的特点,早期很多游戏的都使用 midi 音乐。所以,本文讲怎样使用 midi 音乐。

【1. 素材获取】

网上搜索吧,网上有很多 mid 资源。但是不要尝试将 mp3 转换为 mid,由于原理不同,暂时无法实现 mp3 -> mid 的转换。

【2. 播放】

能播放 mp3 的方法,一般都可以用来播放 mid。所以,可以参考这些文章:

《在游戏中播放音乐》 http://www.easyx.cn/skills/View.aspx?id=44

《将 mp3 以

...

在没有控制台的 Win32 Application 中使用 EasyX 绘图

通常大家学习 VC 都会创建 Win32 Console Application,它的特点就是输入输出简单,调试简单方便。不过对界面要求高的程序有一个控制台窗口似乎并不美观。本文讲怎样在没有控制台的 Win32 Application 中使用 EasyX 绘图。

首先,创建新项目的时候,要选择 Win32 Application 项目。

然后,写主函数的时候,一定要注意,不是 main,而是 WinMain。完整的格式如下:

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	// 在这里写代码

	return 0;
}

这样就是一个没有控制台的、完整的 Win32 程序了。

需要注意的是,因为没有控制台,所以 conio.h 头文件中的函数都不能使用(conio 就是 Console

...

通过 Windows API 获取鼠标位置等状态信息

EasyX 有一个演示鼠标操作的范例程序,这里,我们尝试通过 Windows API 获取鼠标信息。关于 API 的使用都以注释形式写到了程序中,故不再详细讲解,代码如下:

// 程序名称:通过 API 获取鼠标状态
// 编译环境:Visual C++ 6.0 / 2008 / 2010,EasyX 2011惊蛰版
//
#include <graphics.h>
#include <stdio.h>

void main()
{
	initgraph(640, 480);		// 初始化绘图窗口
	HWND hwnd = GetHWnd();		// 获取绘图窗口句柄

	POINT point;
	TCHAR s[10];

	while(true)
	{
		GetCursorPos(&point);			// 获取鼠标指针位置(屏幕坐标)
		ScreenToClient(hwnd, &point);	// 将鼠标指针位置转换为窗口坐标

		// 获取鼠标按
...

将 TC 下的绘图和游戏程序移植到 VC 下

Turbo C(简称tc)是 dos 时代经典的编译器,学习编程时,有很多图形类和游戏类的程序都是用 tc 编写的。由于 c 语言标准的不完善,这些程序大多数都不能直接在 vc 里面编译。本文就讲解怎样将 tc 程序移植到 vc 下。

注:本文以 VC 6.0 为范例(高版本的 vc 大同小异),同时请安装最新版本的 EasyX 图形库。

移植前请注意:

  1. 确保 tc 代码可以正确运行。
  2. 将 tc 代码复制粘贴到 vc 里面。注意,vc 里面代码文件的扩展名要用 .cpp,不能用 .c。
  3. 以下解决办法不分先后顺序,哪条对应就按照哪条修改。
  4. 如果没找到对应的解决办法,可以暂时跳过,先改后面的。可能修改了第 3 条错误,第 2 条错误也就没有了。
  5. 可能解决一个问题后,会出现 10 个新问题,这不要紧。细心、耐心一些,一个一个问题慢慢处理,并不复杂。

以下正文:

错误提示:fatal error C1083: C

...

将 mp3 以资源形式嵌入 exe 中使用

本文讲解怎样将 mp3 等音乐资源以资源形式嵌入 exe 文件中,并通过 mciSendString 调用。嵌入 mp3 和嵌入图片略有不同,将图片嵌入到 exe 中,以及访问嵌入 exe 中的图片,请参考:http://www.easyx.cn/skills/View.aspx?id=6

【一、以资源文件形式嵌入 exe】

关于“资源文件”的介绍和“将 mp3 以资源形式嵌入 exe 文件中”的步骤,请仿照 http://www.easyx.cn/skills/View.aspx?id=6。

【二、播放资源文件中的 mp3】

1. 思路

查看 MSDN 中关于 mciSendString 的使用,发现并不支持直接读取资源文件中的媒体文件,也不支持读取内存中的媒体文件。因此,我们需要提取资源

文件中的 mp3 为成临时文件,然后调用 mciSendString 播放,播放结束后再删掉这个临时文件。

2. 提取资源文件中的为临时文件

...

关于编程中“绝对路径”和“相对路径”的使用

加载图片、音乐等各种文件的时候,都要指定文件路径。通常,可以用绝对路径和相对路径两种方式来指定文件。

先解释一下概念:

  • 绝对路径,就是从盘符开始的路径,例如:“c:\windows\system32\mfc42.dll”。
  • 相对路径,就是从当前路径开始的路径,例如,当前路径是“c:\windows”,那么指定前面范例的文件,可以直接写“system32\mfc42.dll”。
    注意,路径分隔符“\”在 c 语言里面是转义字符,所以表达路径分隔符需要用“\\”。

从功能上讲:

  • 访问每台电脑上路径都固定不变的文件,需要用绝对路径,例如访问 c:\boot.ini。
  • 如果程序所在路径不固定,访问的文件和程序放在一起,就要用相对路径。例如和程序放在一起的图片文件。

在 VC6 的项目中的使用范例:

...

通过程序设置鼠标的样式

在编写程序中(尤其是游戏),有时候需要使用个性的鼠标样式,本文就讲解怎样实现该功能。

实现这个功能需要两步:

  1. 加载鼠标样式,并获取其句柄(HCURSOR);
  2. 设置窗口类的鼠标样式为第一步获取到的句柄。

下面详细解释一下这两步:

一、获取鼠标样式的句柄

使用 API 函数 LoadCursor 实现加载鼠标样式。该函数可以读取系统默认的样式,也可以加载资源形式的 .cur 鼠标样式图片,还可以通过 API 函数 LoadImage 加载文件形式的鼠标样式图片。

涉及到的函数原型如下:

HCURSOR LoadCursor(HINSTANCE hInstance, LPCTSTR lpCursorName);
HMODULE GetModuleHandle(LPCTSTR lpModuleName);
HANDLE LoadImage(HINSTANCE hinst, LPCTSTR l
...