我正在尝试制作国际象棋游戏,但我刚开始学习日冕,而且我在移动棋盘上有些困难
这是我如何做到的:
制作董事会:
首先,我没有任何特殊部分制作整板:
local function MakeBoard()
local boardIndex = 0
for i = 1, tilesAcross do
if not boardImg[i] then
boardImg[i] = {};
end
for j = 1, tilesDown do
boardIndex = boardIndex + 1
boardImg[i][j] = spawn({image = images[1].getFile , w = tileWidth, h = tileHeight, objTable = spawnTableBoard}) -- board image
boardImg[i][j].x = (j - 1) * (tileWidth + tileSpacing) + leftSpacing
boardImg[i][j].y = (i - 1) * (tileHeight + tileSpacing) + topSpacing
boardImg[i][j].testx = i
boardImg[i][j].testy = j
boardImg[i][j]boardIndex = boardIndex
end
end
然后我把这块放在板上:
local pieceIndex = 0
for i = 1, tilesAcross do
if not pieceImg[i] then
pieceImg[i] = {};
end
for j = 1, tilesDown do
pieceIndex = pieceIndex + 1
boardIndex = boardIndex + 1
local imagesId = levels[boardIndex]
if imagesId ~= 1 then
pieceImg[i][j] = spawn({image = images[imagesId].getFile , w = tileWidth, h = tileHeight, objTable = spawnTablePiece})
pieceImg[i][j].x = (j - 1) * (tileWidth + tileSpacing) + leftSpacing
pieceImg[i][j].y = (i - 1) * (tileHeight + tileSpacing) + topSpacing
pieceImg[i][j].testx = i
pieceImg[i][j].testy = j
pieceImg[i][j].pieceIndex = pieceIndex
pieceImg[i][j]:addEventListener("tap", select)
end
end
在我的选择事件中,我在棋盘上添加了一个可以移动的事件(有很多无用的东西和无用的东西,因为我走了很多方向,但这是重要部分的样子:
local function select(event)
if selectedpiece == event.target then
for i = 1, #spawnTableBoard do
spawnTableBoard[i]:setFillColor( 255,255 )
end
selectedpiece = nil -- if you click on the same piece as before, we cancel the selection
else
selectedpiece = nil
for i = 1, #spawnTableBoard do
spawnTableBoard[i]:setFillColor( 255,255 )
spawnTableBoard[i]:removeEventListener( "tap", move )
end
selectedpiece = event.target
selectedpiece._x = event.target.testx -- the x value according to the grid
selectedpiece._y = event.target.testy -- the y value according to the grid
if piece[selectedpiece._x][selectedpiece._y].testx == levelImg[selectedpiece._x][selectedpiece._y].testx then -- temporary test to check which piece we clicked
levelImg[levelImg[selectedpiece._x][selectedpiece._y].testx][2]:setFillColor( 255,0,0 ) -- also for testing purpose
levelImg[1][2]:addEventListener("tap", move)
end
end
return true
end
然后是我的移动事件,我猜问题来自那里,我正在进行过渡以移动玩家点击的部分并且它可以正常工作但是如果我点击我刚刚移动的部分,我的select事件中有一个bug,其中piece对象是nil(piece对象是全局的:local piece = {}),我不能再点击它,但是另一个仍在工作,所以基本上我每次只能移动一次。
我想这是因为当我进行转换时,图像会移动,但数组不会更新为correclty或类似的内容。
local function move(event)
if selectedpiece then
transition.to( selectedpiece, {time = 100, x = spawnTableBoard[event.target.index].x, y = spawnTableBoard[event.target.index].y} )
selectedpiece.playerIndex = event.target.index
piece[selectedpiece._x][selectedpiece._y] = selectedpiece
piece[selectedpiece._x][selectedpiece._y].testx = event.target.testx
piece[selectedpiece._x][selectedpiece._y].testy = event.target.testy
for i = 1, #spawnTableBoard do
spawnTableBoard[i]:setFillColor( 255,255 )
spawnTableBoard[i]:removeEventListener( "tap", move )
spawnTableBoard[i]:removeEventListener( "tap", select )
end
selectedpiece = nil
end
end
任何帮助都会非常感激! 或者,如果我的逻辑错误,请告诉我。
答案 0 :(得分:2)
我认为这是因为你删除了select
函数中的tap事件监听器。您显示的代码并不表示spawnTableBoard
是什么,但这是删除点击侦听器的位置。但是还有其他一些地方可能会出现问题:在选择了已移动的部分之后,selectedpiece
可能仍为零,因此move
什么都不做;或者select
在逻辑方面,您可以通过思考状态来简化或澄清您的代码:在初始化之后,您的游戏似乎处于状态"等待选择","等待目的地"或者"移动"。第三状态"移动"意味着在你的作品到达目的地之前,轮到你了。如果你有两种类型的点击监听器,一个用于分段,一个用于正方形,那么每个监听器可以根据活动状态轻松决定做什么。
例如,在初始化之后,游戏会自动从" init"到#34;等待作品选择" (设置变量currentState='wait for selection'
)。 "正方形"点击处理程序看起来像:
local function someSquare:tap(event)
if currentState == 'wait for piece selection' then
print('square has nothing to do while waiting for piece selection')
elif currentState == 'wait for destination' then
start transition.to with onComplete = function()
if piece there then remove it
set new position, updage grid (undo highlight of from/to squares) etc
transition to 'waiting for piece selection'
end
switch state to 'moving piece'
elif currentState == 'moving piece' then
if tapped square is same as square of selected piece then cancel transition
else
error("BUG: unrecognized state")
end
end
类似地,单件轻敲处理程序看起来像:
local function somePiece:tap(event)
if currentState == 'wait for piece selection' then
transitionObj = transition.to(self, {..., onComplete = function()
if destination has piece then remove it
set new position of piece
updage grid (reset highlights etc)
currentState = 'waiting for piece selection'
end}
currentState = 'moving piece'
elif currentState == 'wait for destination' then
selectedPiece = nil
currentState = 'waiting for piece selection'
inform user that selection cancelled (undo highlight of square, whatever)
elif currentState == 'moving piece' then
transition.cancel(transitionObj)
transitionObj = nil
-- following lines probably identical to 'wait for destination' so probably put in function
selectedPiece = nil
currentState = 'waiting for piece selection'
inform user that selection cancelled (undo highlight of square, whatever)
else
error("BUG: unrecognized state")
end
end
由于您的游戏处于已知状态这一事实,这将大大清理您的逻辑,因此有些事情是不可能的"并且你不需要为它们进行测试(尽管断言是非常方便的,因为健全性检查)。