I have a collision handler detecting for a game over situation, however when the rocket lands (else if), the labels become visible no problems, but there is a second where the touch down even still registers, then the rocket takes off again, then the touch disables. Is there any obvious thing I'm doing wrong?
-(BOOL)ccPhysicsCollisionPreSolve:(CCPhysicsCollisionPair *)pair rocket:(CCNode *)nodeA landingPad:(CCNode *)nodeB{
//if travelling too fast on landing..
if (_rocket.physicsBody.velocity.y < maximumVerticalVelocity){
_crashNotice.visible = TRUE;
crashed = TRUE;
[_rocket removeFromParentAndCleanup:YES];
self.userInteractionEnabled = FALSE;
}else if (_rocket.physicsBody.velocity.y > 0.01){
self.userInteractionEnabled = FALSE;
//show game won state
_scoreLabel.visible = FALSE;
_showScoreLabel.visible = TRUE;
}return TRUE;
}
Instead of enable and disable touch, handle through bool value.
In class.h file declare this
bool mAllowTouch;
In Init/onEnter :
-(void)onEnter
{
[super onEnter];
mAllowTouch = true;
self.userInteractionEnabled = true;
}
In your function
-(BOOL)ccPhysicsCollisionPreSolve
{
if(YOUR_CONDITION_TO_STOP_TOUCH)
{
mAllowTouch = false;
}
else
{
mAllowTouch = true;
}
}
In touch function, use mAllowTouch to process your touch.
-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
if(mAllowTouch)
{
//handle touch here.
}
}
Related
I'm trying to set alpha of a SKNode every time it is clicked either to 0 or 1. My code currently turns it off but won't turn it back on. Any idea why?
- (void)handleTouchedPoint:(CGPoint)touchedPoint {
touchedNode = [self nodeAtPoint:touchedPoint];
// Detects which node was touched by utilizing names.
if ([touchedNode.name isEqualToString:#"play"]) {
isOnPlay = true;
NSLog(#"Touched play");
}
if ([touchedNode.name isEqualToString:#"light1"]) {
//NSLog(#"%.2f", touchedNode.alpha);
if(touchedNode.alpha != 0.0)
{
NSLog(#"Off");
touchedNode.alpha = 0.0;
//[touchedNode setAlpha:0.0];
}
else{
NSLog(#"On");
touchedNode.alpha = 1.0;
//[touchedNode setAlpha:1.0];
}
NSLog(#"Touched light");
}
}
You might be running into the famous float rounding issue. Use debug and check the values. The alpha might not be exactly zero.
I am building a Sprite Kit game where the player shoots a particle whenever the screen is pressed. How can I limit the touch inputs (let's say 2 recognized touch inputs per second) so that the player can't just quickly tap the screen to get unlimited shots?
Another solution:
Create a BOOL (I prefer to work with properties myself, so):
#property (nonatomic, assign) BOOL touchEnabled;
Set it to YES in the scene's init. Then it is fairly simple from thereon:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.touchEnabled){
self.touchEnabled = NO;
[self shootParticle];
[self performSelector:#selector(enableTouch) withObject:nil afterDelay:2.0];
}
...
- (void)shootParticle{
// whatever...
}
- (void)enableTouch{
self.touchEnabled = YES;
}
One of many possibilities:
#interface YourSceneName (){
int _amountBullets; //increase every time you shot and just shoot when _fireStop = NO
BOOL _fireStop; // init as NO at start
BOOL _needStartTime; // init as YES at start
CFTimeInterval _startTime;
}
#end
-(void)update:(CFTimeInterval)currentTime {
//set starttime
if(_needStartTime){
_startTime = currentTime;
_needStartTime = NO;
}
//timeinterval if 2 seconds, renew everything
if(currentTime - _startTime > 2){
_startTime = currentTime;
_amountBullets = 0
_fireStop = NO;
}
//set firestop to yes, method should be executed
if(_amountBullets = 2){
_fireStop = YES;
}
}
I am new in SpriteKit but this should work. I bet there are better possibilities. Also i havenĀ“t test the code. It shell show you the logic of how you could do it, hope I could help.
Here is a great Tutorial for working with time in SpriteKit.
I am developing a game on Xcode, but I ran into a problem. I'm not able to make my objectGuy
from going beyond a roof and I am unable to make my objectGuy from falling beyond the floor.
This is what I tried coding: I need help making the collision stop the jump and make the objectGuy fall back down and once it collides with the ground, to keep him there.
topGround is referring to the roof / bottomGround is referring to the ground
-(void) collision {
if (CGRectIntersectsRect(guy.frame, topGround.frame)) {
guyJump = 0;
}
if (CGRectIntersectsRect(guy.frame, bottomGround.frame)) {
guy.center = CGPointMake(guy.center.x, 261);
}
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
guyJump = 20;
[self collision];
}
-(void) guyMoving {
guy.center = CGPointMake(guy.center.x, guy.center.y - guyJump);
guyJump = guyJump - 5;
if (guyJump < -3) {
guyJump = -3;
}
}
Hi Im making a cocos2d game that has a sprite flying and falling, Im trying to have a first tap touch event for example when the user touches the screen for the first time it'll start the game animation and start the physics engine. Whats happening is that when the user starts the game the sprite falls down right away, can anyone give me a hand with this?
right now Im using something like this but Im not sure how to get the physics engine to wait until the user touches the screen for the first time.
CCSprite *_pixie
CCNode *_start;
BOOL *_firstTap;
CCPhysicsNode *_physicsNode;
-(void)didLoadFromCCB{
_physicsNode.collisionDelegate = self;
_firstTap = True;
}
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
if(_firstTap == TRUE){
_start.visible = FALSE;
_firstTap = False;
}
//flying sounds & so on
if (!_gameOver) {
[[OALSimpleAudio sharedInstance] playEffect:MAGIC volume:0.4 pitch:1 pan:0 loop:NO];
[_pixie.physicsBody applyImpulse:ccp(0, 420.f)];
[_pixie.physicsBody applyAngularImpulse:11000.f];
_sinceTouch = 0.f;
}
}
- (void)update:(CCTime)delta {
if(_firstTap == FALSE){
float yVelocity = clampf(_pixie.physicsBody.velocity.y, -1 * MAXFLOAT, 200.f);
if ((_sinceTouch > .5f)) {
[_pixie.physicsBody applyAngularImpulse:-40000.f*delta];
}
}
}
Change
BOOL *_firstTap;
to
BOOL _firstTap; //No asterisk
And also make sure that you set _firsttap = YES in viewDidLoad functions
- (void)viewDidLoad
{
[super viewDidLoad];
_firstTap = YES;
}
Looks to me like the first touch Boolean value may not be defined until after the update code is called. You are also mixing BOOL values with bool values.
Objective-C : BOOL vs bool
I have a tap gesture on my view that I only want to be able to fire after a certain point and after a different function has run. My solution was to create a outlet for the tap gesture and then call the Enabled function setting to TRUE or FALSE as needed. The code looks like this, with the second function being the tap gestures
- (IBAction)butt:(id)sender
{
if(game == FALSE)
{
tapges.enabled = FALSE;
int sec;
sec = arc4random() % 5;
if(sec == 0){sec++;}
sleep(sec);
tapges.enabled = TRUE;
game = TRUE;
gun.hidden = FALSE;
start = [[NSDate date] timeIntervalSince1970];
}
}
- (IBAction)tap:(id)sender
{
if(game == TRUE)
{
end = [[NSDate date] timeIntervalSince1970];
double total = end - start;
NSString *myString = [NSString stringWithFormat:#"%lf", total];
ss.text = myString;
game = FALSE;
gun.hidden = TRUE;
tapges.enabled = FALSE;
}
}
However it doesn't seem to work. Even after the first function has set tapges.enabled = FALSE if you tap before it reaches tapges.enabled = TRUE it still just queues the tap function for running after the butt function runs.
There is a way to prevent a UIGestureRecognizer from firing (or to call another function before it fires) through using UIGestureRecognizerDelegate method gestureRecognizerShouldBegin but I think the issue is more a question of logic.
Not sure I entirely understand your task but wouldn't something more simple like:
- (IBAction)butt:(id)sender
{
if(game == FALSE)
{
[self callOtherMethod];
}
}
Or
- (IBAction)butt:(id)sender
{
if(game == FALSE)
{
//do set up
} else {
// do other setup
}
}