Как сделать NPS, который понимает, что он делает в python и Pygame? - PullRequest
0 голосов
/ 25 марта 2020

как это сделать? https://i.stack.imgur.com/V8fRP.png

просьба не обращать внимания на русские слова. Я искал нормальный исходный код и нашел только на habr.com

вот весь код:

импорт pygame из pygame import * import os import pyganim

PLATFORM_WIDTH = 32
PLATFORM_HEIGHT = 32
PLATFORM_COLOR = "#000000"
ICON_DIR = os.path.dirname(__file__) #  Полный путь к каталогу с файлами
#Объявляем переменные
WIN_WIDTH = 800 #Ширина создаваемого окна
WIN_HEIGHT = 640 # Высота
DISPLAY = (WIN_WIDTH, WIN_HEIGHT) # Группируем ширину и высоту в одну переменную
BACKGROUND_COLOR = "#000000"


class Platform(sprite.Sprite):
    def __init__(self, x, y):
        sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.image = Surface((PLATFORM_WIDTH, PLATFORM_HEIGHT))
        self.image = image.load("%s/blocks/platform.png" % ICON_DIR)
        self.rect = Rect(x, y, PLATFORM_WIDTH, PLATFORM_HEIGHT)




MOVE_SPEED1 = 4
MOVE_EXTRA_SPEED1 = 2
MOVE_SPEED = 7
MOVE_EXTRA_SPEED = 2.5 # ускорение
WIDTH = 22
HEIGHT = 32
WIDTHp = 10
HEIGHTp = 5
COLOR =  "#888888"
JUMP_POWER = 10
JUMP_EXTRA_POWER = 1  # дополнительная сила прыжка
GRAVITY = 0.35 # Сила, которая будет тянуть нас вниз
ANIMATION_DELAY = 0.1 # скорость смены кадров
ANIMATION_SUPER_SPEED_DELAY = 0.05 # скорость смены кадров при ускорении
ICON_DIR = os.path.dirname(__file__) #  Полный путь к каталогу с файлами

ANIMATION_RIGHT = [('%s/mario/r1.png' % ICON_DIR),
            ('%s/mario/r2.png' % ICON_DIR),
            ('%s/mario/r3.png' % ICON_DIR),
            ('%s/mario/r4.png' % ICON_DIR),
            ('%s/mario/r5.png' % ICON_DIR)]
ANIMATION_LEFT = [('%s/mario/l1.png' % ICON_DIR),
            ('%s/mario/l2.png' % ICON_DIR),
            ('%s/mario/l3.png' % ICON_DIR),
            ('%s/mario/l4.png' % ICON_DIR),
            ('%s/mario/l5.png' % ICON_DIR)]
ANIMATION_JUMP_LEFT = [('%s/mario/jl.png' % ICON_DIR, 0.1)]
ANIMATION_JUMP_RIGHT = [('%s/mario/jr.png' % ICON_DIR, 0.1)]
ANIMATION_JUMP = [('%s/mario/j.png' % ICON_DIR, 0.1)]
ANIMATION_STAY = [('%s/mario/0.png' % ICON_DIR, 0.1)]
PATRON = [('%s/mario/patron1.png' % ICON_DIR,0.1)]




class Player(sprite.Sprite):
    def __init__(self):
        sprite.Sprite.__init__(self)
        self.xvel = 0   #скорость перемещения. 0 - стоять на месте
        self.x = 66
        self.y = 66
        self.yvel = 0 # скорость вертикального перемещения
        self.onGround = False # На земле ли я?
        self.image = Surface((WIDTH,HEIGHT))
        self.image.fill(Color(COLOR))
        self.rect = Rect(self.x, self.y, WIDTH, HEIGHT) # прямоугольный объект
        self.image.set_colorkey(Color(COLOR)) # делаем фон прозрачным
