【问题标题】:Appending items after a number of collisions在多次碰撞后附加项目
【发布时间】:2020-04-22 13:40:00
【问题描述】:

我如何重新编码,而不是在第一次命中时附加块,而是在被命中 五次后附加/删除 - 每当我对这一行进行任何小的编辑时我的游戏的代码部分消失了。

我尝试创建一个变量“easy_block_hits”,然后说,当 easy_block_hits == 5 时,从列表中追加块,但它使所有内容都消失了..

    easy_kept_blocks = []    
    for block in easy_blocks:    
        if block.colliderect(ball):
            speed[1] = -speed[1]
            easy_block_hits += 1

        else:
            easy_kept_blocks.append(block)
    easy_blocks = easy_kept_blocks

我尝试更改它并且块线消失的示例

如果我尝试将其改写为;

    easy_kept_blocks = []    
    for block in easy_blocks:    
        if block.colliderect(ball):
            speed[1] = -speed[1]
            easy_block_hits += 1

        elif easy_block_hits == 5:
            easy_kept_blocks.append(block)
    easy_blocks = easy_kept_blocks

蓝色块线消失。

这是完整的代码,我有一种感觉,如果你给我一个解决方案,它不会起作用,所以也许它与我的其余代码有关?

#December 16, 2019
#Final Project - Breakout

#IMPORTING LIBRARIES-----
import pygame
import sys
import time

#INITIALIZING SCREEN SIZE-----
pygame.init()
screen_size = (597, 700)
screen = pygame.display.set_mode((screen_size),0)
pygame.display.set_caption("BREAKOUT")

#retrieve screen measurements
screen_w = screen.get_width()
screen_h = screen.get_height()

#retrieve position of center of screen
center_x = int(screen_w/2)
center_y = int(screen_h/2)

#COLOURS-----
WHITE = (255,255,255)
BLACK = (0, 0, 0)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
PURPLE = (154, 136, 180)

#BACKGROUND-----
screen.fill(BLACK)
pygame.display.update()


#PICTURES-----
background_image = pygame.image.load("space_background.png")
easy_block_image = pygame.image.load("easy_block.png")
medium_block_image = pygame.image.load("medium_block.png")
hard_block_image = pygame.image.load("hard_block.png")
metal_block_image = pygame.image.load("metal_block.png")
paddle_image = pygame.image.load("paddle.png")
ball_image = pygame.image.load("ball.png")
#title_image = pygame.image.load("S4.png")
#block/paddle/ball pictures were created on pixilart.com by myself
#background - https://www.wallpaperflare.com/dragon-flying-above-sky-artwork-wallpaper-181535
#title made from fontmeme.com

#SPEED-----
clock = pygame.time.Clock()
FPS = 60 #set frames per second
speed = [4,4]
paddle_speed = 6

#VARIABLES-----

#paddle
paddle_x = center_x
paddle_y = 600
paddle_w = 78
paddle_h = 10

paddle_dx = 0
paddle_dy = 0

#ball
ball_x = center_x
ball_y = center_y
ball_w = 12
ball_h = 12

#blocks
block_x = 5
block_w = 40
block_h = 10

#severity block positions
easy_block_y = 172
medium_block_y = 148
hard_block_y = 124
metal_block_y = 100

#severity block hits
easy_block_hits = 0

#lives displayed
lives_displayed_h = 10
lives_displayed_x = 4
lives_displayed_y = screen_h - (lives_displayed_h + 5)
lives_displayed_w = 79

#title
title_x = 5
title_y = 5
title_w = 240
title_h = 50

#test rect
rx = 0
ry = 700
rw = 700
rh = 1

#RECTS-----
paddle = pygame.Rect(paddle_x, paddle_y, paddle_w, paddle_h)
ball = pygame.Rect(ball_x, ball_y, ball_w, ball_h)
title = pygame.Rect(title_x, title_y, title_w, title_h)
lives_displayed_rect = pygame.Rect(lives_displayed_x,lives_displayed_y,lives_displayed_w,lives_displayed_h)
testrect = pygame.Rect(rx, ry, rw, rh)


#FUNCTIONS-----

