首页 > 解决方案 > 使遵循相同规则的障碍物单独移动

问题描述

我正在写一个“简单”的游戏,我不知道如何解决这个问题,红色障碍物不能单独从屏幕的上部到下部。我包括了功能(它只是让障碍物越过窗户)和我正在使用的实际部分(它使障碍物同时改变方向)

我使用 for 和 while 循环尝试了 2 个小时,但我无法解决它

lista_ost = [[some value for the x, some value for the y],[some value for the x, some value for the y]] 
def mov_ost(vel_ost,altezza,ost_grandezza,lista_ost):
    for i in lista_ost:
         i[1] += vel_ost
         if i[1] >= (altezza - ost_grandezza):
             vel_ost = -10

         elif i[1] <= 0:
             vel_ost = 10

while not game_over:

    numero_nemici(lista_ost, spazio_corsie, n_corsie)
    aggiungi_nemici(lista_ost)
    for ost_pos in lista_ost:
        ost_pos[1] += vel_ost
        if ost_pos[1] >= ((altezza - ost_grandezza)):
            vel_ost = -10

我预计障碍会单独移动,但正如我所说,它们会作为一个整体移动,一起移动。

标签: python-3.xpygame

解决方案


不幸的是,我的意大利语有限,但我对问题代码的理解是,一个对象应该有一个运动路径lista_ost,其中包含一堆控制屏幕上对​​象运动的坐标。(我希望这是正确的!)

正如@Eric 在评论中所说,处理屏幕对象的一种简单方法是使用PyGame sprite,如果有多个,请使用sprite group

所以在下面的示例代码中,代码创建了一组EnemySprite对象。这些是用屏幕上的图像和move_path. 这move_path是对精灵坐标的调整列表。每次EnemySprite.update()调用 sprite 函数时,都会将下一个坐标更新应用于当前位置sprite.rect(最终是 sprite 的屏幕上[x,y])。当坐标列表全部用完后,它又从第一个元素开始。

这允许我们给精灵一条在屏幕上跟随的路径。为了在程序中创建一个快速的移动路径,此代码跟踪鼠标,然后在退出时输出一个相对坐标列表。为了制作示例中使用的循环路径,我只是用鼠标在窗口中拖动了一个循环,然后将其编辑到代码中。我当然可以在方格纸上手动制作路径。

import pygame
import random

# Window size
WINDOW_WIDTH      = 400
WINDOW_HEIGHT     = 400

SPACE_BLUE = ( 23,  55,  84)


# Global millisecond count since start
NOW_MS = 0

class EnemySprite( pygame.sprite.Sprite ):
    def __init__( self, image, move_path = [ (1, 1) ] ):
        pygame.sprite.Sprite.__init__( self )
        self.image      = image
        self.rect       = self.image.get_rect()
        self.path       = move_path
        self.path_index = 0
        # Start position is randomly across the screen, and a little off the top
        self.rect.center   = ( random.randrange( 0, WINDOW_WIDTH ), random.randrange( 0, WINDOW_HEIGHT ) )

    def wrapAroundScreen(self):
        """ Ensure the sprite's position remains on-screen,
            wrapping around if necessary """
        if (self.rect.left >= WINDOW_WIDTH ):
            self.rect.right = 0
        elif (self.rect.right <= 0 ):
            self.rect.left = WINDOW_WIDTH
        if (self.rect.top >= WINDOW_HEIGHT ):
            self.rect.bottom = 0
        elif (self.rect.bottom <= 0):
            self.rect.top = WINDOW_HEIGHT

    def update(self):
        """ Move the sprite, by adjusting the poistion by the next 
            pair of offsets in the movement path """
        x,y = self.rect.center # Where is the drop, right now
        ### Get the next movement offsets.  
        offset = self.path[ self.path_index ]
        self.path_index += 1
        ### If we have run out of path offsets, start again
        if ( self.path_index >= len( self.path ) ):
            self.path_index = 0
        self.rect.center = ( x + offset[0], y + offset[1] )
        self.wrapAroundScreen()




### MAIN
pygame.init()
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
WINDOW  = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
pygame.display.set_caption( "Path Following" )


# Add some enemy sprites
LOOPY_PATH = [  (18,0), (15,0), (12,0), (13,0), (13,0), (12,-3), (14,-2), (11,-4), (7,-2), (8,-3), (9,-3), (9,-5), (9,-3), (9,-6), (9,-5), (10,-8), (9,-5), (9,-4), (8,-5), (4,-3), (5,-4), (2,-3), (1,-3), (0,-6), (2,-7), (1,-5), (1,-4), (0,-5), (0,-3), (-1,-4), (-2,-4), (-3,-4), (-5,-5), (-4,-4), (-4,-2), (-7,-3), (-7,-1), (-9,-1), (-11,0), (-9,0), (-8,0), (-5,1), (-5,3), (-5,3), (-5,4), (-4,4), (-5,4), (-3,7), (-1,6), (0,6), (0,6), (1,6), (3,5), (3,6), (4,7), (4,7), (7,8), (5,9), (7,6), (11,6), (14,7), (15,5), (16,4), (17,4), (18,2), (20,3), (18,2), (20,1), (20,0), (19,0), (23,0), (22,0), (12,0) ]
ENEMY_IMAGE = pygame.image.load( 'tiny_alien.png' )
SPRITES = pygame.sprite.Group()
for i in range(10):
    SPRITES.add( EnemySprite( ENEMY_IMAGE, LOOPY_PATH ) )

mouse_path = []

clock = pygame.time.Clock()
done = False
while not done:
    NOW_MS = pygame.time.get_ticks()

    # re-position all the drops
    SPRITES.update()

    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True
        elif ( event.type == pygame.VIDEORESIZE ):
            WINDOW_WIDTH  = event.w
            WINDOW_HEIGHT = event.h
            WINDOW  = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )

    # Record mouse movements for new paths
    new_pos = pygame.mouse.get_pos()
    if ( new_pos != (0,0) ):
        mouse_path.append( new_pos )

    # Movement keys
    keys = pygame.key.get_pressed()
    if ( keys[pygame.K_UP] ):
        print("up")
    elif ( keys[pygame.K_DOWN] ):
        print("down")
    elif ( keys[pygame.K_LEFT] ):
        print("left")
    elif ( keys[pygame.K_RIGHT] ):
        print("right")
    elif ( keys[pygame.K_q] and ( keys[pygame.K_RCTRL] or keys[pygame.K_LCTRL] ) ):
        print("^Q")
        done = True

    # Update the window, but not more than 60fps
    WINDOW.fill( SPACE_BLUE )
    SPRITES.draw( WINDOW )
    pygame.display.flip()

    # Limit FPS
    clock.tick_busy_loop(60)

### Print the relative co-orinates of the mouse moving through the window
### just in case the user was recording a path to use on the sprites
print( "Mouse Movement Path: ")
print( "[", end='' )
for i in range(1, len(mouse_path)):
    print("(%d,%d), " %( mouse_path[i][0] - mouse_path[i-1][0], mouse_path[i][1] - mouse_path[i-1][1]), end='')
print( " ]" )

pygame.quit()

这个例子产生了一些不稳定的运动,但考虑到它是在窗口上跟随鼠标拖动,没关系。

任何小的 PNG 图像都可以替换为tiny_alien.png.

pygame窗口的动画jif


推荐阅读