IOS SpriteKit Colision Detection: Resetting Positi

2019-09-22 07:41发布

问题:

I'm attempting to make a game with objects that bounce between the left and right walls of the screen until they reach the bottom.

Currently, my working didBeginContact method looks like this:

- (void)didBeginContact:(SKPhysicsContact *)contact {
    uint32_t collision = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask);

    if (collision == (crabCategory | leftWallCategory)) {
    // figure out which crab in the array made the contact...
        for(HHCrab *object in crabs) {
            if(([object.name isEqualToString:contact.bodyB.node.name]) || ([object.name isEqualToString:contact.bodyA.node.name])) {
                [object stop];
                [object moveRight];
            }
        } 
    } else if (collision == (crabCategory | rightWallCategory)) {
    // figure out which crab in the array made the contact...
        for(HHCrab *object in crabs) {
            if(([object.name isEqualToString:contact.bodyB.node.name]) || ([object.name isEqualToString:contact.bodyA.node.name])) {
                [object stop];
                [object moveLeft];
            }
        }
    }

When I attempt to add an additional statement:

else if (collision == (crabCategory | bottomWallCategory)) {
    // figure out which crab in the array made the contact...
    for(HHCrab *object in crabs) {
        if(([object.name isEqualToString:contact.bodyB.node.name]) || ([object.name isEqualToString:contact.bodyA.node.name])) {
            [object stop];
            [object resetPosition];
            [object moveLeft];
        }
    }
}

to reset the crabs position when they reach the bottom of the screen, the crabs will not move. In a previous question I was made aware that this may be due to the fact that drawing the crab was being overwritten by the physics simulation. We solved the issue by creating a Boolean which would be toggled on and off when the crab intersects the bottom wall, and then repositions the crab in the didSimulatePhysics method as such:

-(void)didSimulatePhysics{
    if(self.shouldResetPosition){
       self.player.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY(self.frame)- _player.size.height-30);
        self.shouldResetPosition = NO;
    }
}  

Although this works with one crab, now that I am using an NSMutable Array of Crabs each with a unique name, it does not. I tried moving the Boolean value to the Crab class, so each crab has that property but this did not solve the problem.

回答1:

You need to do some study on OOD (Object Oriented Development) concepts. I'd suggest buying a book on Objective-C programming that teaches those concepts.

You're on the right track creating a custom Crab object. Make it a subclass of UIView (or of a custom base class, but ignore that for a moment). Then you might create an "Arena" or "Scene" object that would serve as the container for your crab objects. It would have a mutable array that would hold your array of crab objects.

You might want to generalize your Arena object so it manages an array of abstract view objects that know how to draw themselves and have some common animation setup methods. Create a base class for all your custom view objects, and then make the crab object a subclass of this custom view object. That way, if you later want to add Fish objects, or Snail objects, or even Boat objects or Net objects or whatever, you can do so without having to re-do everything.

You could use UIView animation or Core Animation to make your crab objects animate by themselves, or you could use timers and frame-based animation. You'll get smoother animation and better performance using one of the built-in animation approaches.

Your control code would spawn multiple custom view objects (e.g. 10 Crabs, 12 Fish, a Boat, a Fisherman, and a Net), configure them for location and speed/behavior, and add them to the arena object. (The arena would likely add them to an array in order to keep track of them.) The arena object would then manage those objects using the shared methods of the base class.



回答2:

Try using objects.

An object CRAB class can be created with those methods in place.

Then for each crab, create an instance of the CRAB class and add them to an array for reference.

Basically, you shall end up with an array of CRAB classes.

Have Fun Coding :)



回答3:

I would create a class crab reflecting this object. Thus the class would consist out of several functions as well as attributes. Then you application could hold a list or an array of several crabs. Furthermore, each crab would behave similar.