#https://nerdparadise.com/programming/pygameblitopacity
def blit_alpha(target, source, location, opacity):
        x = location[0]
        y = location[1]
        temp = pygame.Surface((source.get_width(), source.get_height())).convert()
        temp.blit(target, (-x, -y))
        temp.blit(source, (0, 0))
        temp.set_alpha(opacity)        
        target.blit(temp, location)

#ARRAYS-----

#empty array to store rects for each block row of level
easy_blocks = []
medium_blocks = []
hard_blocks = []
metal_blocks = []
lives_displayed = []

#layout of blocks for each level
easy_block_array = [
"B B B B B B B B B B B B B B",
"B B B B B B B B B B B B B B",
]

medium_block_array = [
"P P P P P P P P P P P P P P",
"P P P P P P P P P P P P P P",
]

hard_block_array = [
"I I I I I I I I I I I I I I",
"I I I I I I I I I I I I I I",
]

metal_block_array = [
"G G G G G G G G G G G G G G",
"G G G G G G G G G G G G G G",
]

lives_displayed_array = [
"L L L",
]

#read the array and create the appropriate Rects FOR EACH LEVEL, store them in the walls array
for row in easy_block_array: #easy/blue
    for col in row:
        if col == "B":
            easy_block_rect = pygame.Rect(block_x, easy_block_y, block_w, block_h)
            easy_blocks.append(easy_block_rect)
        block_x += 21
    easy_block_y += 12
    block_x = 5

for row in medium_block_array: #medium/purple
    for col in row:
        if col == "P":
            medium_block_rect = pygame.Rect(block_x, medium_block_y, block_w, block_h)
            medium_blocks.append(medium_block_rect)
        block_x += 21
    medium_block_y += 12
    block_x = 5

for row in hard_block_array: #hard/pink
    for col in row:
        if col == "I":
            hard_block_rect = pygame.Rect(block_x, hard_block_y, block_w, block_h)
            hard_blocks.append(hard_block_rect)
        block_x += 21
    hard_block_y += 12
    block_x = 5

for row in metal_block_array: #metal/gray
    for col in row:
        if col == "G":
            metal_block_rect = pygame.Rect(block_x, metal_block_y, block_w, block_h)
            metal_blocks.append(metal_block_rect)
        block_x += 21
    metal_block_y += 12
    block_x = 5

for row in lives_displayed_array: #lives/paddle
    for col in row:
        if col == "L":
            lives_displayed_rect = pygame.Rect(lives_displayed_x, lives_displayed_y, lives_displayed_w, lives_displayed_h)
            lives_displayed.append(lives_displayed_rect)
        lives_displayed_x += 41
    lives_displayed_y += 12
    lives_displayed_x = 5

#LOOPS-----
intro_screen = False
game_screen = False
end_screen = False

#----------INTRO_SCREEN LOOP----------

