📄 mycanvas.java
字号:
import javax.microedition.rms.*;
import javax.microedition.lcdui.*;
public final class MyCanvas extends Canvas implements Runnable, CommandListener {
private static final int STATE_PREPARE = 0;
private static final int STATE_PLAYING = 1;
private static final int STATE_PAUSED = 2;
private static final int STATE_GAMEOVER = 3;
private static final int STATE_INFO = 4;
private static final int NEXT_NO_ACTION = 0;
private static final int NEXT_GO_LEFT = 1;
private static final int NEXT_GO_RIGHT = 2;
private static final int NEXT_GO_BOTTOM = 3;
public static final int BORDER_COLOR = 0xeeeeee;
public static final int INIT_ROWS = 20;
public static final int INIT_COLS = 12;
public static final int INIT_LEFT = 4;
private int screen_width;
private int screen_height;
private int box_width;
private int box_height;
private int reserved_width;
private long speed = 500;
private boolean running = true;
private int state = STATE_PREPARE;
private int score = 0;
private Thread thread = null;
private Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL);
private String message;
private boolean part_repaint = false;
private Background background;
private ActiveShape active;
private Command exitCommand = new Command("退出", Command.EXIT, 0);
private Command startCommand = new Command("开始", Command.ITEM, 0);
private Command pauseCommand = new Command("暂停", Command.ITEM, 0);
private Command resumeCommand = new Command("继续", Command.ITEM, 0);
private Command storeCommand = new Command("储存", Command.ITEM, 0);
private Command top10Command = new Command("TOP 10", Command.ITEM, 0);
public MyCanvas(boolean loadGame) {
setCommandListener(this);
this.screen_width = getWidth();
this.screen_height = getHeight();
this.reserved_width = font.stringWidth("123456");
this.box_width = (screen_width-reserved_width) / INIT_COLS;
this.box_height = screen_height / INIT_ROWS;
box_width = Math.min(box_width, box_height);
box_height = box_width;
if(box_width<3)
throw new IllegalArgumentException("Sorry, the screen of your cell phone is too small, and the game cannot continue.");
background = new Background(INIT_COLS, INIT_ROWS);
active = new ActiveShape(INIT_LEFT);
if(loadGame) {
if(load()) {
thread = new Thread(this);
thread.start();
while(!thread.isAlive());
pauseGame();
}
else prepareGame();
}
else
prepareGame();
}
public void addScore(int rows) {
score += (rows * 10);
if(rows==4) score+=10;
}
private void removeCommands() {
removeCommand(exitCommand);
removeCommand(startCommand);
removeCommand(pauseCommand);
removeCommand(resumeCommand);
removeCommand(top10Command);
removeCommand(storeCommand);
}
public void prepareGame() {
removeCommands();
addCommand(exitCommand);
addCommand(startCommand);
state = STATE_PREPARE;
background.init();
active.init();
active.reset(background);
repaint();
}
public void startGame() {
removeCommands();
addCommand(exitCommand);
addCommand(pauseCommand);
addCommand(storeCommand);
state = STATE_PLAYING;
repaint();
thread = new Thread(this);
thread.start();
while(!thread.isAlive());
}
public void pauseGame() {
removeCommands();
addCommand(exitCommand);
addCommand(storeCommand);
addCommand(resumeCommand);
state = STATE_PAUSED;
repaint();
}
public void resumeGame() {
removeCommands();
addCommand(exitCommand);
addCommand(pauseCommand);
addCommand(storeCommand);
state = STATE_PLAYING;
repaint();
}
public void gameOver() {
removeCommands();
addCommand(exitCommand);
addCommand(top10Command);
state = STATE_GAMEOVER;
repaint();
}
public void exitGame() {
running = false;
if(thread!=null) while(thread.isAlive());
RussiaMIDlet.quitApp();
}
public void speedUp() {
if(speed>=200)
speed-=100;
}
public void speedDown() {
if(speed<=1900)
speed+=100;
}
private void setPartRepaint() {
part_repaint = true;
}
protected void paint(Graphics g) {
if(!part_repaint) {
g.translate(0 - g.getTranslateX(), 0 - g.getTranslateY());
g.setColor(0);
g.fillRect(0, 0, screen_width, screen_height);
background.paint(g, box_width);
g.translate(INIT_COLS*box_width+6 - g.getTranslateX(), box_height*4+font.getHeight()*2 - g.getTranslateY());
g.setColor(0xffffff);
g.drawString("SCORE", 0, 0, Graphics.LEFT|Graphics.TOP);
g.translate(0, font.getHeight()+2);
g.setColor(0xff00);
g.drawString(" "+score, 0, 0, Graphics.LEFT|Graphics.TOP);
}
part_repaint=false;
if(state==STATE_GAMEOVER) {
showInfo(g, "GAME OVER");
}
if(state==STATE_PLAYING) {
g.translate(1 - g.getTranslateX(), 1 - g.getTranslateY()); // (1,1)
active.paint(g, box_width);
g.translate(INIT_COLS*box_width+6 - g.getTranslateX(), 0 - g.getTranslateY());
g.setColor(0xffffff);
g.drawString("NEXT", 0, 0, Graphics.LEFT|Graphics.TOP);
g.translate(0, font.getHeight()+2);
active.getNextShape().paint(g, box_width, 0xffffff);
}
if(state==STATE_PREPARE) {
showInfo(g, "开始");
}
if(state==STATE_PAUSED) {
showInfo(g, "暂停");
}
if(state==STATE_INFO) {
showInfo(g, message);
}
}
private void showInfo(Graphics g, String str) {
g.translate(0 - g.getTranslateX(), 0 - g.getTranslateY());
int str_width = g.getFont().stringWidth(str);
int str_height = g.getFont().getHeight();
int center_x = box_width*INIT_COLS / 2;
int center_y = box_height*INIT_ROWS / 2;
int left = center_x - str_width / 2;
int top = center_y - str_height / 2;
g.setColor(0xffffff);
g.drawRect(left-4, top-2, str_width+8, str_height+4);
g.setColor(0);
g.fillRect(left-3, top-1, str_width+6, str_height+2);
g.setColor(0xffffff);
g.drawString(str, left, top, Graphics.LEFT|Graphics.TOP);
}
public void run() {
long startTime = 0;
long interruptedTime = 0;
long sleepTime = 0;
int shapeCount = Shape.SHAPES.length;
while(running) {
if(state==STATE_PLAYING) {
startTime = System.currentTimeMillis();
if(sleepTime<=0)
sleepTime=speed;
try {
Thread.sleep(sleepTime);
sleepTime = 0;
}
catch(InterruptedException ie) {
interruptedTime = System.currentTimeMillis();
sleepTime = speed - (interruptedTime - startTime);
if(sleepTime>0) continue;
}
boolean b = active.moveDown(background);
if(b) {
repaint();
}
else {
background.merge(active);
background.markRemovingRows();
int removedRows = background.doRemove();
if(removedRows>0) {
System.out.println("Removed " + removedRows + " rows.");
addScore(removedRows);
}
boolean ok = active.reset(background);
if(!ok) {
gameOver();
}
repaint();
}
}
}
}
protected void keyRepeated(int keyCode) {
keyPressed(keyCode);
}
protected void keyPressed(int keyCode) {
if(state==STATE_PLAYING) {
int action = getGameAction(keyCode);
switch(action) {
case Canvas.UP:
if(active.change(background)) {
setPartRepaint();
repaint();
}
break;
case Canvas.LEFT:
if(active.moveLeft(background)) {
setPartRepaint();
repaint();
}
break;
case Canvas.RIGHT:
if(active.moveRight(background)) {
setPartRepaint();
repaint();
}
break;
case Canvas.DOWN:
active.fallDown(background);
repaint();
break;
default:
if(keyCode==Canvas.KEY_NUM0)
pauseGame();
}
}
else if(state==STATE_PAUSED) {
if(keyCode==Canvas.KEY_NUM0)
resumeGame();
}
else if(state==STATE_PREPARE) {
startGame();
}
else if(state==STATE_GAMEOVER) {
}
}
public void commandAction(Command c, Displayable d) {
if(c==exitCommand) exitGame();
if(c==pauseCommand) pauseGame();
if(c==resumeCommand) resumeGame();
if(c==startCommand) startGame();
if(c==top10Command) {
}
if(c==storeCommand) {
int currentState = this.state;
state = STATE_INFO;
message = "请稍后...";
repaint();
message = store() ? "OK" : "FAILED";
repaint();
try {
Thread.sleep(1000);
}
catch(Exception e) {
System.out.println("interrupted");
}
this.state = currentState;
}
}
private RecordStore openRecordStore() {
try {
return RecordStore.openRecordStore("R_LXF_V10", true);
}
catch(RecordStoreException re) {
return null;
}
}
private boolean load() {
RecordStore rs = openRecordStore();
if(rs==null) return false;
RecordEnumeration re = null;
try {
re = rs.enumerateRecords(null, null, true);
if(re.hasNextElement()) {
byte[] data = re.nextRecord();
int n1 = active.setRecordData(data, 0);
if(n1==(-1)) return false;
int n2 = background.setRecordData(data, n1);
if(n2==(-1)) return false;
if(data.length<=n1+n2) return false;
try {
String s = new String(data, n1+n2, data.length-n1-n2);
score = Integer.parseInt(s);
return true;
}
catch(NumberFormatException ne) {
return false;
}
}
}
catch(Exception e) {}
finally {
try { re.destroy(); } catch(Exception e) {}
try {rs.closeRecordStore(); } catch(Exception e) {}
}
return false;
}
private boolean store() {
RecordStore rs = openRecordStore();
if(rs==null) return false;
try {
byte[] data1 = active.getRecordData();
byte[] data2 = background.getRecordData();
byte[] data3 = (""+score).getBytes();
byte[] data = new byte[data1.length + data2.length + data3.length];
for(int i=0; i<data1.length; i++)
data[i] = data1[i];
int offset=data1.length;
for(int i=0; i<data2.length; i++)
data[i+offset] = data2[i];
offset = data1.length+data2.length;
for(int i=0; i<data3.length; i++)
data[i+offset] = data3[i];
if(rs.getNumRecords()==0) {
rs.addRecord(data, 0, data.length);
return true;
}
else {
RecordEnumeration re = null;
try {
re = rs.enumerateRecords(null, null, true);
int id = re.nextRecordId();
rs.setRecord(id, data, 0, data.length);
return true;
}
catch(Exception e) {}
finally {
try { re.destroy(); } catch(Exception e) {}
}
}
}
catch(Exception e) {}
finally {
try {rs.closeRecordStore(); } catch(Exception e) {}
}
return false;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -