Allegro学习笔记十

http://wiki.allegro.cc/AllegroExamples 以上是英文例子站点。

by Shawn Hargreaves,allegro的作者

目录: 1 Allegro 例子

1.1 exhello
1.2 exmem
1.3 expat
1.4 expal
1.5 exflame
1.6 exbuf
1.7 exflip
1.8 exfixed
1.9 exfont
1.10exmouse

这个例子展示了如何处理鼠标输入。
在第1个部分,鼠标被隐藏了,但是相关的信息都显示在了屏幕上。
如果你按下任何键盘按键,基本的“箭头”图表就显示在屏幕上。
你并不是只能使用这个形状,当你再次按下键盘按键的时候,
默认的鼠标形状就变成了一组彩色的同心圆。
这些演示部分并不是组合在一起的,所以你可以通过显示在屏幕上的
信息来观察当你移动或按下鼠标的时候一些状态的改变。


#include <stdio.h>

#include <allegro.h>

 

static void print_all_buttons(void)
{
   int i;
   int fc = makecol(0, 0, 0);
   int bc = makecol(255, 255, 255);
   textprintf_right_ex(screen, font, 320, 50, fc, bc, "buttons");
   for (i = 0; i < 8; i++) {
      int x = 320;
      int y = 60 + i * 10;
      if (mouse_b & (1 << i))
         textprintf_right_ex(screen, font, x, y, fc, bc, "%2d", 1 + i);
      else
         textprintf_right_ex(screen, font, x, y, fc, bc, "  ");
   }
}

 

int main(void)
{
   int mickeyx = 0;
   int mickeyy = 0;
   BITMAP *custom_cursor;
   int c = 0;

   if (allegro_init() != 0)
      return 1;
   install_keyboard();
   install_timer();

   if (set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0) != 0) {
      if (set_gfx_mode(GFX_SAFE, 320, 200, 0, 0) != 0) {
  set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
  allegro_message("Unable to set any graphic mode/n%s/n", allegro_error);
  return 1;
      }
   }

   set_palette(desktop_palette);
   clear_to_color(screen, makecol(255, 255, 255));

   /* Detect mouse presence */
   if (install_mouse() < 0) {
      textout_centre_ex(screen, font, "No mouse detected, but you need one!",
   SCREEN_W/2, SCREEN_H/2, makecol(0, 0, 0),
   makecol(255, 255, 255));
      readkey();
      return 0;
   }

   textprintf_centre_ex(screen, font, SCREEN_W/2, 8, makecol(0, 0, 0),
   makecol(255, 255, 255),
   "Driver: %s", mouse_driver->name);

   do {
      /* 在大多数平台(例如DOS)即使不调用这个函数,(鼠标)仍然工作的很好
       * 但是如果你想让自己的程序变得更加通用,调用它不失为一个非常好的
       * 主意,因为在一些平台上,你不调用的话说不定得不到任何鼠标输入
       */
      poll_mouse();

      acquire_screen();

      /* 鼠标的坐标信息已经被自动保存到变量mouse_x 和mouse_y */
      textprintf_ex(screen, font, 16, 48, makecol(0, 0, 0),
      makecol(255, 255, 255), "mouse_x = %-5d", mouse_x);
      textprintf_ex(screen, font, 16, 64, makecol(0, 0, 0),
      makecol(255, 255, 255), "mouse_y = %-5d", mouse_y);

      /* 或者你可以使用这个函数来测量鼠标的速度。
       * 注意我们每4个周期检测1次:所以你没必要降低这个数字(4),
       * 以便让你有时间去“阅读”它们当前的值。(就是说变的太快了)
       */
      c++;
      if ((c & 3) == 0)
  get_mouse_mickeys(&mickeyx, &mickeyy);

      textprintf_ex(screen, font, 16,  88, makecol(0, 0, 0),
      makecol(255, 255, 255), "mickey_x = %-7d", mickeyx);
      textprintf_ex(screen, font, 16, 104, makecol(0, 0, 0),
      makecol(255, 255, 255), "mickey_y = %-7d", mickeyy);

      /* 按键的状态信息被储存在了变量 mouse_b */
      if (mouse_b & 1)
  textout_ex(screen, font, "left button is pressed ", 16, 128,
      makecol(0, 0, 0), makecol(255, 255, 255));
      else
  textout_ex(screen, font, "left button not pressed", 16, 128,
      makecol(0, 0, 0), makecol(255, 255, 255));

      if (mouse_b & 2)
  textout_ex(screen, font, "right button is pressed ", 16, 144,
      makecol(0, 0, 0), makecol(255, 255, 255));
      else
  textout_ex(screen, font, "right button not pressed", 16, 144,
      makecol(0, 0, 0), makecol(255, 255, 255));

      if (mouse_b & 4)
  textout_ex(screen, font, "middle button is pressed ", 16, 160,
      makecol(0, 0, 0), makecol(255, 255, 255));
      else
  textout_ex(screen, font, "middle button not pressed", 16, 160,
      makecol(0, 0, 0), makecol(255, 255, 255));

      /* 滚轮的位置信息被储存在了变量 mouse_z */
      textprintf_ex(screen, font, 16, 184, makecol(0, 0, 0),
      makecol(255, 255, 255), "mouse_z = %-5d mouse_w = %-5d", mouse_z, mouse_w);

      print_all_buttons();

      release_screen();

      vsync();

   } while (!keypressed());

   clear_keybuf();

   /*  显示鼠标使用show_mouse().
    *  这里有一些事情是在你调用它之前应该做的.
    *  首先在响应鼠标之前必须调用install_timer()
    *  然后在绘制位图之前应该隐藏鼠标show_mouse(NULL);
    *  绘制完成了再显示出来
    */
   clear_to_color(screen, makecol(255, 255, 255));
   textout_centre_ex(screen, font, "Press a key to change cursor",
       SCREEN_W/2, SCREEN_H/2, makecol(0, 0, 0),
       makecol(255, 255, 255));
   show_mouse(screen);
   readkey();
   show_mouse(NULL);

   /* 创建一个自定义鼠标位图... */
   custom_cursor = create_bitmap(32, 32);
   clear_to_color(custom_cursor, bitmap_mask_color(screen));
   for (c=0; c<8; c++)
      circle(custom_cursor, 16, 16, c*2, palette_color[c]);

   /* 加载自定义鼠标位图,并且将鼠标焦点设置为位图的正中心 */
   set_mouse_sprite(custom_cursor);
   set_mouse_sprite_focus(16, 16);

   clear_to_color(screen, makecol(255, 255, 255));
   textout_centre_ex(screen, font, "Press a key to quit", SCREEN_W/2,
       SCREEN_H/2, makecol(0, 0, 0), makecol(255, 255, 255));
   show_mouse(screen);
   readkey();
   show_mouse(NULL);

   destroy_bitmap(custom_cursor);

   return 0;
}

