Sprites will not reappear in same position after a timer - pygame

So I have fixed the issue where a platform disappears after a certain time when player is stood on it without removing all instances, but now need to make the platform reappear after a certain time so player can progress.
I have tried creating instance and adding to group again in the game loop and in the code shown below adding a new timer, but nothing happens. If I add to group after this code the platfroms don;t disappear, so I assume the adding sprite to group is working, I just can't get a time delay on it re-appearing.
if self.rect.bottom == trick_platform.rect.top -1:
trick_platform.timer += 1
if trick_platform.timer > 24:
trick_platform.kill()
The instance originates when world is drawn in tile '24' as below in world class...
elif tile == 24:#create trick_platform
trick_platform = TrickPlatform(x * TILESIZE, y * TILESIZE)
trick_platform_group.add(trick_platform)

pygame.sprite.Sprite.kill remove the Sprite from all Groups. This means the Sprite object gets destroyed an cannot "reappear".
I suggest to use 2 pygame.sprite.Group objects. One for the visible platforms and one for the invisible platforms.
trick_platform_group = pygame.sprite.Group()
invisble_platform_group = pygame.sprite.Group()
Remove the platform form the trick_platform_group Group and add it to the invisble_platform_group Group when it becomes invisible:
trick_platform_group.remove(trick_platform)
invisble_platform_group.add(trick_platform)
Do the opposite when it becomes visible again
trick_platform_group.add(trick_platform)
invisble_platform_group.remove(trick_platform)

Related

How to remove something once drawn?

