block.script
go.property("block", hash("block_1"))
function init(self)
-- Add initialization code here
-- Learn more: https://defold.com/manuals/script/
-- Remove this function if not needed
sprite.play_flipbook("#el", self.block)
end
local function move(receiver, to_x, speed)
local pos = go.get_position()
local to = vmath.vector3(to_x, 150, 0)
local distance = pos.y - to.y
local duration = distance / speed
go.animate(".", "position", go.PLAYBACK_ONCE_FORWARD, to, go.EASING_INOUTCUBIC, duration, 0, function()
-- 移动完成后,将块添加到槽位实例数组中
msg.post(receiver, hash("block_move_end"))
end)
end
function on_message(self, message_id, message, sender)
-- Add message-handling code here
-- Learn more: https://defold.com/manuals/message-passing/
-- Remove this function if not needed
if message_id == hash("block_move") then
print(self.block .. " moving: ", message.to_x, message.speed)
move(sender, message.to_x, message.speed)
end
if message_id == hash("block_remove") then
print(msg.url("."))
go.animate(".", "scale", go.PLAYBACK_ONCE_FORWARD, vmath.vector3(), go.EASING_INOUTCUBIC, 0.5, 0, function()
go.delete(".")
msg.post(sender, hash("block_remove_end"), message)
end)
end
end
board.scripit
function init(self)
msg.post(".", "acquire_input_focus")
self.instances = build_board()
self.slot_instances = {}
self.remove = 0
end
function build_board()
-- 设置随机数种子
math.randomseed(os.time())
local instances = {}
-- 创建 7x7 的数组
local pos = vmath.vector3()
for i = 1, 7 do
pos.x = 120 * 0.8 * i
for j = 1, 7 do
pos.y = 1300 - 135 * 0.8 * j
local r = math.random(0, 16) -- 随机生成 0-16
if r ~= 0 then
table.insert(instances,
factory.create("#block_factory", pos, nil, { block = hash("block_" .. r) },
vmath.vector3(0.8, 0.8, 0.8)))
end
end
end
return instances
end
-- 删除指定范围的方块
function remove_blocks(self, start_index, count)
self.remove = 3
print("删除 " .. count .. " 个方块,从位置 " .. start_index .. " 开始")
-- 删除方块实例
for i = start_index, start_index + count - 1 do
msg.post(self.slot_instances[i], hash("block_remove"), { start_index = start_index })
end
-- 从数组中移除
for i = 1, count do
table.remove(self.slot_instances, start_index)
end
end
-- 检查是否有3个或以上相同类型的方块
function check_and_remove_matches(self)
if #self.slot_instances < 3 then
return false
end
local i = 1
while i <= #self.slot_instances do
local current_hash = go.get(self.slot_instances[i], "block")
local match_start = i
local match_count = 1
-- 向后查找相同类型的方块
for j = i + 1, #self.slot_instances do
local block_hash = go.get(self.slot_instances[j], "block")
if block_hash == current_hash then
match_count = match_count + 1
else
break
end
end
-- 如果找到3个或以上相同类型的方块,删除它们
if match_count >= 3 then
msg.post("#", hash("block_remove"), { match_start = match_start, match_count = match_count })
return true
else
i = i + match_count
end
end
return false
end
function on_message(self, message_id, message, sender)
if message_id == hash("instance_clicked") then
local clicked_instance = msg.url(nil, message.instance, "block")
local clicked_block_hash = go.get(clicked_instance, "block")
-- 查找相同元素的最后位置
local insert_index = #self.slot_instances + 1 -- 默认插入到末尾
for i, instance in ipairs(self.slot_instances) do
local block_hash = go.get(instance, "block")
if block_hash == clicked_block_hash then
insert_index = i + 1
end
end
-- 在找到的位置插入元素
table.insert(self.slot_instances, insert_index, clicked_instance)
-- 更新从插入位置开始的所有元素的坐标
for i = insert_index, #self.slot_instances do
local target_x = i * 96
if i == insert_index then
-- 新插入的元素使用动画移动
msg.post(self.slot_instances[i], hash("block_move"), { to_x = target_x, speed = 2500 })
else
-- 其他元素直接更新位置
local pos = go.get_position(self.slot_instances[i])
pos.x = target_x
go.set_position(pos, self.slot_instances[i])
end
end
end
if message_id == hash("block_remove") then
remove_blocks(self, message.match_start, message.match_count)
end
if message_id == hash("block_remove_end") then
self.remove = self.remove - 1
if self.remove == 0 then
-- 重新调整剩余方块的位置
for i = message.start_index, #self.slot_instances do
local target_x = i * 96
local pos = go.get_position(self.slot_instances[i])
pos.x = target_x
go.set_position(pos, self.slot_instances[i])
end
end
end
if message_id == hash("block_move_end") then
-- 检查是否有3个或以上相同类型的方块需要消除
check_and_remove_matches(self)
end
end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.released then
for i, instance in ipairs(self.instances) do
-- Check if instance is valid before getting position
local success, pos = pcall(go.get_position, instance)
if success then
local scale = go.get_scale(instance)
if action.x >= pos.x - 120 * scale.x / 2 and action.x <= pos.x + 120 * scale.x / 2 then
if action.y <= pos.y + 135 * scale.y / 2 and action.y >= pos.y - 135 * scale.y / 2 then
print("点击位置: ", action.x, action.y, "元素: ", instance)
msg.post("#", hash("instance_clicked"), { instance = instance })
-- Remove clicked instance from the board instances
table.remove(self.instances, i)
break
end
end
end
end
end
end