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;//用来显示 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类的某些方法,仅自己使用到的,如果你喜欢可以封装更多:)

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 language
CONST = {
screen_width  = 240,
screen_height = 320,
--定义键值
KEY_UP 		=  -1,	--上
KEY_DOWN 	=  -2,	--下
KEY_LEFT 	=  -3,	--左
KEY_RIGHT 	=  -4,	--右
KEY_FIRE 	=  -5,	--中间确认键
--J2ME方法ID
METHOD_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;		--当前方块初始化坐标X
local init_y 		= 0;		--当前方块初始化坐标y
	
local s_box_x		= init_x;	--当前方块坐标X
local s_box_y		= init_y;	--当前方块坐标Y
local 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 );
end
function 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() then
							return true;
						else
							act_off_x=2;
							s_box_x = s_box_x + 1;
							if isCanMoveDef()	then
								return true;
							else
								act_off_x = 0;
							end
						end
					end
					print( "left s_box_x="..s_box_x.." matrix["..i.."]["..j.."]="..matrix[i][j] )
					return false;
				end
				if 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() then
							return true;
						else
							act_off_x = 0;
						end
					end
					print( "right s_box_x="..s_box_x.." matrix["..i.."]["..j.."]="..matrix[i][j] );
					return false;
				end
				if 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;
				end
				if  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;
				end
			end
		end
	end
	return true;
end
	

function init_game()
	print( "LUA>> init_game" )
	level	= 2;				--等级
	success	= 0;				--得分

	map = {}			-- create the matrix
	for i=1,s_box_h_sum do
		map[i] = {}		-- create a new row
		for j=1,s_box_w_sum do
			map[i][j] = 0
		end
	end
	
	setNextBox()					--设置下一个BOX
	setBox()						--将下一个BOX设置成当前BOX
	setGameOver( false );			--恢复游戏
end

function setGameOver( _isGameOver )
	isGameOver = _isGameOver;
end

function setNextBox()
	s_next_box= math.random( 1, 7 );
	for i=1,4 do
		next_box[i] = box_sum[s_next_box][i];
	end
	s_next_box = s_next_box +1;
end

function setBox()
	box_state 		= 1;										--box 状态
	s_box_x			= init_x;									--当前方块坐标X
	s_box_y			= init_y;									--当前方块坐标Y
	boxColor		= s_next_box;								--设置当前BOX颜色
	--System.arraycopy( next_box, 0, box, 0, next_box.length );	--box = next_box
	for i=1,4 do
		box[i] = next_box[i];
	end

	goDownPreTime = updatas		--os.time()				--设置好当前BOX后 计时
	print( "LUA>> goDownPreTime = " .. goDownPreTime )
	
	setNextBox();							--设置下一个BOX
	if isCanMoveDef()==false then
		setGameOver( true );
	end
end




function lua_paint()
	beginTime = os.time()
	updatas = updatas + 1;
	--print( "LUA>> lua_paint = " .. updatas )
	paint()
	endTime = os.time()
	upTime  = endTime-beginTime;
	fps = 1000/upTime;
end
function 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();							--绘制下一BOX
	paintMap();								--绘制地图上不可以动BOX
	paintBox( 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 then
		for 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])
		end
		for 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])
		end
	end
end
--绘制下一BOX
function paintNextBox()
	local off_x = s_line_between_x+( s_width - s_line_between_x - 4*s_box_w )/2
	local off_y = s_height/2
	
	J2ME_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])
		end
		for 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])
		end
	end

	for i=1,4 do		--行
		for j=1,4 do	--列 
			if bit:_and( next_box[1], matrix[i][j] ) == matrix[i][j] then
				J2ME_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 )
			end
		end
	end
	J2ME_METHOD( CONST.METHOD_ID_translate, -off_x, -off_y )
end

function 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 )
			end
		end
	end
end

function paintBox( off_x, off_y )
	off_x = off_x - 1
	off_y = off_y - 1
	
	for i=1,4 do		--行
		for j=1,4 do	--列 
			if bit:_and( box[box_state], matrix[i][j] ) == matrix[i][j] then
				J2ME_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 )
			end
		end
	end
	goDown();	--BOX是否下降
end

function goDown()		--当前BOX下降
	if isGameOver then	--游戏结束
		return
	end
	--isKeyDown按了向下移动就需要检查 不需要时间
	if isKeyDown==1 or (updatas - goDownPreTime >= goDownDelayTime[level]) then
		
		s_box_y = s_box_y + 1
		goDownPreTime = updatas
		if isCanMoveDef() == false  then
			print( "LUA>> isKeyDown = " .. isKeyDown )
			isKeyDown = 0;	--没有按下
			s_box_y = s_box_y-1
			setMap()		--将BOX放进map 
			setBox()		--新的BOX
		end
	end
end

function 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;
			end
		end
	end
	--检测是否可以消去一行
	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;
	--	end
	end
	
	success = success + line_success*line_success	--设置得分
	level_up =  goDownDelayTime[1] - goDownDelayTime[level]
	if success >= level_up then		--设置升级
		level = level % 10	-- goDownDelayTime.length
		level = level + 1
	end
end
	
function keyPressed( key )
	if key == "-1" then		--顺时针旋转
		isKeyDown = 0		--0没有按下
		box_state = box_state + 1
		box_state = box_state % 4
		if isCanMove( act_transfiguration ) == false then
			box_state = box_state - 1
			if box_state<0 then
				box_state = 3
			end
		end
	elseif key == "-2" then		--向下移动
		act_off_x = 0		--恢复BOX旋转位置偏移为0
		if isKeyDown == 2 then
			isKeyDown = 1
		end
		if isKeyDown == 1 then
			s_box_y = s_box_y + 1
			if isCanMoveDef() == false then
				s_box_y = s_box_y - 1
			end
		end
	elseif key == "-3" then	--向左移动BOX
		act_off_x = 0		--恢复BOX旋转位置偏移为0
		isKeyDown = 0		--0没有按下
		s_box_x = s_box_x -1
		if isCanMoveDef() == false then
			s_box_x = s_box_x + 1
		end
	elseif key == "-4" then	--向右移动BOX
		act_off_x = 0		--恢复BOX旋转位置偏移为0
		isKeyDown = 0		--0没有按下
		s_box_x = s_box_x + 1
		if isCanMoveDef() == false then
			s_box_x = s_box_x - 1
		end
	end
end

function keyReleased( key )
	isKeyDown = 2
end













--位运算模块
bit={data32={}}
for i=1,32 do
    bit.data32[i]=2^(32-i)
end

function 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   tr
end   --bit:d2b

function    bit:b2d(arg)
    local   nr=0
    for i=1,32 do
        if arg[i] ==1 then
        nr=nr+2^(32-i)
        end
    end
    return  nr
end   --bit:b2d

function    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:xor

function    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:_and

function    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:_or

function    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:_not

function    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:_rshift

function    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:_lshift


function    bit:print(ta)
    local   sr=""
    for i=1,32 do
        sr=sr..ta[i]
    end
    print(sr)
end


工程里其他文件可以忽略了!有些是测试用的垃圾代码

本来想用require "constDB" 导入其他LUA文件,但没成功!你试试吧!

另外lua调用J2ME方法的时候不是很方便,这个卡鲁瓦貌似没能解决调用多个方法的问题,害得我只好自己增加了个方法标识

--J2ME方法ID
METHOD_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程序移植玩吧!:)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值