Lua实现Unity堆叠消除小游戏,游戏功能每次随机生成四个不同形状的方块,将方块拖入10*10的格子棋盘,如果放入的棋盘格都有空格则可以放入方块,当放满一行或者一列时,消除满行满列的放入格。

- 创建拼图地图格数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
---拼图地图格数据
---@class ROPuzzleMapTileData
local m = {
---@type number 位置标记
index = 0,
---@type number 所在行
x = 0,
---@type number 所在列
y = 0,
---@type number 地图格上放置的方块ID 为0 表示空格
blockId = 0,
}

function m.New(index,x,y,id)
local o = Clone(m)
o:Init(index,x,y,id)
return o
end

function m:Init(index,x,y,id)
self.index = index
self.x = x
self.y = y
self.blockId = id
end

return m

- 创建拼图游戏数据结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
---@class ROPuzzleGameData
local m = {
---@type CfgRestaurantOperationPuzzleControlData
cfgPuzzleGameControlData = nil,
---@type number 当前积分
score = 0,
---@type ROPuzzleMapTileData[]
tileMaps = {},
---@type number 最大行数
maxLine = 10,
---@type number 最大列数
maxColumn = 10,
---@type number 单次生成的方块数量(上限为4)
randomBlock = {},
---@type boolean 游戏是否已经开始(点了开始按钮视为游戏开始)
isGameStart = false,
}

local ROPuzzleMapTileData = require("IQIGame.Module.CommonActivity.RestaurantOperation.ROPuzzleGame.ROPuzzleMapTileData")

function m.New(cfgData)
local o = Clone(m)
o:Init(cfgData)
return o
end

function m:Init(cfgData)
self.score = 0
self.cfgPuzzleGameControlData = cfgData
self.tileMaps = self:CreateTiles()
self.isGameStart = true
end

---开始新游戏,创建拼图地图
function m:CreateTiles()
local tab = {}
local index = 0
for line = 1, self.maxLine do
for column = 1, self.maxColumn do
index = index + 1
local tileData = ROPuzzleMapTileData.New(index,line,column,0)
tab[index] = tileData
end
end
return tab
end

---随机生成四个方块
function m:RefreshRandomBlock()
self.randomBlock = {}
local blockGroup = table.clone(self.cfgPuzzleGameControlData.BlockGroup)
---洗牌操作
for i = #blockGroup, 2, -1 do
local random_index = math.random(i)
blockGroup[i], blockGroup[random_index] = blockGroup[random_index],blockGroup[i]
end
---根据配置数据取方块
for i = 1, self.cfgPuzzleGameControlData.BlockNum do
local id = blockGroup[i]
table.insert(self.randomBlock,id)
end
end

---消除满行满列,并返回消除的行列
---@return number, number[],number[] 消除的总行数,同时消除的行和列
function m:Eliminate()
local lines = {}
local columns = {}
---行检测
for i = 1, self.maxLine do
local isFull = true
for j = 1, self.maxColumn do
local pos = (i-1) * self.maxLine + j
if self.tileMaps[pos].blockId == 0 then
isFull = false
break
end
end
if isFull then
table.insert(lines,i)
end
end
---列检测
for j = 1, self.maxColumn do
local isFull = true
for i = 1, self.maxLine do
local pos = (i-1) * self.maxLine + j
if self.tileMaps[pos].blockId == 0 then
isFull = false
break
end
end
if isFull then
table.insert(columns,j)
end
end
local totalNum = #lines + #columns
return totalNum,lines,columns
end

---增加积分
---@param score number
function m:AddScore(score)
self.score = self.score + score
end

---检测方块还有没有空地能放下
---@param blockCell PuzzleGameBlockCell
---@return boolean
function m:CheckBlockCellCanPutDown(blockCell)
local posTab = blockCell.blockData
for i, tileData in pairs(self.tileMaps) do
---找到了一个空格子
local canPutDown = false
if tileData.blockId == 0 then
---所有检测点都满足返回true
for j, pos in pairs(posTab) do

end
end
end
return false
end

return m

通过调用RefreshRandomBlock()方法,每次随机生成不重复的四个方块

阅读全文 »

用Lua实现Unity连连看游戏要点记录:

游戏功能描述,通过游戏关卡配置从水果类型中,生成指定类型水果及其数量,位置随机。连线要求最多支持两个拐点,三段线相连通才能消除。

- 创建游戏关卡数据结构

创建关卡水果数据结构 ROFruitData

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
---水果连连看水果数据
---@class ROFruitData
local m = {
---@type number 配置ID
cid = nil,
---@type boolean 是否消除
isClean = false,
---@type number 所在位置
pos = 0,
---@type number 行
x = 0,
---@type number 列
y = 0,
}

function m.New(cid,clean)
local o = Clone(m)
o:Init(cid,clean)
return o
end

function m:Init(cid,clean)
self.cid = cid
self.isClean = clean
end

---@param pos number
function m:SetPos(pos)
self.pos = pos
local x,y = self:GetX_Y()
self.x = x
self.y = y
end

---@return CfgRestaurantOperationFruitListData
function m:GetCfgData()
if self.cid > 0 then
return CfgRestaurantOperationFruitListTable[self.cid]
end
return nil
end

