欢迎光临
我们一直在努力

布局设计、落点计算、棋盘完善

        上一期我们创建了游戏项目,绘制了棋盘,并解决了游戏画面随着窗口大小变化的问题。但是棋盘显示不全、位置距离边界太近等问题还是没有解决。这期我们就来解决这个问题。且添加一个计算落点的功能(为了后续棋子的放置)。

# 布局设计

        首先还是点击左上角[项目]->[项目设置] 然后在[常规]里找到[显示]目录下的[窗口]。将视口大小修改为下图所示。

        然后我们再在代码开头添加这几个常量:

#棋盘总长度
const BOARD_PX :=(BOARD_SIZE-1)*CELL_SIZE

#布局参数
const LEFT_MARGIN :=40.0 #棋盘左边距离左侧的距离
const RIGHT_UI_WIDTH :=400.0 #窗口右边给UI选项留出的空间。

        再通过以下函数计算棋盘绘制的基准坐标(同时上一期定义的有关基准坐标也需要进行调整):

var _origin: Vector2

func _update_origin():
var viewsize :=get_viewport_rect().size
var left_area_width :=viewsize.x-RIGHT_UI_WIDTH
var x :=(left_area_width-BOARD_PX)/2.0
x=max(x,LEFT_MARGIN)

var y :=(viewsize.y-BOARD_PX)/2.0
y=max(y,LEFT_MARGIN)
_origin=Vector2(x,y)
queue_redraw()#用于重绘,当某些变量改变时重新绘制棋盘
#这个函数只是简单的数学计算,为了棋盘位置的合理美观,相信大家不用太费力就能理解

        但是运行后会发现,棋盘并没有我们预想到的那样处于合适的位置。别灰心,这并不是我们上段代码计算错误的原因,而是因为这个函数还没被调用。

        这个代码则是用于调用_update_origin()函数的。_ready()函数我也不了解,等我了解后再出介绍。

func _ready():
_update_origin()
get_viewport().size_changed.connect(_update_origin)#在视图大小改变时重新调用该函数。

        再次运行后就可以看到棋盘的位置正常了。

        下面就我们开始写落点计算的函数

# 落点计算

        这个部分主要解决的是玩家下棋时将棋子绘制在距离鼠标点击点最近的棋子落点上。

#坐标转换
func _board_to_screen(board_pos: Vector2i) -> Vector2:#Vector2i只有整数
return _origin + Vector2(board_pos.x,board_pos.y) * CELL_SIZE
#_pos后缀表示位置,是常见的书写习惯。

func _screen_to_board(screen_pos: Vector2) -> Vector2i:
var local :=(screen_pos – _origin) / CELL_SIZE
return Vector2i(round(local.x),round(local.y))

        这两个函数同样是简单的数学计算,一个将棋盘上的位置转换为屏幕上的位置,一个则反过来。

#棋盘完善

        我们从网上找到一张围棋棋盘的图片。可以看到上面有9个星位。

        借助上面落点计算的函数我们可以很方便的绘制星位。

func _draw_grid():
for i in range(BOARD_SIZE):
var line_y=_origin.y+i*CELL_SIZE
draw_line(
Vector2(_origin.x,line_y),
Vector2(_origin.x+(BOARD_SIZE-1)*CELL_SIZE,line_y),
LINE_COLOR,LINE_WIDTH
)#绘制横线
for i in range(BOARD_SIZE):
var line_x=_origin.x+i*CELL_SIZE
draw_line(
Vector2(line_x,_origin.y),
Vector2(line_x,_origin.y+(BOARD_SIZE-1)*CELL_SIZE),
LINE_COLOR,LINE_WIDTH
)#绘制竖线
for pos in [
Vector2i(3,3), Vector2i(3,9), Vector2i(3,15),
Vector2i(9,3), Vector2i(9,9), Vector2i(9,15),
Vector2i(15,3), Vector2i(15,9), Vector2i(15,15)
]:#星位的坐标
draw_circle(_board_to_screen(pos), STAR_POINT_RADIUS, LINE_COLOR)#绘制星位。
#pos也是代表位置的书写习惯。

        运行后的效果:

# 目前为止的全部代码:

extends Node2D

#棋盘参数
const BOARD_SIZE := 19
const CELL_SIZE := 40.0
const LINE_WIDTH := 1.5
const LINE_COLOR := Color(0.2, 0.15, 0.1)
const STAR_POINT_RADIUS := 4.0

#棋盘总长度
const BOARD_PX :=(BOARD_SIZE-1)*CELL_SIZE

#布局参数
const LEFT_MARGIN :=40.0 #棋盘左边距离左侧的距离
const RIGHT_UI_WIDTH :=400.0 #窗口右边给UI选项留出的空间。

var _origin: Vector2

func _update_origin():
var viewsize :=get_viewport_rect().size
var left_area_width :=viewsize.x-RIGHT_UI_WIDTH
var x :=(left_area_width-BOARD_PX)/2.0
x=max(x,LEFT_MARGIN)

var y :=(viewsize.y-BOARD_PX)/2.0
y=max(y,LEFT_MARGIN)
_origin=Vector2(x,y)
queue_redraw()

func _ready():
_update_origin()
get_viewport().size_changed.connect(_update_origin)#在视图大小改变时重新调用该函数。
#只有在_draw()函数里才能执行绘制
func _draw():
_draw_grid()

func _draw_grid():
for i in range(BOARD_SIZE):
var line_y=_origin.y+i*CELL_SIZE
draw_line(
Vector2(_origin.x,line_y),
Vector2(_origin.x+(BOARD_SIZE-1)*CELL_SIZE,line_y),
LINE_COLOR,LINE_WIDTH
)#绘制横线
for i in range(BOARD_SIZE):
var line_x=_origin.x+i*CELL_SIZE
draw_line(
Vector2(line_x,_origin.y),
Vector2(line_x,_origin.y+(BOARD_SIZE-1)*CELL_SIZE),
LINE_COLOR,LINE_WIDTH
)#绘制竖线
for pos in [
Vector2i(3,3), Vector2i(3,9), Vector2i(3,15),
Vector2i(9,3), Vector2i(9,9), Vector2i(9,15),
Vector2i(15,3), Vector2i(15,9), Vector2i(15,15)
]:#星位的坐标
draw_circle(_board_to_screen(pos), STAR_POINT_RADIUS, LINE_COLOR)#绘制星位。

#坐标转换
func _board_to_screen(board_pos: Vector2i) -> Vector2:#Vector2i只有整数
return _origin + Vector2(board_pos.x,board_pos.y) * CELL_SIZE
#_pos后缀表示位置,是常见的书写习惯。

func _screen_to_board(screen_pos: Vector2) -> Vector2i:
var local :=(screen_pos – _origin) / CELL_SIZE
return Vector2i(round(local.x),round(local.y))

        下期进行棋子的处理。

赞(0)
未经允许不得转载:171主机测评 » 布局设计、落点计算、棋盘完善
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址