how to preload texture atlas to improve performance and reduce lagging? swift, spritekit
I'm not sure what imageLoad
does, but here's one way to preload and reuse a texture.
Add the following code to your SKScene subclass
let ballTexture = SKTexture(imageNamed: "Ball")
Modify your addBall
method to create your ball sprite from a texture by
func addBall() {
let ball = SKSpriteNode(texture: ballTexture)
...
I recommend you create a performSelector
SKAction
to add balls at fixed intervals instead of adding them in the update
method.
Lastly, I suggest you move self.physicsWorld.contactDelegate = self
and self.physicsWorld.speed = 1
from addBall
to the didMoveToView
method, so they aren't called repeatedly whenever you create balls.
Optimizing SKLabelNode to reduce performance issues
Try to preload SKLabelNode
with all chars you need. Maybe, SpriteKit renders only required glyphs into texture.
// Preloaded model label (private property that is initialized in the class init method).
_modelLabel = [[SKLabelNode alloc] initWithFontNamed:_fontName];
_modelLabel.fontColor = _fontColor;
_modelLabel.fontSize = _fontSize;
_modelLabel.text = @"ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz0123456789-+=_()";
And then add your model into scene with minimal alpha (but no zero, because if node has 0 alpha, it will not drawn); Try to keep that node in scene
_modelLabel.alpha = CGFLOAT_MIN;
[self addChild:_modelLabel];
If not helps:
- Organize nodes by aligning their
zPosition
(akaz-index
). You should disableignoresSiblingOrder
for having control overzPosition
.
Make your allSKLabelNode
be drawn at one z level. - Switch to bitmap fonts. Writing custom bitmap font renderer is super easy. The only thing you should remember - Make all glyphs be in only texture atlas, so you can draw your text in one draw call
- Use native labels. I'm not sure, how much does it help. If you're having heavy FPS drops (~5..10FPS) This may help you
What causes the game to lag when I try to spawn instances after a collision?
The way the question was originally written, I would have suggested to use a particle system. However, with the code, I see you are trying to spawn projectiles that can cause damage…
Before going further, I should point you to the profiler, which might give you some insight in what is actually happening. You can enable the Debugger profiler from the bottom panel of the editor, on the profile tab. Once enabled start the game. The profiler will make graphs (you can select what to graph on the left) showing you what takes more time. You may also be interested on the graphs on the Monitors tab. Then you would reproduce the problematic situation, and see what is eating more time (you would looking for some graph suddenly rising around the time your code spawns the projectiles).
I don't know what it is for sure, but I can make some educated guesses and give you some advice on how to handle them.
One of the reasons you might lose frames is shaders loading and compiling.
You can diagnose this problem by checking if this only happens the first time you spawn your projectiles. For the second time the shaders would have already been loaded and compiled, so there would be no frames drops due to this.
That also tells you how to address this: have something with the shader loaded and visible beforehand. On a similar note, try to reuse your shaders.
Anyway, I don't think shaders is the problem. A more likely culprit is physics: When the projectile spawns, it intercepts the other areas, and the multiple projectiles intercept each other. You would address that with collision_layer
and collision_mask
.
In an ideal scenario, you would not even need this check at all:
if (area.name == "Player"):
Instead you would have the player on its own layer. And these Area2D
have a mask that have only collide with that layer. That way Godot will not even check for collisions between the projectiles and something other than the player.
Something else that will ease the above issue is to spread the instantiations.
By the way, if the issue if that the projectile scene is just that heavy to instantiate, aside from trying to making it less heavy (smaller textures, simpler shapes, less expensive shaders…), you can also try spreading the instantiations.
The easiest way to do that is to insert this line in your loop:
yield(get_tree(), "idle_frame")
Or perhaps physics frame is better:
yield(get_tree(), "physics_frame")
This line will have the Godot halt execution until a frame (or physics frame) passes, then Godot resumes the execution of the code on the next line.
Similarly, if instantiating is expensive (or if the problem were a large number of instances being created, which does not seem to be the case), you could pool the instances.
This is probably not necessary in your case... Anyway, the idea is two fold:
- Have your projectiles instanced in an array (the pool). So when you need them you only have to remove them form the array and add them to the scene. You would only instance more if the array is empty.
- Similarly, don't
queue_free
them, instead remove them from the scene (withremove_child
) and add them back to the array to be reused.
How do I pre-cache images for quick viewing with javascript?
You don't need to create any page elements, it can all be preloaded using JavaScript:
tempImg = new Image()
tempImg.src="pic2.jpg"
EDIT:
If you have a lot of images, you can use the poor-man's multi-preloader:
preloads = "red.gif,green.gif,blue.gif".split(",")
var tempImg = []
for(var x=0;x<preloads.length;x++) {
tempImg[x] = new Image()
tempImg[x].src = preloads[x]
}
First time setting a gameobject to active it lags
The accepted answer is a workaround, not a solution. Keeping hundreds of UI elements loaded is an utter waste of memory.
You should instead divide up your canvases, as written in this wonderful article by Unity. The reason for the lag is Unity's updating all canvas contents, even disabled objects, when you enable an object for the first time. To prevent unused objects from updating, isolate them in a different canvases. You can even put those canvases as children of your original canvas if you wish.
Related Topics
Characteristic.Value from Bluetooth Reading in Swift
Cannot Increment Beyond Endindex
Swift - Rotate Gesture and Rotation Increments of 90 Degrees
How to Put a View with Loadmore Button in UItableview After The Cell
How to Decorate Siesta Request with an Asynchronous Task
How to Show an Alert in Swift UIalertview Not Working
Firebase - Swift 4: Message Sent But Not Received
Swiftui Tabview with List Not Refreshing After Objected Deleted From/Added to Core Data
How to Detect Encoding in Data Based on a String
Qlpreviewcontroller Showing File Then Going Blank in Swiftui
Connecting Avaudiosourcenode to Avaudiosinknode Does Not Work
Having Trouble with Musickit Sample App Provided by Apple
External Library Usage in Xcode
When Creating Thread Safe Reads in Swift, Why Is a Variable Create Outside The Concurrent Queue
Swift Execute Command Line Command in Sandbox Mode
Trouble Passing Array Through Prepareforsegue
How to Get The Advantages of Scenekit's Level Editor Programatically