Howdy! This question is in reference to a student rendition of the game Galaga: Code.org - Game Lab
To highlight the issue, please open the project and add a variable watcher for enemies.length and playerShots.length (or log them to the console).
Notice that when the enemies are hit by a projectile, both sprites disappear and everything appears to be working properly. However, notice that the length of the enemies group and the playerShots group is NOT going down. It appears that the sprites in these groups are continuing to exist, which eventually causes the game to lag. The code that SHOULD destroy the sprites is the for-loop on lines 226-235, but it seems like the sprite.destroy() method isnât working as it should.
If anyone can help me understand whatâs going on here, Iâd be grateful!
Non-expert opinion here, but a few observationsâŚ
The documentation for destroy says: The removed sprites wonât be drawn or updated anymore.
It doesnât say they wonât exist, so itâs likely they still exist, but arenât being drawn and updated.
I attempted to verify this by using the sample code in the documentation and sure enough when I changed it a little to cause the sprite.x to increase by 1 inside the draw loop, I could click on it and destroy it, but the watcher still showed itâs x value increasing, so even then, it appeared to exist and be updating (but wasnât drawn anymore).
On the other hand, when I ran the sample code given in the documentation for group.destroyEach and group.setLifetimeEach, the âremovedâ sprites no longer showed up when I watched for them. Could you maybe have your student look at one of those blocks to see if they could figure out a way to use one of those instead?
At either rate, the last observation I have is that GameLab is an educational tool rather than a professional environment and it does have limits. The limits are high enough that a beginner and even intermediate student will likely be able to create some very advanced projects, but there are limits and it is possible to find test cases that will appear to break GameLab. I donât know that this is an example of that, but it could be.
There are some users who have created some pretty sophisticated games who frequent the forum. Maybe one of them will see this and have an idea for you.
If the sprite was actually getting removed from the group the for loop would be returning an error, as it would loop through an element that doesnât exist at the end of the loop.
To not get this error and remove the sprite from the group, youâre gonna have to use the break
Note: using sprite.remove on the sprite that got hit/the bullet is not necessary, but you can still do that.
statement in javascript. Just replace this: for(var j = 0; j < playerShots.length; j++){ for(var k = 0; k < enemies.length; k++){ if(playerShots[j].isTouching(enemies[k])){ score+=50; explode(enemies[k].x, enemies[k].y); enemies[k].destroy(); // DOESN'T REMOVE SPRITE FROM ENEMIES GROUP playerShots[j].destroy(); // DOESN'T REMOVE SPRITE PLAYERSHOTS FROM GROUP } } }
by collisionsLoop: for(var j = 0; j < playerShots.length; j++){ for(var k = 0; k < enemies.length; k++){ if(playerShots[j].isTouching(enemies[k])){ score+=50; explode(enemies[k].x, enemies[k].y); enemies.remove(enemies[k]) playerShots.remove(playerShots[y]) break collisionsLoop } } }
Also after noticing this didnât work I realized your student was drawing sprites using drawSprites() and not drawSprites(group). That matters a lot because drawSprites() without parameters draws the sprites from World.allSprites. He has already created 2 groups.
On line 53, replace drawSprites();
by drawSprites(movingEnemies) drawSprites(playerShots) drawSprites(enemies) drawSprites(enemyShots) drawSprites(playerGroup)
Your student hasnât created a group for the player.
Add this right after the thirteenth line: var playerGroup = createGroup() playerGroup.add(player)
Thanks for your helpful response and for taking the time to investigate. I hear you about the limitations of the platform, Iâm just trying to push it as far as I can, as the leap to Phaser or Unity introduces a lot of platform-specific library/interface content that seems potentially too niche for a well-rounded coding class. My hope is that the developers of Game Lab intend to continue to improve and optimize the platform (âAHEM, JavaScript ES6 pleaseâ) to make it as capable as possible.
This is extremely helpful. Thanks so much for taking the time to figure this out! Itâs great to know about the drawSprites(group) parameter. I had also never used loop labels, so thatâs great to know about too. The only thing Iâm left wondering is whether removing a sprite from the group and no longer drawing it (or checking it for collisions) is enough to prevent the game from eventually lagging. In your experience, would you say itâs acceptable to have all of these projectile sprites continue to exist as long as theyâre not being used in any way?
Honestly, I would spend the time to remove these sprites if I could, but it wonât have any impacts on the game. It will still be getting 60 fps (or the amount of fps you have set in your game). The spriteâs existence in the game doesnât make the game lag (it does but really not a lot). However, if you have 1000 sprites in your game, the game will take up A LOT of memory. The code.org GameLab compiler is a lot slower than the normal chrome compiler, so if your game has a lot of sprites created, the player of your game will shortly see this error pop up:
Great, thatâs really good to know! I have very limited experience with compilers, but I have noticed that compared to P5js, the Game Lab is quite slow. For example, I coded Tetris in P5: https://editor.p5js.org/dhartman/present/26Sk8jsjA, and then ported it over to the Game Lab (since it includes the P5 library, although I did have to swap âletâ for âvarâ as it doesnât yet have ES6), but in Game Lab it runs so slow as to be unplayable: Code.org - Game Lab
Hereâs hoping that code.org adds support for ES6 and makes some optimizations!