BestAns

路漫漫其修远兮,吾将上下而求索

VC绘图/游戏简易教程--6:实现简单动画 铜牌收录

教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括VC下的graphics.h的配置方法)

所谓动画,其实是连续显示一系列图形而已。
结合到程序上,我们需要以下几个步骤:

  1. 绘制图像
  2. 延时
  3. 擦掉图像

循环以上即可实现动画。

举一个例子,我们实现一条直线从上往下移动:

#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);

		// 绘制黑色直线(即擦掉之前画的绿线)
		setlinecolor(BLACK);
		line(0, y, 639, y);
	}

	closegraph();
	return 0;
}

再看一个例子,实现一个圆从左往右跳动:

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

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

	for(int x = 100; x < 540; x += 20)
	{
		// 绘制黄线、绿色填充的圆
		setlinecolor(YELLOW);
		setfillcolor(GREEN);
		fillcircle(x, 100, 20);

		// 延时
		Sleep(500);

		// 绘制黑线、黑色填充的圆
		setlinecolor(BLACK);
		setfillcolor(BLACK);
		fillcircle(x, 100, 20);
	}

	closegraph();
	return 0;
}

也就是说,移动的间距小、延时短,动画就会越细腻。但当画面较复杂时,会带来画面的闪烁(怎样消除闪烁是以后的话题)。

[作业]
绘制一个沿 45 度移动的球,碰到窗口边界后反弹。