#        Анимация движения вправо
        boltAnim = []
        boltAnimSuperSpeed = []
        for anim in ANIMATION_RIGHT:
            boltAnim.append((anim, ANIMATION_DELAY))
            boltAnimSuperSpeed.append((anim, ANIMATION_SUPER_SPEED_DELAY))
        self.boltAnimRight = pyganim.PygAnimation(boltAnim)
        self.boltAnimRight.play()
        self.boltAnimRightSuperSpeed = pyganim.PygAnimation(boltAnimSuperSpeed)
        self.boltAnimRightSuperSpeed.play()
#        Анимация движения влево
        boltAnim = []
        boltAnimSuperSpeed = []
        for anim in ANIMATION_LEFT:
            boltAnim.append((anim, ANIMATION_DELAY))
            boltAnimSuperSpeed.append((anim, ANIMATION_SUPER_SPEED_DELAY))
        self.boltAnimLeft = pyganim.PygAnimation(boltAnim)
        self.boltAnimLeft.play()
        self.boltAnimLeftSuperSpeed = pyganim.PygAnimation(boltAnimSuperSpeed)
        self.boltAnimLeftSuperSpeed.play()

        self.boltAnimStay = pyganim.PygAnimation(ANIMATION_STAY)
        self.boltAnimStay.play()
        self.boltAnimStay.blit(self.image, (0, 0)) # По-умолчанию, стоим

        self.boltAnimJumpLeft= pyganim.PygAnimation(ANIMATION_JUMP_LEFT)
        self.boltAnimJumpLeft.play()

        self.boltAnimJumpRight= pyganim.PygAnimation(ANIMATION_JUMP_RIGHT)
        self.boltAnimJumpRight.play()

        self.boltAnimJump= pyganim.PygAnimation(ANIMATION_JUMP)
        self.boltAnimJump.play()

    def shoot(self):
        bullet = Bullet((self.rect.x + 20),(self.rect.y+10))
        entities.add(bullet)
        bullets.add(bullet)

    def update(self,left, right, up, running, platforms):


        if up:

            if self.onGround: # прыгаем, только когда можем оттолкнуться от земли
                self.yvel = -JUMP_POWER
                if running and (left or right): # если есть ускорение и мы движемся
                       self.yvel -= JUMP_EXTRA_POWER # то прыгаем выше
                self.image.fill(Color(COLOR))
                self.boltAnimJump.blit(self.image, (0, 0))

        if left:
            self.xvel = -MOVE_SPEED # Лево = x- n
            self.image.fill(Color(COLOR))
            if running: # если усkорение
                self.xvel-=MOVE_EXTRA_SPEED # то передвигаемся быстрее
                if not up: # и если не прыгаем
                    self.boltAnimLeftSuperSpeed.blit(self.image, (0, 0)) # то отображаем быструю анимацию
            else: # если не бежим
                if not up: # и не прыгаем
                    self.boltAnimLeft.blit(self.image, (0, 0)) # отображаем анимацию движения
            if up: # если же прыгаем
                    self.boltAnimJumpLeft.blit(self.image, (0, 0)) # отображаем анимацию прыжка

        if right:
            self.xvel = MOVE_SPEED # Право = x + n
            self.image.fill(Color(COLOR))
            if running:
                self.xvel+=MOVE_EXTRA_SPEED
                if not up:
                    self.boltAnimRightSuperSpeed.blit(self.image, (0, 0))
            else:
                if not up:
                    self.boltAnimRight.blit(self.image, (0, 0))
            if up:
                    self.boltAnimJumpRight.blit(self.image, (0, 0))


        if not(left or right): # стоим, когда нет указаний идти
            self.xvel = 0
            if not up:
                self.image.fill(Color(COLOR))
                self.boltAnimStay.blit(self.image, (0, 0))

        if not self.onGround:
            self.yvel +=  GRAVITY






        self.onGround = False; # Мы не знаем, когда мы на земле((
        self.rect.y += self.yvel
        self.collide1(0, self.yvel, platforms)

        self.rect.x += self.xvel # переносим свои положение на xvel
        self.collide1(self.xvel, 0, platforms)

    def collide1(self, xvel, yvel, platforms):
        for p in platforms:
            if sprite.collide_rect(self, p): # если есть пересечение платформы с игроком
                    if xvel > 0:                      # если движется вправо
                        self.rect.right = p.rect.left # то не движется вправо

                    if xvel < 0:                      # если движется влево
                        self.rect.left = p.rect.right # то не движется влево

                    if yvel > 0:                      # если падает вниз
                        self.rect.bottom = p.rect.top # то не падает вниз
                        self.onGround = True          # и становится на что-то твердое
                        self.yvel = 0                 # и энергия падения пропадает

                    if yvel < 0:                      # если движется вверх
                        self.rect.top = p.rect.bottom # то не движется вверх
                        self.yvel = 0                 # и энергия прыжка пропадает

