找不到工作,开始研究lua。
看网上较少这方面的教程就写一下以供参考,顺便加深记忆。
我把需要修改的地方作一个简单介绍吧。
一 注册控制器和场景
CtrlNames = {
Snake = "SnakeCtrl"
}
PanelNames = {
"SnakePanel",
}
在Comman/define下注册,将你需要用到的控制器和场景写进上面的table。
注册的控制器和场景会在Logic/Game下加载,代码如下
function Game.InitViewPanels()
for i = 1, #PanelNames do
require ("View/"..tostring(PanelNames[i]))
end
end
--加载场景
CtrlManager.Init();
local ctrl = CtrlManager.GetCtrl(CtrlNames.Snake);
if ctrl ~= nil and AppConst.ExampleMode == 1 then
ctrl:Awake();
end
function CtrlManager.Init()
logWarn("CtrlManager.Init----->>>");
ctrlList[CtrlNames.Snake] = SnakeCtrl.New();
return this;
end
--加载控制器
二 场景类
-----
require "Common/define"
local gameobject;
local transform;
SnakePanel = {};
local this = SnakePanel;
function SnakePanel.Awake(obj)
gameObject = obj;
transform = obj.transform;
this.InitPanel();
end
function SnakePanel.InitPanel()
this.text = transform:FindChild("Text").gameObject;
this.head = transform:FindChild("head").gameObject;
end
–获得场景中的控件,这里没有进行优化直接使用Find。场景是在控制类下加载出来。transform储存的是场景中名为Guicamera的相机。资源加载出来后一般是以它作为父节点。
三 控制类
require "Common/define"
require "Logic/Snake"
SnakeCtrl = {};
local this = SnakeCtrl;
local gameObject;
local transform;
local SnakeText
math.randomseed(os.time());
local SnakeTailPool = {};
local direction = {
x = 0,
y = 57
};
local lastDirection = {
x = 0,
y = 57
};
local lastTailDirection = {
x = 0,
y = 0
};
local directionContorl = 1; --为1是向上 为2是向下 为3是向左 为4是向右--
local isRun = 1;
local GoldTable = {};
local directionStoreTable = {};
function SnakeCtrl.New()
return this;
end
function SnakeCtrl.Awake()
panelMgr:CreatePanel('Snake',this.OnCreate);
end
function SnakeCtrl.OnCreate(obj)
gameObject = obj;
transform = obj.transform;
SnakeCtrl.AddTail(); --给尾巴--
SnakeText = gameObject:GetComponent('LuaBehaviour');
SnakeText:AddText(SnakePanel.text);
coroutine.start(this.Move);
UpdateBeat:Add(this.Update);
end
function SnakeCtrl.Move()
while isRun>0 do
if direction.x==0 and direction.y>0 then
directionContorl = 1;
end
if direction.x==0 and direction.y<0 then
directionContorl = 2;
end
if direction.y==0 and direction.x<0 then
directionContorl = 3;
end
if direction.y==0 and direction.x>0 then
directionContorl = 4;
end
SnakeCtrl.NewGold();
SnakePanel.head.transform:Translate(direction.x,direction.y,0);
if #SnakeTailPool ~= 0 then
for i = 1,#SnakeTailPool do
if SnakeTailPool[i].go~=0 then
SnakeTailPool[i]:Move();
-- LuaFramework.Util.Log("SnakeID"..i);
end
end
for i = 1,#SnakeTailPool do
if SnakePanel.head.transform.x == SnakeTailPool[i].position.x and SnakePanel.head.transform.y == SnakeTailPool[i].position.y then
LuaFramework.Util.Log("SnakeDead");
end
directionStoreTable[i].x = SnakeTailPool[i].direction.x;
directionStoreTable[i].y = SnakeTailPool[i].direction.y;
end
SnakeCtrl.CheckGold(SnakePanel.head.transform.localPosition.x,SnakePanel.head.transform.localPosition.y);
for i = 1,#SnakeTailPool-1 do
if SnakeTailPool[i+1].direction.x ~= directionStoreTable[i].x or SnakeTailPool[i+1].direction.y ~= directionStoreTable[i].y then
if i + 1 <= #SnakeTailPool then
SnakeTailPool[i+1]:ChangeSwitch(directionStoreTable[i].x,directionStoreTable[i].y);
LuaFramework.Util.Log("SnakeID"..i);
LuaFramework.Util.Log(directionStoreTable[i].x..directionStoreTable[i].y);
end
end
end
end
if lastDirection.x ~= direction.x or lastDirection.y ~= direction.y then
lastDirection.x = direction.x;
lastDirection.y = direction.y;
if #SnakeTailPool ~=0 then
SnakeTailPool[1]:ChangeSwitch(direction.x,direction.y);
directionStoreTable[1].x = direction.x;
directionStoreTable[1].y = direction.y;
end
end
coroutine.wait(0.8);
end
end
function SnakeCtrl.Update()
local keyCode = UnityEngine.KeyCode;
if Input.GetKeyDown(keyCode.W) then
Util.Log("w");
if (directionContorl~=2) then
direction.x = 0;
direction.y = 57;
end
end
if Input.GetKeyDown(keyCode.A) then
if (directionContorl~=4) then
direction.x =-57;
direction.y = 0;
end
Util.Log("a");
end
if Input.GetKeyDown(keyCode.D) then
if(directionContorl~=3) then
direction.x = 57;
direction.y = 0;
end
Util.Log("d");
end
if Input.GetKeyDown(keyCode.S) then
if(directionContorl~=1) then
direction.x = 0;
direction.y = -57;
end
Util.Log("s");
end
end
function SnakeCtrl.NewGold()
resMgr:LoadPrefab('snake',{'GoldPrefab'},this.CreateGold);
end
function SnakeCtrl.CreateGold(goes)
local go = GameObject.Instantiate(goes[0]);
local randomController = true;
local x;
local y;
while randomController do
x = math.random(-5,5)*57;
y = math.random(-5,5)*57;
if #GoldTable ~= 0 then
for i = 1,#GoldTable do
if GoldTable[i][2] ~= x or GoldTable[i][3] ~=y then
randomController = false;
else
randomController = true;
break;
end
end
else
randomController = false;
end
end
go.transform:SetParent(gameObject.transform);
go.transform.localPosition = Vector3.New(x,y,0);
table.insert(GoldTable,1,{go,go.transform.localPosition.x,go.transform.localPosition.y,go.transform.localPosition.z});
end
function SnakeCtrl.CheckGold(x,y)
if #GoldTable ~= 0 then
for i = 1,#GoldTable do
if GoldTable[i][2] == x and GoldTable[i][3] == y then
GameObject.Destroy(GoldTable[i][1]);
table.remove(GoldTable,i);
SnakeText:AddText(SnakePanel.text);
SnakeCtrl.AddTail();
break;
end
end
end
end
function SnakeCtrl.AddTail()
if #SnakeTailPool == 0 then
local snake = Snake:New(SnakePanel.head.transform.localPosition.x,SnakePanel.head.transform.localPosition.y,direction.x,direction.y);
table.insert(SnakeTailPool,#SnakeTailPool+1,snake);
table.insert(directionStoreTable,#directionStoreTable+1,{x=direction.x,y=direction.y});
else
local n = #SnakeTailPool;
local snake=Snake:New(SnakeTailPool[n].position.x,SnakeTailPool[n].position.y,SnakeTailPool[n].direction.x,SnakeTailPool[n].direction.y);
table.insert(SnakeTailPool,#SnakeTailPool+1,snake);
end
resMgr:LoadPrefab('snake',{'BodyPrefab'},this.CreateTail);
end
function SnakeCtrl.CreateTail(objs)
local n = #SnakeTailPool;
SnakeTailPool[n].go = GameObject.Instantiate(objs[0]);
SnakeTailPool[n].go.transform:SetParent(transform);
if n ~= 1 then
SnakeTailPool[n].position.x = SnakeTailPool[n].position.x - SnakeTailPool[n].direction.x;
SnakeTailPool[n].position.y = SnakeTailPool[n].position.y - SnakeTailPool[n].direction.y;
table.insert(directionStoreTable,#directionStoreTable + 1,{x = SnakeTailPool[#SnakeTailPool].direction.x,y =SnakeTailPool[#SnakeTailPool].direction.y});
end
SnakeTailPool[n].go.transform.localPosition = Vector3.New(SnakeTailPool[n].position.x,SnakeTailPool[n].position.y,0);
end
逻辑其实挺简单,头节点移动后通知下一个节点改变,通过每一次移动的时候前一个节点和后一个节点方向如果不同就让后一个节点方向与前一个节点相同,逻辑上的困难点是如何在线程上实现,因为前一个节点会使后一个节点发生变化会导致后面节点一连串的改变,比如节点是abcdefg,a发生改变那么会使bcdefg发生改变,我只希望b发生改变的话就需要一个table储存 发生改变前的方向,就不会导致连锁反应。顺便一提57是我的每一个贪吃蛇节点期望距离。PS 应该用一个变量存储。。。
很多知识点比如如何在lua内与C#通信是在
https://zhuanlan.zhihu.com/p/21386682 学习到的,我就不在此赘述。不过有一点需要特别注意。
resMgr:LoadPrefab(‘snake’,{‘BodyPrefab’},this.CreateTail); 使用这个方法是会有延迟即调用createTail至完成是有延迟的,原因是luaFramework框架加载assetbundle使用了协程。
四 逻辑层
require "Common/define"
Snake = {
};
Snake.__index = Snake;
function Snake:Move()
self.go.transform:Translate(self.direction.x,self.direction.y,0);
self.position.x = self.direction.x + self.position.x;
self.position.y = self.direction.y + self.position.y;
end
function Snake:ChangeSwitch(directionX,directionY)
self.direction.x = directionX;
self.direction.y = directionY;
end
function Snake:New(x,y,directionX,directionY)
local self = {direction = {x = 0,y = 0},position = {x = 0,y = 0},ChangeMoveRecord = {},go = 0,directionX = 0,directionY = 0,switch = false,timer = 0,lastDirectionX,lastDirectionY,nowDirectionX = 0,nowDirectionY = 0};
setmetatable(self,Snake);
self.direction.x = directionX;
self.direction.y = directionY;
self.position.x = x;
self.position.y = y;
self.lastDirectionX = directionX;
self.lastDirectionY = directionY;
self.switch = false;
self.timer = 0;
return self;
end
关于table类的使用和继承在网上有资料就不赘述了。
五 C#
public void AddText(GameObject go)
{
if (go == null) return;
string textStr = go.GetComponent<Text>().text;
string regex = @"\d+$";
Regex rgClass = new Regex(regex, RegexOptions.Singleline);
Match match = rgClass.Match(textStr);
int i = 0;
if (match.Length != 0)
{
i = int.Parse(match.Value);
i++;
}
{
i = 0;
}
go.GetComponent<Text>().text = "得分:" + i.ToString();
}
关于得分 使用了正则表达式