0

我正在开发一个非常简单的游戏。这是我的敌人类名为 Machine 的行为代码:

#import "Machine.h"

@implementation Machine

+(id)machineWithWorld:(b2World*)world position:(CGPoint)pos
{
    return [[[self alloc] initWithWorld:world position:pos] autorelease];
}

-(id)initWithWorld:(b2World*)world position:(CGPoint)pos
{
    if(self = [super initWithShape:[AppDelegate renameFrameForIpad:@"machine"] inWorld:world])
    {
        size = [CCDirector sharedDirector].winSize;

        self.body->SetTransform([Helper toMeters:pos], 0.0);
        self.body->SetType(b2_staticBody);

        safetyCounter = 5;
        [self schedule:@selector(machineSafetyCounter)];

        movementWidthInMeters = (size.width-self.contentSize.width)/PTM_RATIO;
        linearSpeed = 0.5;
        [self schedule:@selector(startMoving) interval:1.5];
    }

    return self;
}

#pragma mark<Machine Behavior>

-(void)startMoving
{
    [self unschedule:_cmd];

    float distanceFromCenterInMeters = (size.width/2 - self.position.x)/PTM_RATIO;
    float interval = ABS(distanceFromCenterInMeters/linearSpeed);
    if(interval < 0.01f)
        interval = 0.02f;

    b2Vec2 motionDirection = (distanceFromCenterInMeters > 0.0f) ? b2Vec2(1.0, 0.0) : b2Vec2(-1.0, 0.0);
    self.body->SetType(b2_kinematicBody);
    self.body->SetLinearVelocity(linearSpeed*motionDirection);

    [self schedule:@selector(startMotionFromBeginning) interval:interval-0.01];

    CCLOG(@"startMoving distance-->%f, interval-->%f", distanceFromCenterInMeters, interval);
}

-(void)startMotionFromBeginning
{
    [self unschedule:_cmd];

    float interval = (movementWidthInMeters/2)/linearSpeed;

    self.body->SetLinearVelocity(0.5*b2Vec2(1.0, 0.0));
    [self schedule:@selector(moveRTL) interval:interval-0.01];

    [self schedule:@selector(checkIfHelmetIsBelowMachine) interval:0.1];

    CCLOG(@"startMotionFromBeginning interval-->%f", interval);
}

-(void)moveRTL
{
    [self unschedule:_cmd];

    float interval = movementWidthInMeters/linearSpeed;

    self.body->SetLinearVelocity(0.5*b2Vec2(-1.0, 0.0));
    [self schedule:@selector(moveLTR) interval:interval-0.01];

    CCLOG(@"moveRTL interval-->%f", interval);
}

-(void)moveLTR
{
    [self unschedule:_cmd];

    float interval = movementWidthInMeters/linearSpeed;

    self.body->SetLinearVelocity(0.5*b2Vec2(1.0, 0.0));
    [self schedule:@selector(moveRTL) interval:interval-0.01];

    CCLOG(@"moveLTR interval-->%f", interval);
}

-(void)checkIfHelmetIsBelowMachine
{
    [self unschedule:_cmd];

    Helmet* helmet = (Helmet*)[[[[[CCDirector sharedDirector] runningScene] children] objectAtIndex:0] getChildByTag:kTagHelmet];
    float helmetPosX = helmet.position.x;

    if((self.position.x > helmetPosX) && (self.position.x < helmetPosX+helmet.contentSize.width))
    {
        [self unscheduleAllSelectors];
        [self schedule:@selector(machineSafetyCounter) interval:0.1];

        [self schedule:@selector(startMovingDownwards) interval:0.0];

        return;
    }

    [self schedule:_cmd interval:0.1];
}

-(void)startMovingDownwards
{
    [self unschedule:_cmd];

    self.body->SetLinearVelocity(0.25*b2Vec2(0.0, -1.0));
    [self schedule:@selector(stopMovingDownwards) interval:1.0];

    CCLOG(@"startMovingDownwards");
}

-(void)stopMovingDownwards
{
    [self unschedule:_cmd];

    self.body->SetLinearVelocity(b2Vec2(0.0, 0.0));
    [self schedule:@selector(startMoving) interval:0.2];

    CCLOG(@"stopMovingDownwards");
}

我所做的一切如下:

1) body 最初是静态的,定位在 ccp(size.width*0.5, size.height*0.75)。

2) 1.5 秒后,它开始运动并开始以 0.5 m/s 的线速度移动。

3)它检查它的当前距离(从屏幕宽度中心保持高度相同),评估到达该点所需的时间,然后开始沿该方向水平移动。

4)到达那个点后,它开始它的标志性运动,它开始从左到右移动,如果任何时候头盔(另一个游戏对象)从它下面经过,它开始向下移动并在1.0秒后停止,然后整个循环重复。

5)它移动 LTR 和 RTL 直到它在它下面找到头盔时开始向下移动。

现在的问题是,有时行为与预期完全相同。很多次,它开始向上移动,我从来没有为正方向的运动矢量设置 y 位。

4

1 回答 1

0

初始化body后,你不应该改变它bodyType.。当你第一次制作body时,将它设置为kinematic,这样你以后尝试改变它时就不会遇到问题。身体是否附着在一个CCSprite? 如果是这样,您应该使该类成为其子类,CCSprite以便您可以使用
[super initWithFile:(NSString *) world:(b2World *)]或您选择的某种方法来促进您的努力。

于 2013-04-02T16:12:41.567 回答