为什么我的图像会闪烁? (pygame的)

时间:2018-01-17 18:52:41

标签: python pygame

我试图通过简单地在按下指定的左/右按钮的同时加载一组4个图像来“动画”精灵。它主要起作用,除了图像保持闪烁并且不像我预期的那样“切换”。它也大大减缓了。作为Pygame / Python的初学者,我的大脑绝对是油炸的。

import pygame
import os

from test_menu import drawmenu
from game_over import player1wins
from game_over import player2wins
from game_over import tie
pygame.init()

while True: 
    screen_size = (1080, 400)
    screen = pygame.display.set_mode(screen_size)

    background = (255,255,255)
    image = pygame.image.load("background(1).png")
    imagerect = image.get_rect()
    wall_left = pygame.Rect(0,0,1,950)
    wall_right = pygame.Rect(1080,0,1,950)

    square1 = pygame.Rect(750, 350, 20, 20)
    square2 = pygame.Rect(330, 350, 20, 20)
    IMAGE = pygame.image.load("player1standright.png").convert_alpha()
    rect = IMAGE.get_rect()
    rect.x = 100
    rect.y = 225

    x_movement = 0
    y_movement = 0
    x2_movement = 0
    y2_movement = 0

    accelx1 = 0
    accely1 = 0
    accelx2 = 0
    accely2 = 0

    jumping = False
    jumping2 = False

    #This is the function that does it
    def player1runright(images1right, IMAGE, image, imagerect):
        i = -1
        while i <= 2:
            pygame.time.delay(0)
            i += 1
            print (i)
            IMAGE = pygame.image.load(images1right[i])
            print (images1right[i])
            screen.blit(IMAGE, rect)

    images1right = ["player1runright-1.png","player1runright-2.png","player1runright-3.png","player1runright-4.png"]

    def health_bars(player1_health, player2_health):
        if player1_health > 75:
            player1_health_color = (62, 219, 41)
        elif player1_health > 50:
            player1_health_color = (239, 212, 9)
        else:
            player1_health_color = (239, 9, 9)

        if player2_health > 75:
            player2_health_color = (62, 219, 41)
        elif player2_health > 50:
            player2_health_color = (239, 212, 9)
        else:
            player2_health_color = (239, 9, 9)

        pygame.draw.rect(screen, player1_health_color, (70, 50, player1_health, 25))
        pygame.draw.rect(screen, player2_health_color, (900, 50, player2_health, 25))

    player1_health = int(100)
    player2_health = int(100)

    drawmenu()

    while True:
        screen.fill(background)
        screen.blit(image, imagerect)
        pygame.draw.rect(screen, (255,0,0), square1)
        pygame.draw.rect(screen, (0,0,255), square2)
        pygame.draw.rect(screen, (0,0,0), wall_left)
        pygame.draw.rect(screen, (0,0,0), wall_right)
        health_bars(player1_health, player2_health)
        pygame.display.update()
        events = pygame.event.get()
        for event in events:
            if event.type == pygame.QUIT:
                exit()
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_d] != 1:
            screen.blit(IMAGE, rect)

        #MOVEMENT P1

        if keys_pressed[pygame.K_LEFT] == 1:
            x_movement += -1
        elif keys_pressed[pygame.K_RIGHT] == 1:
            x_movement += 1
        else:
            x_movement = 0

        #MOVEMENT P2

        if keys_pressed[pygame.K_a] == 1:
            x2_movement += -1
        elif keys_pressed[pygame.K_d] == 1:
            x2_movement += 1
            player1runright(images1right, IMAGE, image, imagerect)
        else:
            x2_movement = 0

        #MAX SPEED P1
        if x_movement < -7:
            x_movement = -7
        if x_movement > 7:
            x_movement = 7
        if y_movement < -7:
            y_movement = -7
        if y_movement > 7:
            y_movement = 7

        #MAX SPEED P2
        if x2_movement < -7:
            x2_movement = -7
        if x2_movement > 7:
            x2_movement = 7
        if y2_movement < -7:
            y2_movement = -7
        if y2_movement > 7: 
            y2_movement = 7

        #COLLISION (WALL) P1

        if square1.colliderect(wall_left):
            player2_health -= 0.5
            x_movement = 0
            y_movement = 0
            if keys_pressed[pygame.K_RIGHT] == 1:
                x_movement += 1

        if square1.colliderect(wall_right):
            player2_health -= 0.5
            x_movement = 0
            y_movement = 0
            if keys_pressed[pygame.K_LEFT] == 1:
                x_movement += -1

        #COLLISION (WALL) P2

        if rect.colliderect(wall_left):
            player1_health -= 0.5
            x2_movement = 0
            y2_movement = 0
            rect.x = 0
            rect.y = 0
            if keys_pressed[pygame.K_d] == 1:
                x2_movement += 1
                rect.x += 1

        if rect.colliderect(wall_right):
            player1_health -= 0.5
            x2_movement = 0
            y2_movement = 0
            rect.x = 0
            rect.y = 0
            if keys_pressed[pygame.K_a] == 1:
                x2_movement += -1
                rect.x += -1


        #COLLISION (ATTACK) P1
        if square1.colliderect(rect) and keys_pressed[pygame.K_g] == 1:
            player2_health -= 1

        #COLLISION (ATTACK) P2
        if rect.colliderect(square1) and keys_pressed[pygame.K_p] == 1:
            player1_health -= 1

        #JUMPING P1
        if keys_pressed[pygame.K_w] == 1:
            if jumping2 == False:
                jumping2 = True

                y2_movement = -30
                accely2 = 1

        rect = rect.move(x2_movement, y2_movement)

        x2_movement += accelx2
        y2_movement += accely2

        if jumping2 == True:
            if rect.y >= 225:
                jumping2 = False

                rect.y = 225
                y2_movement = 0
                accely2 = 0

        #JUMPING P2
        if keys_pressed[pygame.K_UP] == 1:
            if jumping == False:
                jumping = True

                y_movement = -30
                accely1 = 1

        square1 = square1.move(x_movement, y_movement)

        x_movement += accelx1
        y_movement += accely1

        if jumping == True:
            if square1.y >= 350:
                jumping = False

                square1.y = 350
                y_movement = 0
                accely1 = 0

        pygame.display.update()
        pygame.time.delay(20)

        if player2_health == 0 and player1_health !=0:
            pygame.time.delay(400)
            player1wins()
            pygame.time.delay(3000)
            drawmenu()
            break
        elif player1_health == 0 and player2_health !=0:
            pygame.time.delay(400)
            player2wins()
            pygame.time.delay(3000)
            drawmenu()
            break
        if player1_health == 0 and player2_health == 0:
            pygame.time.delay(400)
            tie()
            pygame.time.delay(3000)
            drawmenu()
            break

