Cocos2D-ObjC:在RPG游戏中混合Swift代码
来源:互联网 发布:怎样把nginx部署到公网 编辑:程序博客网 时间:2024/05/01 18:14
我之前写过一个RPG游戏<<熊猫之魂 SoulOfPanda>>
编译器使用的是SpriteBuilder,很好很强大!全部代码都由Objc完成,现在想尝试一下在其中混入Swift代码.
我的目的很简单,用Swift写一个GCMan9类,派生自Objc中的GameCharacter类,最后在Objc中使用GCMan9这个类.
GameCharacter类是游戏人物的基类,我从中派生了十几个子类分别表示游戏主角,各种NPC,各种敌人等等.
下面是GCMan1类的头文件:
#import "GameCharacter.h"@interface GCMan1 : GameCharacter@end
接着是实现文件:
#import "GCMan1.h"#import "CCAnimation+Helper.h"@implementation GCMan1-(id)initWithGameScene:(GameScene *)gameScene{ self = [super initWithGameScene:gameScene andImageNamed:@"man1_forward_2.png"]; if (self) { _facingForwardAnimation = [CCAnimation animation:@"man1" middle:@"forward" frameCount:3]; _facingBackAnimation = [CCAnimation animation:@"man1" middle:@"back" frameCount:3]; _facingLeftAnimation = [CCAnimation animation:@"man1" middle:@"left" frameCount:3]; _facingRightAnimation = [CCAnimation animation:@"man1" middle:@"right" frameCount:3]; self.speedPerStep = 0.4; self.isNPC = YES; self.gcName = @"GCMan1"; } return self;}@end
可以看到GCMan1里只是根据实际角色初始化对应的纹理和动画,值得注意的是_facingForwardAnimation之类的变量是在其父类GameCharacter中定义的,如下:
@interface GameCharacter : CCSprite{@protected GameScene *_gameScene; //移动的4个方向动画 CCAnimation *_facingForwardAnimation; CCAnimation *_facingBackAnimation; CCAnimation *_facingLeftAnimation; CCAnimation *_facingRightAnimation;}
这些变量增加了保护修饰,这里提一下,因为之后的Swift代码要在这里折腾一下.
按道理,如果在一个纯Objc项目中创建一个Swift文件,Xcode会提示你是否创建一个桥接文件,但是我这里并没有提示,所以我们得手动创建一个,格式是
项目名-Bridging-Header.h
里面导入需要在Swift文件中需要使用的类的头文件,在这里其内容是这样的:
#ifndef SoulOfPanda_Bridging_Header_h#define SoulOfPanda_Bridging_Header_h#import "GameCharacter.h"#import "GameScene.h"#endif /* SoulOfPanda_Bridging_Header_h */
然后新建一个GCMan9.swift文件,内容与Objc中的类似:
class GCMan9:GameCharacter{ override init(gameScene: GameScene!, andImageNamed imageName: String!) { super.init(gameScene: gameScene, andImageNamed: imageName) } override init(gameScene:GameScene?){ super.init(gameScene: gameScene, andImageNamed: "man1_forward_2.png", andTintColor: UIColor.orangeColor()) //怎么设置父类中的保护变量??? speedPerStep = 0.4 isNPC = true gcName = "GCMan9" } }
现在问题来了,父类中的几个@protected定义的变量在Swift中不可见!查阅了一些资料没找到解决办法,只有采用迂回方法,回到GameCharacter.m中新建一个帮助方法:
//设置GameCharacter类中的保护变量,在Swift中调用-(void)setFacingAnimation:(NSString *)name frameCount:(int)count{ _facingForwardAnimation = [CCAnimation animation:name middle:@"forward" frameCount:count]; _facingBackAnimation = [CCAnimation animation:name middle:@"back" frameCount:count]; _facingLeftAnimation = [CCAnimation animation:name middle:@"left" frameCount:count]; _facingRightAnimation = [CCAnimation animation:name middle:@"right" frameCount:count];}
同时别忘了在GameCharacter.h接口中导出该方法,回到GCMan9.swift文件中,将注释那一行替换为如下代码:
setFacingAnimation("man1", frameCount: 3)
因为你要在Objc中使用Swift中的类,所以你需要在对应的m文件中包含如下h文件:
#import "SoulOfPanda-Swift.h"
文件名格式很简单就是”项目名-Swift.h”
在实际测试之前,我们还要找到游戏某个场景的plist文件,将其中的NPC类名换为GCMan9:
运行一下游戏,咦怎么崩溃挂掉了…检查一下栈回溯,发现在以下方法中有问题:
//返回一个"假的"的GC对象,只能用于显示和获取数据,不能实际在场景中存在+(instancetype)gcFakeWithName:(NSString *)name{ Class class = NSClassFromString(name); GameCharacter *gc = [[class alloc] initWithGameScene:nil]; return gc;}
仔细一看,发现NSClassFromString方法返回的是nil,虽然name是正确的@”GCMan9”.
测试了一下发现使用如下代码是没有问题的:
GCMan9 *man9 = [[GCMan9 alloc]initWithGameScene:gameScene];
难道是Swift中的类名在Objc中看到的有所不同么?查看Apple开发文档发现,果然如此!在Swift定义的类在Objc代码中实际看到的名字需要加上前缀,即GCMan9在Objc中看到的名字是SoulOfPanda.GCMan9,所以要把代码修改如下:
Class class = NSClassFromString(@"SoulOfPanda.GCMan9");
但问题还是没有解决,我不想一个一个的添加判断语句,这样非常的繁琐.相反我要利用Swift中提供了一个很好的特性,就是@objc伪指令,该指令告诉Swift不要在类名前添加前缀.回到GCMan9.swift在开头添加如下一句:
@objc(GCMan9)class GCMan9:GameCharacter{
现在运行代码,终于OK啦:
- Cocos2D-ObjC:在RPG游戏中混合Swift代码
- 在swift中 @objc 、private 和事件问题
- 在一个项目中同时使用Swift和Objective-C代码混合编程的方法
- RPG游戏(C++)代码
- cocos2d-x自制RPG游戏总结
- @objc在swift语法中的使用场景
- 使用JNI进行混合编程:在C/C++中调用Java代码--------------------cocos2d-x 3.0正式版本(7.5)
- RPG类游戏主角移动的代码
- 在objc中使用struct
- 早期Swift中Cocos2D初始化代码的重构
- 状态机在RPG游戏中的应用举例
- Cocos2D实现RPG游戏人物地图行走的跟随效果
- RPG游戏
- RPG游戏中造过的BUG
- Swift 中 Selector 方法的访问权限控制问题 @objc
- 在ObjC中使用私有方法
- 在objc项目中使用常量
- swift: @objc的使用
- UVA - 1586 Molar mass?
- UVA - 1588 Kickdown
- 自定义TTF多语言版本之台湾繁体
- UVA - 10361 Automatic Poetry
- 九、STL算法-变值算法(copy、transform)
- Cocos2D-ObjC:在RPG游戏中混合Swift代码
- UVA - UVA - 537 Artificial
- 基于Yarn平台的MapReduce运行机制
- UVA - 409 Excuses, Excuses!
- UVA - 10878 Decode the tape
- NOIP提高组A组7.7模拟总结
- Dynamic len
- UVA - 644 Immediate Decodability
- css3新增属性设置图片特效