VC绘图/游戏简易教程--16:设备上下文句柄(Windows 编程入门2)

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法)

注:学习本节前,请自备 MSDN,以便查阅 Windows GDI 函数。

EasyX的绘图函数最初是模仿的BGI的函数命名。为了让大家借此学习 Windows GDI 绘图,EasyX 增加了获取 HDC 句柄的功能。

对于 Windows GDI 中的绘图函数,很多都需要一个 HDC 句柄。我们用 GetImageHDC() 函数获取该句柄,然后就可以使用 Windows GDI 了。先看看例子吧:

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

void main()
{
	// 初始化绘图窗口,并获取HDC句柄
	initgraph(640, 480);
	HDC hdc = GetImageHDC();

	// 以下是标准Windows G
...

VC绘图/游戏简易教程--15:窗体句柄(Windows 编程入门)

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法)

EasyX 库有一个获取窗口句柄的功能,很是强大,这里介绍一下。

【窗体句柄】

窗体句柄是 Windows 下窗口的标识,可以理解为窗口的 ID。Windows SDK 中的许多窗口操作函数都需要指明窗体句柄,也就是说,有了句柄,我们可以通过 Windows SDK 中的 API 实现许多高级的窗体控制。

【函数原型】

窗体句柄为 HWND 类型,通过 GetHWnd() 函数可以返回绘图窗体的句柄。其函数原型是:
HWND GetHWnd();

【使用句柄】

举个例子,设置窗体标题文字的 Windows API 为:
BOOL SetWindowText(HWND hWnd, LPCTSTR lpString);
参数:
   hWnd: 要设置标题文字的窗口句柄

...

VC绘图/游戏简易教程--14:通过位运算实现颜色的分离与处理

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法)

本节课要求熟练掌握位运算,详见:
http://hi.baidu.com/bestans/blog/item/fb75b439404876e614cecb9f.html

[颜色基础]

在 EasyX 库中,颜色是一个 int 类型的数据,转换为 16 进制后的颜色格式是 0xbbggrr,其中,bb/gg/rr 分别表示两位十六进制的蓝/绿/红颜色值,每种颜色的范围是 0x0~0xff,转换为十进制就是 0~255。

举几个颜色标示的例子:

  • 颜色  直接表示  RGB 宏标示
  • 纯绿色 0x00ff00  RGB(0, 255, 0)
  • 青色  0xffff00  RGB(0, 255, 255)  注:青=蓝+绿
  • 中灰色 0x7f7f7f  RGB(

...

VC绘图/游戏简易教程--13:getimage / putimage / loadimag / saveimage / IMAGE 的用法

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法)

 getimage / putimage / loadimage / saveimage 这一组命令和 IMAGE 对象可以实现图像处理的相关功能,下面逐个介绍。
(有点类似 tc 中的 imagesize)

[加载图片]

实现加载图片主要分三步:
1. 定义 IMAGE 对象
2. 读取图片至 IMAGE 对象
3. 显示 IMAGE 对象到需要的位置

很简单,我们看一下完整的代码:

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

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

	IMAGE img;	// 定义 IMAGE 对象
	loadimage(&

...

VC绘图/游戏简易教程--12:数组

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法) 

课程要求:先复习下课本上对数组的讲解(随便一本教材都行)

[一维数组]
数组可以实现批量操作。比如,我们产生 10 个随机数,产生后先保存起来,然后输出最大的:

	int n[10];
	int i;
	for (i=0; i<10; i++)
		n[i] = rand() % 1000;

	// 按生成的顺序,逆序输出
	for (i=9; i>=0; i--)
		printf("%d\n", n[i]);

	// 找出最大的
	int max = -1;
	for (i=0; i<10; i++)
	{
		if (n[i] > max)
			max = n[i];
	}

	printf("最大的数字是:%d\n", max);

...

VC绘图/游戏简易教程--11:随机函数

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法)

[随机函数简介]
游戏中,许多情况都是随即发生的。还有一些图案程序,例如屏保,也是随即运动的。这就需要用随机函数。

随机函数很简单,只有一个:
rand()
该函数返回 0~32767 之间的一个整数。(不需要记住 32767 这个数字,大概知道这个范围就行了)
该函数在头文件 <stdlib.h> 中,使用前记得引用。

[简单测试]

#include <stdio.h>
#include <stdlib.h>

void main()
{
	int r;
	for(int i=0; i<10; i++)
	{
		r = rand();
		printf("%d\n", r);
	}
}

执行后,

...

VC绘图/游戏简易教程--10:用鼠标控制绘图/游戏程序

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法)

学习本节课前,需要熟练掌握第 7 节。详见:http://www.easyx.cn/skills/View.aspx?id=21

==本节课开始==

捕获鼠标消息就像捕获按键消息一样简单。
对于按键,通常我们会先检查是否有按键,然后定义一个变量保存按键,再然后根据该按键的值,执行相应的程序。
对于鼠标,道理是一样的。

先写个代码对比一下:

获取按键:               获取鼠标:
  char c;               &

...

VC绘图/游戏简易教程--9:绘图中的位运算

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法)

========================

位运算和绘图有什么关系?先举个例子来个感性认识:使用XOR运算可以实现擦除图形后不破坏背景,这在时钟程序中绘制表针是很有用的。稍后我们会给出这样的例子。

一、位运算的运算法则

位运算主要分 4 种:NOT、AND、OR、XOR,位运算的运算对象是二进制数(十进制要转换为二进制,计算机会自动转换)。

运算法则如下:

1. NOT

表示“取反”,将二进制位的 1 变 0、0 变 1。
C 语言用符号 ~ 表示。

如:
二进制: ~1101 = 0010
用十进制表示就是:~13 = 2

2. AND

表示“并且”,只有两数的对应二进制位都为 1,结果的二进制位才为

...

VC绘图/游戏简易教程--8:用函数简化相同图案的制作

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法)

实际中有许多类似的图案,如果一一单独绘制,太麻烦。于是,我们需要一个公用的绘制过程,就是函数。

例如,我们需要画5个三角形,位于不同的位置。我们可以将绘制单个三角形的过程写成函数,函数内是一个独立的程序段,这个绘制过程很简单。
然后,在需要绘制的时候,调用这个函数即可。可以通过参数来解决细微差异(图案的坐标、颜色等),例如:

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

// 在坐标 (x,y) 处,用颜色 c 绘制三角形
void sanjiaoxing(int x, int y, int c)
{
	// 设置画线颜色
	setlinecolor(c);

	// 画三角形的三条边
	line(x, y, x+50, y);
	line(x, y, 

...

VC绘图/游戏简易教程--7:捕获按键,实现动画的简单控制

教程总目录:http://www.easyx.cn/skills/View.aspx?id=45 (里面包括VC下的graphics.h的配置方法)

最常用的一个捕获按键的函数:getch()
前几课,都把这个函数当做“按任意键继续”来用,现在我们用变量保存这个按键:

char c = getch();

然后再做判断即可。

不过程序执行到 getch() 是会阻塞的,直到用户有按键才能继续执行。可游戏中总不能因为等待按键而停止游戏执行吧?所以,要有一个函数,判断是否有用户按键:kbhit()
这个函数返回当前是否有用户按键,如果有,再用 getch() 获取即可,这样是不会阻塞的。

即:

char c;
if (kbhit())
	c = getch();

举一个简单的例子,如果有按键,就输出相关按键。否则,输出“.”。每隔 100

...