python-3.x - 使遵循相同规则的障碍物单独移动
问题描述
我正在写一个“简单”的游戏,我不知道如何解决这个问题,红色障碍物不能单独从屏幕的上部到下部。我包括了功能(它只是让障碍物越过窗户)和我正在使用的实际部分(它使障碍物同时改变方向)
我使用 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
我预计障碍会单独移动,但正如我所说,它们会作为一个整体移动,一起移动。
解决方案
不幸的是,我的意大利语有限,但我对问题代码的理解是,一个对象应该有一个运动路径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
.
推荐阅读
- docker - 尝试与外部主机通信时,由于 unknownhost 异常,docker 映像无法启动
- c# - 如何获取每个 DbContext 下的所有 DbContext 类和所有 DbSet
- r - 在 R 中使用附加列标记数据集中的异常值
- jquery - 如何获得绝对位置的孩子身高?
- typescript - 根据先前类型的输入(TypeScript)将输入的可能值限制为派生类型
- sql-server - 按月/年计算平均值
- bash - 将相邻数字相加
- angular - 如何在不提供 Angular CLI 的情况下生成服务?
- javascript - 地图功能值不显示
- angular - 将第三方 scss 文件捆绑到使用 angular-cli 创建的 angular 库中