该程序是基于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类的某些方法,