如何让我的怪物在我的游戏中随机移动 [英] How do I make my monster move randomly in my game

查看:44
本文介绍了如何让我的怪物在我的游戏中随机移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对编程还很陌生,通过教程创建了一个迷宫游戏,我也添加了它.一切都运行良好,但我现在想添加一个或两个怪物以使其更具挑战性!我只是想保持简单,让怪物在迷宫中随机移动.我创造了一个怪物,但尽管尝试了不同的东西,但它不会移动.我怀疑我需要在主循环中添加一些东西,但我不知道是什么.代码如下.任何帮助表示赞赏!

I'm fairly new to programming and via a tutorial created a maze game which I've added too. It's all working well but I'd now like to add a monster or 2 to make it more of a challenge! I just want to keep it simple and have the monster randomly moving around the maze. I have created a monster but despite trying different things it won't move. I suspect I need to add something to the main loop but I don't know what. The code is below. Any help is appreciated!

import os
import random
import pygame

os.environ['SDL_VIDEO_CENTERED'] = '1'
#Initalise pygame
pygame.init()

#Colours required
black = (0,0,0)
blue = (0,0,255)
green = (0,255,0)
red = (255,0,0)
orange = (255,200,0)

#Set up the display
width = 640
height = 480
screen = pygame.display.set_mode((width, height))
background = pygame.image.load('path.png')
caption = pygame.display.set_caption('Escape from the mazes!')
clock = pygame.time.Clock()

#Class for the player rect
class Player(object):
    def __init__(self, pos):
        self.rect = pygame.Rect(pos[0], pos[1], 32, 32) #x-axis, y-axis, width, height
        self.image = pygame.image.load('player.png')

    def move(self, dx, dy):
        #Move each axis separately. NB this checks for collisions both times
        if dx != 0:
            self.move_single_axis(dx, 0)
        if dy != 0:
            self.move_single_axis(0, dy)

    def move_single_axis(self, dx, dy):
        #Move the rect
        self.rect.x += dx
        self.rect.y += dy

        #If you collide with a wall, move out based on velocity
        for wall in walls:
            if self.rect.colliderect(wall.rect):
                if dx > 0: #Moving right, hit the left side of wall
                    self.rect.right = wall.rect.left
                if dx < 0: #Moving left, hit the right side of wall
                    self.rect.left = wall.rect.right
                if dy > 0: #Moving down, hit the top side of wall
                    self.rect.bottom = wall.rect.top
                if dy < 0: #Moving up, hit the bottom side of wall
                    self.rect.top = wall.rect.bottom

#Class for the monster rect
class Monster(object):
    def __init__(self, pos):
        self.rect = pygame.Rect(pos[0], pos[1], 32, 32)
        self.direction = random.randint(1,4)
        self.dist = 3
        #self.moves = random.randint(100,200)
        #self.moveCount = 0

    def move(self, x, y):
        xMove, yMove = 0,0

        if self.direction == 1:
            xMove = -self.dist
        elif self.direction == 2:
            yMove = -self.dist
        elif self.direction == 3:
            xMove = self.dist
        elif self.direction == 4:
            yMove = self.dist

        self.rect.move_ip(xMove, yMove)
        #self.moveCount += 1

        for wall in walls:
            if self.rect.colliderect(wall.rect):
                if x > 0: #Moving right, hit the left side of wall
                    self.rect.right = wall.rect.left
                if x < 0: #Moving left, hit the right side of wall
                    self.rect.left = wall.rect.right
                if y > 0: #Moving down, hit the top side of wall
                    self.rect.bottom = wall.rect.top
                if y < 0: #Moving up, hit the bottom side of wall
                    self.rect.top = wall.rect.bottom
                self.rect.move_ip(-xMove, -yMove)
                self.direction = random.randint(1,4)

#Class for the wall rect
class Wall(object):
    def __init__(self, pos):
        self.rect = pygame.Rect(pos[0], pos[1], 32, 32)
        self.image = pygame.image.load('hedge.png')

#Class for end rect
class Finish(object):
    def __init__(self, pos):
        self.rect = pygame.Rect(pos[0], pos[1], 32, 32)
        self.image = pygame.image.load('gate.png')

#Variables
currentLevel = 0

