我之前写过一个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代码的更多相关文章

  1. SpriteBuilder中使用GUI界面快速搭建RPG游戏中的地图名显示动画

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在RPG游戏中我们在进入一个新的场景时,比如一个房间,一个村庄, ...

  2. 在 OC 中调用 Swift 代码

    1.在 Objective-C 项目中使用 Swift 代码 1)在 OC 项目中创建 .Swift 文件,文件中的格式为其本有的格式. 2)Xcode 提示是否创建 Objective-C brid ...

  3. RPG游戏中如何判断敌人是否在玩家的攻击范围之内

    // 方式1:通过主角和场景中的所有敌人比较 private void AtkCondition1(float _range,float _angle) { // 搜索所有敌人列表(在动态创建敌人时生 ...

  4. 概念:RPG游戏中两个兵种互相攻击的逻辑

    直接上题目: 解析题目: 根据题目的解析,进行代码的实现: 输出结果: 心得: (1) 当我们面对‘公式结果不是我们想要的’时,应该在脑海里将一个完整的攻击流程进行想象,就会对流程有个更清晰的思路 ( ...

  5. 项目中 添加 swift代码 真机调试 错误

    错误: dyld: Library not loaded: @rpath/libswiftCore.dylib Referenced from: /private/var/mobile/Contain ...

  6. 在Objc项目中调用Swift

    之前的文字中记录了在Swift项目中调用OC的相关代码,比较简单直接 传送门 但是在OC中调用swift代码则不是那么的和谐,网络上很多文章业已经有点陈旧.记录步骤如下: 1.创建OC项目 (1)启动 ...

  7. Swift & Objc 在同一个项目中的使用

    在WWDC大会中发布了Swift让人眼前一亮.终于加了很多的现代编程语言该有的东西.很早年以前玩C#3.0+的时候这些差不多类似的 已经用的烂熟的东西终于一点一点的在看Swift Programmin ...

  8. 在同个工程中使用 Swift 和 Objective-C(Swift 2.0更新)-b

    本节包含内容: Mix and Match 概述(Mix and Match Overview) 在同个应用的 target 中导入(Importing Code from Within the Sa ...

  9. Using Swift with Cocoa and Objective-C--在同个project中使用Swift和在同个project中

    http://www.cocoachina.com/newbie/basic/2014/0605/8688.html watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5u ...

随机推荐

  1. 【js 笔记】读阮一峰老师 es6 入门笔记 —— 第一章

      鉴于最近用 vuejs 框架开发项目,其中有很多涉及到 es6 语法不太理解所以便认真地读了一下这本书. 地址:http://es6.ruanyifeng.com/#README 第一章:let ...

  2. 数据结构-快速排序(C#实现)

    快速排序的主要思路: 1.在数组首尾处各设一个标记 2.取出数组第一个值作为中枢值 3.所有数据跟中枢值比较:比中枢值小的放中枢值左边,首部标记++往右推一位,大的放中枢值右边,尾部标记--往左推一位 ...

  3. Unity3D UGUI 自动调节大小

    可添加以下组件 组件包含的两个枚举参数,可以自行设定适应方式. 例如一个Text UI元素,当文字过多的时候他不会自动增加高度而导致文字不能完全显示,这时候就可以挂载这个组件,如上图设置参数,就可以自 ...

  4. servlet之cookie实现

    三个servlet的实现: package app02c;import java.io.IOException;import java.io.PrintWriter;import javax.serv ...

  5. 第三届“百越杯”福建省高校网络空间安全大赛_Do you know upload?

    题目在i春秋的ctf训练营 既然是上传,那就直接抓包 二话不说上来先给个00截断传个一句话助助兴 直接就成功了.... 赶紧操起菜刀去连接 进去之后发现ctf.sql是个空文件,那么flag应该在数据 ...

  6. thymeleaf-迭代

    迭代 1.迭代基础 要在/WEB-INF/templates/product/list.html页面中显示产品,将使用一个表格.都将显示在一行(一个<tr>元素),所以对于我们的模板,我们 ...

  7. [HNOI 2001]求正整数

    Description 对于任意输入的正整数n,请编程求出具有n个不同因子的最小正整数m.例如:n=4,则m=6,因为6有4个不同整数因子1,2,3,6:而且是最小的有4个因子的整数. Input n ...

  8. [SCOI2008]天平

    题目描述 你有n个砝码,均为1克,2克或者3克.你并不清楚每个砝码的重量,但你知道其中一些砝码重量的大小关系.你把其中两个砝码A 和B 放在天平的左边,需要另外选出两个砝码放在天平的右边.问:有多少种 ...

  9. 【HNOI2017】影魔

    题目描述 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄. 每一个灵魂,都有着自 ...

  10. ●BZOJ 1416 [NOI2006]神奇的口袋

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1416题解: Pòlya瓦罐模型: 给定罐子里每种颜色的球的个数A[i],按题目要求随机操作若 ...