hero = Player()




class npc(sprite.Sprite):
    def __init__(self,x,y):
        sprite.Sprite.__init__(self)
        self.xvel = 0   #скорость перемещения. 0 - стоять на месте
        self.x = x
        self.y = y
        self.yvel = 0 # скорость вертикального перемещения
        self.onGround = False # На земле ли я?
        self.image = Surface((WIDTH,HEIGHT))
        self.image.fill(Color(COLOR))
        self.rect = Rect(x, y, WIDTH, HEIGHT) # прямоугольный объект
        self.image.set_colorkey(Color(COLOR)) # делаем фон прозрачным
#        Анимация движения вправо
        boltAnim = []
        boltAnimSuperSpeed = []
        for anim in ANIMATION_RIGHT:
            boltAnim.append((anim, ANIMATION_DELAY))
            boltAnimSuperSpeed.append((anim, ANIMATION_SUPER_SPEED_DELAY))
        self.boltAnimRight = pyganim.PygAnimation(boltAnim)
        self.boltAnimRight.play()
        self.boltAnimRightSuperSpeed = pyganim.PygAnimation(boltAnimSuperSpeed)
        self.boltAnimRightSuperSpeed.play()
#        Анимация движения влево
        boltAnim = []
        boltAnimSuperSpeed = []
        for anim in ANIMATION_LEFT:
            boltAnim.append((anim, ANIMATION_DELAY))
            boltAnimSuperSpeed.append((anim, ANIMATION_SUPER_SPEED_DELAY))
        self.boltAnimLeft = pyganim.PygAnimation(boltAnim)
        self.boltAnimLeft.play()
        self.boltAnimLeftSuperSpeed = pyganim.PygAnimation(boltAnimSuperSpeed)
        self.boltAnimLeftSuperSpeed.play()

        self.boltAnimStay = pyganim.PygAnimation(ANIMATION_STAY)
        self.boltAnimStay.play()
        self.boltAnimStay.blit(self.image, (0, 0)) # По-умолчанию, стоим

        self.boltAnimJumpLeft= pyganim.PygAnimation(ANIMATION_JUMP_LEFT)
        self.boltAnimJumpLeft.play()

        self.boltAnimJumpRight= pyganim.PygAnimation(ANIMATION_JUMP_RIGHT)
        self.boltAnimJumpRight.play()

        self.boltAnimJump= pyganim.PygAnimation(ANIMATION_JUMP)
        self.boltAnimJump.play()


    def shoot(self):
        bullet = Bullet((self.rect.x + 20),(self.rect.y+10))
        entities.add(bullet)
        bullets.add(bullet)

    def update(self,left1, right1, up1, running1, platforms,hero):

        #логика моего нпс
        if hero.rect.x + 20 <= self.rect.x:
            left1 = True
            right1 = False

        if hero.rect.x - 20 >= self.rect.x:
            left1 = False
            right1 = True
        if hero.rect.y < self.rect.y  :
            up1 = True
        self.rect.y + 10 and self.rect.x + 10
            left1 = False
            right1 = False



        if up1:

            if self.onGround: # прыгаем, только когда можем оттолкнуться от земли
                self.yvel = -JUMP_POWER
                if running1 and (left1 or right1): # если есть ускорение и мы движемся
                       self.yvel -= JUMP_EXTRA_POWER # то прыгаем выше
                self.image.fill(Color(COLOR))
                self.boltAnimJump.blit(self.image, (0, 0))

        if left1:
            self.xvel = -MOVE_SPEED1 # Лево = x- n
            self.image.fill(Color(COLOR))
            if running1: # если усkорение
                self.xvel-=MOVE_EXTRA_SPEED1 # то передвигаемся быстрее
                if not up1: # и если не прыгаем
                    self.boltAnimLeftSuperSpeed.blit(self.image, (0, 0)) # то отображаем быструю анимацию
            else: # если не бежим
                if not up1: # и не прыгаем
                    self.boltAnimLeft.blit(self.image, (0, 0)) # отображаем анимацию движения
            if up1: # если же прыгаем
                    self.boltAnimJumpLeft.blit(self.image, (0, 0)) # отображаем анимацию прыжка

        if right1:
            self.xvel = MOVE_SPEED1 # Право = x + n
            self.image.fill(Color(COLOR))
            if running1:
                self.xvel+=MOVE_EXTRA_SPEED1
                if not up1:
                    self.boltAnimRightSuperSpeed.blit(self.image, (0, 0))
            else:
                if not up1:
                    self.boltAnimRight.blit(self.image, (0, 0))
            if up1:
                    self.boltAnimJumpRight.blit(self.image, (0, 0))


        if not(left1 or right1): # стоим, когда нет указаний идти
            self.xvel = 0
            if not up1:
                self.image.fill(Color(COLOR))
                self.boltAnimStay.blit(self.image, (0, 0))

        if not self.onGround:
            self.yvel +=  GRAVITY






        self.onGround = False; # Мы не знаем, когда мы на земле((
        self.rect.y += self.yvel
        self.collide1(0, self.yvel, platforms)

        self.rect.x += self.xvel # переносим свои положение на xvel
        self.collide1(self.xvel, 0, platforms)

    def collide1(self, xvel, yvel, platforms):
        for p in platforms:
            if sprite.collide_rect(self, p): # если есть пересечение платформы с игроком
                    if xvel > 0:                      # если движется вправо
                        self.rect.right = p.rect.left # то не движется вправо

                    if xvel < 0:                      # если движется влево
                        self.rect.left = p.rect.right # то не движется влево

                    if yvel > 0:                      # если падает вниз
                        self.rect.bottom = p.rect.top # то не падает вниз
                        self.onGround = True          # и становится на что-то твердое
                        self.yvel = 0                 # и энергия падения пропадает

                    if yvel < 0:                      # если движется вверх
                        self.rect.top = p.rect.bottom # то не движется вверх
                        self.yvel = 0                 # и энергия прыжка пропадает






