VC绘图/游戏简易教程--7:捕获按键,实现动画的简单控制
2010-4-27 ~ 2021-5-28
(8)
教程总目录: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 毫秒输出一次。按 ESC 退出。
注:ESC 的 ASCII 码是 27。
完整代码如下:
#include <graphics.h>
#include <stdio.h>
#include <conio.h>
int main()
{
char c = 0;
while(c != 27)
{
if (_kbhit())
c = _getch();
else
c = '.';
printf("%c", c);
Sleep(100);
}
return 0;
}
结合上一课的简单动画,就可以做出来靠按键移动的图形了吧,看以下代码,实现 a、d 控制圆的左右移动:
#include <graphics.h>
#include <conio.h>
int main()
{
initgraph(640, 480);
int x = 320;
// 画初始图形
setlinecolor(YELLOW);
setfillcolor(GREEN);
fillcircle(x, 240, 20);
char c = 0;
while(c != 27)
{
// 获取按键
c = _getch();
// 先擦掉上次显示的旧图形
setlinecolor(BLACK);
setfillcolor(BLACK);
fillcircle(x, 240, 20);
// 根据输入,计算新的坐标
switch(c)
{
case 'a': x-=2; break;
case 'd': x+=2; break;
case 27: break;
}
// 绘制新的图形
setlinecolor(YELLOW);
setfillcolor(GREEN);
fillcircle(x, 240, 20);
// 延时
Sleep(10);
}
closegraph();
return 0;
}
[作业]
请继续完成这个程序,实现以下功能:
- 上下的控制;
- 边界检测;
- 结合 kbhit 实现惯性移动(即按一下方向键,圆就会一直向这个方向移动)
注:上下左右等按键的控制,会返回 2 个字符。由于该系列教程面向初学者,因此有兴趣的请查看 MSDN。
#include <conio.h>
int eage(int x,int y) { //返回方向
if (x <= 20)return 180;
else if (x >= 620) return 360;
else if (y <= 20) return 90;
else if (y >= 460) return 270;
else return 0;
}
int main()
{
initgraph(640, 480);
int x = 320;
int y = 240;
// 画初始图形
setlinecolor(YELLOW);
setfillcolor(GREEN);
solidcircle(x, 240, 20);
char c = 0;
int dx = 0, dy = 0;
while (c != 27)
{
// 获取按键
if (_kbhit()) {
c = _getch();
dx= 5, dy = 5;
}
else {
if (!eage(x,y)) ; //未触碰边缘 且没有键入
else dx = 0, dy = 0;
}
// 先擦掉上次显示的旧图形
setlinecolor(BLACK);
setfillcolor(BLACK);
solidcircle(x, y, 20);
// 根据输入,计算新的坐标
//如果到边界,则回退一个,变色
if (eage(x,y)==360) {
setfillcolor(RED);
x -= dx;
}
else if (eage(x, y) == 180) {
setfillcolor(RED);
x += dx;
}
else if (eage(x, y) == 270) {
setfillcolor(RED);
y -= dy;
}
else if (eage(x, y) == 90) {
setfillcolor(RED);
y += dy;
}
else {
setfillcolor(GREEN);
switch (c)
{
case 'a': x -= dx; break;
case 'd': x += dx; break;
case 's': y += dy; break;
case 'w': y -= dy; break;
case 27: break;
}
}
// 绘制新的图形
//setlinecolor(YELLOW);
//setfillcolor(GREEN);
solidcircle(x, y, 20);
// 延时
Sleep(10);
}
closegraph();
return 0;
}
#include <conio.h>
int main()
{
initgraph(640, 480);
int x = 320, y = 240;
// 画初始图形
setlinecolor(YELLOW);
setfillcolor(GREEN);
fillcircle(x, y, 20);
char c = 0;
while (c != 27)
{
// 获取按键
if(_kbhit())
c = _getch();
// 先擦掉上次显示的旧图形
setlinecolor(BLACK);
setfillcolor(BLACK);
fillcircle(x, y, 20);
// 根据输入,计算新的坐标
switch (c)
{
case 'a': x -= 20; break;
case 'd': x += 20; break;
case 's': y += 20; break;
case 'w': y -= 20; break;
case 27: break;
}
// 绘制新的图形
setlinecolor(YELLOW);
setfillcolor(GREEN);
fillcircle(x, y, 20);
// 延时
Sleep(400);
//边界检测,到边界就不动
if (x - 20 == 0 || y - 20 == 0 || x + 20 == 640 || y + 20 == 480)
c = 0;
}
closegraph();
return 0;
}