评论 (9) -

  • #include <graphics.h>
    #include <conio.h>
    int main()
    {
      int x=10, y=10,dx=2,dy=2;
      initgraph(800, 600);
      while (true) {
        solidcircle(x, y, 10);
        Sleep(10);
        clearcircle(x, y, 10);
        x += dx;
        y += dy;
        if (x >= 790||x<=10)
          dx=- dx;
        if (y >= 590||y<=10)
          dy=- dy;
        if (_kbhit())
          break;
      }
      closegraph();
      return 0;
    }
  • //小球沿随机的初始方向(pi/4,3*pi/4,5*pi/4,7*pi/4)发射,遇到屏幕边缘则以与入射角相同的反射角反弹
    #include <graphics.h>
    #include <conio.h>
    #include <cstdlib>
    #include <time.h>
    int main()
    {
      initgraph(640, 480);
      int x = 100, y = 100;
      int r = 16;
      int i = 4; //x每次移动的距离
      int j = 4; //y每次移动的距离

      srand(time(0));
      int direction = rand() % 4; /*构建随机初始方向(共四个方向)
      1 | 0
      — —
      2 | 3
      */
      while (!(x <= r && y <= r) || !(x <= r && y >= 479-r) || !(x >= 639 - r && y <= r) || !(x >= 639 - r && y >= 479 - r))
      {
        // 绘制黄线、绿色填充的圆
        setlinecolor(YELLOW);
        setfillcolor(GREEN);
        fillcircle(x, y, 20);

        // 延时
        Sleep(20);

        // 绘制黑线、黑色填充的圆
        setlinecolor(BLACK);
        setfillcolor(BLACK);
        fillcircle(x, y, 20);

        switch (direction)
        {
        case 0:
          if (y <= r)
          {
            direction = 3;
            break;
          }
          if (x >= 639 - r)
          {
            direction = 1;
            break;
          }
          i = 1;
          j = -1;
          break;
        case 1:
          if (y <= r)
          {
            direction = 2;
            break;
          }
          if (x <= r)
          {
            direction = 0;
            break;
          }
          i = -1;
          j = -1;
          break;
        case 2:
          if (y >= 479 - r)
          {
            direction = 1;
            break;
          }
          if (x <= r)
          {
            direction = 3;
            break;
          }
          i = -1;
          j = 1;
          break;
        case 3:
          if (y >= 479 - r)
          {
            direction = 0;
            break;
          }
          if (x >= 639 - r)
          {
            direction = 2;
            break;
          }
          i = 1;
          j = 1;
          break;
        }
        x = x + i*r;
        y = y + j*r;
      }
      closegraph();
      return 0;
    }
  • #include <graphics.h>
    #include <conio.h>

    int main()
    {
      initgraph(640, 480);
      int i = 1, j = 1;
      for (int x = 100,y = 240; ; x += i * 20, y -= j * 20 )
      {
        // 绘制白线、蓝色填充的圆
        setlinecolor(WHITE);
        setfillcolor(LIGHTBLUE);
        fillcircle(x, y, 20);

        // 延时
        Sleep(500);

        // 绘制黑线、黑色填充的圆
        setlinecolor(BLACK);
        setfillcolor(BLACK);
        fillcircle(x, y, 20);

        //碰倒窗口边界后反弹
        if (y - 20 == 0 || y + 20 == 480)
          j *= -1;
        if (x + 20 == 640 || x - 20 == 0)
          i *= -1;
      }

      closegraph();
      return 0;
    }
    //bug是没有办法按任意键退出,因为是无限循环
  • int x = 20, y = 20, i = 1,j=1;
      while(1){
        // 绘制圆
        setlinecolor(YELLOW);
        setfillcolor(BLUE);
        if (x+20<=640 && y+20<=480) {
          fillcircle(x, y, 20);
          // 延时
          Sleep(10);
          //绘制黑色直线(即擦掉之前画的绿线)
          setlinecolor(BLACK);
          setfillcolor(BLACK);
          fillcircle(x, y, 20);
          x = x + i; y = y + j;
        }
        if (y + 20 == 480) {
          j--;
        }
        if (x + 20==640) {
          i--;
        }
        if (x==20) {
          i++;
        }
        if (y==20) {
          j++;
        }

      }
  • 按这种方法如何解决绘图闪烁的问题呢
  • //绘制一个沿45°移动的球,碰到窗口界面后反弹
    #include <graphics.h>
    #include <conio.h>
    int main()
    {
      initgraph(640, 480);
      int x=20,y=20,i=1,j=1;
      
        for(x,y; (x <= 620)&&(y <= 460); x+=i,y+=j)
        {   // 绘制黄线、绿色填充的圆
          setlinecolor(YELLOW);
          setfillcolor(GREEN);
          fillcircle(x,y, 20);
          Sleep(5);// 延时
          // 绘制黑线、黑色填充的圆
          setlinecolor(BLACK);
          setfillcolor(BLACK);
          fillcircle(x,y, 20);      
          if(x==20){i=1;} else if(x==620){i=-1;}
          if(y==20){j=1;} else if(y==460){j=-1;}
          if((x==310)&&(y==230)){
            setlinecolor(YELLOW);
            setfillcolor(GREEN);
            fillcircle(x,y, 20);
            break;            }
        }  
        for(int k=0;k<621;k++)
        {
          setlinecolor(RED);
          setfillcolor(YELLOW);
          fillcircle(310,230, k);    
          Sleep(5);// 延时
        }
      _getch();
      closegraph();
      return 0;
    }
  • //绘制一个沿45°移动的球,碰到窗口界面后反弹
    #include<graphics.h>
    #include<conio.h>
    void main()
    {
      initgraph(640,640);
      int x,y;
      for(x=320,y=320;y>40;x+=40,y-=40)
      {
        setfillcolor(RED);
        setlinecolor(BLUE);
        fillcircle(x,y,40);
        Sleep(200);
        setfillcolor(BLACK);
        setlinecolor(BLACK);
        fillcircle(x,y,40);
      }
      for(;x>320;x-=40,y+=40)
      {
        setfillcolor(RED);
        setlinecolor(BLUE);
        fillcircle(x,y,40);
        Sleep(200);
        setfillcolor(BLACK);
        setlinecolor(BLACK);
        fillcircle(x,y,40);
      }
      _getch();
      closegraph();
    }
  • #include<graphics.h>
    #include<conio.h>
    void main()
    {
         initgraph( 600 , 600 );
       for(int x=100,y=400;y>0;x+=5,y-=5)
       {
       setlinecolor(GREEN);
       circle(x,y,50);
      
       Sleep(50);
      
         setlinecolor(BLACK);
       circle(x,y,50);
       if(y==0)
       for(int x=500,y=0;x<600;x+=5,y+=5)
       {
       setlinecolor(GREEN);
       circle(x,y,50);
      
       Sleep(200);
      
         setlinecolor(BLACK);
       circle(x,y,50);
       }
        
       }
      
      
       _getch();
         closegraph();
    }
    老哥,我这个为啥碰到窗口就消失了啊,程序没有提示error,我感觉if里的错了

添加评论