该程序是基于07年底写的一个J2ME小游戏 俄罗斯方块,将全部逻辑绘制都放到LUA脚本里来做,J2ME方面仅作一个绘制库来使用!
建立J2ME程序这里就不说了,
详见我的BLOG
由于J2ME代码比较少就全贴出来了!
///
//
// Tetris.java
//
// Project: J2ME_LUA_TEST 俄罗斯方块
// Author(s): Gao Lei
// Create: 2012-07-08
///
import javax.microedition.midlet.*; //j2me MIDlet程序必须继承MIDlet类,所以要引入此包
import javax.microedition.lcdui.*; //Display这个类所在包
///
public class Tetris extends MIDlet
{
static Tetris s_midlet; //MIDlet类的静态对象,方便实用 MIDlet类方法
static Display s_display = null;//用来显示 Canvas
static cGame s_game = null; //Canvas类对象,主要实现游戏的类
public Tetris()
{
s_midlet = this;
}
/**
* 程序开始 系统会调用这个函数
* 也有些手机 可以把程序初始化部分放到构造函数里,这连个地方应视手机的不同而定!
*/
public void startApp()
{
if (s_display == null)
{
s_display = Display.getDisplay(this);//创建Display对象,参数是MIDlet类对象,也就是我们当前写的这个Minesweeper类
}
if (s_game == null)
{
s_game = new cGame(); //创建 Canvas对象
s_display.setCurrent(s_game); //把Canvas对象设置成当前显示
}
else
{
s_display.setCurrent(s_game);
}
}
/**
* 程序暂停 系统会自动调用这个函数,不是所有手机都支持,
* 手机在接到中断,如 来电,来短信时候会调用这个函数,这个函数 通常是空的!
*/
public void pauseApp()
{
}
/**
* 程序关闭 系统会调用这个函数,如果希望关闭程序的时候保存数据,可在这个函数里添加保存数据的方法
* 比如游戏进行中,按了关机键,程序就会调用这个函数,也可以在程序中调用这个函数来结束游戏!
*/
public void destroyApp(boolean unconditional)
{
notifyDestroyed();
}
}
主游戏控制类
//
// cGame.java
//
// Project: J2ME_LUA_TEST
// Author(s): Gao Lei
// Create: 2012-07-08
import java.io.InputStream;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import se.krka.kahlua.luaj.compiler.LuaCompiler;
import se.krka.kahlua.stdlib.BaseLib;
import se.krka.kahlua.stdlib.OsLib;
import se.krka.kahlua.test.UserdataArray;
import se.krka.kahlua.vm.JavaFunction;
import se.krka.kahlua.vm.LuaCallFrame;
import se.krka.kahlua.vm.LuaClosure;
import se.krka.kahlua.vm.LuaState;
import se.krka.kahlua.vm.LuaTable;
//实现 Runnable 这个接口 必须创建Thread的对象,重写run()这个方法
class cGame extends Canvas implements Runnable,JavaFunction
{
private Thread thread; //创建线程对象
private InputStream is; //LUA文件输入
private LuaState state; //LUA 虚拟机
private LuaTable table; //LUA全局表
private LuaClosure closure;//LoadCompiler为编译器,loadis为加载输入流的方法
private static Graphics GRAP;
cGame()
{
setFullScreenMode(true); //设置游戏为全屏幕模式,该函数只能在支持midp2.0的手机上使用
//LUA开始
state=new LuaState(System.out);
UserdataArray.register(state);
OsLib.register(state);
LuaCompiler.register(state);
table=state.getEnvironment();
try
{
is = getClass().getResourceAsStream("/game.lua");
closure=LuaCompiler.loadis(is , "lua" , table);
state.call(closure, null);
} catch (Exception e)
{
e.printStackTrace();
}
table.rawset("J2ME_METHOD", this);//添加到全局表,这样就可以在对应Lua脚本中使用say方法了。
state.call( table.rawget("init_game"), null ); //调用脚本初始化
System.out.println( "System.currentTimeMillis:"+System.currentTimeMillis() );
thread = new Thread(this); //参数为 实现Runnable的类对象
thread.start(); //启动线程
}
public void run()
{
while( true )
{
try
{
/**
* 重新执行 paint() 但该函数是立刻返回,也就是说他不会等待paint()执行完毕就返回了,
* 如果 需要 paint()执行完毕才返回,可以使用serviceRepaints(),也可以两个都是用,但
* repaint()应该在serviceRepaints()之前.
*/
repaint(); //刷屏
serviceRepaints();
thread.sleep(1); //线程休眠 100毫秒
}catch(Exception e)
{
e.printStackTrace();
}
}
}
/**
* 系统自动调用该绘图函数,并传入绘图设备g,通过该设备,我们可以绘制如直线,矩形快,字符串,图片等,
*/
public void paint(Graphics g)
{
if( !g.equals(GRAP) )
{
GRAP = g;
System.out.println( "j2me paint !g.equals(GRAP)" );
}
state.call( table.rawget("lua_paint"), null );
}
/**
* 系统自动调用该函数,当有键盘事件发生为按下某键,参数key为按下键的键值
*/
public void keyPressed(int key)
{
System.out.println("j2me keyPressed.." + key);
String strKey = ""+key;
state.call( table.rawget("keyPressed"), new String[]{strKey} );
}
public void keyReleased( int key ) //释放按键
{
state.call( table.rawget("keyReleased"), new String[]{""+key} );
}
public void J2ME_METHOD(String str)
{
System.out.println( "J2ME_METHOD:" + str);
}
//LUA脚本调用的方法
/* callFrame用于获取输入参数及指定返回值,
* nArguments获取输入参数数量。
* 返回值为返回参数的个数,因为lua函数可以有多个返回值的。
*/
public int call(LuaCallFrame callFrame, int nArguments)
{
String index = BaseLib.rawTostring( callFrame.get(0) );
int methodIndex = Integer.parseInt(index);//获取输入参数
//System.out.println( "J2ME: call " + methodIndex+" nArguments="+nArguments);
switch( methodIndex )
{
case 0:
{
String str=BaseLib.rawTostring(callFrame.get(1));//获取输入参数
J2ME_METHOD(str);//执行对应Java内容
break;
}
case tool.METHOD_ID_drawLine:
{
String x1 = BaseLib.rawTostring( callFrame.get(1) );
String y1 = BaseLib.rawTostring( callFrame.get(2) );
String x2 = BaseLib.rawTostring( callFrame.get(3) );
String y2 = BaseLib.rawTostring( callFrame.get(4) );
String color= BaseLib.rawTostring( callFrame.get(5) );
tool.drawLine( GRAP, Integer.parseInt(x1),
Integer.parseInt(y1),
Integer.parseInt(x2),
Integer.parseInt(y2),
Integer.parseInt(color) );
break;
}
case tool.METHOD_ID_drawString:
{
String str = BaseLib.rawTostring( callFrame.get(1) );
String x = BaseLib.rawTostring( callFrame.get(2) );
String y = BaseLib.rawTostring( callFrame.get(3) );
String anchor = BaseLib.rawTostring( callFrame.get(4) );
String color = BaseLib.rawTostring( callFrame.get(5) );
tool.drawString( GRAP, str,
Integer.parseInt(x),
Integer.parseInt(y),
Integer.parseInt(anchor),
Integer.parseInt(color) );
break;
}
case tool.METHOD_ID_fillRect:
{
String x = BaseLib.rawTostring( callFrame.get(1) );
String y = BaseLib.rawTostring( callFrame.get(2) );
String w = BaseLib.rawTostring( callFrame.get(3) );
String h = BaseLib.rawTostring( callFrame.get(4) );
String color= BaseLib.rawTostring( callFrame.get(5) );
tool.fillRect( GRAP, Integer.parseInt(x),
Integer.parseInt(y),
Integer.parseInt(w),
Integer.parseInt(h),
Integer.parseInt(color) );
break;
}
case tool.METHOD_ID_drawRect:
{
String x = BaseLib.rawTostring( callFrame.get(1) );
String y = BaseLib.rawTostring( callFrame.get(2) );
String w = BaseLib.rawTostring( callFrame.get(3) );
String h = BaseLib.rawTostring( callFrame.get(4) );
String color= BaseLib.rawTostring( callFrame.get(5) );
tool.drawRect( GRAP, Integer.parseInt(x),
Integer.parseInt(y),
Integer.parseInt(w),
Integer.parseInt(h),
Integer.parseInt(color) );
break;
}
case tool.METHOD_ID_translate:
{
String x = BaseLib.rawTostring( callFrame.get(1) );
String y = BaseLib.rawTostring( callFrame.get(2) );
tool.translate( GRAP, Integer.parseInt(x),
Integer.parseInt(y) );
break;
}
}
callFrame.push("result");//返回参数
return 1;
}
}
这个类里使用的LUA接口稍后再说,先把代码贴完
还有一个 工具类,主要是提供了一些LUA使用的绘图函数库,就是包装一下GRAPHICS类的某些方法,