1

I'm making a catch game. But when the apples fall from the sky the apples are flickering. I tried to rewrite the falling system but it doesn't work. There's no rect override.

There is no double screen update or something like this. If I noticed right, it's only flickering when there's more than one apple on the screen.

import pygame
import time
import catch
import random

pygame.init()

pygame.display.set_caption("apple")

clock = pygame.time.Clock()
prev_time = time.time()
last_apple = time.time()
dt = 0

running = True
velocity = 1300
FPS = 60
appleSize = 50
WIDTH, HEIGHT = 1200, 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))

catch = catch.Catch(487.5, 600, 225, 100,"images/catch.jpg", WIDTH, HEIGHT)


apples = []

appleImg = pygame.image.load("images/apple.png")
appleImg = pygame.transform.scale(appleImg, (appleSize, appleSize))
index = 0
apples.insert(index,[random.randint(0,WIDTH-appleSize),50])

def game(dt):
    global last_apple
    global index
    if(time.time() - last_apple >= 0.7):
        last_apple = time.time()
        index += 1
        apples.insert(index,[random.randint(0,WIDTH-appleSize),50])
    pressedKeys = pygame.key.get_pressed()
    if (pressedKeys[pygame.K_a]):
        catch.moveLeft(velocity * dt)
    if (pressedKeys[pygame.K_d]):
        catch.moveRight(velocity * dt)
    if (pressedKeys[pygame.K_w]):
        index += 1
        apples.insert(index,[random.randint(0,WIDTH-appleSize),50])

    for i, x in enumerate(apples):
        value = (velocity - 1000) * dt
        apples[i][1] += value
        col = pygame.Rect(apples[i][0],apples[i][1],appleSize,appleSize).colliderect(pygame.Rect(catch.x,catch.y+5,catch.w,catch.h))
        screen.blit(appleImg,(apples[i][0],apples[i][1]))
        if(col and apples[i][1]+appleSize <= catch.y+30) or (apples[i][1]+appleSize >= catch.height):
            apples.pop(i)

    catch.draw()


    pygame.draw.rect(screen,(30,30,30),pygame.Rect(0,HEIGHT-75,WIDTH,75))



while running:
    clock.tick(FPS)
    now = time.time()
    dt = now - prev_time
    prev_time = now

    for event in pygame.event.get():
        if (event.type == pygame.QUIT):
            running = False

    screen.fill((0, 157, 255))
    game(dt)

    pygame.display.update()

pygame.quit()


Marci
  • 13
  • 4
  • This question cannot be answered without seeing the update loop. Please read [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) – Rabbid76 Jun 09 '23 at 16:23
  • A strikingly similar question was asked here: https://stackoverflow.com/questions/76436304/pygame-image-flickering – Rabbid76 Jun 09 '23 at 16:37
  • catch.draw() has 1 line, simply screen blit – Marci Jun 09 '23 at 16:54
  • How do you mean? `pygame.draw.rect(screen,(30,30,30),pygame.Rect(0,HEIGHT-75,WIDTH,75))` is just a small and wide rext bottom of the screen, like a taskbar – Marci Jun 09 '23 at 17:17

1 Answers1

0

The problem is that you remove objects from the container apples while iterating. You have to iterate through a shallow copy of the list, when you want to remove objects from the list in the loop (e.g. for apple in apples[:]:). Also see How to remove items from a list while iterating?.

def game(dt):
    # [...]

    catch_rect = pygame.Rect(catch.x, catch.y+5, catch.w, catch.h)
    value = (velocity - 1000) * dt
    for apple in apples[:]:
        apple[1] += value
        screen.blit(appleImg, apple)
        col = pygame.Rect(*apple, appleSize, appleSize).colliderect(catch_rect)
        if(col and apple[1]+appleSize <= catch.y+30) or (apple[1]+appleSize >= catch.height):
            apples.remove(apple)

    # [...]
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • @Marci Do you have the feeling or do you know? I can not reproduce the problem. I've answered your question. If you have another problem, you have to [Ask a public question](https://stackoverflow.com/questions/ask). – Rabbid76 Jun 10 '23 at 15:25