Pygame:将.png文件转换为rect?

时间:2018-01-15 18:51:13

标签: python pygame python-3.6

我已经在这个小游戏上工作了一段时间,我遇到了头疼。下面你可以看到“square1”和“square2”是用pygame绘制的。我想用图像替换它们,但它弄乱了我所做的碰撞事情。是否可以将加载的.png图像“转换”为rect对象?

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)

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

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

    jumping = False
    jumping2 = False

    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.display.update()
        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()
        pygame.time.delay(20)

        #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
        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 square2.colliderect(wall_left):
            player1_health -= 0.5
            x2_movement = 0
            y2_movement = 0
            if keys_pressed[pygame.K_d] == 1:
                x2_movement += 1

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


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

        #COLLISION (ATTACK) P2
        if square2.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

        square2 = square2.move(x2_movement, y2_movement)

        x2_movement += accelx2
        y2_movement += accely2

        if jumping2 == True:
            if square2.y >= 350:
                jumping2 = False

                square2.y = 350
                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 :(得分:2)

获取具有图像/表面尺寸的矩形的标准方法是调用曲面的get_rect方法。

import pygame as pg

pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()

# Use the convert or convert_alpha methods to improve the performance.
IMAGE = pg.image.load('an_image.png').convert_alpha()
rect = IMAGE.get_rect()  # A rect with the dimensions of the image.
# Set the position of the rect.
rect.x = 100
rect.y = 200

done = False
while not done:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            done = True

    keys = pg.key.get_pressed()
    # Move the rect.
    if keys[pg.K_RIGHT]:
        rect.x += 2
    elif keys[pg.K_LEFT]:
        rect.x -= 2

    # Draw everything.
    screen.fill((30, 30, 30))
    # Just pass the rect as the destination argument.
    screen.blit(IMAGE, rect)

    pg.display.flip()
    clock.tick(30)

pg.quit()

您还可以使用其他rect attributes来设置其位置:

x,y
top, left, bottom, right
topleft, bottomleft, topright, bottomright
midtop, midleft, midbottom, midright
center, centerx, centery

我实际上将精灵/对象的位置存储在一个向量中,因为它允许更精确的移动(rects只能存储整数和截断浮点数)。要移动对象,我首先将速度(另一个向量)添加到它,然后将rect的centertopleft属性设置为新的位置向量。仍然需要矩形作为blit位置和碰撞检测。以下是精灵模板的示例:

class Player(pg.sprite.Sprite):

    def __init__(self, pos):
        super().__init__()
        self.image = IMAGE
        self.rect = self.image.get_rect(center=pos)
        self.vel = Vector2(0, 0)
        self.pos = Vector2(pos)

    def update(self):
        self.pos += self.vel
        self.rect.center = self.pos

答案 1 :(得分:1)

我不知道可以这样做的方法。但是,您可以保留一个Surface对象来渲染图像,另一个Rect对象来处理所有碰撞检测业务。

这很常见。

怎么做:

  • 创建Rect对象。

  • 创建Surface对象。

  • 加载.png文件并将其blit到您刚刚创建的Surface上。

  • 确保Rect对象和Surface对象的x和y值在每个帧的末尾都相同。

我已经提供了一些示例代码来帮助您入门。我注释了代码加载图像但是。

使用您自己的图片:

  • 将图像文件复制到所需的目录中。 (如果有疑问,请选择脚本目录)

  • 获取正确的路径名称并在下面的代码中使用。

现在,您可以使用Rect进行碰撞检测和移动,并且始终会在Rect所在的位置绘制图像曲面。

注意:这种方法通常以面向对象的方式完成。

我希望这个答案对您有所帮助,如果您有任何其他问题,请随时在下面发表评论!

示例代码

# create Rects
square1 = pygame.Rect(100, 100, 100, 100)
square2 = pygame.Rect(100, 300, 100, 100)

# create the image surfaces
img = pygame.Surface((100, 100))

image_file = pygame.image.load("path/to/image_file")
img.blit(image_file, [0, 0])

img2 = pygame.Surface((100,100))


image_file2 = pygame.image.load("path/to/image_file")
img.blit(image_file2, [0, 0])

将这些Surface blit到屏幕上:

# draw the image Surfaces
screen.blit(img, [square1.x, square1.y])
screen.blit(img2, [square2.x, square2.y])