キー操作
ゲームボーイは、十字キー4つ、STARTボタン、SELECTボタン、Bボタン、Aボタンの合計8つのボタンを備えています。
今回はそれら8つのボタンが押されたときの制御方法について見ていきます。
#include <stdio.h>
#include <gb.h>
#include <drawing.h>
void main( )
{
UBYTE key; /* ボタン情報 */
UBYTE x; /* X座標 */
UBYTE y; /* Y座標 */
UBYTE prevx; /* 前回X座標 */
UBYTE prevy; /* 前回Y座標 */
UBYTE clr; /* 色情報 */
UBYTE radius; /* 円の半径 */
x = 40;
y = 40;
prevx = x;
prevy = y;
clr = 1;
radius = 10;
color(BLACK, WHITE, SOLID); /* 前景色を黒に設定 */
circle(x, y, radius, M_FILL); /* 半径20の塗潰し円を描く */
while(1){
prevx = x; /* 前回のX座標を保存しておく*/
prevy = y; /* 前回のY座標を保存しておく*/
waitpad(0xFF); /* ボタンが押されるまで待つ */
key=joypad(); /* 押下ボタンを取得する */
waitpadup(); /* ボタンが放されるまで待つ */
delay(100); /* 100ミリ秒一時停止 */
if(key & J_RIGHT){ /* 右ボタンが押されたとき */
x = x + radius * 2; /* X座標を加算する */
if(x >= 160){ /* X座標が右端へはみだすとき */
x = x - radius * 2;
}
}
if(key & J_LEFT){ /* 左ボタンが押されたとき */
x = x - radius * 2; /* X座標を減算する */
if(x <= radius){ /* X座標が左端へはみだすとき */
x = x + radius * 2; /* X座標を元に戻す */
}
}
if(key & J_DOWN){ /* 下ボタンが押されたとき */
y = y + radius * 2; /* Y座標を加算する */
if(y >= 140){ /* Y座標が下端へはみだすとき */
y = y - radius * 2; /* Y座標を加算する */
}
}
if(key & J_UP){ /* 上ボタンが押されたとき */
y = y - radius * 2; /* Y座標を減算する */
if(y <= radius){ /* Y座標が上端へはみだすとき */
y = y + radius * 2; /* Y座標を元に戻す */
}
}
color(WHITE, WHITE, SOLID); /* 前景色を白に設定 */
circle(prevx, prevy, radius, M_FILL); /* 前回描いた円を消す */
color(BLACK, WHITE, SOLID); /* 前景色を黒に設定 */
circle(x, y, radius, M_FILL); /* 半径20の塗潰し円を描く */
}
}
waitpad関数
UBYTE waitpad(UBYTE mask);
waitpad関数はボタンが押されるまで処理を停止させる関数です。
引数では押されるまで待つボタンの種類を指定します。
全てのボタンを対象とするときは「0xFF」を指定します。
waitpadup関数
void waitpadup(void);
waitpadup関数は押されたボタンが放されるまで処理を停止させる関数です。
joypad関数
UBYTE joypad(void);
joypad関数は押されたボタンの種類を教えてくれる関数です。
何のボタンも押されていないときに呼ばれたら0を返します。
・ボタン種類と定数の対応関係
ボタン種類 |
ボタン定数 |
値 |
START |
J_START |
0x80U |
SELECT |
J_SELECT |
0x40U |
B |
J_B |
0x20U |
A |
J_A |
0x10U |
下 |
J_DOWN |
0x08U |
上 |
J_UP |
0x04U |
左 |
J_LEFT |
0x02U |
右 |
J_RIGHT |
0x01U |
上記サンプルコードでは押されたボタンごとに、ボタン押下後の処理を実装しています。
ここで、if文の判定式で使っている演算子が「==」ではなく「&」であることに着目してください。
GBDKでは、ボタンが押されたかどうかの情報を1バイト(8ビット)で管理し、各ビットを8つのボタンそれぞれと対応させています。
そして、ボタンが押されたとき、そのボタンと対応するビットを「1」としています。
例えば、Bボタンを押した場合、joypad関数は「0x20」を返しますが、これを2進数で表すと「00100000」となります。
このとき6ビット目が「1」になっていることに着目してください。
Bボタンは6ビット目と対応しており、その6ビット目が「1」になっているためBボタンが押されたと判断できます。
次に、複数のボタンが同時に押された場合はjoypad関数はどんな値を返すかを見てみます。
例えば、右ボタンとAボタンが同時に押された場合、joypad関数は「0x10 + 0x01」、つまり「0x11」を返します。
これを2進数で表すと「00010001」となります。
5ビット目と1ビット目が「1」になっているので、Aボタンと右ボタンが押されたと判断できます。
このようにjoypad関数は、複数のボタンが押されたときは、それぞれのボタン定数の和を返すため、演算子「==」ではひとつのボタンが押されたときの判定しかできません。
しかし、演算子「&」を使えば、複数のボタンが押されたときの判定も正しく行うことができます。
例えば、上ボタンとAボタンが押された場合のjoypad関数が返す値と各ボタン定数との論理積の結果は、
上ボタンの押下判定
00010100
AND 00000100 ← J_UP
-------------
00000100
Aボタンの押下判定
00010100
AND 00010000 ← J_A
-------------
00010000
と、なります。
if文は0を偽、0以外を真と判定しますので、押されたボタンを判定することができるということです。
|