iphone - Images (slide show) and audio snychronization - iphone

I have 20 images and some audio. I would like to show a single image at a time and change the images at (unequal) intervals. For example, I want to show image 1 for 1.44 seconds and image 2 for 1.67 seconds and so on. Can someone suggest how to go about doing this please? What I have seen are examples that show how to setup an array of images with one field that denotes total time. This causes the images to show for an equal amount of time (each). ... and that not what I am looking for ...

Make an NSTimer with some time interval, say 1 second. When the timer fires, figure out how long you want the new slide to remain and use setFireData to set when the next timer should fire.
-(void) timerFired:(NSTimer *)inTimer {
NSTimeInterval timeForSlide = [self advanceToSlideReturningDuration];
if ( timeForSlide > 0 ) [inTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:timeForSlide]];
else [inTimer invalidate]; // the show is over
}

Related

How to get current frame from Animated Tile/Tilemap.animationFrameRate in Unity

I am using tilemaps and animated tiles from the 2dExtras in unity.
My tiles have 6 frames, at speed=2f, and my tilemap frame rate is 2.
New tiles placed always start on frame 1 and then immediately jump to the current frame of the other tiles already placed, the tilemap is keeping every tile at the same pace, which is working as I want.
However I would like the newly placed tiles to start at the frame the others are currently on,(instead of placing a tile that jumps from frame 1 to frame 4) I would like the new tile to start on frame 4
I've found how to pick the frame I want to start on, however I am having trouble retrieving which frame the animation is currently on, so I was wondering how exactly can I access the current frame of animation of a given tilemap ( Or a given tile, I can create a dummy tile and just read the info out of it, how can I get the current frame of an animated tile? )
The animated tilemaps feature seems to lack the feature to retrieve this information, also when I try tilemap.getsprite it always returns the first frame of the sequence(does not return the sprite currently displayed), and there doesn't seem to be any method to poll info from tilemap.animationFrameRate.
I thought another method would be to set a clock and sync it to the rate of the animation but since I can't get the exact framerate duration the clock eventually goes out of sync.
Any help would be appreciated!
I found a way to solve this question. But it's not 100% insurance.
First of all, I used SuperTile2Unity. That doesn't seem to be the point.
private void LateUpdate()
{
// I use this variable to monitor the run time of the game
this.totalTime += Time.deltaTime;
}
private void func()
{
// ...
TileBase[] currentTiles = tilemap.GetTilesBlock(new BoundsInt(new Vector3Int(0, 0, 0), new Vector3Int(x, y, 1)));
Dictionary<string, Sprite> tempTiles = new Dictionary<string, Sprite>();
//I use SuperTiled2Unity. But it doesn't matter, the point is to find animated tile
foreach (SuperTiled2Unity.SuperTile tile in currentTiles)
{
if (tile == null)
{
continue;
}
if (tile.m_AnimationSprites.Length > 1 && !tempTiles.ContainsKey(tile.name))
{
// find animated tile current frame
// You can easily find that the way SuperTile2Unity is used to process animation is to generate a sprite array based on the time of each frame set by Tiled animation and the value of AnimationFrameRate parameter.
// The length of array is always n times of AnimationFrameRate. You can debug to find this.
tempTiles.Add(tile.name, tile.m_AnimationSprites[GetProbablyFrameIndex(tile.m_AnimationSprites.Length)]);
}
}
//...
}
private int GetProbablyFrameIndex(int totalFrame)
{
//According to the total running time and the total length of tile animation and AnimationFrameRate, the approximate frame index can be deduced.
int overFrameTime = (int)(totalTime * animationFrameRate);
return overFrameTime % totalFrame;
}
I have done some tests. At least in 30 minutes, there will be no deviation in animations, but there may be a critical value. If the critical time is exceeded, there may be errors. It depends on the size of AnimationFrameRate and the accumulation mode of totalTime. After all, we don't know when and how the unity deals with animatedTile.
You could try using implementation presented in [1] which looks as follows:
MyAnimator.GetCurrentAnimatorClipInfo(0)[0].clip.length * (MyAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime % 1) * MyAnimator.GetCurrentAnimatorClipInfo(0)[0].clip.frameRate;
[1] https://gamedev.stackexchange.com/questions/165289/how-to-fetch-a-frame-number-from-animation-clip

Detecting if zoomIn or zoomOut on 'zoomstart'

I wrote a function which, on zoomstart, (should) do_something1 if I zoomIn and do_something2 when I zoomOut:
'var prevzoom = map.getZoom;
map.on('zoomstart', do_something);
function do_something(e){
var currzoom = map.getZoom();
var diff = currzoom - prevzoom;
if(diff > 0){do_something1}
else {do_something2}
prevzoom = currzoom;'
It behaves as follows:
1)when loading, if I zoomOut it do_something2 (and the second, third... time as well
2)when loading if I zoomIn it do_something2 (uncorrectly) but it do_something1 the second, third... time and so on...
3) when I change from ZoomIn to ZoomOut and viceversa the first time it behaves as the previous time and it behaves correctly on the second, third...time when zooming in the same way (i.e. In or Out).
I read in the post "Detecting if is zoom-in or zoom-out with leaflet" its it not possible to know if zoomIn or Out when the event zoomstart is triggered.
In my case it seems to work most of the time (which is not good anyway).
What I am missing/did wrong?
I have no knowledge in coding: thank you for help.
Giuseppe

Fading 2 sounds in Wed Audio API

