更多精品文章
http://dingxiaowei.cn/ (手动复制到浏览器)
前言
在xLua没出来之前,开源的lua框架基本都是以界面用Lua开发为主,核心战斗用C#开发,但xLua出来之后主推C#开发,Lua用作HotFix,这里我展示的第一个例子就是基于界面的经典2D小游戏——俄罗斯方块,界面逻辑是用C#写,启动加载逻辑是用lua,后面我会继续第二个同样的Demo,但是以纯Lua为主,这个案例明天更新。
效果图
由于我不会美术,所以这里使用的开源的游戏资源,感谢此作者。
游戏启动
C#启动Lua逻辑
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using XLua;
using System;
[LuaCallCSharp]
public class LuaRunningBehaviour : MonoBehaviour
{
public TextAsset luaScript;
internal static LuaEnv luaEnv = new LuaEnv(); //all lua behaviour shared one luaenv only!
internal static float lastGCTime = 0;
internal const float GCInterval = 1;//1 second
private Action luaStart;
private Action luaUpdate;
private Action luaOnDestroy;
private LuaTable scriptEnv;
void Awake()
{
scriptEnv = luaEnv.NewTable();
LuaTable meta = luaEnv.NewTable();
meta.Set("__index", luaEnv.Global);
scriptEnv.SetMetaTable(meta);
meta.Dispose();
scriptEnv.Set("self", this);
luaEnv.DoString(luaScript.text, "LuaBehaviour", scriptEnv);
Action luaAwake = scriptEnv.Get("awake");
scriptEnv.Get("start", out luaStart);
scriptEnv.Get("update", out luaUpdate);
scriptEnv.Get("ondestroy", out luaOnDestroy);
if (luaAwake != null)
{
luaAwake();
}
}
// Use this for initialization
void Start()
{
if (luaStart != null)
{
luaStart();
}
}
// Update is called once per frame
void Update()
{
if (luaUpdate != null)
{
luaUpdate();
}
if (Time.time - LuaBehaviour.lastGCTime > GCInterval)
{
luaEnv.Tick();
LuaBehaviour.lastGCTime = Time.time;
}
}
void OnDestroy()
{
if (luaOnDestroy != null)
{
luaOnDestroy();
}
luaOnDestroy = null;
luaUpdate = null;
luaStart = null;
scriptEnv.Dispose();
}
}
Lua加载游戏界面预设逻辑
local util = require 'xlua.util'
local function initGamePanel()
local obj = CS.UnityEngine.Resources.Load("TetrisPanelOne")
local gamePanel = CS.UnityEngine.Object.Instantiate(obj.gameObject).transform
gamePanel.name = "GamePanel"
gamePanel.gameObject.name = "GamePanel"
gamePanel:SetParent(self.transform)
gamePanel.localPosition = CS.UnityEngine.Vector3.zero
gamePanel.localScale = CS.UnityEngine.Vector3.one
end
function start()
print("lua start, 游戏开始...")
initGamePanel()
end
function ondestroy()
print("lua destroy")
end
游戏主要界面对应的C#逻辑
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class MainGameCSScript : MonoBehaviour
{
const int cRow = 16;
const int cCol = 10;
List[] aTable = new List[cRow];
int lineCount = 0;
public Texture[] BoxTexture = new Texture[4];
private string[] boxColors = new string[] { "eluosi_lan", "eluosi_zi", "eluosi_lv", "eluosi_hong" };
public int LineCount
{
get { return lineCount; }
set
{
lineCount = value;
this.onLineCountChange();
}
}
int score = 0;
public int Score
{
get { return score; }
set
{
score = value;
this.onScoreChange();
}
}
int nextCellID = 0;
int curCellID = 0;
float curSpeed = 1;
float fCurSpeed = 1;
float fDeltaTime = 0;
bool bPause = false;
bool bStart = false;
bool bGameOver = false;
public bool BGameOver
{
get { return bGameOver; }
set
{
bGameOver = value;
this.onGameOverChange(bGameOver);
}
}
System.Random rdm = new System.Random();
const int boxTop = 16;
const int boxLeft = 290;
///
/// 彩色砖块的宽度
///
const int boxSize = 38;
int[][] nextCell = null;
int[][] curCell = null;
int curCellCol = 0;
int curCellRow = 0;
public GameObject BtnUp, BtnDown, BtnLeft, BtnRight, BtnIsPause;
public UILabel TimeLabel, ScoreLabel, LineCountLabel;
private Action onScoreChange = null;
private Action onLineCountChange = null;
private Action onGameOverChange = null;
public GameObject EndPanel, BtnRestart;
public UISprite[] BoxSprites = null;
void Start()
{
BoxSprites = new UISprite[4];
for (int i = 0; i (boxColors[i]);
}
this.onScoreChange = this.ScoreChange;
this.onLineCountChange = this.LineCountChange;
this.onGameOverChange = this.GameOverChange;
TimeLabel = transform.Find("LeftNode/CutDownBG/CountLabel").GetComponent();
LineCountLabel = transform.Find("ScoreNode/LineCount").GetComponent();
ScoreLabel = transform.Find("ScoreNode/Score").GetComponent();
BtnLeft = transform.Find("InputNode/Left").gameObject;
BtnRight = transform.Find("InputNode/Right").gameObject;
BtnUp = transform.Find("InputNode/Up").gameObject;
BtnDown = transform.Find("InputNode/Down").gameObject;
BtnIsPause = transform.Find("LeftNode/RestartBtn").gameObject;
EndPanel = transform.Find("EndPanel").gameObject;
BtnRestart = transform.Find("EndPanel/ReplayBtn").gameObject;
for (int i = 1; i ();
BoxSprites[i - 1] = sprite;
}
UIEventListener.Get(BtnRestart).onClick = go =>
{
EndPanel.gameObject.SetActive(false);
Debug.Log("重新开始");
DoStart();
};
UIEventListener.Get(BtnIsPause).onClick = go =>
{
Debug.Log("开始/暂停");
bPause = !bPause;
};
UIEventListener.Get(BtnUp).onClick = go =>
{
Debug.Log("上翻");
DoTransform();
};
UIEventListener.Get(BtnDown).onPress = (go, state) =>
{
Debug.Log("下按");
//state true:按下 false:松开
if (state)
DoSpeedUp();
else
DoSpeedRestore();
};
UIEventListener.Get(BtnLeft).onClick = go =>
{
Debug.Log("左移");
DoLeft();
};
UIEventListener.Get(BtnRight).onClick = go =>
{
Debug.Log("右移");
DoRight();
};
this.DoStart();
}
void ScoreChange()
{
ScoreLabel.text = "获得积分:" + this.Score.ToString();
}
void LineCountChange()
{
LineCountLabel.text = "消灭行数:" + this.LineCount.ToString();
}
void GameOverChange(bool state)
{
if (state)
EndPanel.SetActive(true);
}
///
/// 初始化10*16的格子
///
void DoInit()
{
this.LineCount = 0;
this.Score = 0;
curSpeed = 1;
for (int i = 0; i ();
for (int j = 0; j
/// 随机生成下面一个模型
///
void DoNextCell()
{
if (nextCell == null)
{
nextCellID = rdm.Next(aCells.Length);
nextCell = aCells[nextCellID];
}
curCellCol = cCol / 2 - 2;
curCellRow = -4;
curCell = nextCell;
curCellID = nextCellID;
nextCellID = rdm.Next(aCells.Length);
nextCell = aCells[nextCellID];
DrawNextBox();
DetectIsFail();
}
///
/// 放置当前的模型
///
private void DoSetCurCellDown()
{
for (int i = 0; i fCurSpeed)
{
fDeltaTime -= fCurSpeed;
if (CanMoveTo(curCellCol, curCellRow + 1))
{
curCellRow++;
}
else
{
DoSetCurCellDown();
return;
}
}
if (BGameOver)
{
return;
}
if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) //左移
{
DoLeft();
}
if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow)) //右移
{
DoRight();
}
if (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow)) //上翻
{
DoTransform();
}
if (Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) //按下快速下移
{
DoSpeedUp();
}
if (Input.GetKeyUp(KeyCode.S) || Input.GetKeyUp(KeyCode.DownArrow)) //按键取消 取消快速下移
{
DoSpeedRestore();
}
}
///
/// 检测游戏是否结束
///
private void DetectIsFail()
{
if (CanMoveTo(curCellCol, curCellRow))
{
return;
}
BGameOver = true;
}
///
/// 判断模型移动
///
///
///
///
///
bool CanMoveTo(int x, int y, int[][] cell = null) // 3, -4
{
if (cell == null)
{
cell = curCell;
}
for (int i = 0; i = cCol)
{
return false;
}
if (y + i >= cRow) //到顶了
{
return false;
}
if (y + i
/// 消除一行
///
private void DoLine()
{
List fulledLines = new List();
for (int i = curCellRow; i = cRow)
{
continue;
}
if (i
/// 各种形态的砖块 28个
///
private int[][][] aCells = new int[][][]
{
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,1,0},
new int[]{0,1,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,1,0},
new int[]{0,1,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,1,0},
new int[]{0,1,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,1,0},
new int[]{0,1,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,0,1,1},
new int[]{0,1,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,0,0},
new int[]{0,1,1,0},
new int[]{0,0,1,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,0,1,1},
new int[]{0,1,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,0,0},
new int[]{0,1,1,0},
new int[]{0,0,1,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{1,1,0,0},
new int[]{0,1,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,0,1,0},
new int[]{0,1,1,0},
new int[]{0,1,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{1,1,0,0},
new int[]{0,1,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,0,1,0},
new int[]{0,1,1,0},
new int[]{0,1,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{1,1,1,1},
new int[]{0,0,0,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,1,0},
new int[]{0,0,1,0},
new int[]{0,0,1,0},
new int[]{0,0,1,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{1,1,1,1},
new int[]{0,0,0,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,1,0},
new int[]{0,0,1,0},
new int[]{0,0,1,0},
new int[]{0,0,1,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,0,0},
new int[]{1,1,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,0,0},
new int[]{0,1,1,0},
new int[]{0,1,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,0,0,0},
new int[]{1,1,1,0},
new int[]{0,1,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,0,0},
new int[]{1,1,0,0},
new int[]{0,1,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,1,0},
new int[]{0,0,1,0},
new int[]{0,0,1,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,0,1,0},
new int[]{1,1,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,0,0},
new int[]{0,1,0,0},
new int[]{0,1,1,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{1,1,1,0},
new int[]{1,0,0,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,1,1,0},
new int[]{0,1,0,0},
new int[]{0,1,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{1,1,1,0},
new int[]{0,0,1,0},
new int[]{0,0,0,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{0,0,1,0},
new int[]{0,0,1,0},
new int[]{0,1,1,0},
},
new int[][]
{
new int[]{0,0,0,0},
new int[]{1,0,0,0},
new int[]{1,1,1,0},
new int[]{0,0,0,0},
},
};
}
下载地址
Github同步:https://github.com/dingxiaowei/Aladdin_XLua 关注后续更新请点start或者fork,感谢!
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net