将 SKSpriteNode 与类别一起使用时,未找到精灵的纹理且未显示精灵
Texture for sprite not found and sprite not displayed when using SKSpriteNode with a category
我开始使用 SKSpriteNode 类别系统来扩展 SKSpriteNode 的基本功能,现在场景中缺少通过编辑器添加到 .sks 场景的精灵(不是以编程方式添加到场景的精灵,在运行)。当我在 .sks 上记录一些精灵时,我可以看到它们的正确位置和比例参数,但在 XCode 的调试控制台中纹理总是 ['nil']。例如,当我在 GameScene1.sks 的场景编辑器上的静态 SKNoe 中记录名为 "house1" 的元素时,就会发生这种情况(见下面的 NSLog 行)。在场景编辑器上,我可以看到所有元素(包括 house1 元素)都很好,但是当我启动项目时,显示了添加到该 .sks 文件的 none 个精灵。这是相关代码:
GameScene 头文件是:
//GameScene.h
#import "Hero.h"
#import "SKSpriteNode+StaticLevelElement.h"
@interface GameScene : SKScene <SKPhysicsContactDelegate>
-(void) initStaticLevelElements;
@end
GameScene 实现文件是:
//GameScene.m
#import "SKSpriteNode+StaticLevelElement.h"
@implementation SKScene (Unarchive)
+ (instancetype)unarchiveFromFile:(NSString *)file {
/* Retrieve scene file path from the application bundle */
NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
/* Unarchive the file to an SKScene object */
NSData *data = [NSData dataWithContentsOfFile:nodePath
options:NSDataReadingMappedIfSafe
error:nil];
NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
[arch setClass:self forClassName:@"SKScene"];
SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
[arch finishDecoding];
return scene;
}
@end
@implementation GameScene
-(void)didMoveToView:(SKView *)view {
//Overriden in each level scene
[self initStaticLevelElements];
}
-(void) initStaticLevelElements {
}
@end
GameScene1.m 是:
// GameScene1.m
#import "GameScene1.h"
#import "Customer.h"
#import "Competitor.h"
@implementation SKScene (Unarchive)
+ (instancetype)unarchiveFromFile:(NSString *)file {
NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
NSData *data = [NSData dataWithContentsOfFile:nodePath
options:NSDataReadingMappedIfSafe
error:nil];
NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
[arch setClass:self forClassName:@"SKScene"];
SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
[arch finishDecoding];
return scene;
}
@end
@implementation GameScene1
#include "GoodsConstants.h"
-(void) initStaticLevelElements {
self.staticLevelElements = [[NSMutableArray alloc] init];
self.name = @"name for scene one";
SKNode * statics = [self childNodeWithName:@"statics"];
statics.zPosition = 100;
SKSpriteNode * e = (SKSpriteNode *)[statics childNodeWithName:@"house1"];
NSLog(@"house one is: %@", e);
}
GameScene1.h 是:
// GameScene1.h
#import <SpriteKit/SpriteKit.h>
#import "GameScene.h"
@interface GameScene1 : GameScene
@end
SKSpriteNode+StaticLevelElement.h 是:
// SKSpriteNode+StaticLevelElement.h
#import <SpriteKit/SpriteKit.h>
#import <SpriteKit/SKSpriteNode.h>
@interface SKSpriteNode (StaticLevelElement)
-(void) initWithSKNode:(SKNode *)node;
@property NSNumber * pseudoDepth;
@end
SKSpriteNode+StaticLevelElement.m 是:
//SKSpriteNode+StaticLevelElement.m
#import <objc/runtime.h>
#import "SKSpriteNode+StaticLevelElement.h"
NSString * const pseudoDepthSelector = @"pseudoDepth";
@implementation SKSpriteNode (StaticLevelElement)
@dynamic pseudoDepth;
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
self.userInteractionEnabled = YES;
return self;
}
- (void)setPseudoDepth:(NSNumber *)pseudoDepth
{
objc_setAssociatedObject(self, (__bridge const void *)(pseudoDepthSelector), pseudoDepth, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSNumber *)pseudoDepth
{
return objc_getAssociatedObject(self, (__bridge const void *)(pseudoDepthSelector));
}
-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
}
-(void) touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
}
@end
为了设置每个场景(级别)的具体数据,我使用了基本 GameScene 的继承 class - 因此我得到了 GameScene1、GameScene2 等。
有谁知道我错过了什么才能看到纹理?
我从中删除了 initWithCoder 覆盖方法
SKSpriteNode+StaticLevelElement.m
现在一切正常,纹理和精灵都显示在屏幕上。
我开始使用 SKSpriteNode 类别系统来扩展 SKSpriteNode 的基本功能,现在场景中缺少通过编辑器添加到 .sks 场景的精灵(不是以编程方式添加到场景的精灵,在运行)。当我在 .sks 上记录一些精灵时,我可以看到它们的正确位置和比例参数,但在 XCode 的调试控制台中纹理总是 ['nil']。例如,当我在 GameScene1.sks 的场景编辑器上的静态 SKNoe 中记录名为 "house1" 的元素时,就会发生这种情况(见下面的 NSLog 行)。在场景编辑器上,我可以看到所有元素(包括 house1 元素)都很好,但是当我启动项目时,显示了添加到该 .sks 文件的 none 个精灵。这是相关代码:
GameScene 头文件是:
//GameScene.h
#import "Hero.h"
#import "SKSpriteNode+StaticLevelElement.h"
@interface GameScene : SKScene <SKPhysicsContactDelegate>
-(void) initStaticLevelElements;
@end
GameScene 实现文件是:
//GameScene.m
#import "SKSpriteNode+StaticLevelElement.h"
@implementation SKScene (Unarchive)
+ (instancetype)unarchiveFromFile:(NSString *)file {
/* Retrieve scene file path from the application bundle */
NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
/* Unarchive the file to an SKScene object */
NSData *data = [NSData dataWithContentsOfFile:nodePath
options:NSDataReadingMappedIfSafe
error:nil];
NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
[arch setClass:self forClassName:@"SKScene"];
SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
[arch finishDecoding];
return scene;
}
@end
@implementation GameScene
-(void)didMoveToView:(SKView *)view {
//Overriden in each level scene
[self initStaticLevelElements];
}
-(void) initStaticLevelElements {
}
@end
GameScene1.m 是:
// GameScene1.m
#import "GameScene1.h"
#import "Customer.h"
#import "Competitor.h"
@implementation SKScene (Unarchive)
+ (instancetype)unarchiveFromFile:(NSString *)file {
NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
NSData *data = [NSData dataWithContentsOfFile:nodePath
options:NSDataReadingMappedIfSafe
error:nil];
NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
[arch setClass:self forClassName:@"SKScene"];
SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
[arch finishDecoding];
return scene;
}
@end
@implementation GameScene1
#include "GoodsConstants.h"
-(void) initStaticLevelElements {
self.staticLevelElements = [[NSMutableArray alloc] init];
self.name = @"name for scene one";
SKNode * statics = [self childNodeWithName:@"statics"];
statics.zPosition = 100;
SKSpriteNode * e = (SKSpriteNode *)[statics childNodeWithName:@"house1"];
NSLog(@"house one is: %@", e);
}
GameScene1.h 是:
// GameScene1.h
#import <SpriteKit/SpriteKit.h>
#import "GameScene.h"
@interface GameScene1 : GameScene
@end
SKSpriteNode+StaticLevelElement.h 是:
// SKSpriteNode+StaticLevelElement.h
#import <SpriteKit/SpriteKit.h>
#import <SpriteKit/SKSpriteNode.h>
@interface SKSpriteNode (StaticLevelElement)
-(void) initWithSKNode:(SKNode *)node;
@property NSNumber * pseudoDepth;
@end
SKSpriteNode+StaticLevelElement.m 是:
//SKSpriteNode+StaticLevelElement.m
#import <objc/runtime.h>
#import "SKSpriteNode+StaticLevelElement.h"
NSString * const pseudoDepthSelector = @"pseudoDepth";
@implementation SKSpriteNode (StaticLevelElement)
@dynamic pseudoDepth;
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
self.userInteractionEnabled = YES;
return self;
}
- (void)setPseudoDepth:(NSNumber *)pseudoDepth
{
objc_setAssociatedObject(self, (__bridge const void *)(pseudoDepthSelector), pseudoDepth, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSNumber *)pseudoDepth
{
return objc_getAssociatedObject(self, (__bridge const void *)(pseudoDepthSelector));
}
-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
}
-(void) touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
}
@end
为了设置每个场景(级别)的具体数据,我使用了基本 GameScene 的继承 class - 因此我得到了 GameScene1、GameScene2 等。 有谁知道我错过了什么才能看到纹理?
我从中删除了 initWithCoder 覆盖方法 SKSpriteNode+StaticLevelElement.m 现在一切正常,纹理和精灵都显示在屏幕上。