---通过Pos获取格子位置 (每行10个格子)
---@return number,number 行,列
function m:GetX_Y()
local x = math.ceil(self.pos / 10)
local y = self.pos - 10 * (x-1)
return x,y
end

return m
阅读全文 »

12月16日,星期六

今天是大降温的头一天,寒潮来袭。气温明显比昨天低了好几度,最高温度仅有7度。办完上午的事情后,我决定去河边钓鱼,看看这个寒冷的天气对鱼情的影响。

来到西来河边,我发现河水已经干涸了。回忆起夏天的时候,河里马口特别多,当时我玩路亚微物,钓上了好多美丽的马口。但是现在水太浅,温度又低,估计没有鱼儿了。况且,上周河边野钓,那么好的环境,水比较深,都没钓到鱼,这让我有些犹豫。于是,我决定改变原计划,去水库钓小红尾。

到了水库已经过了中午12点。虽然温度很低,但是水温并没有那么冷,感觉还可以。我打开包装袋,准备使用新买的虾拉饵料作钓。钓具方面,我选择了15尺的枯法师,配以小钩和细线。寒风迎面吹来,非常寒冷,水面波浪也相对较大。然而,令我欣喜的是,鱼儿们的咬口非常好。

阅读全文 »

12月10日,星期天

今天是一个悠闲的周末,在寿安镇参加完一场热闹的酒席后,午后与表弟满怀期待地踏上了一段探秘之旅,我们的目标是一直传说中的南河旧沙场,那里据说是个钓鱼的好地方。从网络上朋友们晒出的满载而归的照片就可以看出,这里的鱼种颇为丰富。因为距离比较远,一直没有机会前往,幸运的是今天结束酒席我们便在附近,于是决定去实地探探。

第一次踏上这片朴实的乡间,对于指向南河边的路途,我们了解甚少,我与表弟开车沿着曲折蜿蜒的小路前行,朝着心中模糊的目标寻找。沿路的风景如同幅幅静谧的田园画卷,然而美丽背后却隐藏着迷宫般的复杂,好几次我们信心满满地沿一条道路驶入,却不料终结于荒郊的尽头,只得无奈掉头,重新寻找踪迹。我们一次又一次地尝试,转进又转出, 终于在曲折迂回后,一条幽深的小径映入眼帘。摇晃的车辆随着小径的痕迹颠簸前行,终于我们抵达了心中期待已久的钓鱼之地。

阅读全文 »

用Lua实现Unity弹幕飞行游戏要点记录:

- 对象池

创建游戏中可循环利用的游戏对象池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
---获取一个可用子弹
---@return FlightGameBullet
function m:GetBullet()
for i, v in pairs(self.flightGameBulletPool) do
if not v.active then
return v
end
end
---如果没有可用子弹,动态创建一个新的子弹
local bulletCell = FlightGameBullet.New(UnityEngine.Object.Instantiate(self.BulletModel))
self.flightGameBulletPool[bulletCell.View:GetInstanceID()] = bulletCell
return bulletCell
end

---回收子弹
---@param bullet FlightGameBullet
function m:RecycleBullet(bullet)
bullet.View.transform:SetParent(self.RecoveryNode.transform, false)
bullet:Reset()
self.flightGameBulletPool[bullet.View:GetInstanceID()] = bullet
end

---获取一个未被激活的敌人
---@return FlightGameEnemy
function m:GetEnemy()
for i, v in pairs(self.flightGameEnemyPool) do
if not v.active and v:IsPlayDamageEnd() then
return v
end
end
---如果没有未被激活的敌人,动态创建一个新的敌人
local enemy = FlightGameEnemy.New(UnityEngine.Object.Instantiate(self.EnemyModel),self.rootScene)
self.flightGameEnemyPool[enemy.View:GetInstanceID()] = enemy
return enemy
end

---回收敌人设置成未激活状态
---@param enemy FlightGameEnemy
function m:RecycleEnemy(enemy)
enemy.View.transform:SetParent(self.RecoveryNode.transform, false)
enemy:Reset()
self.flightGameEnemyPool[enemy.View:GetInstanceID()] = enemy
end
--endregion Object Management

- 碰撞检测

实现场景中游戏对象的碰撞检测

阅读全文 »

12月2日

周六,阴冷的冬日,我决定去三一水库钓小红尾。此次的钓鱼之旅,我特意选择了15尺枯法师7,想和以前经常使用的15尺普天元独步,进行一个详细的对比。在网上,对于15尺枯法师7的评论褒贬不一,相对于其他尺寸而言,人们普遍认为15尺是整个枯7系列最不好的一款,持感重头,整体偏软。

刚开始使用枯法师的时候,确实能感受到比独步有明显的重头感,相比于15尺独步,枯7的竿身要细一些,竿壁也更厚。我发现15尺枯法师7,在抛投时和独步一样都比较精准,但刺鱼没有独步那么犀利,独步龙凤尾,刺鱼没延迟很直接。然而,枯法师7代的腰力明显优于独步,当我遇到相同的鱼情时,独步只是竿稍前两节稍微弯曲,就能将鱼飞出水面,而枯法师则能更大幅度地弯曲,甚至大弯弓。

阅读全文 »