class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((10, 5))
        self.rect = self.image.get_rect()
        self.rect.bottom = y
        self.rect.centerx = x
        self.speedy = 1
        self.left = pyganim.PygAnimation(PATRON)
        self.left.play()
        self.left.blit(self.image, (0, 0)) # По-умолчанию, стоим




    def update(self):
        self.rect.x += self.speedy
        self.left.blit(self.image, (0, 0))
        if self.rect.right > 640:
            self.kill()

        self.collide1(0, self.rect.y, platforms)

        self.collide1(self.rect.x, 0, platforms)

    def collide1(self, x, y, platforms):
        for p in platforms:
            if sprite.collide_rect(self, p): # если есть пересечение платформы с игроком
                    if x > 0:                      # если движется вправо
                        self.kill()

                    if x < 0:                      # если движется влево
                        self.kill()


FILE_DIR = os.path.dirname(__file__)

class Camera(object):
    def __init__(self, camera_func, width, height):
        self.camera_func = camera_func
        self.state = Rect(0, 0, width, height)

    def apply(self, target):
        return target.rect.move(self.state.topleft)

    def update(self, target):
        self.state = self.camera_func(self.state, target.rect)

def camera_configure(camera, target_rect):
    l, t, _, _ = target_rect
    _, _, w, h = camera
    l, t = -l+WIN_WIDTH / 2, -t+WIN_HEIGHT / 2

    #l = min(0, l)                           # Не движемся дальше левой границы
    #l = max(-(camera.width-WIN_WIDTH), l)   # Не движемся дальше правой границы
    #t = max(-(camera.height-WIN_HEIGHT), t) # Не движемся дальше нижней границы
    #t = min(0, t)                           # Не движемся дальше верхней границы

    return Rect(l, t, w, h)
