如何使用Python的Pygame库更改类中参数的值

问题描述 投票:0回答:1

我正在尝试写像游戏这样的太空入侵者。我最初编写代码时只提供了1个入侵者,可以给我一些东西。当我开始添加更多入侵者时,我决定创建一个类,在其中可以让入侵者列表循环。

我曾尝试在列表中的方法中更改入侵者的x坐标,但发现它不会更改值,因此将入侵者保留在原位。任何帮助将不胜感激!

这是我正在从事的课程:

import sys, pygame, random
from pygame.locals import *
import itertools
#from bullet import Invader

pygame.init()
screen_height = 600
screen_width = 800
DISPLAYSURF = pygame.display.set_mode((screen_width, screen_height))
FPS = 200

score = 0

pygame.display.set_caption('Testing Pygame')
spaceship = pygame.image.load('spaceship copy.bmp')

spaceship_rect = spaceship.get_rect()
DISPLAYSURF_rect = DISPLAYSURF.get_rect()

FONT = pygame.font.Font('freesansbold.ttf', 32)
text = FONT.render('Score ' + str(score), True, (180, 180, 180))
text_rect = text.get_rect()
text_rect.centerx = DISPLAYSURF_rect.centerx
text_rect.centery = DISPLAYSURF_rect.centery

invader1 = pygame.image.load('invader.bmp')
invader2 = pygame.image.load('invader.bmp')
invader3 = pygame.image.load('invader.bmp')
invader4 = pygame.image.load('invader.bmp')
invader5 = pygame.image.load('invader.bmp')

invader1_rect = invader1.get_rect()
invader2_rect = invader2.get_rect()
invader3_rect = invader3.get_rect()
invader4_rect = invader4.get_rect()
invader5_rect = invader5.get_rect()

invaders = [invader1, invader2, invader3, invader4, invader5]
invaders_rect = [invader1_rect, invader2_rect, invader3_rect, invader4_rect, invader5_rect]
invaders_x = [10, 90, 170, 250, 330]
#invaders_x = [20, 180, 340, 500, 660]
invaders_y = 40

spaceship_rect.centerx = DISPLAYSURF_rect.centerx
spaceship_rect.centery = DISPLAYSURF_rect.bottom - 40

move_right = False
move_left = False
move_rate = 5

invader_right_movement = False
invader_left_movement = True

bullet_firing = False
num = 0

#Testing bullet firing
RED = (240, 0, 0)
x = spaceship_rect.centerx - 3
y = spaceship_rect.top
width = 6
height = 24
bullet = pygame.draw.rect(DISPLAYSURF, RED, (x, y, width, height))
bullet.centerx = spaceship_rect.centerx - 3
bullet.centery = spaceship_rect.top + height
bullet_rect = pygame.draw.rect(DISPLAYSURF, RED, (x, y, width, height))
bullets_fired = []
bullet_fired = False


class Invader():

    def __init__(self, invader, invader_x, invader_y, movement):
        self.invader = invader
        self.x = invader_x
        self.y = invader_y
        self.invader_right_movement = False
        self.invader_left_movement = True
        self.movement = movement

    def move_invader(self):
        #Move invader
        if self.invader_right_movement == True:
            self.x += self.movement
        if self.invader_left_movement == True:
            self.x -= self.movement
            print(self.x)

        #Check if invader has reached boundary
        if self.x >= screen_width:
            self.invader_left_movement = True
            self.invader_right_movement = False
        if self.x <= 0:
            self.invader_left_movement = False
            self.invader_right_movement = True
        DISPLAYSURF.blit(self.invader, (self.x, self.y))

