簡體   English   中英

如何使我的精靈自己移動(敵人的精靈)?

[英]How do I make my sprites move (the enemy sprites), by themselves?

我需要讓我的敵人精靈在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()

我希望敵人能夠以我所描述的方式移動,但他們根本不移動。

以下是我要做的一些事情,讓您更接近您正在尋找的游戲:

  1. 創建更多敵人對象

現在你在這里創造了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。

  1. 從你的敵人類中掠奪你的敵人

我會在你的Enemy課程中添加一個blitToScreen()方法,而不是按現在的方式進行操作。 就像是:

def BlitToScreen(self,screen):
    screen.blit(self.sprite, self.x, self.y)

然后,將所有敵人的blitting變為屏幕變為兩行:

for e in enemiesList:
    e.BlitToScreen(window)
  1. 最后回答你的問題,如果我們真的模仿太空入侵者,每個敵人每幀移動完全相同的數量,這樣我們就可以對每個敵人對象進行相同的更改。

如果你有一個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]

希望這對你有所幫助!

@ Hoog的答案主要涵蓋OP代碼錯誤的基礎知識,以及如何使其工作。

然而,OP 確實應該考慮為每個“敵人”對象使用PyGame精靈類 (實際上,所有對象)。 是的 ,最初進行設置需要更多的工作,但它提供了許多額外的(預優化的)功能,否則您將需要編寫代碼。 這需要編程中的一些繁瑣的工作,並允許您花更多的時間編寫有趣的游戲。

將現有對象轉換為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,除了使用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的功能(和輕松)在主循環中輕松處理Moving和Drawing:

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()函數。

這將我們帶到您問題的運動部分。 讓我們來思考一下太空入侵者如何移動 - 從右到左,向下,從左到右,向下,更快, 重復 ...這種聽起來像是一個程序給我;)

所以我建議控制運動,編寫每個入侵者遵循的程序:

# In Enemy.__init__() ~
self.move_program = 'rrrrrrrrrrrrrdllllllllllllds'  #TODO - make better
self.move_cursor  = 0

self.move_program每個字母self.move_program影響每個'tick'的移動。 這導致我們使用sprite的.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

顯然你可以有任何你喜歡的指令。 作為構造函數的一部分,可以將不同的指令集給予不同的精靈。

將游戲射彈和玩家放入精靈將允許代碼輕松找到碰撞等,但這是另一個答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM