如何让物体以不同的模式移动

时间:2018-10-09 03:53:09

标签: python pygame

对于我的代码,我希望鸡(敌人)移动4种不同的方式:

垂直,水平,对角线并跟随播放器(猪)。

每只鸡都应该有自己的动作并独立移动。对角线只能放两只鸡。

我只对它们的垂直和水平运动进行了编程,但是它们有问题;有时它们都水平移动,有时垂直移动。有时它们根本不动。

这是我的代码:

def game_loop():

    x_change = 0
    y_change = 0
    foodCounter = 0
    Score = 0           
    list =         ["Vertical","Vertical","Horizontal","Horizontal","Follow","Diagonal1","Diagonal2"]
    baddies = []
    item = 0

    x = (display_width * 0.45)
    y = (display_height * 0.8)

    foodx = random.randrange(48, display_width - 48)
    foody = random.randrange(54, display_height - 54)

    gameExit = False
    while not gameExit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit
                quit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    x_change = -8
                if event.key == pygame.K_RIGHT:
                    x_change = 8
                if event.key == pygame.K_UP:
                    y_change = -8
                if event.key == pygame.K_DOWN:
                    y_change = 8

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                    x_change = 0
                if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                    y_change = 0

        if x > 705:
            x_change = 0
            x = 705
        if x < -10:
            x_change = 0
            x = -10
        if y < -15:
            y_change = 0
            y = -15
        if y > 505:
            y_change = 0
            y = 505

        x += x_change
        y += y_change

        gameDisplay.fill(white)
        gameDisplay.blit(background,(-50,-50))

        food = pygame.Rect(foodx, foody,48 , 54)

        if foodCounter == 0:
            gameDisplay.blit(foodImage, food)

        player = pygame.Rect(x, y,108,105)

        if player.colliderect(food):
            foodCounter += -1
            Score += 1
            foodx = random.randrange(48, display_width - 48)
            foody = random.randrange(54, display_height - 54)
            foodCounter += 1

            item = random.randint(1, len(list))
            print(item)

            if item == 1 or item == 2:
                newchicken = {'rect':pygame.Rect(random.randint(0,display_width-45),0,45,63),
                          'surface':pygame.transform.scale(enemyImage,(45,63)),
                          'vertical': "vertical",
                          'down': "down"
                          }
                item = 0
                baddies.append(newchicken)

            if item == 3 or item == 4:
                newchicken = {'rect':pygame.Rect(0,random.randint(0,display_height-45),45,63),
                          'surface': pygame.transform.scale(enemyImage, (45,63)),
                          'horizontal': "horizontal",
                          'right': "right"
                          }
                item = 0
                baddies.append(newchicken)

            if item == 6:
                newchicken = {'rect':pygame.Rect(200,0,45,63),
                          'surface':pygame.transform.scale(enemyImage,(45,63)),
                          'diagonal1': "diagonal1"
                          }
                if "Diagonal1" in list:
                    list.remove("Diagonal1")

                item = 0
                baddies.append(newchicken)

            if len(list) == 7:
                if item == 7:
                    newchicken = {'rect':pygame.Rect(100,600,45,63),
                              'surface':pygame.transform.scale(enemyImage,(45,63)),
                              'diagonal2': "diagonal2"
                          }
                    if "Diagonal2" in list:
                        list.remove("Diagonal2")

                    item = 0
                    baddies.append(newchicken)
            if len(list) == 6:
                if item == 6:
                    newchicken = {'rect':pygame.Rect(100,600,45,63),
                              'surface':pygame.transform.scale(enemyImage,(45,63)),
                              'diagonal2': "diagonal2"
                          }
                    if "Diagonal2" in list:
                        list.remove("Diagonal2")

                    item = 0
                    baddies.append(newchicken)

        gameDisplay.blit(pigImage, player)

        for b in baddies:
            gameDisplay.blit(b['surface'],b['rect'])

        for b in baddies:
            if "vertical" in newchicken:
                if "down" in newchicken:
                    if not b['rect'].bottom >= 600:
                        b['rect'].move_ip(0, 2)
                    if b['rect'].bottom >= 600 :
                        del newchicken['down']
                        newchicken["up"] = "up"
                if "up" in newchicken:
                    if not b['rect'].top <= 0:
                        b['rect'].move_ip(0,-2)
                    if b['rect'].top <= 0:
                        del newchicken ['up']
                        newchicken["down"] = "down"

            if "horizontal" in newchicken:
                print ("horizontal")
                if "right" in newchicken:
                    if not b['rect'].right >= 800:
                        b['rect'].move_ip(2,0)
                    if b['rect'].right >= 800:
                        del newchicken['right']
                        newchicken['left'] = "left"
                if "left" in newchicken:
                    if not b['rect'].left <= 0:
                        b['rect'].move_ip(-2,0)
                    if b['rect'].left <= 0:
                        del newchicken ['left']
                        newchicken['right'] = "right"

        pygame.display.update()
        clock.tick(60)

game_loop()    

1 个答案:

答案 0 :(得分:0)

您的代码不起作用,因为您在遍历newchicken时总是检查baddies中的键,而我猜应该改为检查b

但是,您应该做的是改变代码,以区分游戏的不同逻辑关注点。另外,只需使用类而不是dict来将属于一起的数据和行为分组。


让我们想一想:

我们有某种类型的实体,它基本上由三部分组成:图像,位置和行为。您已经知道了这一点,因为您创建了以下命令:

newchicken = {'rect':pygame.Rect(100,600,45,63),
              'surface':pygame.transform.scale(enemyImage,(45,63)),
              'diagonal2': "diagonal2"
             }

让我们稍作调整,并使用Sprite(真的,请阅读文档),它已经具有(或多或少)这些东西。我们的班级类可能看起来像这样(不要告诉我您不想使用班级。这是愚蠢的恕我直言,因为您已经使用了数十个班级):

class Animal(pg.sprite.Sprite):
    def __init__(self, color, pos, logic, *groups):
        super().__init__(*groups)
        self.image = pg.surface.Surface((40, 40))
        self.image.fill(color)
        self.rect = self.image.get_rect(topleft=pos)
        self.logic = logic
        self.direction = pg.Vector2((0, 0))

    def update(self):
        self.logic(self)

因此,我们有一个image(这是一个简单的矩形,所以我们在最后有个可以正常工作的游戏,每个人都可以复制/粘贴并运行),一个rect存储位置,一个神秘的logic自变量,它是一个函数(我们的动物的“ AI”),将在每个刻度上调用它;还有一个direction,它定义动物向哪个方向行走。

因此,让我们创建将动物迁出的实际逻辑。我们创建了三个功能,一个用于垂直移动,一个用于水平移动,另一个将始终朝着鼠标光标移动:

def move_vertical(animal):
    if animal.direction.length() == 0:
        animal.direction = pg.Vector2(5, 0)

    animal.rect.move_ip(*animal.direction)
    if not screen_rect.contains(animal.rect):
        animal.direction *= -1
        animal.rect.move_ip(animal.direction)

def move_horizontal(animal):
    if animal.direction.length() == 0:
        animal.direction = pg.Vector2(0, 5)

    animal.rect.move_ip(*animal.direction)
    if not screen_rect.contains(animal.rect):
        animal.direction *= -1
        animal.rect.move_ip(animal.direction)

def move_to_mouse(animal):
    pos = pg.mouse.get_pos()
    v = pg.Vector2(pos) - pg.Vector2(animal.rect.center)
    if v.length() > 0:
        v.normalize_ip()
    v *= 5
    animal.rect.move_ip(*v)

如果我们现在想创建一个Animal,我们只需将其中一个函数传递给构造函数即可。在主循环中不需要大量的if / else块(请注意最后它是多么干净和简单)。


因此,这是我们的最后一个示例。请注意我们如何创建四只动物:两只垂直移动,一只水平移动,另一只跟随鼠标。

import pygame as pg
pg.init()
clock = pg.time.Clock()
running = True
screen = pg.display.set_mode((640, 480))
screen.fill((255, 255, 255))
screen_rect = screen.get_rect()

def move_vertical(animal):
    if animal.direction.length() == 0:
        animal.direction = pg.Vector2(5, 0)

    animal.rect.move_ip(*animal.direction)
    if not screen_rect.contains(animal.rect):
        animal.direction *= -1
        animal.rect.move_ip(animal.direction)

def move_horizontal(animal):
    if animal.direction.length() == 0:
        animal.direction = pg.Vector2(0, 5)

    animal.rect.move_ip(*animal.direction)
    if not screen_rect.contains(animal.rect):
        animal.direction *= -1
        animal.rect.move_ip(animal.direction)

def move_to_mouse(animal):
    pos = pg.mouse.get_pos()
    v = pg.Vector2(pos) - pg.Vector2(animal.rect.center)
    if v.length() > 0:
        v.normalize_ip()
    v *= 5
    animal.rect.move_ip(*v)

class Animal(pg.sprite.Sprite):
    def __init__(self, color, pos, logic, *groups):
        super().__init__(*groups)
        self.image = pg.surface.Surface((40, 40))
        self.image.fill(color)
        self.rect = self.image.get_rect(topleft=pos)
        self.logic = logic
        self.direction = pg.Vector2((0, 0))

    def update(self):
        self.logic(self)

sprites = pg.sprite.Group()
Animal(pg.color.Color('yellow'), ( 10,  10), move_vertical,   sprites)
Animal(pg.color.Color('red'),    (200, 400), move_vertical,   sprites)
Animal(pg.color.Color('orange'), (500, 100), move_horizontal, sprites)
Animal(pg.color.Color('brown'),  (100, 200), move_to_mouse,   sprites)

while running:

    for e in pg.event.get():
        if e.type == pg.QUIT:
            running = False

    sprites.update()

    screen.fill((255, 255, 255))
    sprites.draw(screen)
    pg.display.update()

    clock.tick(60)

enter image description here