while True:
    DISPLAYSURF.fill((0, 0, 0))
    DISPLAYSURF.blit(spaceship, spaceship_rect)
    DISPLAYSURF.blit(text, text_rect)

    #get invader to move 1-8 pixels randomly to one side before turning back
    num_movements = 1#random.randint(1, 20)

    for invader, invader_x in zip(invaders, invaders_x):
        Invaderz = Invader(invader, invader_x, invaders_y, num_movements)
        Invaderz.move_invader()

    FPSCLOCK = pygame.time.Clock()

    #movement of bullet

    for bullet, invader_rect, invader_x in zip(bullets_fired, invaders_rect, invaders_x):
        if y > 0 and not bullet_rect.colliderect(invader_rect):
            bullet_fired = True
            y -=  14
            bullet_rect = pygame.draw.rect(DISPLAYSURF, RED, (x, y, width, height))
        else:
            if bullet_rect.colliderect(invader_rect):
                score += 1
                invader_x = DISPLAYSURF_rect.centerx
                invader_x = DISPLAYSURF_rect.top + 40
            bullets_fired.remove(bullet)
            bullet_fired = False

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        elif event.type == KEYDOWN:
            #Movement of player
            if event.key == K_RIGHT:
                move_right = True
            elif event.key == K_LEFT:
                move_left = True

            #Bullet firing
            elif event.key == K_SPACE:
                if bullet_fired == False:
                    x = spaceship_rect.centerx - 3
                    y = spaceship_rect.top
                    bullets_fired.append(y)

        elif event.type == KEYUP:
            #Movement of player
            if event.key == K_RIGHT:
                move_right = False
            elif event.key == K_LEFT:
                move_left = False

    text = FONT.render('Score ' + str(score), True, (180, 180, 180))

    if move_right == True and spaceship_rect.right <= screen_width:
        spaceship_rect.centerx += move_rate
    if move_left == True and spaceship_rect.left >= 0:
        spaceship_rect.centerx -= move_rate

    pygame.display.update()
    FPSCLOCK.tick(FPS)

python python-3.x pygame pygame-surface
1个回答
0
投票

问题是,您正在每帧调用该类,这会将其值恢复为在__init__中分配的值。您应该在开始时调用一次该类,然后每帧调用一次方法。这是Link,以了解有关类的更多信息。

要修复您的代码,请执行以下操作:

while True:

    #do other stuff

    for invader in invaders:
        invader.move_invader()

    #do other stuff

并且由于所有入侵者都具有相同的图像,因此您可以拥有

invader_image = pygame.image.load('invader.bmp')
invaders = []
for x in invader_x:
    invaders.append(Invader(invader_image,x,40,1))

这将使每个入侵者每帧移动1个像素


要获得碰撞的矩形,您可以向该类添加一个矩形

class Invader
    def __init__(self, invader, invader_x, invader_y, movement):
        self.rect = invader.get_rect()
        self.rect.x = invader_x
        self.rect.y = invader_y
        #rest of code

    def move_invader(self):
        #if moveing move x
        self.rect.x = x
        #rest of code

和碰撞

for bullet in range(len(bullets_fired)-1,-1,-1): 
    for invader in invaders:
        if invader.rect.colliderect(bullets_fired[bullet]):
            score += 1
            invader_x = DISPLAYSURF_rect.centerx
            invader_x = DISPLAYSURF_rect.top + 40
            del bullets_fired[bullet]
            bullet_fired = False
       elif bullets_fired[bullet].y > 0:
            bullet_fired = True
            bullets_fired[bullet].y -=  14
            bullet_rect = pygame.draw.rect(DISPLAYSURF, RED, (x, y, width, height))

对于碰撞,我向后循环,因为如果您删除列表中的第二个项目符号,则第三个变为第二个,并且循环转到第三个(即第四个)跳过项目符号。但是,如果向后走,如果删除了项目符号,那么已经检查过的项目符号就会移动,您可以继续检查下一个项目符号。


对于子弹,您拥有bullet和bullet_rect这是同一件事,并且您有子弹列表,就我个人而言,我会摆脱bullet_rect

bullet = pygame.draw.rect(screen,RED,(x,y,w,y))

for

pygame.draw.rect(screen,RED,bullets_fired[bullet]

现在要在哪里添加项目符号,当您按空格键时,不要得到y,而要获得矩形

elif event.key == K_SPACE:
    if bullet_fired == False:
        rect = spaceship_rect
        rect.x = spaceship_rect.centerx - 3
        rect.y = spaceship_rect.top
        bullets_fired.append(rect)

回到碰撞循环,将y更改为bullets_fired [bullet] .y

© www.soinside.com 2019 - 2024. All rights reserved.