Thinkpad x60s が届き、だいたいセットアップが終わったのでさっそく遊びだしています。とりあえず、HDDセンサー付きのPCで一度やってみたかった miyagawaさんのGoogle Maps tilt をやってみました。これは楽しい。わずか数行のコードで Perlからマシンの傾き値が取れるのか。
なら、何か他にも遊んでおきたいな、ということで、古典的ゲーム「パックマン」をThinkpadを傾けて操作するっていうのをやってみることに。それなりにゲームできたので、動画。
JavaScriptで動くPacman を見つけてきて、元記事みたくActiveX でという作戦でもいけると思んだけど、同じだとつまんないので、Thinkpad の前後左右への傾きが上下左右キーを押したのと同じになるようにするコードを書く方向で検討開始。
Perl からキーボード操作をする方法を探そうと CPAN の Win32::* をあさってたら、Win32::GuiTest というものを発見。これは以下のように書くだけで
use Win32::GuiTest qw(:ALL);
SendKeys("{UP}{UP}{DOWN}{DOWN}hello");
キーボードから ↑↑↓↓hello
と打ったのと同じことになるというもので、たぶん本来の用途は名前の通り普通のGUIアプリを操作してテストするもの。本件はこれがそのまま使えるなあと。そこで、以下のようなコードを実行した上で、ここで見つけたFlash版Pacman を開いて遊んでみたのが上の動画です。
# thanks miyagawa: http://blog.bulknews.net/mt/archives/002053.html
use strict;
use Time::HiRes qw(sleep);
use Win32API::File qw(:ALL);
use Win32::GuiTest qw(:ALL);
sub get_tilt {
my @base;
return sub {
my $file = createFile("//./ShockMgr", "r ke") or die "Can't get ShockMgr device";
DeviceIoControl($file, 0x733fc, [], 0, my($buf), 0x24, my($bytes), []);
my @data = unpack "x4s*", $buf if $buf;
@base = @data[3, 2] unless @base;
return {
x => ($data[1] - $base[0]) / 20,
y => ($data[0] - $base[1]) / 20,
};
}
}
my $tilt = get_tilt();
while (1) {
my $move = $tilt->();
my $keys = '';
if ($move->{x} > 0) { $keys .= "{RIGHT}" x int abs $move->{x} }
elsif ($move->{x} {x} }
if ($move->{y} > 0) { $keys .= "{DOWN}" x int abs $move->{y} }
elsif ($move->{y} {y} }
warn $keys if $keys;
SendKeys($keys) if $keys;
sleep 0.1;
}
bulknews.typepad.com に Trackback 打つためにちょっと英語で書こうとしてみたものの、途中で挫折…。しかし、Win32::* いろいろ使えそうなものがあっておもしろいなあ。Win32::Clipboard とか Win32::Screenshot とか。