python战棋游戏代码实现(2):六边形地图寻路和显⽰
python 战棋游戏代码实现(2):六边形地图寻路和显⽰
六边形地图介绍
之前的⽂章 实现了简单的⽅格地图,战棋游戏⼀般是使⽤六边形地图,六边形地图的显⽰和寻路会更加复杂些,所以这边⾃⼰尝试增加了六边形地图的实现。
图1
六边形地图有2种形式,这⾥采⽤上⾯图1的形式。
地图的坐标还是采⽤⼆维数组,如下⾯图2所⽰,六边形⾥⾯的(x, y) 表⽰在地图数组中的坐标。
注意⼀点:奇数⾏的六边形数会⽐偶数⾏少⼀,⽐如图2中第0⾏有10个六边形,第1⾏有9个六边形。
图2
go2map地图北京⽣物的⾏⾛范围如图3所⽰,图3 中的步兵⾏⾛范围属性值是4,表⽰可以⾛4个六边形,图中背景是深蓝⾊的⽅格就是该步兵可以⾛的格⼦,可以⼀步⾛到相邻的6个格⼦。
图3
游戏截图如下:
图4
图4中,⽬前轮到⾏动的⽣物是我⽅的左下⾓背景为浅蓝⾊的步兵,可以看到背景为深蓝⾊的六边形为步兵可以⾏⾛的范围。背景为绿⾊的六边形为⽬前选定要⾏⾛到得⽅格。⿏标指向敌⽅⽣物,如果敌⽅⽣物背景六边形颜⾊变成黄⾊,表⽰可以攻击。图中还有⽯块,表⽰不能移动到的格⼦。
代码介绍
地图六边形显⽰
看下如何在代码中实现图1的六边形显⽰,这边使⽤的pygame的绘制多边形的函数pygame.draw.polygon() 来设置六边形的背景⾊,绘制连续线段的函数pygame.draw.lines() 来画六边形的⿊⾊边。
pygame.draw.polygon()
draw a polygon
polygon(surface, color, points) -> Rect
points (tuple(coordinate) or list(coordinate)):
-- a sequence of 3 or more (x, y)
pygame.draw.lines()
draw multiple contiguous straight line segments
lines(surface, color, closed, points) -> Rect
points的使⽤可以看下⾯drawBackgroundHex函数中的例⼦,points 列表保存了六边形六个顶点的坐标。
图5
如图5所⽰,红⾊长⽅形⾥⾯的六边形,先根据该六边形的坐标计算出左上⾓红点的值(base_x, base_y),HEX_X_SIZE 和
HEX_Y_SIZE 分别表⽰红⾊长⽅形的宽度和长度。
getHexMapPos函数计算出给定坐标的左上⾓红点的值,可以看到奇数⾏相对偶数⾏的x值会有X_LEN的偏移(即长⽅形的宽度的⼀半)。计算y值时也是按照奇数⾏或偶数⾏分别计算。
HEX_Y_SIZE =56
HEX_X_SIZE =48
def getHexMapPos(x, y):
X_LEN = c.HEX_X_SIZE //2
Y_LEN = c.HEX_Y_SIZE //2
if y %2==0:
base_x = X_LEN *2* x
base_y = Y_LEN *3*(y//2)
else:
base_x = X_LEN *2* x + X_LEN
base_y = Y_LEN *3*(y//2)+ Y_LEN//2+ Y_LEN
return(base_x, base_y)
drawBackgroundHex 函数计算出六边形所在长⽅形的左上⾓顶点值 (base_x, base_y) 后,就可以根据固定的偏移量,计算出六边形六个顶点的值, 具体的偏移量可以按照图5上的⽰例算出来。
def drawBackgroundHex(self, surface):
Y_LEN = c.HEX_Y_SIZE //2
X_LEN = c.HEX_X_SIZE //2
(surface, c.LIGHTYELLOW, pg.Rect(0,0, c.MAP_WIDTH, c.MAP_HEIGHT))
for y in range(self.height):
for x in range(self.width):
if self.bg_map[y][x]== c.BG_EMPTY:
color = c.LIGHTYELLOW
elif self.bg_map[y][x]== c.BG_ACTIVE:
color = c.SKY_BLUE
elif self.bg_map[y][x]== c.BG_RANGE:
color = c.NAVYBLUE
elif self.bg_map[y][x]== c.BG_SELECT:
color = c.GREEN
elif self.bg_map[y][x]== c.BG_ATTACK:
color = c.GOLD
base_x, base_y = HexMapPos(x, y)
points =[(base_x, base_y + Y_LEN//2+ Y_LEN),(base_x, base_y + Y_LEN//2),
(base_x + X_LEN, base_y),(base_x + X_LEN *2, base_y + Y_LEN//2),
(base_x + X_LEN *2, base_y + Y_LEN//2+ Y_LEN),(base_x + X_LEN, base_y + Y_LEN*2)]
pg.draw.polygon(surface, color, points)
surface.blit(self.map_image, )
for y in range(self.height):
for x in range(self.width):
if y %2==1and x == self.width -1:
continue
base_x, base_y = HexMapPos(x, y)
points =[(base_x, base_y + Y_LEN//2+ Y_LEN),(base_x, base_y + Y_LEN//2),
(base_x + X_LEN, base_y),(base_x + X_LEN *2, base_y + Y_LEN//2),
(base_x + X_LEN *2, base_y + Y_LEN//2+ Y_LEN),(base_x + X_LEN, base_y + Y_LEN*2)]
pg.draw.lines(surface, c.BLACK,True, points)
A*算法的六边形寻路修改
A* 算法的代码实现可以看我之前的⼀篇⽂章
针对六边形地图的实现修改⽐较简单,就修改2个函数。
getMovePositions函数获取当前位置可以移动的格⼦,从 图2 可以看到奇数⾏和偶数⾏格⼦的相邻坐标是不⼀样的。
def getMovePositions(x, y):
if c.MAP_HEXAGON:
if y %2==0:
offsets =[(-1,0),(-1,-1),(0,-1),(1,0),(-1,1),(0,1)]
else:
offsets =[(-1,0),(0,-1),(1,-1),(1,0),(0,1),(1,1)]
calHeuristicDistance函数⽤来估计两个坐标之前的位置,注意两个坐标间X轴的距离计算:如果X轴距离⼩于Y轴距离的⼀半,就可以忽略,否则需要减去Y轴距离⼀半的值。
def calHeuristicDistance(self, x1, y1, x2, y2):
if c.MAP_HEXAGON:
dis_y =abs(y1 - y2)
dis_x =abs(x1 - x2)
half_y = dis_y //2
if dis_y >= dis_x:
dis_x =0
else:
dis_x -= half_y
return(dis_y + dis_x)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论