How to stop function with Timer interval - objective-c

I would like to stop function like this:
- (void)update:(NSTimeInterval)currentTime
{
if (self.lastUpdateTimeInterval)
{
_dt1 = currentTime - _lastUpdateTimeInterval;
}
else
{
_dt1 = 0;
}
CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
self.lastUpdateTimeInterval = currentTime;
[self moveObject];
}
I now timers stop like: [timer1 invalidate], but how to stop function that is running on timer interval?

If you want to stop the animation you can call removeAllActions on your sprite object:
[_sprite removeAllActions];
But I think you need to also run the animation just if the sprite is not running it already. To do that you can use:
if (![_sprite hasActions])
{
[_sprite runAction:action];
}
If you want to stop just one animation (not all) you can use runAction:withKey: method when you run action and you can see if the action is running by calling actionForKey: or you can stop it by calling removeActionForKey.

Related

What is the best way to create a custom popup interstitial ad?

I currently have an app written in objc and swift.
I would like to implement a custom popup interstitial ad that runs for a few seconds and then presents an X to close the popup and continues doing so every couple minutes unless the
Remove Ad's in-ap purchase has been purchased.
I already have the in-app purchases setup. I would really appreciate the help or a demo/sample would be fantastic!
Create a separate controller with an image view which will popup according to the timer set in app delegate. close X should also have a timer
func applicationDidEnterBackground(application: UIApplication) {
if (!isShowingAd && adTimer != nil) {
adTimerTimeLeft = adTimer!.fireDate.timeIntervalSinceNow
adTimer!.invalidate()
}
if adUpdateTimer != nil
{
adUpdateTimerTimeLeft = 60 * 60 //one hour
self.adUpdateTimer!.invalidate()
}
}
//setting timer, This way you can set timer
var adTimer: NSTimer?
timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: #selector(AppDelegate.updateAd), userInfo: nil, repeats: true)
timer?.fire()

Position of child of instance variable not updating

