Could someone please help with with this issue that I am having with canceling touch event when my character dies. I have Character controller (Touch a sprite and drag left/right to move) based on screen X-axis. My controller class is a subclass of CCNode and has all the required methods to register touch with TouchDispatcher. The ccTouchBegin, ccTouchMove & ccTouchEnd works fine, but while my ccTouchMove is in action and my character dies I want to reset the controller, player position to a start location on the screen but that does not trigger until I lift my finger(thus ccTouchEnd) triggers then my reset player/controller in my GameLayer(CCLayer) fires.
I thought by adding the CCTouchCancel method would do the trick but it is not getting fired. Each of my Touch event methods first checks the controller's state (IDLE, ACTIVE, STOP) before doing any actions. I have an update method also to handle the dragging but it also checks that the controller.state == ACTIVE before allowing player to drag/move character.
In my Gamelayer's update method when my character dies, I set the controller.state = STOP. In the Controller's update method for STOP state, I call [[[CCDirector sharedDirector] touchDispatcher] removeDelegate: self]; which is the same code in the onExit method, but the touch event is not canceling. Touch event is only stopping if I lift my finger. Then the state change made in Gamelayer fires
Please advise.
I figured out why my character's controller was not changing state to STOP when my character dies. I had implemented the CCTouchCancel method but it was not getting triggered, thus the touch event was never cancelling until I lifted my finger off the screen.
I had implemented the update: (ccTime)delta method, in which I checking for ACTIVE state and performing some action. After commenting out the update method, everything worked as I expected. There was no need for the update method as the CCTouchMove method handles continuous touched location detection as long as the finger is touching the screen, no need to run an update method.
Related
I have the follwing declaration:
<Button Tapped="Handler1" DoubleTapped="Handler2" />
Each time I double tap the button the Handler1 gets fired. Handler 2 never gets fired.
Thanks.
You can't do in this way because it will always fire the first event of tap. You can manage the double tap with the single tap event using a boolean or a counter to manage the following tap events.
I do not know why the DoubleTapped handler does not get called. It should. Maybe IsDoubleTapEnabled is set to false? This could not just happen by explicitly setting the property in XAML, but also e.g. by inheriting the value from a style.
But even when DoubleTapped works, the Tapped event will always fire once. The control is no fortune teller: When the first tap happens, it does not know that a second tap will soon follow, so it fires the Tapped event. If you do not want this, you need to implement your own behaviour and either ignore or delay Tapped events.
MSDN:
If a user interaction also fires DoubleTapped, Tapped will fire first to represent the first tap, but the second tap won't fire an additional Tapped. If you want different logic for Tapped versus DoubleTapped, your Tapped handler may need to use app-specific variables and a timer in order to avoid running on interactions that are eventually interpreted as a DoubleTap action.
But using double taps is generally discouraged by the UX guidelines. I would not use them with buttons, because buttons usually do not work that way and you are breaking user expectations.
I have a pause button that's a CCMenuItem that when I touch it, the app goes to the menu. I have the Game Scene set as a static variable on the Menu Scene so that when I resume the game I can resume my current game.
When I press the resume button, I reschedule the update on the Game Scene and replaceScene with the static Game Scene. The pause button is on a layer that the Game Scene owns.
When the game continues, the pause button is there but doesn't respond to my touch. I tried using onEnter to do resumeSchedulerAndActions but nothing.
I've come up with a solution which feels hacky, which is to create my menu in onEnter and remove it in onExit.
Am I missing something? Is there a way to make my menu respond to touches again?
You could use popScene of CCDirector to pop the menu scene from the game scene. You may not have to hack around with scheduling yourself. For this to work, the pause button would have to push the scene on the scenes stack in the first place instead of using replaceScene.
You know what's hacky? Keeping a scene in a static variable. If you replace a scene, you're supposed to let go of it. Cocos2d doesn't handle multiple calls to replaceScene with the same object correctly. Either this, or overriding onEnter and not calling [super onEnter] is causing the input problems.
If you want to continue the game, either
don't replace the scene
push/pop the other scene
write code to save the scene's state and restore it
I would like to create a button in my UIView that when touched spawns another button under the finger which immediately starts to follow the finger.
I have seen a tutorial here that deals with button following finger, but i can not figure out how to make this button follow finger WITHOUT user tapping it after creation.
Using iOS 5.1 SDK with XCode 4.3.2
Any help?
You can add target/action pairs to a button for various control events: to make something immediately start following your finger, you probably want UIControlEventTouchDown.
Hook up your first button to call a method on your view controller for that control state. In that action method, create your new button, and shove it in a property on your view controller so that you can refer to it later. Also set a BOOL property on your view controller that's called something like shouldTrackButton.
To make the new button follow your finger, I guess the easiest way is a pan gesture recogniser on the superview. Set that up to call a method on your view controller. In that method, if the gesture recogniser's state is UIGestureRecognizerStateChanged, call translationInView: on the gesture recogniser, passing in the view controller's view (i.e. the superview of the buttons). Now, if and only if shouldTrackButton is YES, take the frame of the original button, translate it by that amount (using CGRectApplyAffineTransform and CGAffineTransformMakeTranslation), and set the new button's frame to the result.
Finally, in the same method, if the gesture recogniser's state is UIGestureRecognizerStateEnded, set shouldTrackButton to NO.
I have a menu which I'd like to have automatically hide if it's inactive after a certain amount of time. This menu is composed of a hierarchy of UIViewControllers, which present various different views.
I'm thinking along the lines of running a timer, which invalidates and starts over whenever there's a touch.
Is it possible to catch all touch events in a set of UIViews? Perhaps just keep a boolean lying around and use the main UIWindow to catch touch events?
EDIT:
My app is a kiosk app of sorts, with a main screen and a menu. When the menu is up, I want it to run an auto dismiss timer, which resets after any touch in the entire menu screen. The menu is displayed over the entire screen, modally.
One way to be sure is to subclass UIApplication and override - (void)sendEvent:(UIEvent *)event method, every touch event happening in your app goes through this method and you can check the UIEvent type to see if it's UIEventTypeTouches and reset the timer.
Another way to do this simply involves adding a transparent layer over whole user accesible UI and override hitTest:withEvent:.
You can have an invisible view on top of your modals view controllers, and put have either a gesture recognizer on it which can start a timer, either a
-touchesBegan:withTouches
method, and then send to the .nextResponder the same method.
i want to fire a timer as user slides the slider when the touch ends.
is there a way to handle touch events of uislider?
Make sure your slider's continuous property is set to YES; then use -addTarget:action:forControlEvents: with... UIControlEventValueChanged?... in the usual way. The slider should continuously call whatever action method you give it.
I set the continuous property to NO and kept UIControlEventValueChanged and it manages to only fire off the event when the user releases the slider