NSMutableArray Acting Weird - ios

I have an NSMutableArray in my game, in which the array stores "cloud" objects. When spawning the cloud, I iterate through the array and check whether there is a cloud that is nearby, if there is, then I do not spawn the cloud. Here is the code:
BOOL isCloudInRange = NO;
float distance;
do {
//Horizontal Position
isCloudInRange = NO;
if (self.sprite.physicsBody.velocity.dx > 0) {
cloud.position = CGPointMake(self.sprite.position.x + HW*16/5, 0);
}
else if (self.sprite.physicsBody.velocity.dx <0) {
cloud.position = CGPointMake(self.sprite.position.x-HW*16/5, 0);
}
else {
cloud.position = CGPointMake(self.sprite.position.x, 0);
}
//Vertical Position
int offset = arc4random() % (int) 2*self.frame.size.height;
offset -= (int) (self.frame.size.height);
if (self.sprite.physicsBody.velocity.dy > 0) {
cloud.position = CGPointMake(cloud.position.x, self.sprite.position.y + offset + self.sprite.physicsBody.velocity.dy);
}
else if (self.sprite.physicsBody.velocity.dy <0) {
cloud.position = CGPointMake(cloud.position.x, self.sprite.position.y - offset - self.sprite.physicsBody.velocity.dy);
}
else {
cloud.position = CGPointMake(cloud.position.x, self.sprite.position.y + 16*HW/5);
}
if (cloud.position.y <= 300) {
cloud.position = CGPointMake(cloud.position.x, 100 + arc4random() %200);
}
// THIS IS WHERE THE ERROR HAPPENS
for (SKNode *myNode in arrayOfClouds) {
float xPos = myNode.position.x;
float yPos = myNode.position.y;
distance = sqrt((cloud.position.x - xPos) * (cloud.position.x - xPos) + (cloud.position.y - yPos) * (cloud.position.y - yPos));
if (distance < 300.0f) {
NSLog(#"%f",distance);
isCloudInRange = YES;
}
}
} while (isCloudInRange);
If the bottom piece of code is changed to if (distance < 150.0f) everything works fine. If the distance is kept at 300.0f, however, in a couple seconds or runtime, the game starts iterating forever. Here is an example of a typical log file with this code:
![hola][1]
Click this link if above image doesn't appear (I don't know why it isn't): http://i.stack.imgur.com/qX8h7.png
The logged floats are the distances between the cloud and whatever cloud is nearby. None of these distances seem to match (I don't have a million clouds spawning every second, they're set to spawn every second or so), and since it freezes with these logs as soon as the game starts, I know there cannot be that many clouds. What is happening? Please help.. Thanks!

The main issue I can see here is the following:
You have a do..while loop running checking your cloud distance. Once a cloud is in range, you mark it as YES and re-run the loop. The cloud's X position is never changed in the loop which means it will never move out of range again (infinite loop).
Ideally this is a check that should happen once per game loop (remove the do while).
Also it will be a little more efficient if you put a break; in your for loop. Once a cloud has been found in range there is no need to check the others so you may as well end you loop here.
for (SKNode *myNode in arrayOfClouds) {
float xPos = myNode.position.x;
float yPos = myNode.position.y;
distance = sqrt((cloud.position.x - xPos) * (cloud.position.x - xPos) + (cloud.position.y - yPos) * (cloud.position.y - yPos));
if (distance < 300.0f) {
NSLog(#"%f",distance);
isCloudInRange = YES;
break; // <--drop out of the for each loop now
}
}

You say "When spawning the cloud, I iterate through the array and check whether there is a cloud that is nearby, if there is, then I do not spawn the cloud" but to me it looks like your doing the exact opposite. If a cloud is in range (<300) you set isCloudInRange to yes and repeat. Once there are enough clouds it always finds a cloud in range it should loop indefinitely. The more clouds you spawn the harder and harder this is to every get out of the loop ( noting you set it to no at top)
If you are moving clouds and checking to create them on the same thread ( same run loop of code or function calls that are synchronous), you can try moving this code to a background thread, using dispatch_asynch(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), your code block here); and see if that helps.
Info on how to set up concurrency with dispatch_asynch is here:
https://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/ConcurrencyProgrammingGuide.pdf
and blocks are explained:
https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html#//apple_ref/doc/uid/TP40011210-CH8-SW1

Related

Simple combo multiplier in sprite-kit

I am making a reaction game, where you can destroy enemys and earn points. Now I would like to have combo points if you destroy them fast and if there is a specific time gap the combo multiplier should go to zero again.
I would like to multiple the points like this: 2 * 2 = 4 * 2 = 8 * 2 = 16 * 2...
(you get 2 points if you destroy an enemy).
I add the points here:
if (CGRectIntersectsRect(enemy.frame, player.frame)) {
points = points + 1;
[enemy removeFromParent];
}
I could always multiply the current points with 2, but I want to reset the combo multiplier if there is specific amount of time without getting points.
I hope someone can help me.
(code in objective c please)
It seems no more complicated than recording the time the last enemy was destroyed and then in the update: method deciding if the combo has elapsed as no more enemies were hit in whatever timeout period you allow.
I am not familiar with Sprite kit, but the update appears to pass the current time; excellent. You will need to record the following:
timeout (time): The current timeout. This will reduce as the game progresses, making it harder.
lastEnemyKillTime (time): the time the last enemy was killed.
comboPoints (integer): How many points the user gets per hit. This will increase as the combo extends.
points (integer): The current score.
So, something like this:
#interface MyClass ()
{
NSTimeInterval _timeout;
NSTimeInterval _lastEnemyKillTime;
BOOL _comboFactor;
NSUInteger _points;
}
#end
I guess Sprite Kit uses an init: method; use it to initialize the variables:
- (id)init
{
self = [super init];
if (self != nil) {
_timeout = 1.0;
_lastEnemyKillTime = 0.0;
_points = 0;
_comboPoints = 1;
}
}
The update: method would be something like:
- (void)update:(NSTimeInterval)currentTime
{
BOOL withinTimeout = currentTime - _lastEnemyKillTime <= _timeout;
if (CGRectIntersectsRect(enemy.frame, player.frame)) {
_inCombo = withinTimeout;
if (_inCombo)
_comboPoints *= 2;
_points += _comboPoint;
_lastEnemyKillTime = currentTime;
[enemy removeFromParent];
} else if (_comboPoints > 1 && !withinTimeout) {
_lastEnemyKillTime = 0.0;
_comboPoints = 1;
}
}
You need to keep track on the last enemy casual timestamp and the factor. When the next kill is processed, you check the timestamp, if it is below threshold, you raise the factor. The time of the current kill replaces the timestamp.
You could create a FightRecorder class as singleton, if you don't have a better place yet (services or sth).
NSDate *newKillTime = new NSDate;
FightRecorder recorder = [FightRecorder instance];
if([newKillTime timeIntervalSinceDate:recorder.lastKillTime] < SCORE_BOUNDS_IN_SEC) {
recorder.factor++; // could also be a method
points = points + [recorder calculateScore]; // do your score math here
}
else {
[recorder reset]; // set the inner state of the fight recorder to no-bonus
}
recorder.lastKillTime = newKillTime; // record the date for the next kill

How to know when all physics bodies have stopped moving in Cocos2d V3.0 with Chipmunk

The only way I can think to do it is to check velocities for all physics bodies during every collisions.
- (BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair piece:(CCNode *)pieceA piece:(CCNode *)pieceB{
float x = 0;
float y = 0;
for (int i = 0; i < [[_physicsWorld children] count]; i++) {
x = x + [[[_physicsWorld children][i] physicsBody] velocity].x;
y = y + [[[_physicsWorld children][i] physicsBody] velocity].y;
}
if ( x == 0 && y == 0 ) {
NSLog(#"stopped");
}
return YES;
}
This logs “stopped” multiple times when the scene first loads, then doesn’t log “stopped” again, even after physics bodies have clearly started moving and colliding and then come to a stop.
Ideally I'd like a delegate method that would notify me when all physics bodies have stopped moving, but I can't seem to find one.
FYI: I'm using the standard Chipmunk physics engine that's baked into Cocos2d V3.0
Chipmunk has a internal mechanism, which can, if activated, automatically deactivate physics bodies. My approach (I am using cocos2dx 3.11.1 and not -obj version with chipmunk 7.0.1) is:
activate the chipmunk idle mechanism (0.5 second - meaning, if an object is not moving for longer than 0.5 second it will be deactivated):
cpSpaceSetSleepTimeThreshold(space, 0.5f);
You do not need to use
cpSpaceSetIdleSpeedThreshold(space, <speed>);
because chipmunk calculates the threshold speed for you (according the gravitation used).
use this code for determination if all objects are not moving (static and kinetic bodies never sleep):
bool isAnyPhysicsBodyMoving(){
int i = 0; bool isMoving = false;
const Vector<PhysicsBody*>& bodies = getPhysicsWorld()->getAllBodies();
while( i < bodies.size() && !isMoving){
PhysicsBody *body = bodies.at(i);
isMoving = cpBodyGetType(body->getCPBody()) == CP_BODY_TYPE_DYNAMIC
&& !body->isResting();
i++;
}
return isMoving;
}
use static (and not kinetic) body for walls, in order to let objects sleep:
// wall
Size visibleSize = Director::getInstance()->getWinSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
float border = 10.0f;
Size wallBodySize = Size(visibleSize.width+2*border, visibleSize.height+2*border);
PhysicsBody *wallBody = PhysicsBody::createEdgeBox(wallBodySize, PhysicsMaterial(1.0f, 1.0f, 0.5f), border);
Node* wall = Node::create();
wall->addComponent(wallBody);
wall->setAnchorPoint(Vec2(0.5f, 0.5f));
wall->setPosition(Point(visibleSize.width/2+origin.x, visibleSize.height/2+origin.y));
cpVect tt;
tt.x = wall->getPosition().x; tt.y = wall->getPosition().y;
//set position manually and BEFORE adding the object into the space
cpBodySetPosition(wallBody->getCPBody(), tt);
cpBodySetType(wallBody->getCPBody(), CP_BODY_TYPE_STATIC);
addChild(wall);
Any dynamic body connected to a kinetic body (for example laying on) will never sleep.
test it with DEBUG activated
getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
the boxes (their content) must become grey (=sleeping) and not red (=active):
In order to let it work, I have:
added an access method (to get cpSpace) in CCPhysicsWorld.h:
inline cpSpace* getSpace() const { return _cpSpace; }
Fix call of
cpBodySetTorque(body, 0.0f);`
in CCPhysicsBody.cpp to
if (body->t != 0.0f){
cpBodySetTorque(body, 0.0f);
}
Fix call of
cpBodySetPosition(_cpBody, tt);`
in CCPhysicsBody.cpp to
if (!cpveql(tt, cpBodyGetPosition(_cpBody))){
cpBodySetPosition(_cpBody, tt);
}
Steps 2. and 3. are necessary to avoid setting of the same physics body properties, which wake up a sleeping body.
The advantage of this approach is, that the chipmunk does not make any calculations for such physical bodies - saving CPU and battery.
I found something that works.
tl;dr
The basic idea is to keep track of the positions of the sprites myself, and then periodically check them to see if any of them have moved since they were last checked.
Longer version
I created a subclass of CCNode with the class name Piece.
These are my objects that are added to the physics world.
#implementation Piece {
float _previousX;
float _previousY;
}
-(void)updatePreviousScreenXandY{
_previousX = self.position.x;
_previousY = self.position.y;
}
-(BOOL)hasntMoved{
float currentX = self.position.x;
float currentY = self.position.y;
if ( currentX == _previousX && currentY == _previousY ) {
return TRUE;
}else{
return FALSE;
}
}
This is in my CCNode that acts as the game scene
-(void)doStuffAfterPiecesStopMoving:(NSTimer*)timer{
BOOL noPiecesHaveMoved = TRUE;
for (int i = 0; i < [[_physicsWorld children] count]; i++) {
if ( [[_physicsWorld children][i] hasntMoved] == FALSE ) {
noPiecesHaveMoved = FALSE;
break;
}
}
if ( noPiecesHaveMoved ) {
[timer invalidate];
NSLog(“Pieces have stopped moving”);
}else{
NSLog(“Pieces are still moving”);
[self updateAllPreviousPiecePositions];
}
}
-(void)updateAllPreviousPiecePositions{
for (int i=0; i < [[_physicsWorld children] count]; i++) {
Piece *piece = (Piece*)[_physicsWorld children][i];
[piece updatePreviousScreenXandY];
}
}
All I have to do is
[NSTimer scheduledTimerWithTimeInterval:TIME_BETWEEN_CHECKS
target:_gamePlay
selector:#selector(doStuffAfterPiecesStopMoving:)
userInfo:nil
repeats:YES];
and it’ll run whatever code I want after all Piece nodes have stopped moving.
The key to getting it to work well is to get the values for the Chipmunk space’s sleepTimeThreshold and the timer above’s time as low as possible.
My experimenting suggests the following settings work okay, but anything lower will cause problems (i.e. collisions not taking place properly):
sleepTimeThreshold = 0.15
my timer = 0.05
If anyone has a different/better solution or improvements to the above code, please post.

Moving and rotating a sprite with Accelerometer in SpriteKit

I'm trying to make my first game using Spritekit, so i have a sprite that i need to move around using my accelerometer. Well, no problem doing that; movement are really smooth and responsive, the problem is that when i try to rotate my sprite in order to get it facing its own movement often i got it "shaking" like he has parkinson. (:D)
i did realize that this happens when accelerometer data are too close to 0 on one of x, y axes.
So the question: Is there a fix for my pet parkinson?? :D
Here is some code:
-(void) update:(NSTimeInterval)currentTime{
static CGPoint oldVelocity;
//static CGFloat oldAngle;
if(_lastUpdatedTime) {
_dt = currentTime - _lastUpdatedTime;
} else {
_dt = 0;
}
_lastUpdatedTime = currentTime;
CGFloat updatedAccelX = self.motionManager.accelerometerData.acceleration.y;
CGFloat updatedAccelY = -self.motionManager.accelerometerData.acceleration.x+sinf(M_PI/4.0);
CGFloat angle = vectorAngle(CGPointMake(updatedAccelX, updatedAccelY));
_velocity = cartesianFromPolarCoordinate(MAX_MOVE_PER_SEC, angle);
if(oldVelocity.x != _velocity.x || oldVelocity.y != _velocity.y){
_sprite.physicsBody.velocity = CGVectorMake(0, 0);
[_sprite.physicsBody applyImpulse:CGVectorMake(_velocity.x*_sprite.physicsBody.mass, _velocity.y*_sprite.physicsBody.mass)];
_sprite.zRotation = vectorAngle(_velocity);
oldVelocity = _velocity;
}
}
static inline CGFloat vectorAngle(CGPoint v){
return atan2f(v.y, v.x);
}
i did try to launch the update of the _velocity vector only when updatedAccelX or updatedAccelY are, in absolute value >= of some values, but the result was that i got the movement not smooth, when changing direction if the value is between 0.1 and 0.2, and the problem wasn't disappearing when the value was under 0.1.
i would like to maintain direction responsive, but i also would like to fix this "shake" of the sprite rotation.
I'm sorry for my bad english, and thanks in advance for any advice.
You can try a low pass filter (cf. to isolate effect of gravity) or high pass filter (to isolate effects of user acceleration).
#define filteringFactor 0.1
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
//low pass
accelerX = (acceleration.x * filteringFactor) + (accelerX * (1.0 - filteringFactor));
//idem … accelerY
//idem … accelerZ
//or high pass
accelerX = acceleration.x - ( (acceleration.x * filteringFactor) + (accelerX * (1.0 - filteringFactor)) );
//idem … accelerY
//idem … accelerZ
}

How to simulate Gravity in z-axis in a 2D game with Sprite Kit

I'm writing a 2D ball game with sprite kit on iOS 7 and currently struggling on one physic simulation.
To explain the expected behavior: if a ball is dropped into a tea cup, it will circle around, loosing speed and finally stand still in the center of the cup.
I've tried to archive this with gravity, but gravity in sprite kit only applies to vertical X and Y axis, not Z-axis. I also tried to use level gravity by switching gravity values with small physic bodies on beginContact depending on the current ball position in the tea cup. But some contacts are dropped and the result is far away to look realistic.
I think I need to solve this in the update: method, but I have no idea which way to go.
Any advice greatly welcome and I need to mention that I'm not an expert on math, please explain your path to go. :-)
Since there's no built-in support for this kind of behavior in SpriteKit, rather than trying to hack existing functions to get what you want, you're probably better off integrating some published 2D physics formulas in your x,y 2D world. I would think that something like simulating magnetic or a homing behavior might be right for this.
A simple example would be something like (in the scene's -update: method):
CGFloat strength = 0.5; //(some scaling value)
CGPoint ballLocation = ball.position;
CGPoint cupLocation = cup.position;
[ball.physicsBody applyForce:CGVectorMake((cupLocation.x - ballLocation.x) * strength,
(cupLocation.y - ballLocation.y) * strength)];
following Joshd great idea, I have created an NSArray with like explained in my comment above. Hope this snippets does help some others...
The result could be found on youtube: http://youtu.be/Uephg94UH30
Sorry for the bad Airplay frame rate, it runs perfectly smooth on my iPad
The -update: functions does the work but only triggered if _meditationIsActive. This bool is set in -didBeginContact: when any ball gets in contact with a hole.
if (_lastCheck > 0.005)
{
if (_meditationIsActive)
{
CGFloat strength = 0.1; //(some scaling value)
CGPoint ballLocation;
CGPoint holeLocation;
for (MeditationHole * holeObj in _meditationHoles)
{
if (holeObj.connectedMeditationBall != nil)
{
ballLocation = holeObj.connectedMeditationBall.position;
holeLocation = holeObj.position;
[holeObj.connectedMeditationBall.physicsBody applyForce:CGVectorMake(
(holeLocation.x - ballLocation.x) * strength, (holeLocation.y - ballLocation.y) * strength)];
}
}
_meditationIsActive = [self doesMeditationApplies];
}
_lastCheck = 0;
}
At the end I'm checking if there is a valid ball out of the array in contact with a hole to avoid checking during every update. This is done with the following function where position check +/- 48 detects a ball close to a hole and +/-1 ball stands still
- (bool)doesMeditationApplies
{
bool isInArea = NO;
int perfectMatchCount = 0;
for (MeditationHole * holeObj in _meditationHoles)
{
if (holeObj)
{
if (holeObj.connectedMeditationBall != nil)
{
MeditationBall * ballObj = holeObj.connectedMeditationBall;
if ((ballObj.position.x >= holeObj.position.x - 48) &&
(ballObj.position.x <= holeObj.position.x + 48) &&
(ballObj.position.y >= holeObj.position.y - 48) &&
(ballObj.position.y <= holeObj.position.y + 48))
{
isInArea = YES;
}
else
{
holeObj.connectedMeditationBall = nil;
}
if ((ballObj.position.x >= holeObj.position.x - 1) &&
(ballObj.position.x <= holeObj.position.x + 1) &&
(ballObj.position.y >= holeObj.position.y - 1) &&
(ballObj.position.y <= holeObj.position.y + 1))
{
perfectMatchCount++;
isInArea = YES;
}
}
}
}
if (perfectMatchCount == _oxydStonesMax)
{
if (_sound)
{
self.pauseMusicPlaybackBlock(YES);
NSLog(#"PlaySound Meditation");
[OxydScene PlaySystemSound:#"Win2"];
}
isInArea = NO;
[self showPauseScreenWithWin:YES andPauseOnly:NO];
}
return isInArea;
}

Moving Platforms? Cocos2d and Tiled

I'm trying to make some moving tiles from a Tiled map editor tmx file.
I have the moving tiles in their own layer, and I just want to simply have them move up, and then when they reach a certain y, move back down, and etc.
I have been looking around for a bit on a clear way of accomplishing this, but my efforts have been unsuccessful.
I tried using some of the methods here.
I'm still really new to cocos2d development in general, so I wold appreciate any insight on this. Thank you very much for your time. If you have any questions, please ask! :)
Also if it helps, the tiles I'm trying to move are in a big T shape.
FINAL UPDATE:
(Removed more irrelevant code so anyone in the future can easily find my solution (the full answer is below), you can find where I got my layer iterate method at the link above).
Okay, so I have finally got it working close to how I want.. I don't think this is exactly the most ideal way of doing it, but this is what I've got.
Note: In order for this to work for you, you have to run your app out of debug mode or it will lag/make the player fall through the ground (at least it did for me..).
I have an update function that calls certain functions every frame. (Checking collisions, moving platforms, etc).
That update function calls my move platforms function..
like this:
[self movePlatforms:0.1];
this is my movePlatforms function..
-(void)movePlatforms: (ccTime) dt{
if(goingDown){
moveCount++;
}else{
moveCount--;
}
CGSize s = [movingTiles layerSize];
for( int x=0; x<s.width;x++) {
for( int y=0; y< s.height; y++ ) {
CCSprite *tile = [movingTiles tileAt:ccp(x,y)];
if(goingDown){
CGPoint newPosition = ccp(tile.position.x, tile.position.y - 1);
tile.position = newPosition;
if(moveCount >= 100){
goingDown = false;
}
}else{
CGPoint newPosition = ccp(tile.position.x, tile.position.y + 1);
tile.position = newPosition;
if(moveCount <= 0){
goingDown = true;
}
}
}
}
}
So basically, I created a int moveCount and a BOOL goingDown to keep track of how many times my movePlatform function has been called. So after 100 calls, it switches direction.
(This works fine for me, you might need something else like a collision detecter if that is the case use this).
if (CGRectIntersectsRect([someSprite boundingBox], [someSprite boundingBox])) {
//Do something
}
Hopefully this works for someone in the future, I know this was quite the headache for me, and it probably isn't even done correctly or there is a much better way to do it, but if this helps you, that is awesome!
Creating and removing tiles will effect your performance.
Instead of it, try to move the tile changing their position:
CCSprite *tile = [movingTiles tileAt:ccp(92,platformY)];
[movingTiles removeTileAt:ccp(92,platformY)];
CGPoint newTilePosition = tile.position;
if (goingDown){
newTilePosition.y ++;
if(newTilePosition.y >= 20){
goingDown = false;
}
}else{
newTilePosition.y --;
if(newTilePosition.y <= 10){
goingDown = true;
}
}
tile.position = newTilePosition;
Here is the (kind of) step by step of how I got my moving tiles working, this is only related to the moving tiles, and nothing else.
Note: You will need to run this as a release (not debug) in order to get everything running smoothly, and not having your character fall through the ground.
In the interface I created these variables:
#interface HelloWorldLayer(){
CCTMXTiledMap *map;
BOOL goingDown;
int moveCount;
}
The CCTMXTiledMap is the instance of my map.
The BOOL and int are two variables I use to keep track of my moving tiles.
-(id) init {
if( (self=[super init]) ) {
// add our map
map = [[CCTMXTiledMap alloc] initWithTMXFile:#"level1-1.tmx"];
map.position = ccp(0,0);
[self addChild:map];
//add our moving platforms layer
movingTiles = [map layerNamed:#"moving_platforms"];
//set the variables I use to keep track of the moving platforms
goingDown = true;
moveCount = 0;
//schedule my update method
[self schedule:#selector(update:)];
}
return self;
}
After the init method, I then create my move platforms method:
-(void)movePlatforms: (ccTime) dt{
if(goingDown){
moveCount++;
}else{
moveCount--;
}
CGSize s = [movingTiles layerSize];
for( int x=0; x<s.width;x++) {
for( int y=0; y< s.height; y++ ) {
CCSprite *tile = [movingTiles tileAt:ccp(x,y)];
if(goingDown){
CGPoint newPosition = ccp(tile.position.x, tile.position.y - 1);
tile.position = newPosition;
if(moveCount >= 100){
goingDown = false;
}
}else{
CGPoint newPosition = ccp(tile.position.x, tile.position.y + 1);
tile.position = newPosition;
if(moveCount <= 0){
goingDown = true;
}
}
}
}
}
So this is where the magic happens, I use methods I got from here, and the gentleman Mauricio Tollin told me I could update a tile position rather than destroy and recreate them.
So I iterate through every tile in my moving platforms layer, and tell them to go down 1 every call, until moveCount >= 100, then it says goingDown is now false, and it switches its direction. From there it just goes back and forth, counting to 100, and then back down.
If you want it to move longer, just increase 100 to 200 or whatever you want. (Or you can use a check to detect collision, and when it collides with a specified sprite, you can have it change then. If that is more of what you want, use this).
if (CGRectIntersectsRect([someSprite boundingBox], [someSprite boundingBox])) {
//Do something
}
After all of that, I create my update method:
-(void)update:(ccTime)dt{
[self movePlatforms:0.1];
}
In the init method it schedules the update method to be called every frame, and then the update method will run the movePlatforms method (or any other function that needs to be checked frequently, such as hazard detection, etc).
You can also make the platforms move slower by changing the time passed into movePlatforms, or you can schedule a slower update interval in the init method.
I hope this helps someone out in the future, I just wanted to create this answer with a more in depth process of how I got this working, since my question post was really unorganized and heavily edited while I was learning.

Resources