class w(object):
    def __init__(self, x, y):
        self.image = Platform(x,y)
        entities.add(self.image)
        platforms.append(self.image)




def main():

    pygame.init() # Инициация PyGame, обязательная строчка
    screen = pygame.display.set_mode(DISPLAY) # Создаем окошко
    pygame.display.set_caption("Super Mario Boy") # Пишем в шапку
    bg = Surface((WIN_WIDTH,WIN_HEIGHT)) # Создание видимой поверхности
                                         # будем использовать как фон
    bg.fill(Color(BACKGROUND_COLOR))     # Заливаем поверхность сплошным цветом
    #вот он УРОВЕНЬ
    w(0,0)

    #конец уровня


    running = up = left = right = False
    running1 = up1 = left1 = right1 = False
    npc1 = npc(99,99)
    hero = Player()
    entities.add(hero)
    entities.add(npc1)
    x=y=0
    for col in level: # вся строка
        for row in col: # каждый символ
            if row == "-":
                pf = Platform(x,y)
                entities.add(pf)
                platforms.append(pf)
            x += PLATFORM_WIDTH #блоки платформы ставятся на ширине блоков
        y += PLATFORM_HEIGHT    #то же самое и с высотой
        x = 0

    timer = pygame.time.Clock()



    total_level_width  = len(level[0])*PLATFORM_WIDTH # Высчитываем фактическую ширину уровня
    total_level_height = len(level)*PLATFORM_HEIGHT   # высоту

    camera = Camera(camera_configure, total_level_width, total_level_height)
    run = True
    while run:


        for e in pygame.event.get(): # Обрабатываем события
            if e.type == QUIT:
                exit()


            if e.type == KEYDOWN and e.key == K_e:
                hero.shoot()
                npc1.shoot()



            if e.type == KEYDOWN and e.key == K_q:
                q = True

            if e.type == KEYDOWN and (e.key == K_w or e.key == K_SPACE):
                up = True
            if e.type == KEYDOWN and e.key == K_a:
                left = True
            if e.type == KEYDOWN and e.key == K_d:
                right = True
            if e.type == KEYDOWN and e.key == K_LSHIFT:
                running = True



            if e.type == KEYUP and e.key == K_q:
                q = False
            if e.type == KEYUP and (e.key == K_w or e.key == K_SPACE):
                up = False
            if e.type == KEYUP and e.key == K_a:
                left = False
            if e.type == KEYUP and e.key == K_d:
                right = False
            if e.type == KEYUP and e.key == K_LSHIFT:
                running = False

        screen.blit(bg, (0,0))      # Каждую итерацию необходимо всё перерисовывать
        timer.tick(90)

        camera.update(hero) # центризируем камеру относительно персонажа
        bullets.update()
        hero.update(left, right, up, running, platforms) # передвижение
        npc1.update(left1, right1, up1, running1, platforms,hero)
        for e in entities:
            screen.blit(e.image, camera.apply(e))
        pygame.display.update()     # обновление и вывод всех изменений на экран

level = ["----------------",
        "-              -",
         "-              -",
         "-              -",
         "-              -",
         "-              -",
         "-         -    -",
         "-      -       -",
         "-      -       -",
         "----------------"]

entities = pygame.sprite.Group() #група вещей героев и тд.
bullets = pygame.sprite.Group()
platforms = [] # то, во что мы будем врезаться или опираться
if __name__ == "__main__":
    main()

Мне искренне нужна помощь в этом вопросе.

пожалуйста, помогите мне с ним.

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