Как позволить объектам двигаться по разным шаблонам - PullRequest
0 голосов
/ 09 октября 2018

Для моего кода я бы хотел, чтобы цыплята (враги) двигались 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 голосов
/ 09 октября 2018

Ваш код не работает, потому что вы всегда проверяете ключи в 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...