#Holds the level layout in a list of strings
levels = [[
'WWWWWWWWWWWWWWWWWWWW',
'WP          W      W',
'W         WWWWWW   W',
'W   WWWW       W   W',
'W   W        WWWW  W',
'W WWW  WWWW        W',
'W   W    MW W      W',
'W   W     W   WWW WW',
'W   WWW WWW   W W  W',
'W     W   W   W W  W',
'WWW   W   WWWWW W  W',
'W W      WW        W',
'W W   WWWW   WWWWWWW',
'W     W           FW',
'WWWWWWWWWWWWWWWWWWWW',
],
[
'WWWWWWWWWWWWWWWWWWWW',
'W W     W     W   FW',
'W W     W     W    W',
'W W  W  W  W  W  WWW',
'W W  W  W  W  W    W',
'W W  W  W  W  W    W',
'W W  W  W  W  W  W W',
'W    W     W  W  W W',
'W    W     W  W  WWW',
'WWW  WWWWWWW  W    W',
'W      W      W    W',
'W      W  WWWWWWW  W',
'WWWWW  W           W',
'WP     W           W',
'WWWWWWWWWWWWWWWWWWWW',
],
[
'WWWWWWWWWWWWWWWWWWWW',
'WP W           W   W',
'W  W  WWWW  WWWW W W',
'W  W     W       W W',
'W  WWWW  W    WWWW W',
'W     W  W  WW     W',
'W     W  W  W  WWWWW',
'WWWW  W  W  W     FW',
'W  W  W  W  WWWWWWWW',
'W  W     W         W',
'W  W     W         W',
'W  W  WWWWWWWWWWW  W',
'W               W  W',
'W               W  W',
'WWWWWWWWWWWWWWWWWWWW',
],
[
'WWWWWWWWWWWWWWWWWWWW',
'W     W            W',
'W     W            W',
'W  W  W  WWWWWWWW  W',
'W  W  W  W         W',
'W  W  W  W         W',
'W  W  W  W  WWWWWWWW',
'WP W  W  W         W',
'WWWW  W  W         W',
'W     W  WWWWWWWW  W',
'W     W  W         W',
'W  WWWW  W         W',
'W        W  WWWWWWWW',
'W        W        FW',
'WWWWWWWWWWWWWWWWWWWW',
],
[
'WWWWWWWWWWWWWWWWWWWW',
'W  W        W     FW',
'W  W        WWW W  W',
'W  W  WWWW    W WWWW',
'W  W     W    W    W',
'W  WWWW  WWWW W  W W',
'W     W     W WWWW W',
'W     W     W      W',
'W  W  WWWW  WWWWWWWW',
'W  W     W         W',
'W  W     W         W',
'WWWW  W  WWWWWWWW  W',
'W     W            W',
'WP    W            W',
'WWWWWWWWWWWWWWWWWWWW',
],
[
'WWWWWWWWWWWWWWWWWWWW',
'WP     W     W   W W',
'WWWWW  W     W W W W',
'W  W  W  WWWWWWW W W',
'W W  W   W         W',
'WW  W  W W WWWWW   W',
'W  W   W W     W WWW',
'W  WWWWW WWWWW W WFW',
'W      W       W W W',
'WWWWWW W WWWWWWW W W',
'W      W W       W W',
'W W  WWW W       W W',
'W W      W WWWWWWW W',
'W W      W         W',
'WWWWWWWWWWWWWWWWWWWW',
]]

def load_level(level):
    walls = []
    players = []
    monsters = []
    finishes = []

    #Parse the level string above. W = wall, F = exit, P = player
    x = y = 0
    for row in levels[level]:
        for col in row:
            if col == 'W':
                walls.append(Wall((x, y)))
            if col == 'P':
                players.append(Player((x, y)))
            if col == 'M':
                monsters.append(Monster((x, y)))
            if col == 'F':
                finishes.append(Finish((x, y)))
            x += 32
        y += 32
        x = 0
    return walls, players, monsters, finishes

walls, players, monsters, finishes = load_level(currentLevel)
Highest_level = len(levels)-1 #index of last level

def text_objects(text, font):
    textSurface = font.render(text, True, black)
    return textSurface, textSurface.get_rect()

