C++第九课:逐步深入[独自思考]

putimage(图片x的坐标,图片y的坐标,IMAGE *srcSource,SRCAND);

SRCAND这里代表绘制出的像素颜色 = 屏幕颜色 AND 图像颜色,与运算规则。

putimage(图片x的坐标,图片y的坐标,IMAGE *srcSource,SRCPAINT);

SRCPAINT这里代表绘制出的像素颜色 = 屏幕颜色 OR 图像颜色,或运算规则。

最后一位参数本是默认过的,也可以不写,但在这里,你添加上这些参数,就能对图像进行操作。

当然还有很多参数,下面罗列出一些,有兴趣的朋友,可以自己查查看,但是能用到的几乎就这SRCAND和SRCPAINT两种。

DSTINVERT 绘制出的像素颜色 = NOT 屏幕颜色

MERGECOPY 绘制出的像素颜色 = 图像颜色 AND 当前填充颜色

MERGEPAINT 绘制出的像素颜色 = 屏幕颜色 OR (NOT 图像颜色)

NOTSRCCOPY 绘制出的像素颜色 = NOT 图像颜色

NOTSRCERASE 绘制出的像素颜色 = NOT (屏幕颜色 OR 图像颜色)

PATCOPY 绘制出的像素颜色 = 当前填充颜色

PATINVERT 绘制出的像素颜色 = 屏幕颜色 XOR 当前填充颜色

PATPAINT 绘制出的像素颜色 = 屏幕颜色 OR ((NOT 图像颜色) OR 当前填充颜色)

SRCCOPY 绘制出的像素颜色 = 图像颜色

SRCERASE 绘制出的像素颜色 = (NOT 屏幕颜色) AND 图像颜色

SRCINVERT 绘制出的像素颜色 = 屏幕颜色 XOR 图像颜色

前面已经能输出图片,下面小编就给图片弄些字体在上面,首先排除中文字,因为在运行后,如果敲击中文字会很麻烦,这里就用字母代替。

下面写到的功能就是从A~Z的字母随机性产生,你敲击一个字母,只要跟图片上显示的字母一致,就让图片消失,然后消失的图片再次重新出现。

既然是随机机制,就需要用到rand()函数:

rand()%6;

这句代码的意思就是随机0-5之中某个数,返回值是int类型,或者char也行。

我们都知道大写字母对应的二进制数是65到90,小写字母对应的二进制数是97到122,不懂的请搜索ASCII编码对照表。

那么我想输出大写的随机字母,该如何写呢?首先要保证它的数值在65~90之中,不能超出也不能低于这些数。

思考的方法,英文字母有多少个?如何让它等于65-90,代码如下:

rand()%26+65;

就是说随机为0的值时,再加上65,是不是等于65了?以此类推,为最高值25时,再加上65,不就是90了吗?

想通了的话,下面就实现代码输出字母的功能。

char m_Output = rand() % 26 + 65;

outtextxy(i + 25, j + 25, output);

outtextxy();三个参数的意思依次是:字母出现的x坐标、y坐标、输出的字

因为考虑到输出的字母要保证在绘制的图形内部,也要考虑到它的坐标问题,所以它放置的位置一定要符合逻辑,传统的思维都是写一段代码让它执行即可,但是编译器它没有思维,我们怎么能让编译器读懂你所写的代码意思呢?

实现代码如下:

char m_Output = rand() % 26 + 65;
for (j = 0; j < background.getheight(); j++)
{

	putimage(0, 0, &background);
	putimage(i, j, &LB2, SRCAND);
	putimage(i, j, &LB1, SRCPAINT);

	outtextxy(i+25,j+25,output);
}

不管行与不行,先运行看看,你会发现字母出现了,但也出现了黑底,问题就需要解决。这里就用到了清除黑底的函数,也就是透明化。

setbkmode(TRANSPARENT);透明化

加在outtextxy()函数下面,保证每次出现图片和字母时都在透明化。

最后就是写出一个功能,敲出同样的字母,使萝卜图消失。

而键盘有两种状态,一个是敲击,还有未敲击。敲击时编译器能得到你所按下键钮的消息,就可以执行下面的操作。

kbhit();就是实现敲击键钮状态的函数

当然有些编译器会报错:The POSIX name for this item is deprecated。Instead, use the ISO C++ conformant name : _kbhit。

意思:这个物品的 posix 名称已经过时了。相反,使用 iso c + + 相符的名称:_kbhit()

还需要引用一个头文件:

#include <conio.h>

这个头文件就是包含了_kbhit()函数

if(_kbhit())  //如果敲击才会执行下面的代码

{

   char cInput = _getch();  //_getch();敲击键盘不需要按回车键

   if(cinput==output || cinput==output+32)  //加上32代表小写字母a-z,也就是97-122

    {

    break;      //当输入的键钮和出现的字母相同,就退出当前循环

    }

}
实现的代码如下:

void InitGame()
{
  //保存图片的对象
  IMAGE background, LB1, LB2;
  //同步
  srand((unsigned int)time(NULL));

  //载入图片
  loadimage(&background, "images//background.jpg", 600, 600);
  loadimage(&LB1, "images//LB1.jpg", 50, 50);
  loadimage(&LB2, "images//LB2.jpg", 50, 50);

  //初始化界面的宽度和高度,在这里用background对象就能获取宽度和高度
  initgraph(background.getwidth(), background.getheight());
  //随机的大写字母
  char output = rand() % 26 + 65;
  int i = rand() % background.getwidth();
  int j = 0;
  for (j = 0; j < background.getheight(); j++)
  {

    putimage(0, 0, &background);
    putimage(i, j, &LB2, SRCAND);
    putimage(i, j, &LB1, SRCPAINT);

    outtextxy(i+25,j+25,output);
    setbkmode(TRANSPARENT);
    if (_kbhit()) //有操作
    {
      char input = _getch();
      if (input == output || input==output+32)
      {
        break;
      }
    }

    sleep(100);    //图片消失后,缓冲一些十分之一秒
  }

}

写好后,就能运行成功一次,当图片消失后,它就不会再重新出现萝卜图了,为什么?因为没有无限循环。

while();先想想放置在哪?

考虑的问题:字母消失后是不是需要再循环?萝卜图是不是需要再循环?萝卜上的字体消失后是不是需要再循环?输入的按钮消息是不是需要再循环?

BeginBatchDraw();双缓冲,作用:减少跳屏

EndBatchDraw();关闭

遥看漫漫长路,任重而道远。

posted @ 2020-01-01 10:48  邪气凛然  阅读(919)  评论(0编辑  收藏  举报