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
Related
I'm working on an alternate version of a program I already wrote, it's mostly for the sake of understanding a little more.
In x-Code (Objective-C), I have a ViewController that calls out a UIView (GraphicsView) that draws a line from the center to the touch point. This sub-view is smaller than the larger ViewController.
The view controller has a label that outputs the coordinates of the touched point.
So far I was able to get everything working, so that if you touch inside the sub-view you get the line AND the coordinates updated and if you touch outside the sub-view you only get the coordinates updated. I did this using delegates which was a little complicated.
I've been reading some books and I learned about using the extern feature and global variables (which are supposed to be bad practice) and I wanted to try the same app but using global variables.
I declared my externCGPoint in the ViewController.h and imported it on the GraphicsView.m file and in the method touches began I put the definition of myGlobalPoint = touchedpoint; followed by an NSLog that displays the coordinates. So far it works. (However it does not update the coordinates)
However whenever I touch outside the sub-view, into the main view the app crashes with a EXC_BAD_ACCESS message. From what I understand the main View cannot access the global variable if it's declared in another class ?
I've read many there stack overflows about this and I;ve tried it in the methods suggested but I keep getting this error.
So basically what I am trying to do is when the player of my game completes a level (for example level 1), it switches scenes back to the level select scene, and swaps the sprite picture of level 1 to a different one (for example one that has a check mark over it). I can replace the scene but I don't know how to change the sprite in the new scene, specifically when the scene change occurs after the level is completed. So I am assuming I would use a singleton class, am I right? If so, how would I go about using it?
Singletons are ok, don't be afraid to use them. Many components of cocos2d are singletons.
I think what you need is some sort of structure that keeps track of the state of the game. (How many levels are completed/What should be the next level/etc). When your level select scene is loaded it should look up that 'state of the game' object (be it a singleton, plist, etc ) and displays itself accordingly.
I would stay away from passing information directly from one scene to another, this makes reordering them a headache later on.
First, let me make sure I understand the problem correctly.
You have a scene (A) with a sprite in it.
You transition to another scene (B) for the game play.
The game ends and you transition back to scene A.
When scene A redisplays, you want to change the image displayed by the sprite.
If I've got this right, then regardless of whether singletons are good or bad, you don't need one for this.
If, like me, you've created your sprite using a display frame from the CCSpriteFrameCache, then you can simply change the frame you want the sprite to use when "A" is redisplayed.
Some sample code demonstrating this can be seen in another question:
How to switch the image of a CCSprite
(Certainly, if I've got this right, then feel free to just dupe this)
NOTE: Updated below...
I have a cocoa desktop application which consists of a series of controls around a custom NSView. I am using displayLink to drive the updates.
When a user clicks on an NSControl (a slider, a button, a checkbox, a radio button) the application appears to freeze until the mouse is released. I can confirm in fact that the displayLink callback (getFrameForTime) is NOT firing during the time. If I create a timer, that also does not fire, both remain paused until the user releases the mouse, at which point the application resumes updating.
The control is bound, and if I update that value from another thread (for example, via a callback from a MIDI interface) the slider behaves as expected: it moves, the value updates and the application does not pause.
I feel like this should be a fairly obvious fix, but I'm stumped.
Checking "continuous" in IB does as advertised: sends the values continuously, but still exhibits this behavior (preventing the UI update) until the mouse is released.
This seems to be related specifically to mouseDown on NSControl? Why would this block, and do I really need to subclass all my UI elements to change this behavior (seems extreme)
DisplayLink is in its own thread, so why mouseDown on the main thread block it? If this is the case, given the injunction on updating the Cocoa UI from other than the main thread, how do I deal with it?
Any help much appreciated.
Update
Per #Nikolai's comments below, I can confirm that using an NSTimer and adding it to NSEventTrackingRunLoopMode does NOT block. However, I would really like to use CVDisplayLink which (according to the documentation) runs in it's own thread and should not be blocked in this way. Unlike CADisplayLink, I cannot find a way to explicitly assign a runloop to CVDisplayLink (it seems it doesn't work that way), so perhaps the new question should be:
Why does CVDisplayLink block on NSEventTrackingRunLoopMode?
When clicking on an NSControl the runloop mode goes from NSDefaultRunLoopMode to NSEventTrackingRunLoopMode, as long as the mouse is down. That means that only run loop sources (display link) and timers fire that have been added to this mode.
You can add timers to any mode by using -[NSRunLoop addTimer:forMode:]. For a display link the equivalent method is -[CADisplayLink addToRunLoop:forMode:].
To make your animation continue during event tracking you would do something like:
[myDisplayLink addToRunLoop:[NSRunLoop currentRunLoop]
forMode:NSEventTrackingRunLoopMode];
Your test project shows that you are calling a view's display method from within the display link's callback.
When commenting the display message out, the display link is called continuously even while moving the slider.
So what goes wrong is that when the runloop goes into event tracking mode, the call to display on the display link's thread blocks until the mouse is released and the run loop goes back to default mode. You can easily confirm this by putting a log statement before the call and one after it.
Why exactly that happens is not clear to me. What is clear is that it's illegal to call a view's methods from a background thread. You have to trigger the view's display by dispatching a setNeedsDisplay: on the main thread:
static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
dispatch_async(dispatch_get_main_queue(), ^{
[(__bridge MyCustomView*)displayLinkContext setNeedsDisplay:YES];
});
return kCVReturnSuccess;
}
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);
In my cocos2d game, I'm trying to have two joysticks, one for moving the player and one for shooting. However, I can't figure out how to have touches from both joysticks register at the same time.
Right now, only one of the two joysticks will register a touch event at a time. How can I get both to take input simultaneously?
When using cocos2d, you need to set multitouch enabled on the EAGLView. In your app delegate, add this line after you initialize your EAGLView.
view.multipleTouchEnabled = YES;