ios joystick仮想ロッカー実装(Cocos 2 d以外)
このDemoコードはGithubにアップロードされています
https://github.com/pyzhangxiang/joystick-iosiphone
ios上で人物の移動を制御するのは,加速センサ計算装置の傾斜角を利用して制御できることと,仮想ロッカーを使用することである.センサを使用する方法は追加のUI開発を必要とせず,比較的簡単であるが,必ずしもすべてのゲームに適しているとは限らない.次に、自分で作った仮想ロッカーを共有します.
ネット上にはいくつかのシミュレーションロッカーの実現がありますが、すべてCocos 2 dに基づいています.私はCocos 2 dではしません.
先にdemoの効果図を表示します.
左下にあるのがバーチャルロッカーです.クラスを個別に作成し、UIViewを継承します.
mCenterはロッカーの中心位置で、私のロッカー画像は128*128なので、mCenterは初期化関数で(64,64)に設定されています.
stickViewBaseはロッカーのシャーシです
stickView ロッカーのレバーです
この2つのUIImageViewはxibで直接構成されています.私のシャーシは変わらないのでxibで直接画像を指定しました.レバーには2つの状態があり、通常の状態と手を握る状態があります.指がスイングレバーに触れていない場合、ジョイスティックは通常の状態で、stickView.image=imgStickNormalを設定します.レバーに手を触れると、stickView.image=imgStickHoldを設定します.具体的な実装はUIViewの3つのtouch eventで行われる.
touchesBeganはまずロッカーの状態を修正します.次に、touchesMovedと同様に、別の関数を呼び出してロッカーの位置を計算します.touchesEndedはロッカーの状態と位置を回復します.
touchEventでロッカーの位置を計算して設定します.次のコードを参照してください.
最後にstickMoveToを呼び出してロッカー位置を修正し、ロッカー変化の通知をゲームロジックに送信する.
https://github.com/pyzhangxiang/joystick-iosiphone
ios上で人物の移動を制御するのは,加速センサ計算装置の傾斜角を利用して制御できることと,仮想ロッカーを使用することである.センサを使用する方法は追加のUI開発を必要とせず,比較的簡単であるが,必ずしもすべてのゲームに適しているとは限らない.次に、自分で作った仮想ロッカーを共有します.
ネット上にはいくつかのシミュレーションロッカーの実現がありますが、すべてCocos 2 dに基づいています.私はCocos 2 dではしません.
先にdemoの効果図を表示します.
左下にあるのがバーチャルロッカーです.クラスを個別に作成し、UIViewを継承します.
@interface JoyStickView : UIView
{
IBOutlet UIImageView *stickViewBase;
IBOutlet UIImageView *stickView;
UIImage *imgStickNormal;
UIImage *imgStickHold;
CGPoint mCenter;
}
mCenterはロッカーの中心位置で、私のロッカー画像は128*128なので、mCenterは初期化関数で(64,64)に設定されています.
stickViewBaseはロッカーのシャーシです
stickView ロッカーのレバーです
この2つのUIImageViewはxibで直接構成されています.私のシャーシは変わらないのでxibで直接画像を指定しました.レバーには2つの状態があり、通常の状態と手を握る状態があります.指がスイングレバーに触れていない場合、ジョイスティックは通常の状態で、stickView.image=imgStickNormalを設定します.レバーに手を触れると、stickView.image=imgStickHoldを設定します.具体的な実装はUIViewの3つのtouch eventで行われる.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
stickView.image = imgStickHold;
[self touchEvent:touches];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchEvent:touches];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
stickView.image = imgStickNormal;
CGPoint dtarget, dir;
dir.x = dtarget.x = 0.0;
dir.y = dtarget.y = 0.0;
[self stickMoveTo:dtarget];
[self notifyDir:dir];
}
touchesBeganはまずロッカーの状態を修正します.次に、touchesMovedと同様に、別の関数を呼び出してロッカーの位置を計算します.touchesEndedはロッカーの状態と位置を回復します.
touchEventでロッカーの位置を計算して設定します.次のコードを参照してください.
- (void)touchEvent:(NSSet *)touches
{
if([touches count] != 1)
return ;
UITouch *touch = [touches anyObject];
UIView *view = [touch view];
if(view != self)
return ;
CGPoint touchPoint = [touch locationInView:view];
CGPoint dtarget, dir;
// calculate stick direction to the center
dir.x = touchPoint.x - mCenter.x;
dir.y = touchPoint.y - mCenter.y;
double len = sqrt(dir.x * dir.x + dir.y * dir.y);
if(len < 10.0 && len > -10.0)
{
// on center pos
dtarget.x = 0.0;
dtarget.y = 0.0;
dir.x = 0;
dir.y = 0;
}
else
{
double len_inv = (1.0 / len);
dir.x *= len_inv;
dir.y *= len_inv;
dtarget.x = dir.x * STICK_CENTER_TARGET_POS_LEN;
dtarget.y = dir.y * STICK_CENTER_TARGET_POS_LEN;
}
[self stickMoveTo:dtarget];
[self notifyDir:dir];
}
コードのdirはロッカーの中心からタッチ位置までの方向であり、ここではタッチ位置が中心から10未満離れたときにロッカーが動かないと規定している.必要に応じて自分の実情に合わせて修正することができます.距離が10より大きい場合はdirを正規化し、ロッキングレバーと中心位置のずれdtargetを計算します.ここで計算に使用する定数値STICK_CENTER_TARGET_POS_LENは20です.最後にstickMoveToを呼び出してロッカー位置を修正し、ロッカー変化の通知をゲームロジックに送信する.
- (void)notifyDir:(CGPoint)dir
{
NSAutoreleasePool * pool = [[NSAutoreleasePoolalloc] init];
NSValue *vdir = [NSValuevalueWithCGPoint:dir];
NSDictionary *userInfo = [NSDictionarydictionaryWithObjectsAndKeys:
vdir, @"dir", nil];
NSNotificationCenter *notificationCenter = [NSNotificationCenterdefaultCenter];
[notificationCenter postNotificationName:@"StickChanged"object:niluserInfo:userInfo];
[pool release];
}
- (void)stickMoveTo:(CGPoint)deltaToCenter
{
// because the original position of stickView is (0, 0)
// so just set its position to the delta is ok
CGRect fr = stickView.frame;
fr.origin = deltaToCenter;
stickView.frame = fr;
}