JAVA游戏编程之三----j2me 手机游戏入门开发--俄罗斯方块_5_使用LUA脚本写游戏
该程序是基于07年底写的一个J2ME小游戏 俄罗斯方块,将全部逻辑绘制都放到LUA脚本里来做,J2ME方面仅作一个绘制库来使用!
建立J2ME程序这里就不说了,
详见我的BLOG
http://blog.csdn.net/kome2000/article/details/4183199
http://kome2000.blog.51cto.com/969562/578555
由于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;//用来显示 Canvasstatic 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 Threadthread;//创建线程对象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类的某些方法,仅自己使用到的,如果你喜欢可以封装更多:)
import javax.microedition.lcdui.Graphics;/** * 工具类 * @author gaolei by 20120706 */public class tool {public static final int METHOD_ID_drawLine = 10;public static final int METHOD_ID_drawString= 11;public static final int METHOD_ID_fillRect = 12;public static final int METHOD_ID_drawRect = 13;public static final int METHOD_ID_translate = 14;public static void drawLine( Graphics g, int x1, int y1, int x2, int y2, int color ){g.setColor( color );g.drawLine(x1, y1, x2, y2);}public static void drawString( Graphics g, String str, int x, int y, int anchor, int color ){g.setColor( color );g.drawString(str, x, y, anchor);}public static void fillRect( Graphics g, int x, int y, int w, int h, int color ){g.setColor( color );//设置颜色为 黑色, 三个16进制数表示,RGB,如0x00ff00 为绿色 g.fillRect(x, y, w, h);//绘制一个实心矩形区域}public static void drawRect(Graphics g,int x, int y, int w, int h, int color) {g.setColor( color );g.drawRect(x, y, w, h);}public static void translate(Graphics g,int x, int y) {g.translate(x, y);}}
看了工程包里的代码及资源目录,你一定看到了
org.luaj.kahluafork.compiler
se.krka.kahlua
这2个包,没错这就是 kahlua 卡鲁瓦,一个J2ME上LUA的实现!遗憾的是,最新版本也是09年06月的!*_*!
什么是Kahlua(卡鲁瓦)?
中文名字念着还是比较顺口的,简单的说,kahlua是一款基于CLDC1.1且非常小巧的Lua解释器,它很容易扩展。只需要配合一个Lua编译器,就可以执行编译后的Lua源代码。目前新版本已经带了编译器。
J2me平台的lua解释器主要有mochalua和Kahlua,mochalua在08年中期后就没有人在维护和更新了,Kahlua最新版本是2009年6月11日的,本次示例就以该版本为基础。
Kahlua和Mochalua的区别?
Mochalua是一个目标尽可能完整实现Lua C功能的解释器,而Kahlua目标是实现LUA JVM最小功能集合的解释器,并且Kahlua在不增加额外开销的情况下,尽可能的模拟实现更多的Lua原版的库函数。所以两者的目标是不同的,一个是尽可能完整,一个是尽可能精简到够用。 毕竟Mochalua原先是给一个GPS项目移植平台使用的,是由一个公司开发的。
Kahlua的目标是jar尽可能的小,只包含核心功能的jar文件为56KB,Mochalua则有200多KB,对于java游戏而言,当然Jar越小越好。Kahlua的代码也非常轻量级,原先的版本只有4605行代码,而Mochalua有16951行代码。所以对比后,哪个更适合你,你可以根据情况决定了!!
下载Kahlua
最新版的源代码下载地址: http://kahlua.googlecode.com/files/kahlua-release-20090611.zip
二进制库地址: http://kahlua.googlecode.com/files/kahlua.jar
下载好后要解压kahlua-release-20090611.zip,使用src里的代码全部COPY 到你的SRC目录下
就有
org.luaj.kahluafork.compiler
se.krka.kahlua
这2个包了!
kahlua-release-20090611.zip\resources\stdlib.lua 这个文件也是我们需要的!但遗憾的是这个是源码放到工程里J2ME不认啊!:(
需要使用LUAC将这个 stdlib.lua 编译成 stdlib.lbc文件
编译方法很简单,如图

什么?你的LUAC是 非内部命令?那是你没LUA环境,
命令是luac -o stdlib.lbc d:\stdlib.lua
路径我就不详细说了!你懂得 
OK,现在说一下我的 game.lua吧!
这个就是全部的游戏逻辑及绘制了,还有键盘事件偶!
--require "constDB"-- the first program in every languageCONST = {screen_width = 240,screen_height = 320,--定义键值KEY_UP = -1,--上KEY_DOWN = -2,--下KEY_LEFT = -3,--左KEY_RIGHT = -4,--右KEY_FIRE = -5,--中间确认键--J2ME方法IDMETHOD_ID_drawLine = 10,METHOD_ID_drawString= 11,METHOD_ID_fillRect = 12,METHOD_ID_drawRect = 13,METHOD_ID_translate = 14,}local s_width = 240;local s_height = 320;local s_box_w = 16;local s_box_h = 16;local s_box_w_sum = 10;--操作区域宽 格子数local s_box_h_sum = 20;--操作区域高 格子数local s_line_between_x = s_box_w * s_box_w_sum;--分割线x位置local init_x = 3;--当前方块初始化坐标Xlocal init_y = 0;--当前方块初始化坐标ylocal s_box_x= init_x;--当前方块坐标Xlocal s_box_y= init_y;--当前方块坐标Ylocal level= 2;--等级local success= 0;--得分local goDownDelayTime= --下降延迟时间 { 10,9,8,7, 6,5,4, 3,2,1 };local level_up= 100;--升级成绩local isShowReseau= true;--是否现实网格local s_next_box= 0;--下一个方块编号local boxColor;--当前box的颜色local gameBG= 0x333333;--游戏区域背景颜色local gameColor = {0x444444,--网格颜色0xEEEEEE,--方块颜色0xEE0000,0x00EE00,0x0000EE,0xEE00EE,0xEEEE00,0x00EEEE};local box_sum = --所有方块图形{{ 0x0660, 0x0660, 0x0660, 0x0660 },{ 0x2222, 0x00F0, 0x2222, 0x00F0 },{ 0x0264, 0x0630, 0x0264, 0x0630 },{ 0x0462, 0x0360, 0x0462, 0x0360 },{ 0x02E0, 0x4460, 0x0740, 0x0622 },{ 0x0E20, 0x2260, 0x0470, 0x0644 },{ 0x0464, 0x00E4, 0x04C4, 0x04E0 }};local next_box = { 0x0660, 0x0660, 0x0660, 0x0660 }; local box = { 0x0660, 0x0660, 0x0660, 0x0660 };local map = {};--地图local box_state = 1;--当前BOX的状态//旋转方向local matrix =--定义矩阵用来计算出box_sum的方块{{ 0x1000, 0x0100, 0x0010, 0x0001 },{ 0x2000, 0x0200, 0x0020, 0x0002 },{ 0x4000, 0x0400, 0x0040, 0x0004 },{ 0x8000, 0x0800, 0x0080, 0x0008 }};local goDownPreTime = 0;--上次下降时间--local currTime = 0;--当前时间local act_off_x = 0;--方块在左右边界旋转的时候调整方块位置的偏移local act_move = 0;local act_transfiguration = 1;local isKeyDown = 0;--0没有按下,1按下,2抬起local isGameOver = false;local updatas = 0;local fps = 0;local startTime, beginTime, endTime;local delay = 25;local upTime = 25;local offx = 0;local offy = 0;function isCanMoveDef()return isCanMove( act_move );endfunction isCanMove( act )for i=1, 4 do--行for j=1,4 do--列if bit:_and( box[1], matrix[i][j] ) == matrix[i][j] then--是格子if s_box_x+j < 1 then--左边界检测if act == act_transfiguration then--左边界检测失败 调整 BOX 位置右移动 最多2格act_off_x=1;s_box_x = s_box_x+1;if isCanMoveDef() thenreturn true;elseact_off_x=2;s_box_x = s_box_x + 1;if isCanMoveDef()thenreturn true;elseact_off_x = 0;endendendprint( "left s_box_x="..s_box_x.." matrix["..i.."]["..j.."]="..matrix[i][j] )return false;endif s_box_x+j > s_box_w_sum then --右边界检测if act == act_transfiguration then--右边界检测失败 调整 BOX 位置左移动 最多1格act_off_x = - 1;s_box_x = s_box_x - 1;if isCanMoveDef() thenreturn true;elseact_off_x = 0;endendprint( "right s_box_x="..s_box_x.." matrix["..i.."]["..j.."]="..matrix[i][j] );return false;endif s_box_y+i > s_box_h_sum-1 then--下边界检测print( "down s_box_y="..s_box_y.." matrix["..i.."]["..j.."]="..matrix[i][j] );return false;endif map[s_box_y+i][s_box_x+j] > 0 then--地图格子检测print( "map s_box_y="..s_box_y.." matrix["..i.."]["..j.."]="..matrix[i][j] );return false;endendendendreturn true;endfunction init_game()print( "LUA>> init_game" )level= 2;--等级success= 0;--得分map = {}-- create the matrixfor i=1,s_box_h_sum domap[i] = {}-- create a new rowfor j=1,s_box_w_sum domap[i][j] = 0endendsetNextBox()--设置下一个BOXsetBox()--将下一个BOX设置成当前BOXsetGameOver( false );--恢复游戏endfunction setGameOver( _isGameOver )isGameOver = _isGameOver;endfunction setNextBox()s_next_box= math.random( 1, 7 );for i=1,4 donext_box[i] = box_sum[s_next_box][i];ends_next_box = s_next_box +1;endfunction setBox()box_state = 1;--box 状态s_box_x= init_x;--当前方块坐标Xs_box_y= init_y;--当前方块坐标YboxColor= s_next_box;--设置当前BOX颜色--System.arraycopy( next_box, 0, box, 0, next_box.length );--box = next_boxfor i=1,4 dobox[i] = next_box[i];endgoDownPreTime = updatas--os.time()--设置好当前BOX后 计时print( "LUA>> goDownPreTime = " .. goDownPreTime )setNextBox();--设置下一个BOXif isCanMoveDef()==false thensetGameOver( true );endendfunction lua_paint()beginTime = os.time()updatas = updatas + 1;--print( "LUA>> lua_paint = " .. updatas )paint()endTime = os.time()upTime = endTime-beginTime;fps = 1000/upTime;endfunction paint()-- gb.setColor( 0x0 );--初始化 画布颜色-- gb.setClip ( 0, 0, s_width, s_height);--初始化 画布区域-- gb.fillRect( 0, 0, s_width, s_height);--初始化 画布填充J2ME_METHOD(CONST.METHOD_ID_fillRect,0, 0, s_width, s_height,0x000000)paintReseau();--绘制网格paintNextBox();--绘制下一BOXpaintMap();--绘制地图上不可以动BOXpaintBox( s_box_x, s_box_y );--绘制当前可控制BOX-- gb.setColor( 0xFF3333 );//分割线颜色-- gb.drawLine( s_line_between_x, 0, s_line_between_x, s_height );//分割线J2ME_METHOD(CONST.METHOD_ID_drawLine,s_line_between_x, 0, s_line_between_x, s_height,0xFF3333)-- gb.drawString( "FPS:"+fps, s_line_between_x+10, 10, g.TOP|g.LEFT );//祯数-- gb.drawString( "等级:"+level, s_line_between_x+10, 30, g.TOP|g.LEFT );//等级-- gb.drawString( "得分:"+success, s_line_between_x+10, 50, g.TOP|g.LEFT );//分数J2ME_METHOD(CONST.METHOD_ID_drawString, "FPS:"..fps,s_line_between_x+10, 10,20,0xFF3333)--J2ME_METHOD(CONST.METHOD_ID_drawString, "等级:level", s_line_between_x+10, 30,20,0xFF3333)--J2ME_METHOD(CONST.METHOD_ID_drawString, "得分:success", s_line_between_x+10, 50,20,0xFF3333)-- if( isGameOver )-- {-- gb.drawImage( gameOverImg,s_width>>1, s_height>>1, g.HCENTER|g.VCENTER );-- }end--绘制网格function paintReseau()J2ME_METHOD(CONST.METHOD_ID_fillRect,0, 0, s_line_between_x, s_height,gameBG)if isShowReseau thenfor i=1, s_line_between_x/s_box_w do-- |J2ME_METHOD(CONST.METHOD_ID_drawLine,i*s_box_h, 0, i*s_box_h, s_height,gameColor[1])endfor j=1, s_height/s_box_h do-- -J2ME_METHOD(CONST.METHOD_ID_drawLine,0, j*s_box_w, s_line_between_x, j*s_box_w,gameColor[1])endendend--绘制下一BOXfunction paintNextBox()local off_x = s_line_between_x+( s_width - s_line_between_x - 4*s_box_w )/2local off_y = s_height/2J2ME_METHOD( CONST.METHOD_ID_translate, off_x, off_y )J2ME_METHOD( CONST.METHOD_ID_fillRect, 0, 0, 4*s_box_w, 4*s_box_h, gameBG )if isShowReseau then--显示格式for i=0,4 do-- |J2ME_METHOD(CONST.METHOD_ID_drawLine,i*s_box_h, 0, i*s_box_h, 4*s_box_h,gameColor[1])endfor j=0,4 do-- -J2ME_METHOD(CONST.METHOD_ID_drawLine,0, j*s_box_w, 4*s_box_w, j*s_box_w,gameColor[1])endendfor i=1,4 do--行for j=1,4 do--列 if bit:_and( next_box[1], matrix[i][j] ) == matrix[i][j] thenJ2ME_METHOD( CONST.METHOD_ID_fillRect, (j-1)*s_box_w, (i-1)*s_box_h, s_box_w, s_box_h, gameColor[ s_next_box ] )J2ME_METHOD( CONST.METHOD_ID_drawRect, (j-1)*s_box_w+1, (i-1)*s_box_h+1, s_box_w-2, s_box_h-2, gameBG )endendendJ2ME_METHOD( CONST.METHOD_ID_translate, -off_x, -off_y )endfunction paintMap()for i=1,s_box_h_sum do--行for j=1,s_box_w_sum do--列if map[i][j] > 0 then--是格子--绘制格子J2ME_METHOD( CONST.METHOD_ID_fillRect, j*s_box_w, i*s_box_h, s_box_w, s_box_h, gameColor[ map[i][j] ] )J2ME_METHOD( CONST.METHOD_ID_drawRect, j*s_box_w+1, i*s_box_h+1, s_box_w-2, s_box_h-2, gameBG )endendendendfunction paintBox( off_x, off_y )off_x = off_x - 1off_y = off_y - 1for i=1,4 do--行for j=1,4 do--列 if bit:_and( box[box_state], matrix[i][j] ) == matrix[i][j] thenJ2ME_METHOD( CONST.METHOD_ID_fillRect, (off_x+j)*s_box_w, (off_y+i)*s_box_h, s_box_w, s_box_h, gameColor[ boxColor ] )J2ME_METHOD( CONST.METHOD_ID_drawRect, (off_x+j)*s_box_w+1, (off_y+i)*s_box_h+1, s_box_w-2, s_box_h-2, gameBG )endendendgoDown();--BOX是否下降endfunction goDown()--当前BOX下降if isGameOver then--游戏结束returnend--isKeyDown按了向下移动就需要检查 不需要时间if isKeyDown==1 or (updatas - goDownPreTime >= goDownDelayTime[level]) thens_box_y = s_box_y + 1goDownPreTime = updatasif isCanMoveDef() == false thenprint( "LUA>> isKeyDown = " .. isKeyDown )isKeyDown = 0;--没有按下s_box_y = s_box_y-1setMap()--将BOX放进map setBox()--新的BOXendendendfunction setMap()for i=1,4 do--行for j=0,4 do--列if bit:_and( box[box_state], matrix[i][j] ) == matrix[i][j] then--是格子map[s_box_y+i][s_box_x+j] = boxColor;endendend--检测是否可以消去一行local line_success = 0;for i=1,s_box_h_sum do--行--if isFullLine( i ) then--这行可以消去--setNullLine( i );--设置第i行为空--setGoDownMap( i );--地图第i行以上的向下移动一行--line_success = line_success + 1;--endendsuccess = success + line_success*line_success--设置得分level_up = goDownDelayTime[1] - goDownDelayTime[level]if success >= level_up then--设置升级level = level % 10-- goDownDelayTime.lengthlevel = level + 1endendfunction keyPressed( key )if key == "-1" then--顺时针旋转isKeyDown = 0--0没有按下box_state = box_state + 1box_state = box_state % 4if isCanMove( act_transfiguration ) == false thenbox_state = box_state - 1if box_state<0 thenbox_state = 3endendelseif key == "-2" then--向下移动act_off_x = 0--恢复BOX旋转位置偏移为0if isKeyDown == 2 thenisKeyDown = 1endif isKeyDown == 1 thens_box_y = s_box_y + 1if isCanMoveDef() == false thens_box_y = s_box_y - 1endendelseif key == "-3" then--向左移动BOXact_off_x = 0--恢复BOX旋转位置偏移为0isKeyDown = 0--0没有按下s_box_x = s_box_x -1if isCanMoveDef() == false thens_box_x = s_box_x + 1endelseif key == "-4" then--向右移动BOXact_off_x = 0--恢复BOX旋转位置偏移为0isKeyDown = 0--0没有按下s_box_x = s_box_x + 1if isCanMoveDef() == false thens_box_x = s_box_x - 1endendendfunction keyReleased( key )isKeyDown = 2end--位运算模块bit={data32={}}for i=1,32 do bit.data32[i]=2^(32-i)endfunction bit:d2b(arg) local tr={} for i=1,32 do if arg >= self.data32[i] then tr[i]=1 arg=arg-self.data32[i] else tr[i]=0 end end return trend --bit:d2bfunction bit:b2d(arg) local nr=0 for i=1,32 do if arg[i] ==1 then nr=nr+2^(32-i) end end return nrend --bit:b2dfunction bit:_xor(a,b) local op1=self:d2b(a) local op2=self:d2b(b) local r={} for i=1,32 do if op1[i]==op2[i] then r[i]=0 else r[i]=1 end end return self:b2d(r)end --bit:xorfunction bit:_and(a,b) local op1=self:d2b(a) local op2=self:d2b(b) local r={} for i=1,32 do if op1[i]==1 and op2[i]==1 then r[i]=1 else r[i]=0 end end return self:b2d(r) end --bit:_andfunction bit:_or(a,b) local op1=self:d2b(a) local op2=self:d2b(b) local r={} for i=1,32 do if op1[i]==1 or op2[i]==1 then r[i]=1 else r[i]=0 end end return self:b2d(r)end --bit:_orfunction bit:_not(a) local op1=self:d2b(a) local r={} for i=1,32 do if op1[i]==1 then r[i]=0 else r[i]=1 end end return self:b2d(r)end --bit:_notfunction bit:_rshift(a,n) local op1=self:d2b(a) local r=self:d2b(0) if n < 32 and n > 0 then for i=1,n do for i=31,1,-1 do op1[i+1]=op1[i] end op1[1]=0 end r=op1 end return self:b2d(r)end --bit:_rshiftfunction bit:_lshift(a,n) local op1=self:d2b(a) local r=self:d2b(0) if n < 32 and n > 0 then for i=1,n do for i=1,31 do op1[i]=op1[i+1] end op1[32]=0 end r=op1 end return self:b2d(r)end --bit:_lshiftfunction bit:print(ta) local sr="" for i=1,32 do sr=sr..ta[i] end print(sr)end工程里其他文件可以忽略了!有些是测试用的垃圾代码
本来想用require "constDB" 导入其他LUA文件,但没成功!你试试吧!
另外lua调用J2ME方法的时候不是很方便,这个卡鲁瓦貌似没能解决调用多个方法的问题,害得我只好自己增加了个方法标识
--J2ME方法IDMETHOD_ID_drawLine = 10,METHOD_ID_drawString= 11,METHOD_ID_fillRect = 12,METHOD_ID_drawRect = 13,METHOD_ID_translate = 14,
后面的drawLine,drawString,就对应 J2ME工程里的Tool.java类的方法了!
这个方块程序 现在没有全部移植完,我就没时间搞了,实现了方块的绘制,方块变形,等
如果你有时间可以参考我的
JAVA游戏编程之三----j2me 手机游戏入门开发--俄罗斯方块_4_增加消除行声音工程代码 把这个LUA程序移植玩吧!:)