END_OF_MAIN()
---------------------------------------------------------------------
小节10:
1、if (mouse_b & (1 << i)); i = 0~7;
mouse_b & (1 << i)  = BUTTONDOWN;鼠标按键是否被按下(而不是点击click)
allegro一次提取全部的鼠标按键信息,使用者必须手动拆分。
关于1 << i:
1   00000001  左键
2   00000010  右键
4   00000100  中键
8   00001000  不知道
16  00010000  不知道
32  00100000  不知道
64  01000000  不知道
128 10000000  不知道

这样设计的目的是保证一些特定的值对应特定的按键状态组合,如3=左+右,6=右+中。但是mouse_b只提供一个
2、poll_mouse();
这是一个4.22新加入的函数,为的是在某些平台上更好的支持鼠标,是Allegro为自身跨平台性的一个扩展。只需要在处理鼠标输入信息之前调用就可以了。

3、变量mouse_x 和mouse_y;
还有许多其他类似变量,这些变量在发生系统时钟中断(或Allegro时钟中断)的时候被更新。
PS:我认为可能存在这些标志信息与实际的按键/状态有偏差,导致这种偏差的原因是代码执行需要花费时间,而如果判断一组标志量的代码跨时间片执行的话,可能就会出现这个问题。但是实际使用中发生这个问题的可能性非常小,并且我坚信Shawn Hargreaves设计Allegro的时候就解决这个问题:要么在我不知道的地方Allegro正做着处理,要么Shawn Hargreaves证明了在他这个架构下,是不会出现我说的那种问题。只是我现在还没有发现...所以现在只需要把mouse_b中的信息当成实时信息就可以了(看成消息吧~)。

4、c++;
   if ((c & 3) == 0)
事实上这两句话与Allegro关系不是很大,但是它给我提供了一种新的节奏控制思路~
5、clear_to_color(custom_cursor, bitmap_mask_color(screen));
int bitmap_mask_color(BITMAP *bmp);
返回指定位图的掩色 (这个色彩值将在画精灵时被忽略). 在 256 色位图里是零, 在真彩位图里是亮粉红色 (红和蓝值最大, 绿值为零).

6、   set_mouse_sprite(custom_cursor);
   set_mouse_sprite_focus(16, 16);
没什么好说的..新出现的知识点。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值