(译)Cocos2d_for_iPhone_1_Game_Development_Cookbook
著作权声明:本文由iam126 翻译,欢迎转载分享。
请尊重作者劳动,转载时保留该声 明和作者博客链接,谢谢!
相关程序代码下载:http://download.csdn.net/detail/iam126/4068610
或搜索“Cocos2d_for_iPhone_1_Game_Development_Cookbook代码”于CSDN;
新手翻译,不准确请见谅,参考代码与原书。
2.1点击、按住、拖拽
点击、按住、拖拽是被使用的最广泛的内部技术。它们形成了用户交互界面中最基本的模块,对于游戏对象中的作用也同样重要。在这个案例中,我们使用CCSprite的子类来创建一个精灵,它可以处理触摸事件,保持自定义的状态信息。这样,加上一些逻辑代码,允许我们触摸、按住、拖动这个精灵。
如何去做…
执行如下代码:
//ColorTouchSprite.h
enum
{
TS_NONE,
TS_TAP,
TS_HOLD,
TS_DRAG
};
@interface ColorTouchSprite : CCSprite
{
@public
float holdTime; //我们能按住多少秒
int touchedState; //当前的触摸状态
bool isTouched; //是否可以触摸
float lastMoved; //我们移动了它多久
CGPoint lastTouchedPoint; //上一次的触电在哪
const float releaseThreshold = 1.0f; //多久之后释放
const float holdThreshold = 0.2f; //多久之后将点击转化为按住
const float lastMovedThreshold = 0.5f; //多久没有移动
const int dragThreshold = 3; //拖动3个像素
}
@end
@implementation ColorTouchSprite
@synthesize touchedState;
-(id) init
{
holdTime = 0;
lastMoved = 0;
touchedState = TS_NONE;
isTouched = NO;
lastTouchedPoint = ccp(0,0);
[self schedule:@selector(step:)];
return [super init];
}
-(void) step:(ccTime)dt
{
//We use holdTime to determine the difference between a tap and a hold
//我们通过点击的持续时间来判断点击与按住的不同
if(isTouched)
{
holdTime += dt;
lastMoved += dt;
}
else
{
holdTime += dt;
if(holdTime > releaseThreshold)
{
touchedState = TS_NONE;
}
}
//If you are holding and you haven't moved in a while change the state
//如果你按住了并且没有移动
if(holdTime > holdThreshold && isTouched && lastMoved> lastMovedThreshold)
{
touchedState = TS_HOLD;
}
}
/* Used to determine whether or not wetouched this object */
//判断是否点击对象的区域
- (CGRect) rect
{
float scaleMod = 1.0f;
float w = [self contentSize].width * [self scale] * scaleMod;
float h = [self contentSize].height * [self scale] * scaleMod;
CGPoint point = CGPointMake([self position].x - (w/2), [self position].y- (h/2));
return CGRectMake(point.x, point.y, w, h);
}
/* Process touches */
//处理触摸事件
-(void) ccTouchesBegan:(NSSet *)toucheswithEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView: [touch view]];
point = [[CCDirector sharedDirector] convertToGL: point];
isTouched = YES;
holdTime = 0;
touchedState = TS_NONE;
lastTouchedPoint = point;
}
-(void) ccTouchesMoved:(NSSet *)toucheswithEvent:(UIEvent *)event
{
if(!isTouched)
{
return;
}
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView: [touch view]];
point = [[CCDirector sharedDirector] convertToGL: point];
if(touchedState == TS_DRAG || distanceBetweenPoints(lastTouchedPoint,point) > dragThreshold)
{
touchedState = TS_DRAG;
self.position = point;
lastMoved = 0;
}
lastTouchedPoint = point;
}
-(void) ccTouchesEnded:(NSSet *)toucheswithEvent:(UIEvent *)event
{
if(!isTouched)
{
return;
}
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView: [touch view]];
point = [[CCDirector sharedDirector] convertToGL: point];
//A short hold time after a touch ended means a tap.
//一个时间很短的按住时间
if(holdTime < 10)
{
touchedState = TS_TAP;
}
holdTime = 0;
isTouched = NO;
lastTouchedPoint = point;
}
@end
#import "Helpers.h"
@implementation Ch2_TapHoldDragInput
-(CCLayer*) runRecipe
{
self.isTouchEnabled = YES;
//Our message sprite
//我们表达信息的精灵
message = [CCLabelBMFont labelWithString:@"Tap, hold or drag thesquare." fntFile:@"eurostile_30.fnt"];
message.position = ccp(240,260);
message.scale = 0.75f;
[self addChild:message];
//Init the ColorTouchSprite
//初始化颜色
colorTouchSprite = [ColorTouchSpritespriteWithFile:@"blank.png"];
colorTouchSprite.position = ccp(240,160);
[colorTouchSprite setTextureRect:CGRectMake(0,0,100,100)];
[self addChild:colorTouchSprite];
[self schedule:@selector(step)];
return self;
}
/* Process touch events */
//处理触摸事件
-(void) ccTouchesBegan:(NSSet *)toucheswithEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView: [touch view]];
point = [[CCDirector sharedDirector] convertToGL: point];
//Helper function 'pointIsInRect' is defined in Helpers.h
//在Helpers.h文件中
if(pointIsInRect(point, [colorTouchSprite rect]))
{
[colorTouchSprite ccTouchesBegan:touches withEvent:event];
}
}
-(void) ccTouchesMoved:(NSSet *)toucheswithEvent:(UIEvent *)event
{
/* CODE OMITTED */
//省略此处代码
}
-(void) ccTouchesEnded:(NSSet *)toucheswithEvent:(UIEvent *)event
{
/* CODE OMITTED */
//省略此处代码
}
@end
如何工作…
首先,我们创建ColorTouchSprite类,它是CCSprite的子类。这是我们保持多种状态的地方,包括点击、按住、拖动。我们也指定运行一个(CGRect)区域方法。使用它可以判断精灵是否被触摸。案例中,主要的层通过触摸动作来判定下面这三个动作:
-(void) ccTouchesBegan:(NSSet *)toucheswithEvent:(UIEvent *)event;
-(void) ccTouchesMoved:(NSSet *)toucheswithEvent:(UIEvent *)event;
-(void) ccTouchesEnded:(NSSet *)toucheswithEvent:(UIEvent *)event;
这三个方法特别简单。无论你什么时候触摸这个层,我们都会触发ccTouchBegan方法。当我们移动时触发ccTouchesMoved方法。最后,当我们离开手指的时候,会出触发ccTouchesEnded方法。每一个方法检测一下pointIsInRect,然后调用必要的触摸精灵的方法。最后,精灵运行一些简单的逻辑去确定状态并且允许拖拽精灵。
更多的事…
这个技术原先并不是捕捉输入的唯一方式。Cocos2d同样也规定了CCTouchDispatcher类。你可以执行在CCTargetedTouchDelegate中的协议的方法并且制定一个委托对象去自动处理你的触摸输入数据。
相关信息请参考官方cocos2d文档以及cocos2d论坛。
(译)Cocos2d_for_iPhone_1_Game_Development_Cookbook
著作权声明:本文由iam126 翻译,欢迎转载分享。
请尊重作者劳动,转载时保留该声 明和作者博客链接,谢谢!
相关程序代码下载:http://download.csdn.net/detail/iam126/4068610
或搜索“Cocos2d_for_iPhone_1_Game_Development_Cookbook代码”于CSDN;
新手翻译,不准确请见谅,参考代码与原书。