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.
Related
I'm having a skspritenode that has applied a force impulse on the update method and an fuel consumptionMethod...
I am testing this on 2 different devices. An 4s and 5s... the 4s has a lower than 60 framerate and differs from the 5s.. (ship can accelerate more on 4s)..
How can i fix this? .. make the 2 functions, consumeFuel and forceUp do not depend on number of frames of the update method?
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
camera.speed = ship.physicsBody.velocity.dy;
camera.distance = ship.position.y;
camera.fuel=fuel_remaining;
if(willPresentGameOver == true){
ship.physicsBody.velocity = CGVectorMake(0, 0);
}else{
if (isAccelerating == true) {
[self consumeFuel];
[self forceUp];
}
}
}
-(void)consumeFuel{
if(fuel_remaining>0){
fuel_remaining-=1;
}
}
-(void)forceUp{
if(fuel_remaining > 0){
[[self childNodeWithName:#"//ship"].physicsBody applyForce:CGVectorMake(0, [[Config sharedSingleton]returnUpForce])];
}else{
[force invalidate];
[shipAccelerationFlame removeAllActions];
[shipAccelerationFlame setTexture:nil];
return;
}
}
im working with AMSlideMenu, and i did in the MainVC
// Enabling Deepnes on left menu
- (BOOL)deepnessForLeftMenu
{
return YES;
}
// Enabling Deepnes on right menu
- (BOOL)deepnessForRightMenu
{
return YES;
}
Normally a deepness effect will be in the left and right menu, but nothing happen .
Did anyone tried AMSlideMenu before and had same pb ?
Yes it is working. You just need to observe it. If -deepnessForLeftMenu is enabled you can see that menu will be transform and it shows animation and scaling of left menu.
Put a debugger check in AMSlideMenuMainViewController.m class for below method and you will see the differences.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Put a break point here.
if (self.leftMenu && [self deepnessForLeftMenu])
{
self.leftMenu.view.layer.transform = kMenuTransformScale;
self.leftMenu.view.layer.opacity = kMenuLayerInitialOpacity;
}
if (self.rightMenu && [self deepnessForRightMenu])
{
self.rightMenu.view.layer.transform = kMenuTransformScale;
self.rightMenu.view.layer.opacity = kMenuLayerInitialOpacity;
}
}
Also the deepnessForLeftMenu bool variable used in other two methods for the same class
- (void)configure3DTransformForMenu:(AMSlideMenu)menu panningView:(UIView *)panningView
{
float cx = 0;
float cy = 0;
float cz = 0;
float opacity = 0;
// Put a break point here.
/********************************************* DEEPNESS EFFECT *******************************************************/
if (menu == AMSlideMenuLeft && panningView.frame.origin.x != 0 && [self deepnessForLeftMenu])
{
// Codes for deepness effect
}
}
If you set NO for deepnessForLeftMenu variable. You will able to see that menu will show flat animation.
I can see here how to use the update() function to monitor properties like "position" on an SKNode but I don't see how I would know how methods like [node.physicsBody applyImpulse:vector] has finished.
-(void)someMethod {
_monitorOn = YES;
[_node.physicsBody applyImpulse:CGVectorMake(10,10)];
}
-(void)update:(CFTimeInterval)currentTime {
if( _monitorOn == YES ) {
NSLog(#"node position: %f,%f", _node.position.x, _node.position.y);
}
// When will this be turned off?
}
Here are two ways to check if the effect of applyImpulse is completed:
if (_node.physicsBody.resting) {
// Node is at rest, do something
}
You'll often find that the resting property is never set because your sprite is moving very slowly (particularly with circle nodes). Therefore, it's better to check if the speed is nearly zero.
static inline CGFloat speed(const CGVector v)
{
return sqrtf(v.dx*v.dx+v.dy*v.dy);
}
if (speed(_node.physicsBody.velocity) < kSmallValue) {
// Node is moving very slowly, do something
}
applyImpulse simply adds some velocity to your _node; it only does so when you call it and is "finished" after one frame. I think what you're really looking for is when _node stops moving (which will happen the physics engine determines that _node's velocity is zero). To check for this, you can look at SKPhysicsBody's resting property. Simply check for it in your update: loop; when it's true your _node has stopped.
-(void)update:(CFTimeInterval)currentTime {
if( _monitorOn == YES ) {
NSLog(#"node position: %f,%f", _node.position.x, _node.position.y);
}
if( _node.physicsBody.resting ) {
NSLog(#"node is stopped");
}
}
Note: You'll probably want to set an addition flag somewhere that you can use to see if you should be checking if _node is resting, otherwise you're going to get a ton of "node is stopped" messages.
-(void)someMethod {
_monitorOn = YES;
_appliedImpulse = YES;
[_node.physicsBody applyImpulse:CGVectorMake(10,10)];
}
-(void)update:(CFTimeInterval)currentTime {
if( _monitorOn == YES ) {
NSLog(#"node position: %f,%f", _node.position.x, _node.position.y);
}
if( _appliedImpulse && _node.physicsBody.resting ) {
_appliedImpulse = NO;
NSLog(#"node is stopped");
}
}
I want to know how to identify the UISlider is tracking towards maximum to its minimum values?
For ex, My slider maximum and minimum values 1.0 and 0.0. How can I identify my slider is tracking from 0.0 to 1.0 and vice versa?
Thanks!
There is an event of UISlider named value changed. Use that event and calculate the difference. If difference is positive then its going towards max value otherwise its moving towards min value. Use below action method.
- (IBAction)sliderdidchanged:(UISlider *)sender {
if (sliderOldValue - sender.value > 0) {
NSLog(#"Value Decreasing");
}
else {
NSLog(#"Value Increasing");
}
sliderOldValue = sender.value;
}
Don't forget to make reference to this method from UISlider object in your xib or Storyboard. Also declare sliderOldValue as instance variable and in viewDidLoad assign its value to the slider's default value.
.h
To track Last Value
#property(nonatomic,assign) float lastValue;
.m
in ViewDidLoad listen for UIControlEventValueChanged
[yourSlider addTarget:self
action:#selector(mySliderValueChanged:)
forControlEvents:UIControlEventValueChanged];
Define the method
- (IBAction)mySliderValueChanged:(UISlider *)sender {
float currentValue = sender.value;
if (currentValue>self.lastValue) {
NSLog(#"moving Right");
}
else{
NSLog(#"moving Left");
}
self.lastValue = sender.value;
}
You can listen for the ValueChanged control event
[slider_ addTarget:self action:#selector(sliderMove:) forControlEvents:UIControlEventValueChanged];
...
- (void) sliderMove:(UISlider*)slider
{
if (slider.value == slider.minimumValue) {
// etc...
}
else if (slider.value == slider.maximumValue) {
// so on and so forth
}
}
I instance a sprite, and then when it collides with a second sprite, the child of that sprite is removed:
if (CGRectIntersectsRect(spriteOne.boundingBox, self.swat.boundingBox))
{
if (spriteOne.tag == 0){
[self removeChild:spriteOne cleanup:YES];
}
if (spriteOne.tag == 1){
[self removeChild:spriteOne cleanup:YES];
}
}
This works how I want it to, and the sprite disappears off the screen. However, it seems that the boundingBox is still there, even if the image is not, and this causes trouble with scoring, etc... So, what I would like to know is how to 'dis-activate' the sprite's boundingBox so that when the first time that the two sprites colide, the collision is detected, but any time after that, it is not.
Thanks in advance.
As far as I understand, you should have some issue with removing the sprite after a collision.
Would you try this?
if (CGRectIntersectsRect(spriteOne.boundingBox, self.swat.boundingBox))
{
if (spriteOne.tag == 0){
[spriteOne removeFromParentAndleanup:YES];
}
if (spriteOne.tag == 1){
[spriteOne removeFromParentAndleanup:YES];
}
}
Have you tried adding some NSLog traces to see whether the sprite is really removed?
You must be retaining spriteOne. If there is a good reason to keep it around, do this:
if ( spriteOne.visible && CGRectIntersectsRect(spriteOne.boundingBox, self.swat.boundingBox))
{
if (spriteOne.tag == 0){
spriteOne.visible=NO;
}
if (spriteOne.visible && spriteOne.tag == 1){
spriteOne.visible=NO;
}
}
Later, when you need spriteOne in play again, just set its visibility to YES;
If not, you have a leak, and do this:
if ( spriteOne && CGRectIntersectsRect(spriteOne.boundingBox, self.swat.boundingBox))
{
if (spriteOne.tag == 0){
[self removeChild:spriteOne cleanup:YES];
self.spriteOne=nil; // assumes you have a property for spriteOne
}
if (spriteOne && spriteOne.tag == 1){
[self removeChild:spriteOne cleanup:YES];
[spriteOne release]; // assumes no property for spriteOne
spriteOne=nil; // dont forget this ! beware of zombies
}
}