This line executes after 7 seconds, all the time. When I select the restart button, the scene loads after 7 seconds have passed.
if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+2*Screen.height/10+10, Screen.width/2-20, Screen.height/10), "RESTART"))
{
Application.LoadLevel(Application.loadedLevel); //works 7 sec later
}
How do I solve this problem?
two reasons for this .. your code which loads objects on scene or something is taking a long time are you relying on resources.load/playerprefs too much or something ?
or you just have a really big scene...
hmm one thing you can do if you have objects that are needed in two scenes or more don't create two objects just don't destroy the objects on load
Related
I have this two functions that measure the elapsed time when the phone is locked or the app is in background:
func saveTimeInBackground(){
startMeasureTime = Int(Date.timeIntervalSinceReferenceDate)
}
func timeOnAppActivated(){
stopMeasureTime = Int(Date.timeIntervalSinceReferenceDate)
elapsedTime = stopMeasureTime - startMeasureTime
seconds = seconds - elapsedTime + 2
if seconds > 0 {
timerLbl.text = "time: \(seconds)"
} else {
seconds = 0
timerLbl.text = "time: \(seconds)"
}
}
and then in the viewDidLoad() i have observers that are trigger the functions when the app becomes active/inactive:
NotificationCenter.default.addObserver(self, selector: #selector(saveTimeInBackground), name: Notification.Name.UIApplicationWillResignActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(timeOnAppActivated), name: Notification.Name.UIApplicationDidBecomeActive, object: nil)
The problem is that when the app becomes active there are 2 seconds (approximately) of difference so i've added 2 seconds and it seems to work fine, but only if the elapsed time is > 15 seconds.
If i lock the phone and immediately unlock it the there are like 5 or more seconds that are missing. For example, if there are 50 seconds left, when i lock and immediately unlock it there are like 42 seconds left.
Can anyone please explain, what i am doing wrong?
Edit: The logic of the app is this:
It starts a match between 2 players with 60 seconds for a game. The problem is that when one of the players locks the phone the app stop to measure the time. This way if the player1 has 10 seconds left to make a move, the player2 still has 50 seconds left. I'm looking for a reliable way to calculate the time even if the player locks the phone or put the app in background.
Edit 2: I think i figured out what the problem is: I think the issue has to do with the fact that the “seconds” are Int, and the Date not and when it gets converted it’s rounded up. I didn't tested it, but when i ahve the solution i'll post the answer. Thanks all for your time!
You're relying on exact timing of notifications that aren't guaranteed to have any exact timing. There's no guarantee about when, exactly, either of those notifications will arrive, and there's nothing you can do about that. Even your two-second fix is, as you say, approximate. It'll probably be different on different models of iPhone or even at different times on the same iPhone, depending how busy iOS is when you check.
What's more, when you go into the background, you can't be certain that you'll stay there. Once in the background, iOS might decide to terminate your app at any time.
I'm not sure what the goal is here but I think you'll need to reconsider what you want to do and see if there's some other approach. Your current two-second hack will, at best, spawn a bunch of other hacks (like the 15 second threshold you mention) without ever being especially accurate. And then it'll probably all break in the next iOS update when some iOS change causes the timing to change.
I would use Date object to track game time.
func gameStart() {
gameStartDate = Date()
}
func timeOnAppActivated() {
let secondsLeft = 60 - abs(gameStartDate?.timeIntervalSinceNow ?? 0)
if secondsLeft > 0 {
timerLbl.text = "time: \(secondsLeft)"
} else {
timerLbl.text = "time: 0"
}
}
Ok, like I mention in the edit 2 of the question:
The first issue was because "seconds" is a Int and then it almost always gains or lose when converting it from Double.
But the main problem was that i had to invalidate the timer when the app enter in background and i didn't.
So now with invalidating the timer when the app gets the notification that will enter background and then starting it when it enter foreground everything works fine.
To test this properly call those methods on button click. It may be coz of delay in releasing some resources in background.
I read all the posts I found about improving performance but my problem is a bit different.
I have a simple physics-based game. no super fancy stuff.
I´ve got max. 40 nodes on the screen and a few sklabelnodes.
my code is efficient - every node which moves outside the screen gets removed from his parent and Iv'e got just 4 physicBodys at once. textures are not to big - max 250x250 which are preloaded in an atlas.
the problem is that it works for a minute or so and then it starts to stutter for 4-5 sec and then it works fine again. that stuttering doesn't appear on a certain point. sometimes it does on startup and sometimes after a few minutes.
I don´t know what to do.
I load my ad´s on another thread and otherwise there isn't anything to load.
EDIT:
NO shapeNodes.
XCode 7 + iPhone 6plus (9.3.2)
#Alessandro Ornano
my update method only handles the background images. i already tried without bg´s. same problem. i read about performance issues in iOS9
do you know something about that?
-(void)update:(NSTimeInterval)currentTime{
//BG
if (self.background1.position.x >= self.size.width*1.5) {
self.background1.position = CGPointMake(self.background2.position.x - self.background1.size.width+1, self.size.height/2);
}
if (self.background2.position.x >= self.size.width*1.5) {
self.background2.position = CGPointMake(self.background1.position.x - self.background2.size.width+1, self.size.height/2);
}
//BG CLOUDS
if (self.backgroundClouds1.position.x >= self.size.width*1.5) {
self.backgroundClouds1.position = CGPointMake(self.backgroundClouds2.position.x - self.backgroundClouds1.size.width+1, self.size.height/2);
}
if (self.backgroundClouds2.position.x >= self.size.width*1.5) {
self.backgroundClouds2.position = CGPointMake(self.backgroundClouds1.position.x - self.backgroundClouds2.size.width+1, self.size.height/2);
}
}
I'm using CADisplayLink to fire the "update" event for a very simple OpenGL ES animation on iOS. The animation has around 10 textured quads. I tried to run this at 60 FPS and I saw some glitches. When changing this to 30 FPS the animation runs smoother. After profiling this I saw that the most of the time is spent in presentRenderBuffer.
These are the results:
m_displayLink.frameInterval = 2;
[379406923.204] Update time 0.000358
[379406923.206] Render time 0.001402
[379406923.207] Present time 0.001136
[379406923.238] Update time 0.000370
[379406923.239] Render time 0.001393
[379406923.241] Present time 0.001148
[379406923.271] Update time 0.000368
[379406923.273] Render time 0.001377
[379406923.274] Present time 0.001226
[379406923.305] Update time 0.000380
[379406923.307] Render time 0.001390
[379406923.308] Present time 0.001183
[379406923.338] Update time 0.000375
[379406923.339] Render time 0.001376
[379406923.341] Present time 0.001178
[379406923.372] Update time 0.000981
[379406923.375] Render time 0.001418
[379406923.379] Present time 0.004452
From the results from m_displayLink.frameInterval = 2 profiling I can see that the total frame time is more than enough to achieve 60 FPS, but when changing m_displayLink.frameInterval value to 1 the results are unexpected:
m_displayLink.frameInterval = 1;
[379407317.151] Update time 0.000204
[379407317.152] Render time 0.000827
[379407317.172] Present time 0.019173
[379407317.172] Update time 0.000231
[379407317.173] Render time 0.000856
[379407317.201] Present time 0.027540
[379407317.202] Update time 0.000204
[379407317.202] Render time 0.000834
[379407317.218] Present time 0.015187
[379407317.218] Update time 0.000192
[379407317.219] Render time 0.000803
[379407317.251] Present time 0.031392
[379407317.252] Update time 0.000215
[379407317.253] Render time 0.000858
[379407317.267] Present time 0.014433
[379407317.268] Update time 0.000196
[379407317.269] Render time 0.001248
[379407317.301] Present time 0.031312
As you can see the present time it several times bigger when using
m_displayLink.frameInterval = 1;
Please note that last command from Render() is glFinish()
Do you have any idea why there is this unexpected behaviour? Is it possible to achieve 60 FPS(from the first profiling I have around 500FPS!)?
I solved the problem (pure luck!) by moving OpenGL initialization from view initWithFrame. I know this sounds very awkward, but this reduced my GPU usage from 96% to 6%. Now the simple application runs very smooth at 60 FPS with 2% CPU and 6% GPU usage(as it should be!).
I have four variables, each saved in 365 mat-files (size: 8 x 92 x 240). I try to load these into my function in a for-loop day=1:365, one variable file per day. However, the two first variables always take abnormally long time to load. My code for loading looks like this:
load([eraFolder sprintf('Y%dD%d-tempSD.mat',year,day)], 'tempSD'); % took 5420 s to load
load([eraFolder sprintf('Y%dD%d-tempDewSD.mat',year,day)], 'tempDewSD')
load([eraFolder sprintf('Y%dD%d-eEraSD.mat',year,day)], 'eEraSD'); % took 6 seconds to load
load([eraFolder sprintf('Y%dD%d-pEraSD.mat',year,day)], 'pEraSD');
Using Profiler, I could see that the first two variables took 5420 seconds to load in 365 calls, whereas the the last two variables took 6 and 4 seconds to load respectively over 365 calls. When I swap the order in which variables are loaded, e.g. eEraSD before tempSD, it is still the first two loads that take more time.
When using tic toc to track the time spent on loading, it appears that the time to load a the first or second variable exponentially increases with the number of calls (with the last calls taking 50 seconds to run) . For the third and fourth variable, the loading time stays around 0.02-0.04 seconds per file, more or less independent on how far in the for loop I have gone. See figures below.
When using importdata instead of 'load', the first line takes about 8000 seconds to load 365 times (with the loading exponentially increasing as shown for T in the second figure). The other lines then take about 10 seconds to load 365 times.
I can't understand why it looks this way and what I can do to decrease the loading time. Would greatly appreciate any idea of a possible solution for this.
I suppose your data sets are in the same directory(over network or local) and with same attributes e.g. access properties and so on.
Then the only option left is with the charateristics of the vairbales stored in those matfiles. Can you check how much those variables appear in size e.g. by loading a sample one. This will narrow down to solve your problem.
Hope that help.
FS
Thanks for your help. I finally found out what caused the problem. In a 'for' loop later in the script, I saved other data to a folder I called temp. After renaming that folder to something else (e.g. temporary), the data loading problem disappeared.
(Doesn't matter so much now that the practical problem is solved, but I can't really say I understand why there was this peculiar relationship between the later 'save' call and this 'importdata' or 'load' call.)
Please see new question about the temp folder
I have two animations of a goalkeeper with two different states (with ball and without ball). After keeper jumps I want to switch to a different action but I want to stay at the same frame index.
I mean if goalkeeper collides with the ball in the frame 19, the second action should start at frame 19 too.
I'm still not quite sure if I completely understand what your trying to do but I can help you with that action. If you want to run a check every frame you should do somethng like this
At the end of your scenes init method add:
` [self schedule: #selector(tick:) interval: 0.3f];
-(void)tick:(ccTime) dt {
if(CGRectIntersectsRect(goalKeeper.textureRect, ball.textureRect) {
[goalKeeper stopAction: myAction]; //where myAction is previously defined
} //now you can start the new action because you're using a timer, it'll be the same frame
That should do it. I hope that helps, if I still didn't quite answer your question feel free to clarify what in more vivid what exactly you're going for. `