- 介绍
- 二、绘制地图并移动
- 在地图上的移动
在 上一讲 中介绍了如何构建游戏地图界面,并实现鼠标移动到消息框上时高亮显示该信息框,在这一讲中将介绍绘制地图、加载英雄头像图片,并用鼠标控制英雄移动。
二、绘制地图并移动地图为网格状,宽高为40 x 40像素,英雄头像为一个jpg图片,宽和高均为40像素,如下图所示。
这个界面实现的原理是用双重for循环,在屏幕不断地画出网格。为此在Game.py的display_map()方法中添加以下代码:
# 会遇到怪的区域 for i in range(0, GameConst.MapBlock_X): position = 0, GameConst.MapBlockSize*i, GameConst.MapBlockSize, GameConst.MapBlockSize pygame.draw.rect(self.DISPLAYSURF, RGB.Red2, position, 0) position = GameConst.MapBox[2]-GameConst.MapBlockSize, GameConst.MapBlockSize*i, GameConst.MapBlockSize, GameConst.MapBlockSize pygame.draw.rect(self.DISPLAYSURF, RGB.Red2, position, 0) position = GameConst.MapBlockSize*i, GameConst.MapBox[3]-GameConst.MapBlockSize, GameConst.MapBlockSize, GameConst.MapBlockSize pygame.draw.rect(self.DISPLAYSURF, RGB.Red2, position, 0) # 画出网格 for i in range(0, GameConst.MapBlock_X): width = 1 # 横 start = 0, (i+1)*GameConst.MapBlockSize end = GameConst.MapBox[2], (i+1)*GameConst.MapBlockSize pygame.draw.line(self.DISPLAYSURF, RGB.SlateGrey, start, end, width) # 竖 start = (i+1)*GameConst.MapBlockSize, 0 end = (i+1)*GameConst.MapBlockSize, GameConst.MapBox[2] pygame.draw.line(self.DISPLAYSURF, RGB.SlateGrey, start, end, width)
然后加载英雄头像,英雄一开始的XY坐标设置为(0, 0)。
为此,在Player类的__init__()方法中添加记录头像图片左上角坐标的变量,并把它们设置为player对象的X和Y属性,并添加一个相关的draw_player_image()方法,根据player对象的X和Y属性绘制头像图片。
# 载入英雄头像 self.master_image = pygame.image.load(GameConst.player_image).convert_alpha() # 记录头像左上角的坐标 self.image_x = 0 self.image_y = 0 def _getx(self): return self.image_x def _setx(self, value): self.image_x= value X = property(_getx, _setx) def _gety(self): return self.image_y def _sety(self, value): self.image_y= value Y = property(_gety, _sety) def draw_player_image(self, game): game.DISPLAYSURF.blit(self.master_image, (self.X, self.Y))
然后在Game类的display_map()方法中添加调用绘制英雄头像方法的语句。
def display_map(self, player, game): ... # 绘制英雄头像 player.draw_player_image(game)
程序运行结果如图所示。
现在想要让英雄头像随着鼠标的点击移动起来,即,鼠标在地图上英雄的上、下、左、右侧点击时,英雄会向上、下、左、右方向移动一格。为此,首先实现鼠标移动到地图上英雄的上、下、左、右侧时,高亮可点击的区域;在Game类的respond_to_mouse_motion()方法中添加如下代码:
leftrect = pygame.Rect(0, player.Y, player.X, GameConst.MapBlockSize) if leftrect.collidepoint(x, y): left, top, width, height = leftrect pygame.draw.rect(self.DISPLAYSURF, RGB.GhostWhite, (left, top, width+5, height+5), 4) rightrect = pygame.Rect(player.X + GameConst.MapBlockSize, player.Y, GameConst.MapBox[2] - player.X - GameConst.MapBlockSize, GameConst.MapBlockSize) if rightrect.collidepoint(x, y): left, top, width, height = rightrect pygame.draw.rect(self.DISPLAYSURF, RGB.GhostWhite, (left, top, width+5, height+5), 4) uprect = pygame.Rect(player.X, 0, GameConst.MapBlockSize, player.Y) if uprect.collidepoint(x, y): left, top, width, height = uprect pygame.draw.rect(self.DISPLAYSURF, RGB.GhostWhite, (left, top, width+5, height+5), 4) downrect = pygame.Rect(player.X, player.Y + GameConst.MapBlockSize, GameConst.MapBlockSize, GameConst.MapBox[3] - player.Y - GameConst.MapBlockSize)
这段代码的意思就是根据英雄头像所处的位置,在其上、下、左、右生成四个矩形,当鼠标移动到其中时就高亮该矩形,如图所示。
接着实现英雄在地图上的移动,在Player类中添加move()方法,然后在Game类的respond_to_click()方法中调用该方法。
def move(self, direction, hero, game): ''' 英雄头像在地图上的移动。''' if self.game_process == GameConst.WALKING_ON_THE_MAP: game.clear_message() if direction == 'down': if self.Y <= 320: self.Y += 40 hero.y_coordinate += 1 self.is_moved = 1 else: self.is_moved = 2 elif direction == 'up': if self.Y >= 40: self.Y -= 40 hero.y_coordinate -= 1 self.is_moved = 1 else: self.is_moved = 2 elif direction == 'left': if self.X >= 40: self.X -= 40 hero.x_coordinate -= 1 self.is_moved = 1 else: self.is_moved = 2 elif direction == 'right': if self.X <= 320: self.X += 40 hero.x_coordinate += 1 self.is_moved = 1 else: self.is_moved = 2 else: self.is_moved = 0
在Game类的respond_to_click()方法中调用Player.move()方法。
MapBox = pygame.Rect(GameConst.MapBox)
if MapBox.collidepoint(x, y):
leftrect = pygame.Rect(0, player.Y, player.X, GameConst.MapBlockSize)
rightrect = pygame.Rect(player.X + GameConst.MapBlockSize, player.Y, GameConst.MapBox[2] - player.X - GameConst.MapBlockSize, GameConst.MapBlockSize)
uprect = pygame.Rect(player.X, 0, GameConst.MapBlockSize, player.Y)
downrect = pygame.Rect(player.X, player.Y + GameConst.MapBlockSize, GameConst.MapBlockSize, GameConst.MapBox[3] - player.Y - GameConst.MapBlockSize)
if leftrect.collidepoint(x, y):
player.move('left', hero, game)
elif rightrect.collidepoint(x, y):
player.move('right', hero, game)
elif uprect.collidepoint(x, y):
player.move('up', hero, game)
elif downrect.collidepoint(x, y):
player.move('down', hero, game)
运行结果如图所示:
完整的代码已经上传到GitCode:class2 · master · 下唐人 / magic_tower_chapter_0 · GitCode



