VC绘图/游戏简易教程--16:设备上下文句柄(Windows 编程入门2)
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括VC下的graphics.h的配置方法)
注:学习本节前,请自备 MSDN,以便查阅 Windows GDI 函数。
对于 Windows GDI 中的绘图函数,操作目标通常是 DC(Device Context),因此需要传入一个 DC 的句柄,数据类型为 HDC(Handle of Device Context)。用 GetImageHDC() 函数可以获取 EasyX 的绘图窗口或 IMAGE 对象的句柄,然后就可以使用 Windows GDI 函数进行绘图操作。看以下示例:
#include <graphics.h>
#include <conio.h>
int main()
{
// 初始化绘图窗口,并获取 HDC 句柄
initgraph(640, 480);
HDC hdc = GetImageHDC();
...
钟表模拟程序(表针形式)
这是个简单的表针式时钟模拟程序。
运行效果如下:
在源代码的基础上,可以通过 API 函数 mciSendString 轻松加上滴答声音,我就不再多写了。
代码如下:
////////////////////////////////////////////
// 程序名称:钟表模拟程序(表针形式)
// 编译环境:Visual C++ 6.0 ~ 2019,EasyX_20210730
// 程序编写:BestAns <BestAns@qq.com>
// 最后更新:2010-10-30
//
#include <graphics.h>
#include <conio.h>
#include <math.h>
#define PI 3.1415926536
void DrawHand(int hour, int minute, int second)
{
double a_hour, a_min,
...
VC绘图/游戏简易教程--15:窗体句柄(Windows 编程入门)
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括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:通过位运算实现颜色的分离与处理
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括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(12
VC绘图/游戏简易教程--13:getimage / putimage / loadimag / saveimage / IMAGE 的用法
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括VC下的graphics.h的配置方法)
getimage / putimage / loadimage / saveimage 这一组命令和 IMAGE 对象可以实现图像处理的相关功能,下面逐个介绍。
(有点类似 tc 中的 imagesize)
[加载图片]
实现加载图片主要分三步:
- 定义 IMAGE 对象
- 读取图片至 IMAGE 对象
- 显示 IMAGE 对象到需要的位置
很简单,我们看一下完整的代码:
#include <graphics.h>
#include <conio.h>
int main()
{
initgraph(640, 480);
IMAGE img; // 定义 IMAGE 对象
...
VC绘图/游戏简易教程--12:数组
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括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("最大的数字是
...
VC绘图/游戏简易教程--11:鼠标控制及高级按键控制
教程总目录:https://codebus.cn/bestans/concise-lesson-contents(里面包括VC下的graphics.h的配置方法)
学习本节课前,需要熟练掌握第 7 节。详见:https://codebus.cn/bestans/concise-lesson-7
==本节课开始==
首先,获取鼠标消息:
ExMessage m;
m = getmessage();
ExMessage 是 EasyX 定义的一个表示消息的结构体类型,以上代码表示用该类型声明了一个变量 m,然后通过 getmessage 函数获取消息,并返回给变量 m。根据 m 的内容,进一步分析获取到的是什么消息。鼠标消息可以通过以下成员获取鼠标消息中的信息:
USHORT message; // 当前消息
bool ctrl; // Ctrl 键是否按下
...
VC绘图/游戏简易教程--10:绘图中的位运算
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括VC下的graphics.h的配置方法)
========================
位运算和绘图有什么关系?先举个例子来个感性认识:使用XOR运算可以实现擦除图形后不破坏背景,这在时钟程序中绘制表针是很有用的。稍后我们会给出这样的例子。
一、位运算的运算法则
位运算主要分 4 种:NOT、AND、OR、XOR,位运算的运算对象是二进制数(十进制要转换为二进制,计算机会自动转换)。
运算法则如下:
- NOT
表示“取反”,将二进制位的 1 变 0、0 变 1。
C 语言用符号 ~ 表示。
如:
二进制: ~1101 = 0010
用十进制表示就是:~13 = 2
- AND
表示“并且”,只有两数的对应
...VC绘图/游戏简易教程--9:用函数简化相同图案的制作
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents
实际中有许多类似的图案,如果一一单独绘制,太麻烦。于是,我们需要一个公用的绘制过程,就是函数。
例如,我们需要画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, x, y+50);
line(x
...
VC绘图/游戏简易教程--8:随机函数
VC绘图/游戏简易教程--7:捕获按键,实现动画的简单控制
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括VC下的graphics.h的配置方法)
最常用的一个捕获按键的函数:_getch()
前几课,都把这个函数当做“按任意键继续”来用,现在我们用变量保存这个按键:
char c = _getch();
然后再做判断即可。
不过程序执行到 _getch() 是会阻塞的,直到用户有按键才能继续执行。可游戏中总不能因为等待按键而停止游戏执行吧?所以,要有一个函数,判断是否有用户按键:_kbhit()
这个函数返回当前是否有用户按键,如果有,再用 _getch() 获取即可,这样是不会阻塞的。
即:
char c;
if (_kbhit())
c = _getch();
举一个简单的例子,如果有按键,就输出相关按键。否则,输出“.”。每隔 100 毫秒输出一次
...VC绘图/游戏简易教程--6:实现简单动画
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括VC下的graphics.h的配置方法)
所谓动画,其实是连续显示一系列图形而已。
结合到程序上,我们需要以下几个步骤:
- 绘制图像
- 延时
- 擦掉图像
循环以上即可实现动画。
举一个例子,我们实现一条直线从上往下移动:
#include <graphics.h>
#include <conio.h>
int main()
{
initgraph(640, 480);
for(int y = 0; y < 480; y++)
{
// 绘制绿色直线
setlinecolor(GREEN);
line(0, y, 639, y);
// 延时
Sleep(10);
// 绘制黑色直线(即擦掉之
...
VC绘图/游戏简易教程--5:数学知识在绘图中的运用
VC绘图/游戏简易教程--4:结合流程控制语句来绘图
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括VC下的graphics.h的配置方法)
[学习目标]
熟练使用循环、判断语句
[熟悉for语句]
这步需要自学,看看自己手边的书,是怎样讲for语句的,简单看看就行。
[范例]
例如,画10条直线的代码:
#include <graphics.h>
#include <conio.h>
int main()
{
initgraph(640, 480);
for(int y=100; y<200; y+=10)
line(100, y, 300, y);
_getch();
closegraph();
return 0;
}
换一下循环的范围和间隔,看看效果。
还可以用来画渐变色,例如:
...