im trying to make my sprite blink, but it just disappears, i have searched google, but i cant find a solution, heres what im doing:
CCBlink * blinker = [CCBlink actionWithDuration: 0.5 blinks: 1];
[player runAction: blinker];
this method is called when two of my sprites collide, when the collision takes place, i want the 'player' sprite to blink for a few seconds. at the moment, when the sprites collide, the 'player' sprite becomes invisible....thanks
CCBlink seems to work by toggling the visibility of your sprite on and off a given number of times within the stated duration you gave it. Depending on the duration you set, you might sometimes end up with an "off" visibility state at the end of the action (very buggy yeah, I had that too before), which isn't quite desired.
Two suggestions:
(1) Play around with the number of blinks.
(2) Always force the sprite to be visible at the end of the blink:
Add: [CCShow action] to the end of your blink action. You can string both actions into a CCSequence.
Verify that when (and where) you process 'onCollision' types of events you do not remove the sprite from its parent.
Blink action is buggy. I always use the following to guarantee that the object remains visible at the end of the animation:
Sequence* action = Sequence::create(Blink::create(BLINK_DURATION, BLINK_TIMES), Show::create(), NULL);
Related
Am a newbie in using sprite builder and cocos2d.
I Have done the sprite continuos running using sprite builder and its timeline. i.e Hero sprite will run continuously once app launches like temple run game.
Here this sprite should jump if user taps the screen. Am struct with implementing this how to make my running sprite to jump on tap on screen ?
Here below is the code which I written inside touchBegan for make my sprite to jump. Here I need to merge this running animation with sprite jump animation. Any suggestion and help will be greatly helpful.
[_hero.physicsBody applyImpulse:ccp(0, 400.f)];
The way I did it is use a typedef enum to set up a set of variables that will store the character state. Set this up in a Definitions.h class. Then, in your hero class, add a method that will use a switch statement to change the state. For example, if jumpState is passed in and current state is runState, the method will change the state to jumpState and run a method called jumpAnim. You can then code your animation in JumpAnim or load it from spritebuilder.
Then, in another class where your Gameplay is finalized, call it a GamePlay layer, that is where your touchBegan method would be. In GameplayLayer.h, set up set up a CCTime variable to store the value of your jumptimer, how long your upward jump animation runs.
In your touchBegan method, you can change the state to jumping and reset the jumpTimer.
Then, in your update method, call a updateHero method. updateHero will have an if statement- if the hero state is jumpState, then move him up by 3 points until the jumpTimer runs out. Once the timer runs out, change the state to fallingState. Falling state should also be in the switch statement in your character class.
Hope this helps
I have a sprite that bouncing around the screen using physics. I am trying to turn on and off the ability of said sprite to rotate.
In init of the scene I set the following:
ball.physicsBody.allowsRotation = NO;
Works just fine. Later, in another method I allow it with:
ball.physicsBody.allowsRotation = YES;
Things are working great. However, when I set it back to NO it just keeps on spinning. I checked the debugger and allowsRotation is indeed set to NO.
Any idea what I am missing?
From apples documentation:
The allowsRotation property determines whether forces can impart angular velocity on the body.
This means that when it is set to no, the ball will keep its spin, but not be affected further by forces.
Set .angularVelocity to 0, when you set the allowsRotation to 0.
Is it possible to detect the collision of two UIImageViews while one is travelling along a path during a CAKeyFrameAnimation?
If so how is this done, I have tried multiple methods including checking both the CGRects for collision during the animation - but can't find a suitable method for performing a method during a CAKeyFrameAnimation and trying to detect collision of the path and the UIImageView.
You need to get the properties from the presentation layer. It will have the best approximation of information that exists during animation. Access it by
view.layer.presentationLayer
Look at the documentation for CALayer/presentationLayer for more details.
When you want to check for collisions, you would grab the presentationLayer of each object, then access whatever properties you want to test for collision. The exact way to check would depend on which type of layer, and whether you wanted simple hitTest-ing or depth checking. Only you know when and what type of collisions you want to look for.
However, to access the properties of an object while it is animating, you need the presentationLayer.
EDIT
You can make these check whenever you want. You can do it in the context of another action, or with an NSTimer to do it at some interval. You can even use CADisplayLink, which while hook you into the animation timer itself.
If you use CADisplayLink, I suggest setting frameInterval at the highest value possible, and still do what you want, so as to not impact performance.
timer = [CADisplayLink displayLinkWithTarget:self selector:#selector(checkForCollisions)];
// Callback is for every frame, which is 60 times per second.
// Only callback every 6 frames (which is ten times per second)
timer.frameInterval = 6;
[timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
Don't forget to invalidate the timer when you are done.
I have some sprites falling from the point A to B with ease. The code:
id move = [CCMoveTo actionWithDuration:time position:new_position];
id move_ease_in = [CCEaseIn actionWithAction:[[move copy] autorelease] rate:ratio];
[sprite runAction:move_ease_in];
When someone taps on the screen, the sprite has to keep falling to the point C, that is below B. The sprites have to keep falling without stopping and falling again. How can I do that? Thanks.
Try CCMoveBy, and add the amount of want them to move each time.
(Note that depending on the version of cocos2d that you're using, you may encounter a jerky behavior. If that is the case, check the cocos2d method definition for the move methods and comment out the flag there that has a comment "bug fix" preceding it. )
I have a NSArray of UIImageViews that I want to loop over and quickly swap out an "on" and "off" state. I wrote the code to do so in a for loop instead a method that was called when the user tapped a UIButton ( the button's action ).
Here's that loop:
for(int i = 0; i < [Images count]; i++) {
if( i > 0 ){
[self toggleImageViewOff:[Images objectAtIndex:i - 1]];
}
[self toggleImageViewOn:[Images objectAtIndex:i]];
[NSThread sleepForTimeInterval:0.5f];
}
The UI did not update as I expected as I only ever saw the last UIImageView in the "on" state. I figured that the drawing update of the views must occur in the main thread this code was also executing in. So I learned about performSelectorInBackground:withObject: . Performing the toggleImageViewOn/Off methods using this made the loop work. The problem is if I make the sleep interval too short I can have an "on" update after an "off" with Threads operating out of order.
So I had the bright idea of moving the whole loop with the sleep into its own method and calling that from the action method using performSelectorInBackground:withObject: . I tried that and I'm back to not getting an updated view until the loop is over.
That's a long winded way to get to my question:
What's the best way to animate this to guarantee the on/off code fires in the right order and still get view updates, even at high speeds? ( i.e. looping very quickly )
I tried to think about how I'd do it with CoreAnimation, but I can't seem to get my head around how to do it there.
For bonus, here are the toggle methods:
- (void)toggleImageViewOn:(UIImageView *)theImageView {
[theImageView setImage:[UIImage imageNamed:#"on.png"]];
}
- (void)toggleImageViewOff:(UIImageView *)theImageView {
[theImageView setImage:[UIImage imageNamed:#"off.png"]];
}
Did you set up an animation context (UIView class method does that) around this for loop? Without it changes are immediate instead of animated.
The problem is that you are not giving any of the UIImages time to draw. The drawing code is optimised to only draw what's needed - rendering all those intermediate stages is optimised out.
Sleeping the main thread doesn't actually give it chance to run.
Bill is right in that you need to set up an animation context around your loop. This will capture all of the UIView changes you make and then play them out. The easiest way to do this is using Core Animation. Core animation 'records' changes in UIElemenets and plays them back. Your code (without the sleep) will work just fine in a Core Animation block.
Apple have a reasonable cookbook for Core Animation on their site
You're on the right track with moving the loop to a background thread, but you also need to make sure that you give the main run loop a chance to update the UI. You should be able to replace the direct calls to toggleImageViewOn: and toggleImageViewOff: with something like
[self performSelectorOnMainThread:#selector(toggleImageViewOn:) withObject:[Images objectAtIndex:i] waitUntilDone:NO];
This will do the UI update on the main thread, and by not waiting until the update is done you give the main run loop a chance to reach its end. You run into the same issue with things like progress bars, where they won't change until the loop ends unless you do your updates from a background thread with a UI update call like the one above.
Hey Patrick. Have a look at UIImageView's animationImages property, as well as the animationRepeatCount and animationDuration properties. If you put your on/off images into an array and assign that as the animationImages property, you should be able to control the repeat and duration to get the desired effect.
Hope that helps!
Thanks for that. I've already looked into UIIMageView's animationImages property. That's not exactly what I'm attempting to do. I'm cycling between several UIImageView's that are placed near each other to give the impression that a light is moving between them and cycling over them. So an individual UIImageView's animation is separate from each other as I need to swap the image as necessary in code.
Calling peformSelectorOnMainThread:withObject:waitUntilDone: from the loop on the background thread does indeed update the view as quickly as I can think I will ever need. I'm curious why I need to do the UIImageView swap on the Main thread? Why wouldn't changing it on the background thread and then using NSThread's sleepForTimeInterval allow the main thread to update the drawing anyway?
I guess I need to go read up on the run loop and where drawing updates occur.
Thanks so much for the help. ( I'm also going to try some additional suggestions from Bill Dudney, that I think will work based on CoreAnimation )