Ios 触摸时更改精灵图像
我正在制作一个游戏,目的是捕捉从屏幕顶部掉落的多个物体。底部有一个篮子用来装东西。我使用raywenderlich的教程从上到下随机生成了对象: 但我想知道的是,当我点击那个随机对象时,那个对象的图像会变成另一个图像,所以想象一下,如果随机对象是猫,在我点击它们之后,它们会变成狗,我该如何编程呢 编辑这是我到目前为止得到的信息:Ios 触摸时更改精灵图像,ios,sprite-kit,skaction,Ios,Sprite Kit,Skaction,我正在制作一个游戏,目的是捕捉从屏幕顶部掉落的多个物体。底部有一个篮子用来装东西。我使用raywenderlich的教程从上到下随机生成了对象: 但我想知道的是,当我点击那个随机对象时,那个对象的图像会变成另一个图像,所以想象一下,如果随机对象是猫,在我点击它们之后,它们会变成狗,我该如何编程呢 编辑这是我到目前为止得到的信息: #import "MyScene.h" static NSString* basketCategoryName = @"basket"; static NSStrin
#import "MyScene.h"
static NSString* basketCategoryName = @"basket";
static NSString* monsterCategoryName= @"monster";
static const uint32_t projectileCategory = 0x1 << 0;
static const uint32_t monsterCategory = 0x1 << 1;
@interface MyScene() <SKPhysicsContactDelegate>
@property (nonatomic) SKLabelNode * scoreLabelNode;
@property int score;
@property (nonatomic) SKSpriteNode * basket;
@property (nonatomic) SKSpriteNode * monster;
@property (nonatomic) BOOL isFingerOnBasket;
@property (nonatomic) BOOL isFingerOnMonster;
@property (nonatomic) BOOL isTouching;
@property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
@property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
//@property (nonatomic, strong) SKSpriteNode *selectedNode;
@end
@implementation MyScene
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
// Initialize label and create a label which holds the score
_score = 0;
_scoreLabelNode = [SKLabelNode labelNodeWithFontNamed:@"MarkerFelt-Wide"];
_scoreLabelNode.position = CGPointMake( CGRectGetMidX( self.frame ), 3 * self.frame.size.height / 4 );
_scoreLabelNode.zPosition = 100;
_scoreLabelNode.text = [NSString stringWithFormat:@"%d", _score];
[self addChild:_scoreLabelNode];
// Set the background
SKTexture* groundTexture = [SKTexture textureWithImageNamed:@"AcornFlipTestBackground1136x640.png"];
groundTexture.filteringMode = SKTextureFilteringNearest;
for( int i = 0; i < 2 + self.frame.size.width / ( groundTexture.size.width * 2 ); ++i ) {
SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:groundTexture];
[sprite setScale:1.0];
sprite.size = CGSizeMake(self.frame.size.width,self.frame.size.height);
sprite.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
[self addChild:sprite];
}
// Make grafity for sprite
self.physicsWorld.gravity = CGVectorMake(0.0f, 0.0f);
self.physicsWorld.contactDelegate = self;
// Make catching object sprite
self.basket = [SKSpriteNode spriteNodeWithImageNamed:@"bedTest.png"];
self.basket.position = CGPointMake(CGRectGetMidX(self.frame), _basket.frame.size.height * 0.5f);
self.basket.name = basketCategoryName;
[self addChild:self.basket];
// For default this is set to no until user touches the basket and the game begins.
self.isTouching = NO;
}
return self;
}
-(void)addAcorn{
if(_isTouching == YES) {
self.monster= [SKSpriteNode spriteNodeWithImageNamed:@"AcornFinal.png"];
// Determine where to spawn the monster along the X axis
int minX = self.monster.size.width;
int maxX = self.frame.size.width - self.monster.size.width;
int rangeX = maxX - minX;
int actualX = (arc4random() % rangeX)+minX;
// Random position along the X axis as calculated above
// This describe from which way the acorns move
// - means moving from top to the right and + means moving from the top to the left
self.monster.position = CGPointMake(actualX ,self.frame.size.height+ self.monster.size.height);
self.monster.name = monsterCategoryName;
[self addChild:self.monster];
CGSize contactSize = CGSizeMake(self.monster.size.width - 5.0, self.monster.size.height - 10.0);
self.monster.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:contactSize]; // 1
self.monster.physicsBody.dynamic = YES; // 2
self.monster.physicsBody.categoryBitMask = monsterCategory; // 3
self.monster.physicsBody.contactTestBitMask = projectileCategory; // 4
self.monster.physicsBody.collisionBitMask = 0; // 5
// Determine speed of the monster
int minDuration = 8.0;
int maxDuration = 10.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
SKAction * actionMove = [SKAction moveTo:CGPointMake(actualX,-self.monster.size.height) duration:actualDuration];
SKAction * actionMoveDone = [SKAction removeFromParent];
[self.monster runAction:[SKAction sequence:@[actionMove, actionMoveDone]]];
}
}
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
self.lastSpawnTimeInterval += timeSinceLast;
if (self.lastSpawnTimeInterval > 0.5) {
self.lastSpawnTimeInterval = 0;
[self addAcorn];
}
}
- (void)update:(NSTimeInterval)currentTime {
// Handle time delta.
// If we drop below 60fps, we still want everything to move the same distance.
CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
self.lastUpdateTimeInterval = currentTime;
if (timeSinceLast > 1) { // more than a second since last update
timeSinceLast = 1.0 / 60.0;
self.lastUpdateTimeInterval = currentTime;
}
[self updateWithTimeSinceLastUpdate:timeSinceLast];
}
-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
self.isTouching = YES;
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode* body = [self nodeAtPoint:location];
if ([body.name isEqualToString:basketCategoryName])
{
NSLog(@"Began touch on basket");
self.isFingerOnBasket = YES;
}
else if ([body.name isEqualToString:monsterCategoryName])
{
NSLog(@"Began touch on MONSTER");
self.isFingerOnMonster = YES;
}
}
-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
if (self.isFingerOnMonster) {
// 2 Get touch location
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
CGPoint previousLocation = [touch previousLocationInNode:self];
// 3 Get node for paddle
SKSpriteNode* monster = (SKSpriteNode*)[self childNodeWithName: monsterCategoryName];
int oldPosition = monster.position.x + (location.x - previousLocation.x);
self.monster = [SKSpriteNode spriteNodeWithImageNamed:@"AcornFinal.png"];
monster.position = CGPointMake(oldPosition, monster.position.y);
NSLog(@"reached the touch though");
}
// 1 Check whether user tapped paddle
if (self.isFingerOnBasket) {
// 2 Get touch location
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
CGPoint previousLocation = [touch previousLocationInNode:self];
// 3 Get node for paddle
SKSpriteNode* basket = (SKSpriteNode*)[self childNodeWithName: basketCategoryName];
// 4 Calculate new position along x for paddle
int basketX = basket.position.x + (location.x - previousLocation.x);
// 5 Limit x so that the paddle will not leave the screen to left or right
basketX = MAX(basketX, basket.size.width/2);
basketX = MIN(basketX, self.size.width - basket.size.width/2);
// 6 Update position of paddle
basket.position = CGPointMake(basketX, basket.position.y);
CGSize contactSize = CGSizeMake(basket.size.width - 8.0, basket.size.height - 8.0);
basket.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:contactSize];
basket.physicsBody.dynamic = YES;
basket.physicsBody.categoryBitMask = projectileCategory;
basket.physicsBody.contactTestBitMask = monsterCategory;
basket.physicsBody.collisionBitMask = 0;
basket.physicsBody.usesPreciseCollisionDetection = YES;
}
}
- (void)projectile:(SKSpriteNode *)basket didCollideWithMonster:(SKSpriteNode *)monster {
NSLog(@"Hit");
[monster removeFromParent];
}
- (void)didBeginContact:(SKPhysicsContact *)contact
{
// 1
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
// 2
if ((firstBody.categoryBitMask & projectileCategory) != 0 &&
(secondBody.categoryBitMask & monsterCategory) != 0)
{
[self projectile:(SKSpriteNode *) firstBody.node didCollideWithMonster:(SKSpriteNode *) secondBody.node];
NSLog(@"test");
_score++;
_scoreLabelNode.text = [NSString stringWithFormat:@"%d", _score];
}
}
// Removing this void will result in being able to drag the basket accross the screen without touching the basket itself.
-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
self.isFingerOnBasket = NO;
self.isFingerOnMonster = NO;
}
@end
#导入“MyScene.h”
静态NSString*basketCategoryName=@“basket”;
静态NSString*monsterCategoryName=@“怪物”;
静态常量uint32\u t projectelecategory=0x1){//自上次更新以来已超过一秒
timeSinceLast=1.0/60.0;
self.lastUpdateTimeInterval=当前时间;
}
[self-updateWithTimeSinceLastUpdate:timeSinceLast];
}
-(无效)触摸开始:(NSSet*)触摸事件:(UIEvent*)事件{
self.isTouching=是;
UITouch*touch=[触摸任何对象];
CGPoint位置=[触摸位置Innode:self];
SKNode*body=[self nodeAtPoint:location];
if([body.name IsequalString:basketCategoryName])
{
NSLog(@“开始触摸篮子”);
self.isFingerOnBasket=是;
}
else if([body.name IsequalString:monsterCategoryName])
{
NSLog(@“开始接触怪物”);
self.isFingerOnMonster=是;
}
}
-(无效)触摸移动:(NSSet*)触摸事件:(UIEvent*)事件{
if(self.isFingerOnMonster){
//2联系地点
UITouch*touch=[触摸任何对象];
CGPoint位置=[触摸位置Innode:self];
CGPoint previousLocation=[触摸previousLocationInNode:self];
//3获取用于划桨的节点
SKSpriteNode*怪物=(SKSpriteNode*)[自身子节点名称:怪物类别名称];
int oldPosition=monster.position.x+(location.x-previousLocation.x);
self.monster=[SKSpriteNode spriteNodeWithImageNamed:@“acornfail.png]”;
monster.position=CGPointMake(旧位置,monster.position.y);
NSLog(@“尽管触摸到了”);
}
//1检查用户是否轻触了拨杆
if(self.isFingerOnBasket){
//2联系地点
UITouch*touch=[触摸任何对象];
CGPoint位置=[触摸位置Innode:self];
CGPoint previousLocation=[触摸previousLocationInNode:self];
//3获取用于划桨的节点
SKSpriteNode*basket=(SKSpriteNode*)[self childNodeWithName:basketCategoryName];
//4计算桨叶沿x的新位置
int basketX=basket.position.x+(location.x-previousLocation.x);
//5限制x,使挡板不会向左或向右离开屏幕
篮筐X=最大值(篮筐X,篮筐.尺寸.宽度/2);
basketX=MIN(basketX,self.size.width-basket.size.width/2);
//6更新拨杆的位置
basket.position=CGPointMake(basketX,basket.position.y);
CGSize contactSize=CGSizeMake(basket.size.width-8.0,basket.size.height-8.0);
basket.physicsBody=[SKPhysicsBody带有矩形大小:contactSize];
basket.physicsBody.dynamic=是;
basket.physicsBody.categoryBitMask=项目类别;
basket.physicsBody.contactTestBitMask=怪物类别;
basket.physicsBody.collisionBitMask=0;
basket.physicsBody.usesprecisecollisondetection=YES;
}
}
-(空)射弹:(斯普林泰诺德*)篮筐与怪物(斯普林泰诺德*)碰撞{
NSLog(@“命中”);
[怪物从父级移除];
}
-(无效)didBeginContact:(SKPhysicsContact*)联系人
{
// 1
SKPhysicsBody*第一个Body,*第二个Body;
if(contact.bodyA.categoryBitMask
骨架模型的每个部分都是一个spritekit节点。查找要更改并更新其纹理属性的节点,如下所示:
spriteKitNode.texture=//更新的SKTexture一旦在精灵上检测到触摸(我假设您已经解决了这个问题),您可以使用
spriteNodeWithImageNamed
再次创建精灵。确保保存上一个节点的位置,并在新精灵上再次设置它,使其与旧精灵的位置匹配
CGPoint oldPosition = touchedSprite.position;
touchedSprite = [SKSpritNode spriteWithImageNamed:@"imgge.png"];
touchedSprite.position = oldPosition;
// If you have any other sprite properties you will have to save them as well
您还可以使用setTexture
方法设置纹理,该方法不需要您更改任何其他内容(例如位置):
编辑:
在评论中回答您的问题时,您可以在精灵父节点的touchesend
方法中实现这一点:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
for (SKSpriteNode *sprite in fallingSprites) { // Assuming fallingSprite is an array containing the cat sprites you want to detect touches for
if (CGRectContainsPoint(sprite.frame, touchLocation)) {
[sprite setTexture:[SKTexture textureWithImageNamed:@"dog.png"]];
}
}
}
另一种方法(还没有尝试过)是将SKSpriteNode子类化并实现相同的方法,但在rect中没有触摸检测,因为如果此方法被称为sprite,则该sprite已被触摸。在TouchesEnded事件中:
在触摸位置添加一个小的skspritenode,该skspritenode带有一个持续时间短的小物理体。(“触摸式spritenode) 在所有可能变换的对象和“触摸spritenode”之间建立联系 创造
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
for (SKSpriteNode *sprite in fallingSprites) { // Assuming fallingSprite is an array containing the cat sprites you want to detect touches for
if (CGRectContainsPoint(sprite.frame, touchLocation)) {
[sprite setTexture:[SKTexture textureWithImageNamed:@"dog.png"]];
}
}
}