我需要移动在drawGrid函数中定义的敌方精灵,我希望它们移至网格的边缘(水平),并且一旦到达网格的末端,它们就会向下移动一定量并开始移动与水平方向相反。 (就像太空入侵者中的外星人一样。)
我试图使它们无济于事。
import pygame
pygame.init()
window = pygame.display.set_mode((650, 630))
pygame.display.set_caption("PeaShooters")
avatar = pygame.image.load('Sprite 1 Red.png')
enemy1 = pygame.image.load('Sprite 3 Red.png')
enemy2 = pygame.image.load('Sprite 3 Yellow.png')
background = pygame.image.load('Bg.jpg')
white = (255, 255, 255)
class player(object):
def __init__(self, x, y, width, height, shots):
self.x = 300
self.y = 500
self.width = 40
self.height = 60
self.vel = shots
def drawGrid():
window.blit(background, (0,0))
window.blit(enemy1, (en.x, en.y))
window.blit(enemy1, (200, en.y))
window.blit(enemy1, (100, en.y))
window.blit(enemy1, (400, en.y))
window.blit(enemy1, (500, en.y))
window.blit(enemy1, (en.x, en.y))
window.blit(enemy2, (50, 200))
window.blit(enemy2, (150, 200))
window.blit(enemy2, (250, 200))
window.blit(enemy2, (350, 200))
window.blit(enemy2, (450, 200))
window.blit(enemy2, (530, 200))
window.blit(avatar, (av.x, av.y))
pygame.draw.line(window, white, [50,50], [50, 600], 5)
pygame.draw.line(window, white, [50,50], [600, 50], 5)
pygame.draw.line(window, white, [600,600], [600, 50], 5)
pygame.draw.line(window, white, [50,600], [600, 600], 5)
pygame.draw.line(window, white, [50,450], [600, 450], 5)
for bullet in bullets:
bullet.draw(window)
pygame.display.update()
class shots(object):
def __init__(self, x, y, radius, colour):
self.x = x
self.y = y
self.radius = radius
self.colour = colour
self.vel = shots
def draw(self, window):
pygame.draw.circle(window, self.colour, (self.x,self.y), self.radius)
class enemy(object):
def __init__(self, x, y, width, height, end):
self.x = x
self.y = y
self.width = width
self.height = height
self.end = end
self.path = [self. x, self.end]
self.vel = 4
def draw(self,window):
self.move()
def move(self):
pass
av = player(300, 500, 40, 60, 9)
en = enemy(300, 100, 40, 60, 500)
bullets = []
running = True
while running:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
for bullet in bullets:
if bullet.y < 600 and bullet.y > 70:
bullet.y -= 8
else:
bullets.pop(bullets.index(bullet))
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and av.y > 440:
av.y -= av.vel
if keys[pygame.K_a] and av.x > 65:
av.x -= av.vel
if keys[pygame.K_s] and av.y < 535:
av.y += av.vel
if keys[pygame.K_d] and av.x < 530:
av.x += av.vel
if keys[pygame.K_SPACE]:
if len(bullets) < 5:
bullets.append(shots(round(av.x + av.width//2), round(av.y + av.height//2), 6, (0,0,0)))
drawGrid()
window.blit(enemy, (en.x, en.y))
window.blit(avatar, (x,y))
pygame.quit()
我希望敌人按照我描述的方式移动,但它们根本不会移动。
答案 0 :(得分:2)
以下是我可以做的一些事情,以使您更接近要寻找的游戏:
现在,您在此处创建1个敌人:en = enemy(300, 100, 40, 60, 500)
,然后将敌人的图像扔到屏幕上的多个位置。要真正利用Enemy
类,我会做这样的事情:
enemiesList = []
for i in range (MAX_ENEMIES_I_WANT):
enemiesList.append(enemy(300, 100*i, 40, 60, 500))
注意:如果希望敌人陷入某种形状,则需要定义将敌人放置在不同位置的位置。对于传统的太空侵略者,您可以循环两次,一次用于y坐标,一次用于x。
我将不再像现在那样处理事情,而是在您的Enemy类中添加一个blitToScreen()
方法。像这样:
def BlitToScreen(self,screen):
screen.blit(self.sprite, self.x, self.y)
然后,将所有敌人吐向屏幕变成两行:
for e in enemiesList:
e.BlitToScreen(window)
如果您有一个frame
数字,它将看起来像这样:
tomove = [0,0]
if(frame%100 == 99):
tomove[0] += 50 # Move down
else if(frame/100%2 == 0):
tomove[1] +=50 # Move right
else:
tomove[1] -=50 # Move left
for e in enemies:
e.x += tomove[0]
e.y += tomove[1]
希望这对您有帮助!
答案 1 :(得分:1)
@Hoog的答案主要涵盖了OP代码存在问题的基本知识,以及如何使其正常工作。
然而,OP 真的应该考虑为每个“敌人”对象(实际上是所有对象)使用PyGame sprite class。 是,开始时要花很多工夫,但是它提供了很多额外的(预先优化的)功能,而这些功能您不得不编写。这省去了一些繁琐的编程工作,并使您可以花更多的时间编写有趣的游戏。
将现有对象转换为Sprites相当简单:
class Enemy( pygame.sprite.Sprite ):
def __init__( self, bitmap, x, y, end=None ):
pygame.sprite.Sprite.__init__( self )
self.image = bitmap
self.rect = bitmap.get_rect()
self.rect.x = x
self.rect.y = y
self.vel = 4
self.end = end
def update():
# TODO - handle any sort of sprite movement
按照@Hoog的建议创建一堆精灵,除了使用Sprite Group来容纳它们:
enemy_image1 = pygame.image.load('Sprite 3 Red.png')
enemy_image2 = pygame.image.load('Sprite 3 Yellow.png')
...
enemies_list = pygame.sprite.Group()
for j in range( ENEMY_LINE_COUNT ):
for i in range( ENEMY_PER_LINE_COUNT ):
enemy_x = 50 + ( i * 30 )
enemy_y = 50 + ( j * 40 )
enemies_list.append( Enemy( enemy_image1, enemy_x, enemy_y ) )
然后使用Sprite Group的功能(和简便性)在主循环中轻松处理移动和绘图:
while running:
...
enemies_list.update() # re-position the sprites
enemies_list.draw( window ) # draw the entire sprite-group to the window
...
对Sprite Group .update()
的调用(在主循环中)将为组中包含的每个Sprite调用Enemy.update()
函数。
这使我们进入您的问题的运动部分。让我们考虑一下Space Invaders的移动方式-从右向左,向下,从左向右,向下,更多速度,重复 ...这种声音对我来说就像是一个程序;)>
因此,我建议控制运动,编写一个程序,让每个入侵者都遵循:
# In Enemy.__init__() ~
self.move_program = 'rrrrrrrrrrrrrdllllllllllllds' #TODO - make better
self.move_cursor = 0
self.move_program
的每个字母在每个“刻度”处影响移动的位置。这将我们带到精灵的.update()
函数:
# In Enemy class ~
def update( self ):
move_instruction = self.move_program[ self.move_cursor ]
self.move_cursor += 1
# If the movement program has ended, restart
if ( self.move_cursor == len( self.move_program ) ):
self.move_cursor = 0
# Interpret the movement instruction
if ( instruction == 'r' ): # right
self.rect.x = self.rect.x + 10
elif ( instruction == 'l' ): # left
self.rect.x = self.rect.x - 10
elif ( instruction == 'd' ): # down
self.rect.y = self.rect.y + 10
elif ( instruction == 's' ): # speedup
self.vel += 1
很显然,您可以按照自己的喜好进行任何操作。作为构造函数的一部分,可以将不同的指令集赋予不同的Sprite。
将游戏弹丸和玩家放入精灵中,可以使代码轻松找到碰撞等,但这是另一个答案。