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);
没什么好说的..新出现的知识点。