我是编程的新手,通过一个教程创建了一个迷宫游戏,我也添加了它。一切都很好,但是我现在想添加一个或两个怪物使其更具挑战性!我只想保持简单,让怪物随机在迷宫中移动。我创建了一个怪物,但是尽管尝试了不同的方法,它还是不会移动。我怀疑我需要在主循环中添加一些内容,但我不知道是什么。代码如下。任何帮助表示赞赏!
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
。但是请注意,该方法不需要任何参数:
while running:
# [...]
#Moving to next level/win
# [...]
# Move monster
for monster in monsters:
monster.move()
此外,您还必须在类
Monster
中进行som更改。将
direction
索引映射到方向矢量(dx
,dy
)并通过矢量更改怪物的位置: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的倍数,因为这是一个图块的长度:#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