I'm using libgdx and recreating pac-man, I'm currently using this code to spawn in the pellets for the level (essentially they spawn everywhere that the walls and Pac-Man aren't)
for(int x = 1; x < 27; x++) {
normalPellet.setX((x * 70) + 25);
normalPellet.setY((y * 70) + 25);
if(!(normalPellet.overlaps(walls)) {
batch.draw(pellet,normalPellet.x,normalPellet.y);
pelletCount++;
}
}
My problem is that I don't know how to make it so that when Pac-Man moves over the pellets they get "eaten" and are removed from the field. When Pac-Man moves over them, they do disappear, but as soon as Pac-Man moves to a different place on the map they immediately reappear. How do I make it so they go away permanently?
Typically a game is redrawn on each render call (the render loop). Your game runs by calling your root render() method repeatedly. At the beginning of your render method, you clear the screen, and then draw everything again. So to remove something, you simply stop drawing it.
You need to create a List of all active pellets. This can be a list of some Pellet class that you create that has coordinates and any other state data that is relevant to your game (such as whether it's a "super-pellet"). Or it could just be a list of Vector2s if all your pellets are identical so the only thing you need to track is their position.
When a round starts, you should create all the pellets you need at the coordinates they should be at and add them all to the List.
Then, instead of doing your for(int x = 1; x < 27; x++) loop to draw them, you should loop through your list instead and draw each pellet based on its position (and possibly other data, for example if there are super pellets, you could choose how big to draw it based on that data).
When the character moves, you can check its overlap with each pellet in the list. When a pellet is overlapped, you can remove it from the list and update your score. When it is removed from the list, it will no longer be drawn in the other part of your code where you loop through the list to draw them.

Disappearing platforms - whole group disappears and can not get them to reappear [duplicate]

So I have fixed the issue where a platform disappears after a certain time when player is stood on it without removing all instances, but now need to make the platform reappear after a certain time so player can progress.
I have tried creating instance and adding to group again in the game loop and in the code shown below adding a new timer, but nothing happens. If I add to group after this code the platfroms don;t disappear, so I assume the adding sprite to group is working, I just can't get a time delay on it re-appearing.
if self.rect.bottom == trick_platform.rect.top -1:
trick_platform.timer += 1
if trick_platform.timer > 24:
trick_platform.kill()
The instance originates when world is drawn in tile '24' as below in world class...
elif tile == 24:#create trick_platform
trick_platform = TrickPlatform(x * TILESIZE, y * TILESIZE)
trick_platform_group.add(trick_platform)
pygame.sprite.Sprite.kill remove the Sprite from all Groups. This means the Sprite object gets destroyed an cannot "reappear".
I suggest to use 2 pygame.sprite.Group objects. One for the visible platforms and one for the invisible platforms.
trick_platform_group = pygame.sprite.Group()
invisble_platform_group = pygame.sprite.Group()
Remove the platform form the trick_platform_group Group and add it to the invisble_platform_group Group when it becomes invisible:
trick_platform_group.remove(trick_platform)
invisble_platform_group.add(trick_platform)
Do the opposite when it becomes visible again
trick_platform_group.add(trick_platform)
invisble_platform_group.remove(trick_platform)

In Pygame, can you draw many sprites to the screen each loop without significant delay? [duplicate]

This question already has an answer here:
Pygame is running slow
(1 answer)
Closed 2 years ago.
In my map editing program, I have 3 key features.
Adding sprites
Removing sprites
Currently selected sprite follows the mouse
Issue I'm having is that I use a loop that iterates through all of the "added sprites" and draws them to the screen. The delay gets significant and drawing becomes harder the more sprites on the screen due to the MS delay from this loop
while item_list_item_amount > item_list_iterator:
display.blit(pygame.image.load("imgs\\tiles\\" + sprite_list[item_list_iterator]), (x_list[item_list_iterator] * 16, y_list[item_list_iterator] * 16))
item_list_iterator += 1
Each "Mainloop" cycle draws the background over these sprites, to make removing / replacing sprites possible. This makes re-drawing the sprites every loop necessary currently.
Loop looks like this:
while main_loop == True:
#Main starts loop here
#Update the currently selected tile
display.fill(BGC)
display_listed_tiles()
#Uses mouse coordinates to blit tile over current mouse location
display.blit(tile, (row * 16, col * 16))
screen.blit(pygame.transform.scale(display, WINDOW_SIZE), (0, 0))
#Updates screen
pygame.display.update()
I've tried making a comparison list and only drawing the background once, but the lag remains on removing sprites and I couldn't get the mouse function to work.
Any thoughts on if this situation is resolvable? Any way to compress the "sprite list" that needs to be drawn to one object rather than having to iterate the entire list of hundreds? Any help is appreciated!
The major issue is that you load the images in every frame. pygame.image.load is a very expensive operation, because it has to read the images from the data store.
Load the images once at initialization and use them when drawing:
surface_list = [pygame.image.load("imgs\\tiles\\" + name) for name in sprite_list]
for item_list_iterator in range(item_list_item_amount):
display.blit(surface_list[item_list_iterator], (x_list[item_list_iterator] * 16, y_list[item_list_iterator] * 16))

AS3 - how to stop moving stage if it reaches the edge of background

I'm using a sidescroller where the stage follows the player until the background reachs the edge.
But how do I make it so the background doesn't show the stage when touching the end of the background? Like when it reaches the near end, the stage needs to stop moving and the player needs to move to the end on it's own. That way the stage won't show when touching the edge of the sky.
I currently have a code for the stage following player, but confused on how to make the stage stop at the end or beginning of map.
x = -(player.x-stage.stageWidth/2)
Maybe something like this.
x = -(player.x-stage.stageWidth/2);
if (x < 0){
x = 0;
} else if(x > stage.stageWidth){
x = stage.stageWidth;
}
Or whatever values you will need to check as your edge cases.

AS3 - Finding an objects x and y position relative to the stage

I'm new to ActionScript 3 and I have a character which you can control, the screen scrolls right along the stage and he can fire missiles.
The problem I'm getting is the missiles are created via these co-ords:
bullet.x = hero.mc.x;
bullet.y = hero.mc.y
These work fine untill the screen has scrolled to the right. I assume it's because the bullets are being spawned as a result of them using the canvas x,y and not the stages x,y
So i'm wondering how to find out the x and y of my hero in relative to the canvas so i can spawn the missiles on top of him!
Thanks, and if you need any more information let me know, I'm new to all this. Thank you.
You can do that with localToGlobal and globalToLocal. Your solution would be something like:
bulletPos = bullet.parent.localToGlobal(new Point(bullet.x, bullet.y));
Beware, though, as those are last resort functions. Normally, you'd have all your elements using the same 'layer', so comparisons are easier and faster.