import java.util.Random;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class TetrisMidlet extends MIDlet
{
private GameCanvas gameCanvas = null;
private Display dis = null;
public TetrisMidlet()
{
long[] shapes = {0x88c002e06220e80l, 0x8e02260e200c88l, 0x8c8004e02620e40l, 0xcc00cc00cc00ccl,
0x6c08c4006c08c4l, 0xc604c800c604c8l, 0x8888000f8888000fl};
Shape player = new Shape(shapes[0]);
GameRound round = new GameRound(shapes, player, (byte)32, (byte)15, (byte)7, (byte) 7);
GameCanvas panel = new GameCanvas(round, player);
gameCanvas = new GameCanvas(round,player);
dis = Display.getDisplay(this);
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException{}
protected void pauseApp(){}
protected void startApp() throws MIDletStateChangeException
{
System.out.println("11111");
dis.setCurrent(gameCanvas);
gameCanvas.repaint();
}
class GameCanvas extends Canvas implements Runnable
{
public static final int VK_UP = -1;
public static final int VK_DOWN = -2;
public static final int VK_LEFT = -3;
public static final int VK_RIGHT = -4;
public static final int VK_FIRE = -5;
public static final int VK_SOFT2 = -7;
private GameRound round;
private Shape player;
public GameCanvas(GameRound round, Shape player)
{
// super(false);
setFullScreenMode(true);
this.round = round;
this.player = player;
new Thread(this).start();
}
public void paint(Graphics g)
{
//清屏
g.setColor(-1);
g.fillRect(0, 0, 800, 480);
g.setColor(0);
g.drawRect(0, 0, 799, 479);
round.show(g);
player.show(g);
}
public void run()
{
long taken = System.currentTimeMillis();
long keyTaken = System.currentTimeMillis();
while(true)
{
if(System.currentTimeMillis() - taken > 1000)
{
taken = System.currentTimeMillis();
keyEvent(VK_DOWN);
}
if(System.currentTimeMillis() - keyTaken > 50 && keepKeyCode != Integer.MAX_VALUE)
{
keyTaken = System.currentTimeMillis();
keyEvent(keepKeyCode);
}
repaint();
try
{
Thread.sleep(1);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public void keyPressed(int keycode)
{
keepKeyCode = keycode;
}
protected void keyReleased(int keyCode)
{
keepKeyCode = Integer.MAX_VALUE;
}
int keepKeyCode = Integer.MAX_VALUE;
public void keyEvent(int keycode)
{
switch(keycode)
{
case VK_DOWN:
round.moveDown();
break;
case VK_LEFT:
round.moveLeft();
break;
case VK_RIGHT:
round.moveRight();
break;
case VK_UP:
round.moveUp();
break;
case VK_FIRE:
byte oldleft = player.getBoundsLeft();
byte oldright = player.getBoundsRight();
player.nextFrame();
if(round.collide(0, 0))
{
player.prevFrame();
}
else
{
if(player.getX() < 0)
{
player.setX((byte)(player.getX() + (oldleft - player.getBoundsLeft())));
}
else if(player.getX() > 31- 3)
{
player.setX((byte)(player.getX() - (oldright - player.getBoundsRight())));
}
}
break;
case VK_SOFT2:
System.exit(0);
break;
}
}
}
private static class GameRound
{
private final byte GAME_ROUND_WIDTH;
private final byte GAME_ROUND_HEIGHT;
private final byte GAME_TILE_WIDTH;
private final byte GAME_TILE_HEIGHT;
private final long[] SHAPES;
private final int[] GAME_DATA;
private Shape player;
private Random ran = new Random();
public GameRound(long[] shapes, Shape player, byte width, byte height, byte twidth, byte theight)
{
//初始化游戏区域的宽和高
//该宽高并不是实际的宽高
//而是指横、纵格子的数量
GAME_ROUND_WIDTH = width;
GAME_ROUND_HEIGHT = height;
//初始化每个格子的宽和高
GAME_TILE_WIDTH = twidth;
GAME_TILE_HEIGHT = theight;
SHAPES = shapes;
this.player = player;
GAME_DATA = new int[GAME_ROUND_HEIGHT];
GAME_DATA[GAME_ROUND_HEIGHT - 2] = 0xaaaaaaaa;
GAME_DATA[GAME_ROUND_HEIGHT - 1] = -1;
}
public void show(Graphics g)
{
g.setColor(0xFFFFFF);
g.fillRect(0, 0, 800, 480);
g.setColor(0xFF0000);
g.drawRect(0, 0, 799, 479);
//渲染数据区
for (int i = 0; i < GAME_ROUND_WIDTH; i++)
{
for (int j = 0; j < GAME_ROUND_HEIGHT; j++)
{
if(((GAME_DATA[j] >> GAME_ROUND_WIDTH-1-i) & 1) == 1)
g.setColor(0xFF0000);
else
g.setColor(0x00FF00);
g.fillRect(i * GAME_TILE_WIDTH, j * GAME_TILE_HEIGHT, GAME_TILE_WIDTH, GAME_TILE_HEIGHT);
g.setColor(0x000000);
g.drawRect(i * GAME_TILE_WIDTH, j * GAME_TILE_HEIGHT, GAME_TILE_WIDTH, GAME_TILE_HEIGHT);
}
}
}
public void moveDown()
{
if(player.getY() < 14 - 3 + player.getBoundsButtom())
{
if(!collide(0,1))
player.y++;
else
shapeDown();
}
else
shapeDown();
}
public void moveUp()
{
if(!collide(0, -1))
{
player.y--;
}
}
public void moveLeft()
{
if(player.getX() > 0 - player.getBoundsLeft())
{
if(!collide(-1,0))
player.x--;
}
}
public void moveRight()
{
if(player.getX() < 31 - 3 + player.getBoundsRight())
{
if(!collide(+1,0))
player.x++;
}
}
public boolean collide(int x, int y)
{
int a,b;
for (int shift = player.getBoundsButtom(); shift < 4; shift++)
{
if(player.getX() < 0)
a = (((((int)player.getFrameData() << (16 + ((3 - shift) << 2) - (player.getX() + x)))) & 0xf0000000));
else
a = (((((int)player.getFrameData() << (16 + ((3 - shift) << 2)))) & 0xf0000000) >>> player.getX() + x);
b = (GAME_DATA[player.getY() + 3 - shift + y]);
if( (a & b) != 0)
{
return true;
}
}
return false;
}
public void shapeDown()
{
int down = 0;
if(player.getY() >= 12)
down = player.getY()+3;
else
down = player.getY() + 3;
for (int shift = player.getBoundsButtom(); shift < 4; shift++)
{
if(player.getX() > -1)
GAME_DATA[down-shift] |= (((((int)player.getFrameData() << (16 + ((3 - shift) << 2)))) & 0xf0000000) >>> player.getX());
else
GAME_DATA[down-shift] |= (((((int)player.getFrameData() << (16 + ((3 - shift) << 2) - player.getX()))) & 0xf0000000));
}
for (int i = GAME_DATA.length - 1; i >= 0; i--)
{
if(GAME_DATA[i] == -1)
{
int[] tmp = new int[i];
System.arraycopy(GAME_DATA, 0, tmp, 0, tmp.length);
System.arraycopy(tmp, 0, GAME_DATA, 1, tmp.length);
}
}
randomShape();
}
public void randomShape()
{
player.initShape(SHAPES[Math.abs(ran.nextInt() % 7)], (byte)(Math.abs(ran.nextInt() % 4)));
}
}
private static class Shape
{
private long data;
private byte curr_frame;
private short frame_data;
private byte bounds_left;
private byte bounds_right;
private byte bounds_buttom;
private byte x;
private byte y;
public Shape(long data)
{
this(data, (byte)0);
}
public Shape(long data, byte curr_frame)
{
initShape(data, curr_frame);
}
public void initShape(long data, byte curr_frame)
{
this.data = data;
setCurrentFrame(curr_frame);
initBounds();
setX((byte)14);
setY((byte)0);
}
public short getFrameData()
{
return this.frame_data;
}
public void show(Graphics g)
{
for (int shift = 0; shift < 4; shift++)
{
for (int bit = 0; bit < 4; bit++)
{
if((((frame_data >> ((3 - shift) << 2)) >> (3 - bit)) & 1) == 1)
{
g.setColor(0x0000FF);
g.fillRect((x + bit) * 7, (y+shift) * 7, 7, 7);
}
}
}
g.setColor(0xFFFF00);
g.drawRect(x * 7 + 1, y * 7 + 1, 28, 28);
}
public void nextFrame()
{
setCurrentFrame(++curr_frame > 3 ? 0 : curr_frame);
initBounds();
}
public void prevFrame()
{
setCurrentFrame(--curr_frame < 0 ? 3 : curr_frame);
initBounds();
}
private void setCurrentFrame(byte curr_frame)
{
this.curr_frame = curr_frame;
this.frame_data = (short) (data >> ((3 - curr_frame) << 4));
}
private void initBounds()
{
bounds_left = 0;
if((frame_data & 0x8888) == 0)
{
if((frame_data & 0x4444) == 0)
{
if((frame_data & 0x2222) == 0)
bounds_left = 3;
else
bounds_left = 2;
}
else
bounds_left = 1;
}
bounds_right = 0;
A:if((frame_data & 0x1111) == 0)
{
if((frame_data & 0x2222) == 0)
{
if((frame_data & 0x4444) == 0)
{
bounds_right = 3;
break A;
}
bounds_right = 2;
break A;
}
bounds_right = 1;
}
bounds_buttom = 0;
A:if((frame_data & 0x000f) == 0)
{
if((frame_data & 0x00f0) == 0)
{
if((frame_data & 0x0f00) == 0)
{
bounds_buttom = 3;
break A;
}
bounds_buttom = 2;
break A;
}
bounds_buttom = 1;
}
}
public byte getBoundsLeft()
{
return bounds_left;
}
public byte getBoundsRight()
{
return bounds_right;
}
public byte getBoundsButtom()
{
return bounds_buttom;
}
public byte getX()
{
return x;
}
public void setX(byte x)
{
this.x = x;
}
public byte getY()
{
return y;
}
public void setY(byte y)
{
this.y = y;
}
}
}
全位运算实现的俄罗斯方块 J2ME版
最新推荐文章于 2021-01-15 22:52:08 发布