我的第一个 J2ME 程序,大家给我看看
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import javax.microedition.midlet.MIDlet;
public class MyGame extends MIDlet implements CommandListener {
public void startApp() {
MyGameCanvas c = new MyGameCanvas(this);
Display display = Display.getDisplay(this);
display.setCurrent(c);
c.gameLoop();
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command c, Displayable d) {
if (c.getCommandType() == Command.EXIT) {
this.notifyDestroyed();
}
}
}
class MyGameCanvas extends GameCanvas {
private MyGame myGame;
private int spriteX = 0;
private int spriteY = 0;
private int blockWidth =14;
private int blockHeight =14;
private int gridWidth = 12;
private int gridHeight = 12;
public MyGameCanvas(MyGame g) {
super(true);
myGame = g;
Command cmdExit = new Command("Exit",Command.EXIT,0);
this.setCommandListener(g);
this.addCommand(cmdExit);
}
public void gameLoop() {
int oldkey = 0;
Graphics g = getGraphics();
while (true) {
g.setColor(0x000000);
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(0xff0000);
int x = spriteX * blockWidth;
int y = spriteY * blockHeight;
g.fillRect(x,y,blockWidth,blockHeight);
int key = this.getKeyStates();
g.drawString(Integer.toString(key),0,160,Graphics.LEFT | Graphics.TOP);
if (key == 0) {
if ((oldkey & GameCanvas.LEFT_PRESSED) != 0) {
moveLeft();
}
else if ((oldkey & GameCanvas.RIGHT_PRESSED) != 0) {
moveRight();
}
else if ((oldkey & GameCanvas.UP_PRESSED) != 0) {
moveUp();
}
else if ((oldkey & GameCanvas.DOWN_PRESSED) != 0) {
moveDown();
}
else if ((oldkey & GameCanvas.FIRE_PRESSED)!= 0) {
//moveUp();
return;
}
}
oldkey = key;
this.flushGraphics();
}
}
public void moveLeft() {
if (spriteX >0) {
spriteX--;
}
}
public void moveRight() {
if (spriteX < gridWidth -1) {
spriteX++;
}
}
public void moveUp() {
if (spriteY >0) {
spriteY--;
}
}
public void moveDown() {
if (spriteY <gridHeight -1) {
spriteY++;
}
}
}
很简单,就是在屏幕上画一个方格,用上下左右键可以移动它。
但现在有几个小问题。
1。关于按键问题 gameLoop 中如果检测 LEFT_PRESSED,RIGHT_PRESSED 的话,那方格会,一下子就移到了最左边或最右边,(现在我的程序是改成按键弹起后才移动的,不过现在速度就慢太多了。要很久才能反映过来)
2. 如何在 gameLoop 中,按退出键,直接退出程序。
3. 我的程序结构可能不合理,谁能给我一个例子程序
多谢各位了。
问题点数:0、回复次数:14Top
1 楼homesos(熊猫贩子)回复于 2005-08-02 16:27:10 得分 0
◆
想要退出程序,需要填写方法destroyApp()内的代码,
public void destroyApp(boolean unconditional)
{
……
notifyDestroyed();
}
◆按键可以写按键捕获事件来处理
由于你采用的是MIDP2.0,我用的是MIDP1.0,所以恕我不能多言。
Top
2 楼fox1999(红狐)回复于 2005-08-03 09:32:47 得分 0
MIDP1.0 没有这个game 包,如何写程序?
我的手机也是1.0 的 Nokia 6610iTop
3 楼murphy008(菩提老祖)回复于 2005-08-03 11:50:42 得分 0
书上抄的?结构完全是教学用的嘛,商业化还是不行的!不过楼主学习精神可佳!:P
建议:1.构造函数里最好不要初始化参数(除非参数全局使用,直到退出游戏才结束)
2.gameLoop里功能多,不要集中写在一个函数里,要分开写,一个功能就是一个方法.
3.MIDlet里没有构造函数?
好象其他的上面的同志都说到了!
反正慢慢来吧,工作学习中总结的!Top
4 楼homesos(熊猫贩子)回复于 2005-08-03 11:58:57 得分 0
没有game包就不能写程序了???
java.lang.Object
javax.microedition.lcdui.Displayable
javax.microedition.lcdui.Canvas
javax.microedition.lcdui.game.GameCanvas
如果用MIDP1.0 就用CanvasTop
5 楼lcrystal623(小水晶)回复于 2005-08-03 16:24:40 得分 0
我也是个初学者,我按你的意思改了改,命令行的问题还没解决,不过移动的问题解决了,你看看。
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import javax.microedition.midlet.MIDlet;
public class MyGame extends MIDlet implements CommandListener
{
public void startApp()
{
MyGameCanvas c = new MyGameCanvas(this);
Display display = Display.getDisplay(this);
display.setCurrent(c);
Thread game = new Thread(c);
game.start();
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
public void commandAction(Command c, Displayable d)
{
if (c.getCommandType() == Command.EXIT)
{
destroyApp(false);
this.notifyDestroyed();
}
}
}
class MyGameCanvas extends GameCanvas implements Runnable
{
private MyGame myGame;
private int spriteX = 0;
private int spriteY = 0;
private int blockWidth =14;
private int blockHeight =14;
private int gridWidth = 12;
private int gridHeight = 12;
public MyGameCanvas(MyGame g)
{
super(true);
this.myGame = g;
Command cmdExit = new Command("Exit",Command.EXIT,1);
this.setCommandListener(g);
this.addCommand(cmdExit);
}
public void run()
{
while (true)
{
try
{
Graphics g = getGraphics();
g.setColor(0x000000);
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(0xff0000);
int x = spriteX * blockWidth;
int y = spriteY * blockHeight;
g.fillRect(x,y,blockWidth,blockHeight);
int key = this.getKeyStates();
switch(key)
{
case GameCanvas.LEFT_PRESSED:
moveLeft();
break;
case GameCanvas.RIGHT_PRESSED:
moveRight();
break;
case GameCanvas.UP_PRESSED:
moveUp();
break;
case GameCanvas.DOWN_PRESSED:
moveDown();
break;
default:
break;
}
this.flushGraphics();
Thread.sleep(200);
Thread.yield();
}
catch(InterruptedException e)
{
}
}
}
public void moveLeft()
{
if (spriteX >0)
{
spriteX--;
}
}
public void moveRight()
{
if (spriteX < gridWidth -1)
{
spriteX++;
}
}
public void moveUp()
{
if (spriteY >0)
{
spriteY--;
}
}
public void moveDown()
{
if (spriteY <gridHeight -1)
{
spriteY++;
}
}
}
Top
6 楼fox1999(红狐)回复于 2005-08-04 09:11:50 得分 0
书上抄的?结构完全是教学用的嘛,商业化还是不行的!不过楼主学习精神可佳!:P
建议:1.构造函数里最好不要初始化参数(除非参数全局使用,直到退出游戏才结束)
2.gameLoop里功能多,不要集中写在一个函数里,要分开写,一个功能就是一个方法.
3.MIDlet里没有构造函数?
好象其他的上面的同志都说到了!
反正慢慢来吧,工作学习中总结的!
--------------------------
不瞒你说,我还没有找到过像样的书呢?我是下了一个 J2MEAPI.chm ,昨天看了看,就自己写了个程序想测试一下。
结构问题,是个大问题,现在我还没看到过什么例子。我也想看看别人的好的结构。谁能给我几个例子看看。大家共享一下吧。Top
7 楼jeal_zhang(jeal)回复于 2005-08-04 10:24:23 得分 0
大家看一下我的代码,多多批评:
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;
public class helloWorld extends MIDlet implements CommandListener
{
private Command exitCommand;
public helloWorld()
{
exitCommand=new Command("Exit",Command.EXIT,1);
}
public void startApp()
{
MyGameCanvas c = new MyGameCanvas();
c.addCommand(exitCommand);
c.setCommandListener(this);
Display.getDisplay(this).setCurrent(c);
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
public void commandAction(Command c, Displayable d)
{
if (c.getCommandType() == Command.EXIT)
{
destroyApp(false);
this.notifyDestroyed();
}
}
}
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
class MyGameCanvas extends GameCanvas implements Runnable
{
private int dx = 0;
private int dy = 0;
private int blockWidth =14;
private int blockHeight =14;
private int screenWidth;
private int screenHeight;
Graphics g;
public MyGameCanvas()
{
super(true);
g = getGraphics();
screenWidth=getWidth();
screenHeight=getHeight();
dx=screenWidth/2-blockWidth/2;
dy=screenHeight/2-blockHeight/2;
draw(g);
new Thread(this).start();
}
private void draw(Graphics g)
{
g.setColor(0x000000);
g.fillRect(0,0,screenWidth,screenHeight);
g.setColor(0xff0000);
g.fillRect(dx,dy,blockWidth,blockHeight);
flushGraphics();
}
private void keyPressed()
{
int key =getKeyStates();
if((key&UP_PRESSED)!=0)
{
if(dy-2>0)
dy-=2;
else
dy=screenHeight;
}
if((key&DOWN_PRESSED)!=0)
{
if(dy+2<screenHeight)
dy+=2;
else
dy=0;
}
if((key&LEFT_PRESSED)!=0)
{
if(dx-2>0)
dx-=2;
else
dx=screenWidth;
}
if((key&RIGHT_PRESSED)!=0)
{
if(dx+2<screenWidth)
dx+=2;
else
dx=0;
}
}
public void run()
{
while (true)
{
keyPressed();
draw(g);
try
{
Thread.sleep(20);
}
catch(InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}Top
8 楼murphy008(菩提老祖)回复于 2005-08-04 14:24:34 得分 0
哇,楼主真的厉害哦,光看J2MEAPI.chm这个就能写成这样了,不错不错!
楼主是哪里人?北京这里关于J2ME的书已经很多了,BREW的书好的就一本,偶已经抢到手!:)Top
9 楼murphy008(菩提老祖)回复于 2005-08-04 14:28:36 得分 0
"关于按键问题 gameLoop 中如果检测 LEFT_PRESSED,RIGHT_PRESSED 的话,那方格会,一下子就移到了最左边或最右边,(现在我的程序是改成按键弹起后才移动的,不过现在速度就慢太多了。要很久才能反映过来)"-------------------在你的gameLoop中加Thread.sleep(200);这样你的gameLoop()就和run()方法差不多了,不过~~~~还是建议不要这样用的好!
建议楼主从MIDP1.0开始学起吧,要透彻的研究!再去弄2.0就好多了!
Top
10 楼fox1999(红狐)回复于 2005-08-04 15:20:06 得分 0
现在我好多事情,感情上也出现些问题。忙呀
那个问题我也知道原因的,因为检测 LEFT_PRESSED ,是检测它是否已按下。我在循环中,因为循环太快,所以 方格就是一下子移动到底了,
而加入 Thread.sleep(200); 是让线程停 200ms .问题是没有
我还想到一个方法:就是检测是否刚被按下 如同 KeyDown 事件。Top
11 楼mingwang(冥王)回复于 2005-08-04 16:42:13 得分 0
public void startApp() {
MyGameCanvas c = new MyGameCanvas(this);
楼主,提醒一句,在startApp不要new对象,因为在游戏中如果有来电,那游戏将会挂起,然后返回的时候是从再执行startApp里的,你自己可以想一下,每次挂起再回来你都会创建一个新的canvas。。。。。。Top
12 楼fox1999(红狐)回复于 2005-08-09 09:56:53 得分 0
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
import java.util.Vector;
import java.util.Random;
import java.util.Date;
import java.lang.*;
/**
* Main Class or MIDlet (MIDP 1.0)
* debug by WTK2.1
*/
public class SnakeMain extends MIDlet implements CommandListener {
private Command cmdExit = new Command("Exit",Command.EXIT,1);
private SnakeCanvas theGame = null;
public SnakeMain() {
theGame = new SnakeCanvas();
theGame.addCommand(cmdExit);
theGame.setCommandListener(this);
}
protected void startApp() {
Display.getDisplay(this).setCurrent(theGame);
try {
Thread thread = new Thread(theGame);
thread.start();
}
catch(Exception e) {
}
}
protected void pauseApp() {
}
protected void destroyApp(boolean unconditional) {
Display.getDisplay(this).setCurrent((Displayable) null);
theGame.exitGame();
}
public void commandAction(Command c, Displayable d) {
if (c.getCommandType() == Command.EXIT) {
this.destroyApp(true);
this.notifyDestroyed();
}
}
}
/**
* the main Canvas or Game
*/
class SnakeCanvas extends Canvas implements Runnable {
private boolean ExitGame = false;
private boolean GameOver = false;
private int CanvasWidth = 0;
private int CanvasHeight = 0;
private int MapWidth = 0;
private int MapHeight = 0;
private int CellWidth = 6;
private int CellHeight = 6;
private int GenFoodSeq = 0;
//private int spriteX = 0;
//private int spriteY = 0;
private int[][] Maps = null;
private Snake snake = null;
public SnakeCanvas() {
super();
CanvasWidth = getWidth();
CanvasHeight = getHeight();
MapWidth = CanvasWidth / CellWidth;
MapHeight = CanvasHeight / CellHeight;
Maps = new int [MapWidth][MapHeight];
clearMaps();
snake = new Snake(CellWidth,CellHeight);
}
protected void clearMaps() {
for (int i = 0; i<MapWidth; i++)
for (int j = 0; j<MapHeight; j++) {
Maps[i][j] = 0;
}
}
protected void paint(Graphics g) {
drawMap(g);
snake.paint(g);
}
protected void drawMap(Graphics g) {
g.setColor(0x000000);
g.fillRect(0,0,CanvasWidth,CanvasHeight);
for (int i = 0; i<MapWidth; i++) {
for (int j = 0; j<MapHeight; j++) {
if (Maps[i][j] != 0) {
int x = i * CellWidth;
int y = j * CellHeight;
g.setColor(0x00ff00);
g.fillRect(x,y,CellWidth,CellHeight);
}
}
}
}
public void exitGame() {
ExitGame = true;
}
public void keyPressed(int keyCode) {
switch(this.getGameAction(keyCode)){
case Canvas.UP:
moveUp();
break;
case Canvas.DOWN:
moveDown();
break;
case Canvas.LEFT:
moveLeft();
break;
case Canvas.RIGHT:
moveRight();
break;
case 0:
switch(keyCode) {
case Canvas.KEY_NUM2:
moveUp();
break;
case Canvas.KEY_NUM8:
moveDown();
break;
case Canvas.KEY_NUM4:
moveLeft();
break;
case Canvas.KEY_NUM6:
moveRight();
break;
default :
break;
}
break;
}
}
public void moveUp() {
snake.setDirection(Snake.UP);
}
public void moveDown() {
snake.setDirection(Snake.DOWN);
}
public void moveLeft() {
snake.setDirection(Snake.LEFT);
}
public void moveRight() {
snake.setDirection(Snake.RIGHT);
}
public void generantFood() {
GenFoodSeq++;
if (GenFoodSeq > 10) {
GenFoodSeq = 0;
Random rand = new Random(new Date().getTime());
int x = rand.nextInt();
int y = rand.nextInt();
x = Math.abs( x % MapWidth);
y = Math.abs( y % MapHeight);
//System.out.println("x = "+x +"; y = "+y);
if (!snake.ptInSnake(x,y)) {
if (Maps[x][y] == 0) {
Maps[x][y] = 1;
}
}
}
}
public void eatFood() {
SnakeNode node = snake.getHead();
if (Maps[node.X][node.Y] != 0) {
Maps[node.X][node.Y] = 0;
snake.addNode();
}
}
public void run() {
repaint();
while ((! ExitGame) && (! GameOver)) {
snake.move();
SnakeNode node = snake.getHead();
if ((node.X<0) || (node.X>MapWidth-1) || (node.Y<0) || (node.Y>MapHeight-1) ) {
GameOver = true;
continue;
}
if (snake.test()) {
GameOver = true;
continue;
}
generantFood();
eatFood();
repaint();
try {
Thread.sleep(200);
Thread.yield();
}
catch(Exception e) {
}
}
}
}
Top
13 楼fox1999(红狐)回复于 2005-08-09 09:57:13 得分 0
/**
* class snake node
*/
class SnakeNode {
public int X = 0;
public int Y = 0;
public SnakeNode(int x,int y) {
super();
this.X = x;
this.Y = y;
}
public boolean equals(SnakeNode obj) {
return ((this.X == obj.X) && (this.Y == obj.Y));
}
}
class Snake {
public final static int UP = 2;
public final static int DOWN = 8;
public final static int LEFT = 4;
public final static int RIGHT = 6;
private Vector snakeData = null;
private int cellWidth = 0;
private int cellHeight= 0;
private int direction;
private int newdir;
private boolean moved = false;
public Snake(int cellwidth,int cellheight) {
super();
cellWidth = cellwidth;
cellHeight = cellheight;
snakeData = new Vector();
SnakeNode node = new SnakeNode(4,0);
snakeData.addElement(node);
node = new SnakeNode(3,0);
snakeData.addElement(node);
node = new SnakeNode(2,0);
snakeData.addElement(node);
node = new SnakeNode(1,0);
snakeData.addElement(node);
node = new SnakeNode(0,0);
snakeData.addElement(node);
setDirection(Snake.RIGHT);
}
public int getDirection() {
return direction;
}
public void setDirection(int dir) {
if (testDirection(direction ,dir)) {
direction = dir;
}
}
public boolean testDirection(int dir1,int dir2) {
if ((dir1 == Snake.UP) && (dir2 == Snake.DOWN)) {
return false;
}
else if ((dir1 == Snake.DOWN) && (dir2 == Snake.UP)) {
return false;
}
else if ((dir1 == Snake.LEFT) && (dir2 == Snake.RIGHT)) {
return false;
}
else if ((dir1 == Snake.RIGHT)&&(dir2 == Snake.LEFT)) {
return false;
}
else {
return true;
}
}
public SnakeNode getHead() {
return (SnakeNode) snakeData.elementAt(0);
}
public SnakeNode getNextHead() {
SnakeNode node = (SnakeNode) snakeData.elementAt(0);
node = new SnakeNode(node.X,node.Y);
switch(this.direction) {
case Snake.UP:
node.Y--;
break;
case Snake.DOWN:
node.Y++;
break;
case Snake.LEFT:
node.X--;
break;
case Snake.RIGHT:
node.X++;
break;
}
return node;
}
public void move() {
SnakeNode node = (SnakeNode)snakeData.elementAt(0);
SnakeNode newNode = this.getNextHead();
for (int i =snakeData.size()-1 ; i>0; i--) {
SnakeNode node1 = (SnakeNode) snakeData.elementAt(i);
SnakeNode node2 = (SnakeNode) snakeData.elementAt(i-1);
node1.X = node2.X;
node1.Y = node2.Y;
}
node.X = newNode.X;
node.Y = newNode.Y;
moved = true;
}
public void addNode() {
SnakeNode node = (SnakeNode) snakeData.lastElement();
SnakeNode newNode = new SnakeNode(node.X,node.Y);
snakeData.addElement(newNode);
}
public boolean test() {
SnakeNode head = this.getHead();
for (int i = 1; i<snakeData.size(); i++) {
SnakeNode node = (SnakeNode) snakeData.elementAt(i);
if (head.equals(node)) {
return true;
}
}
return false;
}
public boolean ptInSnake(int px,int py) {
SnakeNode node;
for (int i = 0; i<snakeData.size(); i++) {
node = (SnakeNode) snakeData.elementAt(i);
if ((node.X == px)&&(node.Y == py)) {
return true;
}
}
return false;
}
public void paint(Graphics g) {
int SnakeColor= 0xff0000;
for (int i = 0; i<snakeData.size(); i++) {
SnakeNode node = (SnakeNode) snakeData.elementAt(i);
g.setColor(SnakeColor);
g.fillRect(node.X * cellWidth,node.Y * cellHeight,cellWidth,cellHeight);
}
}
}
Top
14 楼fox1999(红狐)回复于 2005-08-09 09:57:56 得分 0
我重新写过了, MIDP1.0 的,贪吃蛇Top




