在 pygame 场景中间插入图像

inserting image in middle of pygame scene

我有一个问题我无法理解,请帮助我(对不起,代码太大),但你应该能够看到全貌

import numpy as np
import matplotlib.pyplot as plt
from pygame.locals import  *
import pygame
pygame.init()
screen_width =800
screen_height =800
screen =pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption("Platformer")
sky_img =pygame.image.load("sky.png")
sun_img =pygame.image.load("sun.png")
restart_img =pygame.image.load("restart_btn.png")
start_image =pygame.image.load("start_btn.png")
exit_image =pygame.image.load("exit_btn.png")
clock =pygame.time.Clock()
fps =60
tile_size =40

world_data = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1],
[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 2, 2, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 7, 0, 5, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 1],
[1, 7, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 1],
[1, 0, 2, 0, 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 2, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 2, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 2, 2, 2, 2, 1],
[1, 0, 0, 0, 0, 0, 2, 2, 2, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]
blob_group = pygame.sprite.Group()
lava_group =pygame.sprite.Group()
game_over =0

class World():
    def __init__(self,data):
        self.tile_list =[]
        wall_imag =pygame.image.load("dirt.png")
        grass_img =pygame.image.load("grass.png")
        row_count =0
        for row in data:
            col_count =0
            for tile in row:
                if tile ==1:
                    img =pygame.transform.scale(wall_imag,(tile_size,tile_size))
                    img_rect =img.get_rect()
                    img_rect.x =col_count*tile_size
                    img_rect.y =row_count*tile_size
                    tile =(img,img_rect)
                    self.tile_list.append(tile)
                if tile == 2:
                    img = pygame.transform.scale(grass_img, (tile_size, tile_size))
                    img_rect = img.get_rect()
                    img_rect.x = col_count * tile_size
                    img_rect.y = row_count * tile_size
                    tile = (img, img_rect)
                    self.tile_list.append(tile)
                if tile ==3:
                    blob =Enemy(col_count*tile_size,row_count*tile_size+15)
                    blob_group.add(blob)
                if tile ==6:
                    lava =Lava(col_count*tile_size,row_count*tile_size+(tile_size)//2)
                    lava_group.add(lava)
                col_count+=1
            row_count+=1
    def draw(self):
        for tile in self.tile_list:
            screen.blit(tile[0],tile[1])
class Button():
    def __init__(self,x,y,image):
        self.image =image
        self.rect =self.image.get_rect()
        self.x =x
        self.y =y
        self.clicked =False

    def draw(self):
        action =False
        pos =pygame.mouse.get_pos()
        if self.rect.collidepoint(pos):
            if pygame.mouse.get_pressed()[0]==1 and self.clicked==False:
                action =True
                self.clicked =True
        if pygame.mouse.get_pressed()[0] ==0:
            self.clicked =False
        screen.blit(self.image,self.rect)
        return action
class Player():
    def __init__(self,x,y):
        self.reset(x,y)
    def reset(self,x,y):
        self.images_right = []
        self.images_left = []
        self.index = 0
        self.counter = 0
        for num in range(1, 5):
            player_img = pygame.image.load(f'guy{num}.png')
            player_img = pygame.transform.scale(player_img, (40, 80))
            player_imag_Left = pygame.transform.flip(player_img, True, False)
            self.images_right.append(player_img)
            self.images_left.append(player_imag_Left)

        self.dead_image = pygame.image.load('ghost.png')
        self.image = self.images_right[self.index]
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.vel_y = 0
        self.width = self.image.get_width()
        self.height = self.image.get_height()
        self.jumped = False
        self.direction = 0
        self.in_air =True
    def update(self,game_over):

        dx = 0
        dy =0
        walk_cooldown =5
        if game_over==0:
            key =pygame.key.get_pressed()
            if key[pygame.K_SPACE] and self.jumped ==False and self.in_air==False:
                self.vel_y =-15
                self.jumped =True
            if key[pygame.K_SPACE] == False:
                self.jumped = False
            if key[pygame.K_LEFT] ==True:
                dx -=5
                self.counter+=1
                self.direction =-1
            if key[pygame.K_RIGHT] ==True:
                dx +=5
                self.counter += 1
                self.direction=1
            if key[pygame.K_LEFT]==False and  key[pygame.K_RIGHT]==False:
                self.counter =0
                self.index =0
            if self.direction==1:
                    self.image =self.images_right[self.index]
            if self.direction==-1:
                self.image = self.images_left[self.index]
            if self.counter >walk_cooldown:
                self.counter =0
                self.index+=1
                if self.index>=len(self.images_right):
                    self.index =0
                if self.direction==1:
                    self.image =self.images_right[self.index]
                if self.direction==-1:
                    self.image = self.images_left[self.index]
            self.vel_y +=1
            if self.vel_y >10:
                self.vel_y =10
            dy +=self.vel_y
            self.in_air =True
            for tile in world.tile_list:
                if tile[1].colliderect(self.rect.x+dx,self.rect.y,self.width,self.rect.height):
                    dx =0
                if tile[1].colliderect(self.rect.x,self.rect.y+dy,self.width,self.height):
                    if self.vel_y <0:
                        dy =tile[1].bottom -self.rect.top
                        self.vel_y =0
                    elif self.vel_y>=0:
                        dy =tile[1].top -self.rect.bottom
                        self.vel_y=0
                        self.in_air =False
            if pygame.sprite.spritecollide(self,blob_group,False):
                game_over =-1

            if pygame.sprite.spritecollide(self,lava_group,False):
                game_over =-1
            self.rect.x +=dx
            self.rect.y +=dy
            if self.rect.bottom >screen_height:
                self.rect.bottom =screen_height
                dy =0
        elif game_over==-1:
            self.image =self.dead_image
            if self.rect.y >200:
                self.rect.y-=5


        screen.blit(self.image,self.rect)
        return game_over
class Enemy(pygame.sprite.Sprite):
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.image =pygame.image.load("blob.png")
        self.rect =self.image.get_rect()
        self.rect.x =x
        self.rect.y =y
        self.move_direction =1
        self.move_counter =0
    def update(self):
        self.rect.x +=self.move_direction
        self.move_counter+=1
        if abs(self.move_counter)>50:
            self.move_direction *=-1
            self.move_counter *=-1
        pygame.draw.rect(screen,(255, 255, 255),self.rect)
class Lava(pygame.sprite.Sprite):
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        lava_image =pygame.image.load("lava.png")
        self.image =pygame.transform.scale(lava_image,(tile_size,tile_size//2))
        self.rect =self.image.get_rect()
        self.rect.x =x
        self.rect.y =y

world =World(world_data)
player =Player(100,screen_height-120)
restart_button =Button(screen_width//2-50,screen_height //2+100,restart_img)
start_button =Button(screen_width//2,screen_height//2,start_image)
exit_button  =Button(280,280,exit_image)
def draw_grid():
    for line in range(0,tile_size+1):
        pygame.draw.line(screen,(255,255,255),(0,line*tile_size),(screen_width,line*tile_size))
        pygame.draw.line(screen, (255, 255, 255), (line * tile_size,0), (line * tile_size,screen_height))
run =True
while  run :
    clock.tick(fps)

    screen.blit(sky_img,(0,0))

    screen.blit(sun_img, (100, 100))

    #exit_button.draw()

    #draw_grid()

    world.draw()
    start_button.draw()

    if game_over == 0:
        blob_group.update()

    blob_group.draw(screen)
    lava_group.draw(screen)
    game_over = player.update(game_over)
    if game_over==-1:
        if restart_button.draw():
            player.reset(100,screen_height-130)
            game_over =0
    for event in pygame.event.get():
        if event.type ==pygame.QUIT:
            run =False
    pygame.display.update()
pygame.quit()

这是我的结果:

我想把这个图片(开始菜单)放在游戏中间,但我做不到(我改变了坐标,尝试了几次实验但还没有结果),这是在图像上定位图片的主要部分:

start_button =Button(screen_width//2,screen_height//2,start_image)

我尝试了不同的数字(从(0,0)等开始)但没有结果,我没有明白是什么问题?游戏运行没问题

已更新 根据答案更新我的代码后,按钮坐标为

start_button = Button(screen_width // 2 - 350, screen_height // 2, start_image)
exit_button = Button(screen_width // 2 + 150, screen_height // 2, exit_image)

图像是`

按钮绘制在 `rect 属性中存储的位置:

screen.blit(self.image,self.rect)

因此需要设置rect属性的位置:

class Button():
    def __init__(self,x,y,image):
        self.image = image
        self.rect = self.image.get_rect(center = (x, y))
        # [...]

您根本不需要 xy 属性。您可以删除它们。按钮的左上角位置是(self.rect.x, self.rect.y)。另见 pygame.Rect.