def win():
    screen.fill(blue)
    largeText = pygame.font.Font('freesansbold.ttf', 95)
    TextSurf, TextRect = text_objects('You Escaped!', largeText)
    TextRect.center = (int((width/2)), int((height/2)))
    screen.blit(TextSurf, TextRect)

    while True:
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit()
                quit()

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

running = True
while running:
    clock.tick(60)
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit()
            quit()
        if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
            pygame.quit()
            quit()

    #Move the player if an arrow key is pressed
    key = pygame.key.get_pressed()
    if key[pygame.K_LEFT]:
        player.move(-2, 0)
    if key[pygame.K_RIGHT]:
        player.move(2, 0)
    if key[pygame.K_UP]:
        player.move(0, -2)
    if key[pygame.K_DOWN]:
        player.move(0, 2)

    #Moving to next level/win
    for player in players:
        for finish in finishes:
            if player.rect.colliderect(finish.rect):
                if currentLevel < Highest_level:
                    currentLevel +=1
                    walls, players, monsters, finishes = load_level(currentLevel)
                else:
                    win()

    #Draw the scene
    screen.fill(blue)
    screen.blit(background, (0,0))
    for wall in walls:
        #pygame.draw.rect(screen, green, wall.rect)
        screen.blit(wall.image, wall.rect)
    for player in players:
        #pygame.draw.rect(screen, orange, player.rect)
        screen.blit(player.image, player.rect)
    for monster in monsters:
        pygame.draw.rect(screen, blue, monster.rect)
    for finish in finishes:
        #pygame.draw.rect(screen, red, finish.rect)
        screen.blit(finish.image, finish.rect)
    pygame.display.update()

推荐答案

在主应用程序循环中为每个怪物调用方法 move.但注意该方法不需要任何参数:

Call the method move for each monster in the main application loop. But note the method does not need any parameters:

while running:

  # [...]

  #Moving to next level/win
  # [...]

  # Move monster
  for monster in monsters:
      monster.move()

此外,您必须对 Monster 类进行一些更改.

Furthermore you've to do som changes in the class Monster.

direction索引映射到一个方向向量(dx, dy)并通过向量改变怪物的位置:

Map the direction index to a direction vector (dx, dy) and change the position of the monster by the vector:

direction_list = ((-1, 0), (1, 0), (0, -1), (0, 1))
dx, dy = direction_list[self.direction]
self.rect.x += dx
self.rect.y += dy

当怪物撞墙时,在 range(0, 3) 中创建一个新的随机方向.创建一个随机数量的 steps 并在怪物移动时递减.当步数为 0 时改变方向并创建一个新的随机数.步数应该是32的倍数,因为这是一个tile的长度:

Create a new random direction in range(0, 3), when the monster hits a wall. Create a random number of steps and decrement it when the monster moves. Change the direction when the step count is 0 and create a new random number. The number of steps should be a multiple of 32, because this is the length of one tile:

#Class for the monster rect
class Monster(object):
    def __init__(self, pos):
        self.rect = pygame.Rect(pos[0], pos[1], 32, 32)
        self.dist = 3
        self.direction = random.randint(0, 3)
        self.steps = random.randint(3, 6) * 32

    def move(self):
        direction_list = ((-1, 0), (1, 0), (0, -1), (0, 1))
        dx, dy = direction_list[self.direction]
        self.rect.x += dx
        self.rect.y += dy

        #If you collide with a wall, move out based on velocity
        collide = False
        for wall in walls:
            if self.rect.colliderect(wall.rect):
                collide = True

                if dx > 0: #Moving right, hit the left side of wall
                    self.rect.right = wall.rect.left
                if dx < 0: #Moving left, hit the right side of wall
                    self.rect.left = wall.rect.right
                if dy > 0: #Moving down, hit the top side of wall
                    self.rect.bottom = wall.rect.top
                if dy < 0: #Moving up, hit the bottom side of wall
                    self.rect.top = wall.rect.bottom

        self.steps -= 1
        if collide or self.steps == 0:
            # new random direction
            self.direction = random.randint(0, 3)
            self.steps = random.randint(3, 6) * 32

这篇关于如何让我的怪物在我的游戏中随机移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