在 cocos2d 中子类化精灵

发布于 2024-11-07 01:07:38 字数 242 浏览 0 评论 0原文

几天前,我开始使用cocos2d。我真的很喜欢这个框架。我想用 cocos2d 创建一个游戏,并且有一个可能简单的问题...

我正在制作一个有 4 个角色的游戏,它们都有相似的特征,但有一些不同的属性,如“类型”和“点”。我想将精灵子类化为一个类,该类处理它们的所有逻辑、绘图和动画。

但我的问题是,如何使用“类型”参数 1、2、3 或 4 来调用精灵类,然后让该类使用所有单独的逻辑将正确的精灵绘制到我的场景中?

谢谢!

A few days ago, I started working with cocos2d. I really like the framework. I would like to create a game with cocos2d and have a probably simple question...

I am making a game with 4 characters, which all have similar characteristics, but have some different attributes like "type" and "points". I'd like to subclass the sprites into one class which handles all their logic, drawing, and animation.

My question though, is how do I call the sprite class with say, a "type" parameter of 1, 2, 3, or 4 and then have the class draw the correct sprite into my scene with all of it's individual logic?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

伪装你 2024-11-14 01:07:38

您应该有一个 Enemy 类,其中包含特定敌人的属性且不是特定于类型的(例如位置、当前生命值、CCSprite 实例?),以及一个 EnemyType 类,其中包含特定类型的所有敌人之间共享的属性(最大生命值) ,最大速度,大小,精灵文件名)。您应该在加载关卡之前加载敌人类型,而不是在构造函数中使用适当的类型实例化每个敌人。

例如,如果关卡文件中的敌人元素如下所示

<enemy><type>spider</type>...more properties...</enemy>

代码(伪)将执行类似的操作

   EnemyType *enemyType = nil;
   if (typeElement.value == "spider")
   {
       enemyType = spiderType;
   }
   Enemy *newEnemy = [Enemy enemyWithType:enemyType];

另外,Enemy 类应包含代表它的 CCSprite,而不是它的子类。敌人不是精灵,所以除非我错过了一些东西,否则敌人不应该继承精灵。我读过有关何时包含和何时继承

编辑:
另一篇值得阅读的好文章看起来非常相关,并且可能可以传达一些其他信息比我好。

不管怎样,我的目的并不是让你认为你应该重新考虑你的整个设计。我的建议是“更好”的 MVC,但这并不意味着它更适合您的游戏。如果你把所有的时间都花在“设计正确性”上,你永远不会完成一个游戏,特别是如果你刚刚学习 cocos2d 框架,我实际上不久前正在做一个学习项目,史蒂夫·麦康奈尔本人会过来并如果他看到了就扇我一巴掌。

如果您独自开发一款游戏,并且这是一个小项目,那么如果您更容易管理的话,可以继续进行子类化,那么包括“设计正确性”在内的所有内容都需要正确量化(可能使用“goto”语句除外) :) )。

You should have an Enemy class that contains properties of specific enemies and that are not type specific (like position, current health, a CCSprite instance?) and an EnemyType class that contains properties that are shared among all enemies of a specific type (max health, max speed, size, sprite filename). You should load your enemy types prior to loading the level, than instantiate each enemy using the appropriate type in the constructor.

For example if your enemy element in the level file looks like this

<enemy><type>spider</type>...more properties...</enemy>

The code (pseudo) would do something like

   EnemyType *enemyType = nil;
   if (typeElement.value == "spider")
   {
       enemyType = spiderType;
   }
   Enemy *newEnemy = [Enemy enemyWithType:enemyType];

Also the Enemy class should contain the CCSprite that represents it, not subclass it. An enemy is not a sprite, so unless I'm missing something, as i see it, an enemy should not inherit from a sprite. I'd read about when to contain and when to inherit.

EDIT:
Another nice post to read that seems very relevant and could communicate a few other things probably better than me.

Anyway, my intention was not to make you think you should just rethink your entire design. What i'm proposing is "better" MVC-wise, but it doesn't mean it's better for your game. If you spend all your time on "design correctness" you'll never get a game done, especially if you're just learning the cocos2d framework, i was actually making a learning project not too long ago and Steve McConnel himself would come over and slap me if he saw it.

If you're working on a game alone and it's a small project go ahead and subclass away if it's going to be more manageable to you, everything, including "design correctness" needs to be properly quantified (except maybe usage of "goto" statements :) ).

陌路终见情 2024-11-14 01:07:38

这种方式的多态性可以通过几种不同的方式来实现,其中一些方式比其他方式更好。
1)您可以尝试覆盖 init 或 node 方法并在那里设置您的对象。

+(CCSprite *)node
{
    MySprite * returnSprite = [super node];
    returnSprite.hat = @"fedora";
    returnSprite.hatImage = [CCSprite spriteWithImage:...];

}

2)使用反射(psuedocode)

-(void)drawingMethodHere
{
     [self.hat drawAtPoint:somePoint];
}

然后覆盖-(CCNode *)hat来反映类型。

你可能需要将它们结合起来,但是在开始之前先计划一下,你最终会节省很多时间。

polymorphism in this way can be done a couple of different ways, some better than others.
1) you could try to just override the init or node method and set up your object there.

+(CCSprite *)node
{
    MySprite * returnSprite = [super node];
    returnSprite.hat = @"fedora";
    returnSprite.hatImage = [CCSprite spriteWithImage:...];

}

2) use reflection (psuedocode)

-(void)drawingMethodHere
{
     [self.hat drawAtPoint:somePoint];
}

then override -(CCNode *)hat to reflect the type.

you may have to do some combination of them, but plan a little before you start, you will end up saving a lot of time.

卖梦商人 2024-11-14 01:07:38

您应该子类化 CCNode 而不是子类化 CCSprite。

我认为你的问题很简单。只需创建一个名为“角色”的基类,它具有通用的逻辑、属性等。然后创建 4 个其他类,如敌人、玩家等,并从“角色”基类创建子类。请注意,字符库应该是 CCNode 的子类。

现在您可以重写逻辑以满足您在特定类中的需求。现在您将能够使用多态性,这很好。

对于你的精灵,我会说创建一个 CCSprite 类型的实例变量,然后创建用图像初始化的方法。然后,您只需在初始化对象时将该精灵添加为子对象即可。

You should subclass CCNode instead of subclassing CCSprite.

I think your problem is quite easy. Just create a base class called Character, which has the common logic, properties etc etc. Then you create 4 other classes like, enemy, player and so on and subclass from Character base. Note the character base should be subclassing CCNode.

Now you override the logic to fit your needs in the specific class. Now you will be able to use polymorphism, which is good.

For your sprite I would say create an instance variable of the CCSprite type and then create methods to initialize with an image. Then you will just add that sprite as a child when initializing the object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文