不求与人相比,但求超越自己,要哭就哭出激动的泪水,要笑就笑出成长的性格!
起因
下面这幅图大家都应该很熟悉了,这是微信打飞机游戏的截图,飞机需要我们用手拖动来实现其移动,而不是我们在屏幕上触摸某一个点,然后飞机再进行移动.所以使用移动动作是实现不了这个效果的,那么该如何实现简单的精灵拖动呢?下面听我慢慢道来.
经过
闲话不多说,因为先前在网上找到关于微信打飞机的素材包,所以,直接拿过来用了.下面分别是游戏背景图片和飞机图片素材,有需要的直接拿走不谢.
有了图片素材之后,我们就在场景中先做一些基础的准备.先把游戏场景和飞船布置好.,然后在-(void)didMoveToView:(SKView *)view 方法中调用下面的两个创建方法就好.代码如下
#pragma mark ----创建背景----
-(void)backgroundNode{
SKSpriteNode *backgroundNode = [SKSpriteNode spriteNodeWithImageNamed:@"bg_02.jpg"];
backgroundNode.position = CGPointZero;
backgroundNode.zPosition = 0;
backgroundNode.anchorPoint = CGPointZero;
backgroundNode.size = self.size;
[self addChild:backgroundNode];
}
#pragma mark ---- 创建飞船 ----
-(void)planeNode{
SKSpriteNode *planeNode = [SKSpriteNode spriteNodeWithImageNamed:@"飞机.png"];
planeNode.position = CGPointMake(self.size.width/2, self.size.height/2);
planeNode.anchorPoint = CGPointMake(0.5, 0.5);
planeNode.zPosition = 1;
planeNode.name = @"plane";
[self addChild:planeNode];
}
高潮
先前我们的准备工作已经完成了,接下来就是我们的正题部分了,SKSpriteNode拖动的实现是使用了拖动手势(UIPanGestureRecognizer对象)完成的.首先我们给场景的View添加上手势,这里需要注意的是SKSpriteNode对象是不能添加手势的.所以,我们要把手势添加到场景的View上.代码部分在-(void)didMoveToView:(SKView *)view 里面实现.
-(void)didMoveToView:(SKView *)view{
[super didMoveToView:view];
[self backgroundNode];
[self planeNode];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];
[self.view addGestureRecognizer:pan];
}
添加完手势之后,我们就需要对其进行拖动实现的,思路如下,当用户触摸到屏幕的时候,我们首先判断触摸的位置是否是所需要的拖动的SKSpriteNode对象的位置.如果位置正是需要拖动的SKSpriteNode对象的位置,我们就让其进行移动,否则,SKSpriteNode对象则不会不移动.那么,明白了整体思路之后,我们首先要对用户开始触摸屏幕(-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
)这里进行代码实现,这里使用一个BOOL值,来判断用户每一次触摸是否是SKSpriteNode对象.代码实现如下.
#pragma mark ---- 移动飞船 ----
BOOL isPlane ;//设置一个全局的BOOL值.
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
isPlane = NO;//每一次触摸方法调用isPlane的值都为NO.
UITouch *touch = [touches anyObject];
CGPoint position = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:position];
if ([node.name isEqualToString:@"plane"]) {
isPlane = YES;//如果是需要拖动的SKSpriteNode对象,那么isPlane的值为YES.
}
}
接下来就对拖动方法进行实现,这里面注意的是通过UIPanGestureRecognizer对象获取的CGPoint对象的参考坐标系是Quartz 2D坐标系,而在SpriteKit中的坐标系是OpenGL ES坐标系(坐标系的不同参考这里),这两个坐标系的不同,所以我们要对获得的CGPoint对象进行转化.代码实现如下.
-(void)panAction:(UIPanGestureRecognizer *)sender{
if (isPlane ) {
SKSpriteNode *plane = (SKSpriteNode *)[self childNodeWithName:@"plane"];
CGPoint position = [sender locationInView:sender.view];
position = CGPointMake(position.x, self.size.height -position.y);//因为坐标系不同,所以我们要进行转换..
plane.position = position;
}
}
上面的代码就实现了简单的SKSpriteNode对象的拖动了,下面我们看一下实现的效果图.
落幕
好了,这一篇到此就要结束了,如果您有任何疑问可以在评论区提出,我会及时回复您的,谢谢,最后附上本文的Demo.