Hopefully this is a fairly simple question. I create an instance variable named tutorialBox1 from my main game scene Grid.m. Inside my class TutorialBox.m, I create a sprite named textBox1, and as I tap on the main game scene, I want the position of that sprite, textBox1 to be updated. I've been trying to figure out for hours why the position of the sprite will not update after adding the child once. Here is my attempt, and all the necessary code.
Grid.m
# implementation Grid {
TutorialBox *tutorialBox1;
}
-(void)checkTutorials {
//This method is called upon loading of the scene
tutorialBox1 = (TutorialBox*)[CCBReader load:#"TutorialBox"] //creates instance of variable using Spritebuilder (don't worry if you don't use SB, this part works)
[tutorialBox1 updateBoxDisplay:1] //used to add text box child to textBox1
[self addChild:tutorialBox1];
}
-(void)gridTapped {
//When game scene is tapped, this is called to update position of textBox1 in tutorialBox1
[tutorialBox1 updateBoxDisplay:2]; //updates position of textBox1 in tutorialBox1
}
TutorialBox.m
# implementation Grid {
CCSprite9Slice *textBox1;
}
-(void)didLoadFromCCB {
//Called upon initialization of tutorialBox1
textBox1 = [CCSprite9Slice spriteWithImageNamed:#"RetroSprites/tutorialtextBox1.png"];
}
-(void)updateBoxDisplay:(int)newTutorialLevelNumber {
if (newTutorialLevelNumber == 1) {
textBox1.position = ccp(0,0);
[self addChild:textBox1];
}
else if (newTutorialLevelNumber == 2) {
textBox1.position = ccp(100,100)
}
}
TutorialBox.h
#interface TutorialBox : CCNode
- (void)updateBoxDisplay:(int)newTutorialLevelNumber
#end
I have checked to make sure everything is running properly with print statements, so it isn't an issue with anything else. It is simply being called, but the position in my main game scene, Grid.m is not being updated.
Thanks for the help!
I am not sure about this, but I guess its issue with the threading. Give a try with this code:
-(void)updateBoxDisplay:(int)newTutorialLevelNumber {
dispatch_async(dispatch_get_main_queue(), ^{
if (newTutorialLevelNumber == 1) {
textBox1.position = ccp(0,0);
[self addChild:textBox1];
}
else if (newTutorialLevelNumber == 2) {
textBox1.position = ccp(100,100)
}
});
}

how to load bunch of images to the Image in QML?

I would like to load a few images to the Image object in QML. I want to do it one after another in a loop I think with some delay, because it should pretend to look like an animation. Im new in Qt and QML, so can anybody help me how to begin or somethin'? :)
The simplest solution, that works in QML 1.x and 2.0, is to use a Repeater and a Timer :
import QtQuick 2.0
Rectangle {
id: base;
width: 800;
height: 600;
property variant images : [
"image1.jpg",
"image2.jpg",
"image3.jpg",
"image4.jpg",
"image5.jpg"
];
property int currentImage : 0;
Repeater {
id: repeaterImg;
model: images;
delegate: Image {
source: modelData;
asynchronous: true;
visible: (model.index === currentImage);
}
}
Timer {
id: timerAnimImg:
interval: 500; // here is the delay between 2 images in msecs
running: false; // stopped by default, use start() or running=true to launch
repeat: true;
onTriggered: {
if (currentImage < images.length -1) {
currentImage++; // show next image
}
else {
currentImage = 0; // go back to the first image at the end
}
}
}
}
Should do it, and if you don't want the animation to restart when the last image is reached, just replace currentImage = 0; with stop(); in the timer's onTriggered.
Also, you should possibly have to tweak a little the Image delegate in the Repeater to give it the look you want (size, fill mode, position etc...).
If you are using QtQuick 2 then AnimatedSprite is the best way to do this: http://qt-project.org/doc/qt-5.0/qtquick/qtquick-effects-sprites.html
Otherwise, you could use a Timer or NumberAnimation to trigger changing the image source, but there could be unpredictable delays as images load for the first time (caching should solve this after the first loop). If you only have a few images, you could have three Images and cycle their visibility.

Wait while screen rotates

I wish to put a wait until the iPad screen is done rotating and want to have both rotate and wait in the same function. If I don't add few seconds of wait, then the app doesn't behave as expected. Below is the function:
LandScapeRight = function()
{
return UIATarget.localTarget().setDeviceOrientation(UIA_DEVICE_ORIENTATION_LANDSCAPERIGHT);
}
Please suggest.
You want to use the delay() method on UIATarget. The docs for the class are here
The quick and dirty way to do the delay you want is like so:
LandScapeRight = function()
{
var target = UIATarget.localTarget();
target.setDeviceOrientation(UIA_DEVICE_ORIENTATION_LANDSCAPERIGHT);
target.delay(1); // Delay is in seconds, can be a fraction
}
Check this two method
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

Cocos2D - CCLabelTTF - waiting for end of running actions

simply, before I start new level of my game, I show countdown (using CCLabelTTF, Cocos2D).
I have this code:
centerLevelLabel.string=#"New level";
centerLevelLabel.visible=true;
[centerLevelLabel runAction:[CCFadeOut actionWithDuration:1]];
while (centerLevelLabel.numberOfRunningActions>0) {
}
centerLevelLabel.string=#"3";
while (centerLevelLabel.numberOfRunningActions>0) {
}
centerLevelLabel.string=#"2";
while (centerLevelLabel.numberOfRunningActions>0) {
}
centerLevelLabel.string=#"1";
while (centerLevelLabel.numberOfRunningActions>0) {
}
//some code bellow
I want to show thist label and then I need continue with code bellow. Problem is, that UI is freezed and in first while block is running infinite loop. But i don`t kwon why, because when running actions is finished, numberOfRunningActions is zero.
Is there any other way, how could I wait for end of running actions and then continue?
Thank you
You could serialize the action by using a CCSequence and add the CCCallFuncN to execute some code after the original action completes.
id action1 = [CCFadeOut actionWithDuration:1];
id action2 = [CCCallFuncN actionWithTarget:self selector:#selector(finishedRunning)];
id sequenceActions = [CCSequence actions:action1, action2, nil]];
[centerLevelLabel runAction:sequenceActions];
....
-(void) finishedRunning {
// Do stuff after action finishes
}
This will always be an infinite loop:
while (centerLevelLabel.numberOfRunningActions > 0)
{
}
It's similar to writing:
while (value > 0)
{
}
For the time the while loop is running, the thread is blocked. Therefore no other code will run that updates the number of actions, or that might change the value of value.