I'm trying to fade out 2 sounds at the same time in the piano app on this page:
http://www.intmath.com/trigonometric-graphs/music-note-frequencies-interactive.php
I'm using the "voices" approach and the exponential fadeout is working fine in single-note mode;
vca.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 1);
oscillator.stop(audioContext.currentTime + 1);
However, after choosing "Combined signal: yes" (where you hear a 220 Hz note plus the note played), the above will fade out the non-220 Hz note correctly, but the fundamental A-220 plays at full volume for the whole 1-second duration after key up. It's ugly, especially on small speakers.
I've disabled the fadeout for now in the "combined" case (both sounds just stop immediately, which is better than having one not fade at all.)
This is the function called on key up:
function doUp(thisKey, e) {
if(audioContext) {
for(i=-1; i<18; i++) {
if( typeof(active_voices['key'+i]) != "undefined") {
active_voices['key'+i].stop();
delete active_voices['key'+i];
}
}
}
audioOn = false;
}
I have tried changing the first line of the middle "if" to the following, but it didn't improve things:
active_voices['key'+i].stop(audioContext.currentTime + 1);
How to fade out 2 voices at the same time?
TIA.

Change FPS of Sprite-Kit Game?

Is it possible to change the FPS of a Sprite-Kit game? If it is possible, how can I implement this into my code?
For example, if a user wants to conserve battery the game can change the FPS from 60 (default value) to 30 or 20.
Thanks for helping
Set the SKView's frameInterval to the desired value.
Ref: https://developer.apple.com/library/mac/documentation/SpriteKit/Reference/SKView/index.html#//apple_ref/occ/instp/SKView/frameInterval
Setting the interval to 2 will cause half the default frame rate. (It is an integer though so it appears that the only option would be to cut the frame rate by half, third, fourth, etc.
let gameView = SKView()
if #available(iOS 10.0, *) {
gameView.preferredFramesPerSecond = 30
} else {
gameView.frameInterval = 2 //Deprecated
}

Discursive UIAlertView animation while continuous animation?

I'm trying to write a little app, where on the main screen, I animate a flying "bubble". This animation has to be continuous. (I reuse the bubbles, which fly off the screen) I heard that animations have to run on the main thread, as does every operation which changes the UI. Is this true? When I try to show a UIAlertView on this screen, it's animation becomes very discursive because of the continuous bubble animation. (this is a custom alertview with an indicator) The device is an iPhone 4, so I don't think it should be a problem to show a normal UIAlertView.
And I would like to ask if I use the correct method for the bubble animation. So first of all, I use an NSTimer, which invokes the startAnimation method in every 0.01 seconds (I start it in the controller's viewDidAppear: method). In the startAnimation method, at first I generate bubbles with random x and y coordinates (to see bubbles on the screen right after the viewdidappear), and I generate bubbles on the bottom with random x and y = 460 coordinates. In the startAnimation method, I run a counter (called frames), and when the value of this counter equals 35, I call the bubble generate method again.
The problem:
I store the generated bubbles in an array, and the 'gone' bubbles (which are off the screen) in another array. First I try to reuse the bubbles in the gonebubbles array, then if the array is run out, I generate new bubbles. While this operation is processed, the continuous animation stops, then continues. The break is about one second, but this is very disturbing.
Can anyone help in this problem? Thanks in advice, madik
- (void)viewDidAppear {
.
timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(startAnimation) userInfo:nil repeats:YES];
.
}
- (void)startAnimation {
self.current = [NSDate timeIntervalSinceReferenceDate];
double diff = (self.start - self.current);
if ( diff < 0 ) {
diff = (-1) * diff;
}
self.start = self.current;
frames++;
if ( shouldMoveBubbles ) {
[mug moveBubbles:diff];
}
if ( frames == 35 ) {
DebugLog(#"################################################################");
DebugLog(#"####################### FRAME = 35 ###########################");
DebugLog(#"################################################################");
[mug createNewBubbleOnTheBottomOfView:self.view];
frames = 0;
}
}
In the Mug class:
- (void)moveBubbles:(double)millisElapsed {
for (Bubble *bubble in bubbles) {
int bubbleSpeed = bubble.speed;
float deltaX = (float)(bubbleSpeed * -degrees_sinus * millisElapsed * 100);
float deltaY = (float)(bubbleSpeed * -degrees_cosinus * millisElapsed);
DebugLog(#"movebubbles x: %f, y:%f, speed: %d, sin:%f, cos:%f", deltaX, deltaY, bubbleSpeed, degrees_sinus, degrees_cosinus);
[bubble moveBubbleX:deltaX Y:deltaY];
}
}
And in the Bubble class:
- (void)moveBubbleX:(float)deltaX Y:(float)deltaY {
self.bubbleImage.center = CGPointMake(self.bubbleImage.center.x + deltaX, self.bubbleImage.center.y + deltaY);
}
This sounds like a memory problem. Slow UIAlertView animation is a sure sign of this. It sounds like the way you are generating bubbles is causing the problem. You mentioned the you keep two arrays of bubbles. You never say if you limit the number of bubbles that can be in either array at once. You also don't mention when you clean up these bubbles. It sounds like a memory "black hole". I'd recommend setting a maximum number of bubbles that you can show on screen at once.
Also, you mention a custom alert view. If you're modifying the UIAlertView, you're going to run into problems since that's not officially supported. Additionally, I've seen UIAlertView animation become slow when memory is tight. If you solve the memory issues with your bubbles, you'll probably solve this one too.
Finally, a word of advice. Making an animated game in UIKit is probably not a good idea. NSTimers are not as accurate as many people would like to think. UIImages are relatively expensive to load. Touching moving buttons is known to be unreliable at worst, hackish at best. I suggest looking into a game framework, such as Cocos2d-iphone.
Good luck!