EasyX图形库note4,动画及键盘交互

简介: EasyX图形库note4,动画及键盘交互

动画

在之前的笔记中,我们所绘制的图形都是静态的,现在我们通过代码让图形动起来。

就像小时候我们看的葫芦娃小金刚一样,动画是由一帧一帧的图片逐个快速播放,利用人的视觉停留,就可以达到动画的效果。一般来说电视每秒播放24帧画面,游戏更高,在打游戏时游戏帧率越高,游戏画面也就越流畅。

用前边的知识绘制一个半径100圆形,窗体大小800*600,圆心初始坐标为(-400,0)。颜色可以自己选择。

  • 要实现像动画一样逐帧播放,我们可以不断改变圆心的x坐标,更改后清除上一次画的圆形,然后重新画出位置变化的圆形,同时要使用Sleep()函数暂停程序一段时间。

代码如下

int main()
{
  initgraph(800,600);
  setbkcolor(RGB(150, 205, 205));
  cleardevice();
  setorigin(400, 300);
  setaspectratio(1, -1);
  setfillcolor(RGB(106, 90, 205));
  int dx = 15;
  for (int x = -400; x <= 400; x += dx)
  {
    solidcircle(x, 0, 100);
    Sleep(200);
    cleardevice();
  }
  getchar();
  return 0;
}

画出一个圆形后,Sleep200毫秒,清空屏幕后画出下一个,再Sleep200毫秒。直到运动到最右端循环结束,getchar阻塞进程。

运行后效果如下

因为休眠函数在每次循环时休眠200毫秒,所以在一秒内可以播放五帧画面,每次移动的距离为15像素,所以圆形的移动速度为每秒75像素。

如果想让画面更加流畅,然而圆形的移动速度几乎不变,就要加大帧率,减小每次移动的像素。

  • 将休眠时间改为50毫秒,将每次移动的像素即dx设置为5。
    运行后效果如图

    对比上边流畅很多。

键盘交互

在动画的基础上,加入键盘交互功能,按下w键,圆形向上移动,按下a键,圆形向左移动,按下d键,圆形向右移动,按下s键,圆形向下移动。

首先如何从键盘上读取信息?

我们会想到使用getchar函数,有了思路就开始编写代码实现按下w键,圆形向上移动50像素。

int main()
{
  initgraph(800,600);
  setbkcolor(RGB(150, 205, 205));
  cleardevice();
  setorigin(400, 300);
  setaspectratio(1, -1);
  int x = 0;
  int y = 0;
  setfillcolor(GREEN);
  solidcircle(x, y, 50);//画出圆形
  while (1)
  {
    char c = getchar();
    if (c == 'w')
    {
      y += 50;
    }
    cleardevice();//清除窗体
    solidcircle(x, y, 50);//画出圆形
  }
  getchar();
  return 0;
}

编写完成后运行代码,发现按下’w’键没有任何反应,按下回车后才会向上移动,而且点击n次w键,会直接向上移动n*50像素。这是为什么呢?

  • 让我们深入了解一下getchar函数

getchar函数从输入缓存区中读取一个字符,如果读取成功,就返回读取到的字符,如果缓存区中没有数据,函数将会阻塞进程,直到缓存区里有数据。

在控制台上输入数据,但数据还没有进入输入缓存区,需要按下回车键,才会将输入的全部数据放在缓存区,然后getchar函数取出第一个字符并返回这个字符。若在循环中,getchar会依次取出这些数据,直到没有数据为止。

我们想让动画和键盘交互组合,但getchar函数明显不满足需求,想要实现实时型交互,按下键盘后程序就作出反应,而不是按下回车后才运行,运行之后又堵塞。


这里就要提到getch函数


无需回车,只需要按下键盘就可以将数据送进输入缓存区。

别忘记包含头文件<conio.h>

写一串代码探究其特性

注:在使用getch函数时,要写成_getch的形式。

代码如下

#include <conio.h>
int main()
{
  while (1)
  {
    char c;
    c = _getch();
    putchar(c - 32);
  }
  return 0;
}

运行后输入小写a就直接在控制台打印出A,输入b就直接打印B。

解决了回车问题,我们想在圆形移动的时候就可以控制圆移动的方向,而getch仍然具有阻塞程序运行的作用。这种用户输入之后场景才发生变化的适合推箱子游戏,2048等,然而对于就算没有输入整个场景仍然会变化的场景则不适用。

介绍一下函数kbhit

int kbhit(void);

kbhit函数会检查getch函数的输入缓存区中是否有数据,若没有数据就返回0,如果有数据就返回非0的数。

这个函数不会阻塞程序的运行,可以借此判断是否用户按下了键盘,然后再做出反应,这样就不会阻塞程序的运行。kbhit函数也要写作_kbhit。


对前边的圆形动画做出改变,加上键盘交互功能。

代码如下

int main()
{
  initgraph(800, 600);
  setbkcolor(RGB(150, 205, 205));
  cleardevice();
  setorigin(400, 300);
  setaspectratio(1, -1);
  setfillcolor(RGB(106, 90, 205));
  int x = -400, y = 0;
  int dx = 5 , dy=0;
  while (1)
  {
    cleardevice();
    solidcircle(x, y, 50);
    Sleep(40);
    if (_kbhit() != 0)
    {
      char c = _getch();
      switch (c)
      {
      case'w':
        dx = 0;
        dy = 5;
        break;
      case'a':
        dx = -5;
        dy = 0;
        break;
      case's':
        dx = 0;
        dy = -5;
        break;
      case'd':
        dx = 5;
        dy = 0;
        break;
      }
    }
    x =x+ dx;
    y =y+ dy;
  }
  getchar();
  return 0;
}

起始位置在最左边,刚开始设置dx为5,即圆形向右移动,只有我们按下键盘才会进入switch语句,更改dx与dy的值,从而实现在运动中改变运动的方向。

运行后效果如下

接下来会用今天所学的知识来实现一个简单的弹球小游戏。希望大家有所收获。

目录
相关文章
QT+OpenGL鼠标操作和模型控制
光线追踪法 从鼠标投射 3D 射线, 通过摄像机,进入场景,然后检查该光线是否与某个对象相交。
348 0
|
图形学
unity3d UGUI常用游戏进度条实现方式
测试.png 直接将脚本挂载到进度条image对象上即可,这种方式可以解决当进度条使用图片的时候,防止图片拉伸变形 using UnityEngine; using UnityEngine.
3009 0
|
3月前
QML 界面切换的方法
QML 界面切换的方法
212 1
|
6月前
|
存储 编解码 Windows
EasyX图形库学习(三、用easyX控制图形界面中的小球、图片-加载、输出)
EasyX图形库学习(三、用easyX控制图形界面中的小球、图片-加载、输出)
|
6月前
|
API C语言 图形学
EasyX图形库学习(一、窗口创建函数initgraph、背景颜色设置setbkcolor、图形绘制函数)
EasyX图形库学习(一、窗口创建函数initgraph、背景颜色设置setbkcolor、图形绘制函数)
|
开发者 Windows
EasyX趣味化编程note2,绘制基本图形(上)
EasyX趣味化编程note2,绘制基本图形
71 0
EasyX趣味化编程note2,绘制基本图形(下)
EasyX趣味化编程note2,绘制基本图形(上)
135 0
Easyx图形库趣味编程note3,颜色模型
Easyx图形库趣味编程note3,颜色模型
110 0
|
C语言 C++ Windows
利用EasyX图形库实现趣味化编程note1
利用EasyX图形库实现趣味化编程note1
67 0