精灵运动的 MultiTouch 控制 - cocos2d
我已经处理这个问题有一段时间了。 我想做的是通过屏幕左侧或右侧的触摸来控制 CCSprite 的右/左移动。
如果您在每次触摸后抬起手指,那么这样做就没有问题。但我想要的最好用一个例子来描述: 玩家触摸屏幕的左侧,精灵就会向左移动。现在玩家(仍然触摸左侧)触摸右侧......精灵现在应该向右移动。现在玩家的一根手指在左侧,一根手指在右侧,如果他现在将触摸从右侧移开,精灵应该再次向左侧移动。
这就是我现在所拥有的:
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
//Swipe Detection Part 1
firstTouch = location;
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
//Swipe Detection Part 2
lastTouch = location;
float swipeLength = ccpDistance(firstTouch, lastTouch);
if (firstTouch.y < lastTouch.y && swipeLength > 60) {
[player jump:kkJumpUp];
} else if (firstTouch.y > lastTouch.y && swipeLength > 60){
[player jump:kkJumpDown];
}
[player endWalk];
}
如果有人能告诉我如何解决这个问题,我将不胜感激。谢谢 。
更新我的解决方案:
//1. Enable multitouch in the appDelegate
[glView setMultipleTouchEnabled:YES];
//2. Create an Array to keep track of active touches
touchArray = [[NSMutableArray alloc] init];
//3. Touch Methods
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
if (![touchArray containsObject:touch]) {
[touchArray addObject:touch];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(@"start: %f", location.x);
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
}
}
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
[touchArray removeObject:touch];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(@"end: %f", location.x);
}
for (UITouch *touch in touchArray) {
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(@"still: %f", location.x);
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
}
if ([touchArray count] == 0) {
[player endWalk];
}
}
I've been dealing with this problem for quite some time.
What I am trying to do is have a CCSprite's right/left movement controlled by touches on either the left side of the screen or the right.
Doing this is no problem if you lift your finger after each touch. But what I want is best described by an example:
The player touches the left side of the screen and the sprite moves to the left. Now the player (while still touching the left side) touches the right side...the sprite should now move right. Now the player has one finger on the left and one on the right side, if he now lifts the touch off the right side the sprite should again move to the left.
This is what I have now:
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
//Swipe Detection Part 1
firstTouch = location;
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
//Swipe Detection Part 2
lastTouch = location;
float swipeLength = ccpDistance(firstTouch, lastTouch);
if (firstTouch.y < lastTouch.y && swipeLength > 60) {
[player jump:kkJumpUp];
} else if (firstTouch.y > lastTouch.y && swipeLength > 60){
[player jump:kkJumpDown];
}
[player endWalk];
}
I'd appreciate it if someone could tell me how to go about this. Thank you .
UPDATE MY SOLUTION:
//1. Enable multitouch in the appDelegate
[glView setMultipleTouchEnabled:YES];
//2. Create an Array to keep track of active touches
touchArray = [[NSMutableArray alloc] init];
//3. Touch Methods
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
if (![touchArray containsObject:touch]) {
[touchArray addObject:touch];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(@"start: %f", location.x);
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
}
}
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
[touchArray removeObject:touch];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(@"end: %f", location.x);
}
for (UITouch *touch in touchArray) {
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(@"still: %f", location.x);
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
}
if ([touchArray count] == 0) {
[player endWalk];
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果我正确理解您的问题,您应该做的是:
在
ccTouchesEnded
中,而不是简单地调用endWalk
,检查是否仍然存在任何触摸(以这样做,您可以在ccTouchesEnded
中迭代allTouches
);在适当的情况下(即,触摸仍在激活播放器),调用
startWalk
。如果没有触摸,则调用
endWalk
。该代码与您在
ccTouchesBegan
中的代码类似,只是您进行迭代(我不确定allTouches
在 TouchesEnded 的索引 0 处包含什么)。旧答案:
你没有说任何关于你现在如何处理触摸的事情。无论如何,正确的方法是定义
ccTouches*
方法(相对于ccTouch*
),其中 * 可以是:Began
、已移动
,已结束
。请记住,touchesBegan 会在检测到每个新触摸时触发。因此,如果您想了解当前活动的所有触摸的状态,则必须使用
allTouches
。还可以看看 来自 iphonesdk 的这篇文章,我发现它对语义很有洞察力这些方法中的触摸次数。
If I understand correctly your problem, what you should do is:
in
ccTouchesEnded
, instead of simply callingendWalk
, check to see is any touch is still present (to do so, you could iterate overallTouches
);in the appropriate case (i.e., a touch is still activating the player), call
startWalk
.if no touch is present, call
endWalk
.The code would be similar to what you have in
ccTouchesBegan
, only you iterate (I am not sure whatallTouches
contains at index 0 in touchesEnded).OLD ANSWER:
You are not saying anything about how you are handling touches right now. In any case, the way to go is defining
ccTouches*
methods (vs.ccTouch*
), where * can be:Began
,Moved
,Ended
.Keep in mind that touchesBegan is fired at each new touch that is detected. So, if you want to know the status of all touches currently active, you have to use
allTouches
.Have also a look at this post from iphonesdk which I found insightful as to the semantics of touches in those methods.