#----------GAME_SCREEN LOOP----------
game = True
while game:
    for event in pygame.event.get():
        if event.type ==pygame.QUIT:
            game = False
            pygame.quit()
            sys.exit()
        #moving paddle with keys
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                paddle_dx = -paddle_speed
            elif event.key == pygame.K_RIGHT:
                paddle_dx = paddle_speed

    if event.type == pygame.KEYUP:
        paddle_dx = 0

    #constrain this loop to the specified FPS
    clock.tick(FPS)

    #PADDLE EVENTS-----

    #store old paddle positions
    old_paddle_x = paddle.x
    old_paddle_y = paddle.y

    #moving the paddle rect
    paddle.move_ip(paddle_dx, paddle_dy)

    #check to see if rect has left screen
    if paddle.left < 0 or paddle.right > screen_w:
        paddle.x = old_paddle_x

    #BALL EVENTS-----

    #moving ball
    ball = ball.move(speed)

    #collision bounce left & right
    if ball.left < 0 or ball.right > screen_w:
        speed[0] = -speed[0]

    #collision bounce top & bottom
    if ball.top < 0:
        speed[1] = -speed[1]

    #collision with bottom - life removed
    lives_displayed_kept = []
    for life in lives_displayed:
        if ball.bottom > screen_h:
            speed[1] = -speed[1]
        else:
            lives_displayed_kept.append(life)
    lives_displayed = lives_displayed_kept

    #collision of ball with paddle
    if paddle.colliderect(ball):
        speed[1] = -speed[1]

    #BLOCKS EVENTS-----

    #for blue (easy) blocks
    easy_kept_blocks = []    
    for block in easy_blocks:    
        if block.colliderect(ball):
            speed[1] = -speed[1]
            easy_block_hits += 1

        else:
            easy_kept_blocks.append(block)
    easy_blocks = easy_kept_blocks

    #for purple (medium) blocks
    medium_kept_blocks = []    
    for block in medium_blocks:    
        if block.colliderect(ball):
            speed[1] = -speed[1]
            easy_block_hits += 1
        else:
            medium_kept_blocks.append(block)
    medium_blocks = medium_kept_blocks

    #for pink (hard) blocks
    hard_kept_blocks = []    
    for block in hard_blocks:    
        if block.colliderect(ball):
            speed[1] = -speed[1]
        else:
            hard_kept_blocks.append(block)
    hard_blocks = hard_kept_blocks

    #for gray (metal) blocks
    metal_kept_blocks = []    
    for block in metal_blocks:    
        if block.colliderect(ball):
            speed[1] = -speed[1]
        else:
            metal_kept_blocks.append(block)
    metal_blocks = metal_kept_blocks

    #DRAWING/CREATING OBJECTS-----

    #removes screen trail
    screen.fill(BLACK)
    screen.blit(background_image, [0, 0])

    #drawing paddle/ball inside rect
    screen.blit(paddle_image, paddle)
    screen.blit(ball_image, ball)
    #screen.blit(title_image, title)

    #draws a block for each "B"
    for block in easy_blocks:
        screen.blit(easy_block_image, block)

    #draws a block for each "P"
    for block in medium_blocks:
        screen.blit(medium_block_image, block)

    #draws a block for each "I"
    for block in hard_blocks:
        screen.blit(hard_block_image, block)

    #draws a block for each "G"
    for block in metal_blocks:
        screen.blit(metal_block_image, block)

    #draws a paddle life for each "L"
    for life in lives_displayed:
        screen.blit(paddle_image, life)

    #----------END_SCREEN LOOP----------

    #updating the screen
    pygame.display.update()

pygame.quit()
sys.exit()

【问题讨论】:

  • “每当我对我的游戏的这行代码部分进行任何小的编辑时都会消失”你能举个例子吗
  • 好的,在#for blue (easy) blocks中,取一行编码,“easy_kept_blocks.append(block)”,运行时整行蓝色块消失。
  • 请在原始问题中包含此信息

标签: python arrays list pygame


【解决方案1】:

看起来你的游戏逻辑如下:

  1. 创建一个空列表
  2. 如果方块被击中,则增加计数器
  3. 否则,将保留未命中的块,方法是将每个块附加到列表easy_kept_blocks

现在,如果您按照描述的方式更改代码,关卡将是空的,直到击中 5 个方块,但这不会发生,因为没有可击中的方块。

执行您所描述的操作的一种方法是为每个块创建另一个带有计数器的列表。如果任何块计数器达到 5,则排除该块被追加。

一个例子是:


easy_block_counter = [0] * len(easy_blocks) # under ARRAYS

...
new_easy_block_counter = []
easy_kept_blocks = []    
for count, block in zip(easy_block_counter, easy_blocks):    
    if block.colliderect(ball):
        speed[1] = -speed[1]
        count += 1
    if count < 5:
        new_easy_block_counter.append(count)
        easy_kept_blocks.append(block)
easy_blocks = easy_kept_blocks
easy_block_counter = new_easy_block_counter

将计数作为一个属性具有不同的块类可能会更好。这样,您也可以添加其他属性(例如加电!!)。 :)

【讨论】:

  • 我尝试了代码,甚至尝试了一些受它启发的东西,但它不起作用:(。(如果我知道怎么做,我也很想添加类)
  • @IJH 我已经修复了上面的代码。看看它现在是否有效。
猜你喜欢
  • 1970-01-01
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多