(我知道代码有点冗长,但我不知道是否可以切断任何代码。)

2 个答案:

答案 0 :(得分:0)

你的blit rect错误(至少)有两个原因:

  1. player1runright内,您可以使用名为imagerect的参数,但是您使用rect进行blit,上面定义为来自"player1standright.png"的矩形。那个矩阵总是保持不变。
  2. 当您致电player1runright时,您会传递imagerect的值,该值由"background(1).png"定义为矩形。同样,这永远不会改变,并且它不是你想要使用的矩形。
  3. 这两个问题都是由于变量&#34;泄漏&#34;进入其他范围。有时这是需要的,但这里只是导致错误。我会考虑重新组织你的代码(除非你有意想要捕获你的包含范围,否则不要嵌套你的函数)来帮助找到这些错误。

    关于减速:不要每帧加载图像。文件加载速度很慢。加载一次并将它们存储在某处。

答案 1 :(得分:0)

发生闪烁是因为您每帧更新屏幕两次。删除第一个<access origin="*" /> <allow-intent href="geo:*" /> <allow-navigation href="*" /> 行,它应该可以工作。每帧通常只应进行一次pygame.display.update()pygame.display.update次呼叫。

我想通过连续删除你的程序部分直到只留下一个最小的例子。如果错误仍然存​​在,请在每次删除后检查。

动画问题无关紧要,但这是一个快速的解决方案。首先,必须删除pygame.display.flip函数中的while循环,因为它会立即一帧一帧地逐个blit所有图像。

如果按下d键,我只是每帧递增一个索引变量,从动画列表中取出相应的图像,并将其分配给保存当前图像的变量并对其进行blit。

player1runright

另外,请查看this answer