Disappearing platforms - whole group disappears and can not get them to reappear [duplicate] - 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.

Sprites will not reappear in same position after a timer

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 - can't scrub through FLV using netstream.seek() after FLV finishes loading

I'm trying to play an FLV using the Netstream class - standard stuff, really using nothing more complex than things you can find in the help files. I've created a control panel with a bar you can use to click and drag and scrub through the video.
Exporting to Flash Player 9, it's working fine and I can scrub through the video, but only while the FLV is still loading. As soon as it hits 100% the scrubbing (using Netstream.seek()) becomes incredibly unresponsive, almost to the point of crashing the player.
I've killed all ENTER_FRAMES, removed all unnecessary listeners and nullified everything I can think of but something massively resource-intensive seems to be kicking in as soon as the load finishes.
Has anyone ever seen this? I've never come across this and can't find anything similar across assorted forums.
Code below but I don't think the mouse-move drag actions are the problem! Fine in the Flash CS4 IDE, broken in the browser.
Thanks for any help you might be able to provide,
Gareth
// Drag
private function dragVideo(e:MouseEvent):void {
// Match the x position of the dragger to the x position of the mouse
videoControls.progressBar.dragger.x = videoControls.progressBar.barInner.mouseX;
// If this results in the dragger moving outside the dragging area, constrain it
if (videoControls.progressBar.dragger.x < videoProgressRectangle.left) {
videoControls.progressBar.dragger.x = videoProgressRectangle.left;
} else if (videoControls.progressBar.dragger.x > videoProgressRectangle.right) {
videoControls.progressBar.dragger.x = videoProgressRectangle.right;
}
// As the dragger moves, work out its position as a percentage of the total distance it CAN move
// That distance is the width of the black inner bar but you must also accomodate the centred registration point of the dragger
// So knock off half the dragger's width from it's current position (which gives the left edge of the inner bar)
// Then knock off the dragger's width minus the 2px overhang of the white progress bar border, from the total draggable distance
videoSeekPercentageMouse = (videoControls.progressBar.dragger.x - (videoControls.progressBar.dragger.width / 2)) / (videoControls.progressBar.barInner.width - (videoControls.progressBar.dragger.width - 2));
// Now use that percentage to seek the video to the equivalent percentage of its total time
if (videoSeekPercentageMouse <= 0) {
videoNetStream.seek(0);
} else if (videoSeekPercentageMouse >= 1) {
// Because video metaData says the length is xyz while the real length is xyz + 0.015,
// seek to slightly before the end
videoNetStream.seek(videoDuration - 0.016);
} else {
videoNetStream.seek(videoDuration * videoSeekPercentageMouse);
}
// Show the video's current progress
videoControls.progressBar.barProgress.scaleX = videoSeekPercentageMouse;
// After the mouse moves update the display
e.updateAfterEvent();
}
Got it!
You should try this..
Pause the streaming "before" seeking..
Seek()
And then resume the streaming!