公司准備做手機游戲方面的項目,第一次做DOJA相關的項目,練習了“貪吃蛇”這個游戲,現把自己做的源代碼發布出來,希望給才接觸DOJA的新手一點提示和幫助。也歡迎大家提出改正。
//主運行類
package greedSnake;
import com.nttdocomo.ui.Display;
import com.nttdocomo.ui.IApplication;
public class GreedSnake extends IApplication implements Runnable{
public static final int GRID_WIDTH = 20;
public static final int GRID_HEIGHT = 24;
public static final int NODE_SIZE = 10;
private Grid grid = null;
private Food food = null;
private Snake snake = new Snake();;
private boolean running;
private int score;
private int level;
private int count;
private int countMove;
private int timeInterval;
//----------------------------------------
/** Set up game. */
public void start() {
reset();
grid = new Grid(GRID_WIDTH, GRID_HEIGHT, this);
Display.setCurrent(grid);
Thread runner = new Thread(this);
runner.start();
}
private void reset() {
running = false;
score = 0;
level = 0;
count = 0;
countMove = 6;
timeInterval = 200;
}
/** Runnable interface. */
public void run() {
food=grid.addFood();
grid.addSnake(snake);
grid.repaint();
for(;;) {
if (food == null) {
food=grid.addFood();
continue;
}
try {
Thread.sleep(timeInterval);
} catch (Exception e) {
break;
}
if (!running) {
snake.move();
Node head = snake.getHead();
if (grid.overlapsWith(head)||(snake.ptInSnake(head))){
running = true;
continue;
}
if((head.x==food.getX())&&(head.y==food.getY())){
int scoreGet=(10000-200*countMove)/timeInterval;
score+=scoreGet>0 ? scoreGet : 0;
countMove=0;
snake.eatFood(food);
grid.reduceFood(food);
food=null;
if( ++count%5 == 0){
level++;
}
}else{
countMove++;
}
grid.repaint();
}else{
grid.setGameOver();
break;
}
}
grid.repaint();
}
public int getScore() {
return score;
}
/** Get the current level of the game. */
public int getLevel() {
return level;
}
/** Key event handler. */
public void keyPressed(int key) {
if (key == Display.KEY_SELECT) {
grid.setGameOver();
}
if (key == Display.KEY_LEFT) {
snake.setDirection(Snake.LEFT);
}
if (key == Display.KEY_RIGHT) {
snake.setDirection(Snake.RIGHT);
}
if (key == Display.KEY_DOWN) {
snake.setDirection(Snake.DOWN);
}
if (key == Display.KEY_UP) {
snake.setDirection(Snake.UP);
}
}
}
//畫面框架類
package greedSnake;
import com.nttdocomo.ui.Canvas;
import com.nttdocomo.ui.Display;
import com.nttdocomo.ui.Font;
import com.nttdocomo.ui.Frame;
import com.nttdocomo.ui.Graphics;
//---------------------
/**
* This class represents the grid box that catches
* the pieces dropping from above. If a dropped piece
* fills up one or more horizontal lines in the grid,
* these lines will be removed from it.
*/
public class Grid extends Canvas {
private int width;
private int height;
private GreedSnake listener;
private Snake snake;
private Food food;
private String pad = "0000";
private Font score_font;
private Font game_over_font;
private boolean blDisplay;
private boolean game_over;
static final int SOFT_LEFT = Frame.SOFT_KEY_1;
static final int SOFT_RIGHT = Frame.SOFT_KEY_2;
/**
* Create a new instance of this class.
* @param witdth the width (in tiles) of this grid
* @param height the height (in tiles) of this grid
* @param score the score object to keep track of the score
* @param listener a reference to the owning tetris object
*/
public Grid(int width, int height, GreedSnake listener) {
this.width = width;
this.height = height;
this.listener = listener;
reset();
setSoftLabel(SOFT_LEFT, "New");
setSoftLabel(SOFT_RIGHT, "Quit");
score_font = Font.getFont(Font.FACE_MONOSPACE | Font.SIZE_SMALL);
game_over_font = Font.getFont(Font.FACE_PROPORTIONAL | Font.SIZE_LARGE | Font.STYLE_BOLD);
}
/** Remove all pieces from this instance */
private void reset() {
synchronized (this) {
food = null;
snake= null;
}
game_over = false;
blDisplay = false;
}
public void setGameOver() {
snake = null;
food = null;
game_over = true;
}
/** Get the width (in tiles) of this instance. */
public int getGridWidth() {
return width;
}
/** Get the height (in tiles) of this instance. */
public int getGridHeight() {
return height;
}
/** Add the specified piece to this instance. */
public Food addFood() {
blDisplay= false;
int gs = GreedSnake.GRID_WIDTH;
if(snake == null){
this.food =Food.createRandomFood(gs,gs);
}else{
for(;;){
this.food =Food.createRandomFood(gs,gs);
Node newNode = new Node(food.getX(),food.getY());
if(snake.ptInSnake(newNode)){
this.food = null;
continue;
}else{
break;
}
}
}
return this.food;
}
public void addSnake(Snake snake) {
this.snake=snake;
Node head=(Node)snake.getHead();
}
/**
* Returns <code>true</code> if the specified
* piece overlaps with any tile in this instance,
* <code>false</code> otherwise.
*/
public boolean overlapsWith(Node node) {
if ((node.x<0) || (node.x>getGridWidth()-1)
|| (node.y<0) || (node.y>getGridHeight()-1)) {
return true;
}
return false;
}
public void reduceFood(Food food) {
blDisplay = true;
}
private String format(int n) {
String raw = "" + n;
return pad.substring(0, 4 - raw.length()) + raw;
}
/** Paint this instance onto the specified graphics context. */
public synchronized void paint(Graphics g) {
g.lock();
g.setColor(Graphics.getColorOfName(Graphics.BLACK));
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Graphics.getColorOfName(Graphics.WHITE));
g.drawLine(0, 0, 0, getHeight());
g.drawLine(201, 0, 201, getHeight());
g.drawLine(0, getHeight(), 201, getHeight());
if ((food != null)&& (!blDisplay)) {
food.paint(g);
}
if (snake != null) {
snake.paint(g);
}
g.setColor(Graphics.getColorOfName(Graphics.SILVER));
g.setFont(score_font);
g.drawString("LEVEL", 203, 40);
g.drawString(String.valueOf(listener.getLevel()), 220, 70);
g.drawString("SCORE", 202, 100);
g.drawString(format(listener.getScore()), 208, 130);
if (game_over) {
g.setColor(0x00ffff);
g.setFont(game_over_font);
g.drawString("GAME", 70, 110);
g.drawString("OVER", 70, 140);
}
g.unlock(true);
}
/** Process key events. */
public void processEvent(int type, int param) {
if (type == Display.KEY_PRESSED_EVENT) {
listener.keyPressed(param);
}
}
}
//蛇對象類
package greedSnake;
import java.util.Random;
import java.util.Vector;
import java.util.Enumeration;
import com.nttdocomo.ui.Graphics;
public class Snake {
public final static int UP = 1;
public final static int DOWN = 3;
public final static int LEFT = 2;
public final static int RIGHT = 4;
private int direction;
// private Grid grid;
private Node node;
private Vector snakeData = null;
private static Random rnd= new Random();
/** Private internal constructor. */
public Snake() {
snakeData = new Vector();
Node node = new Node(4,0);
snakeData.addElement(node);
node = new Node(3,0);
snakeData.addElement(node);
node = new Node(2,0);
snakeData.addElement(node);
node = new Node(1,0);
snakeData.addElement(node);
node = new Node(0,0);
snakeData.addElement(node);
setDirection(Snake.DOWN);
}
public int getDirection() {
return direction;
}
public void setDirection(int dir) {
if(direction%2!=dir%2){
direction = dir;
}
}
public Node getHead() {
return (Node) snakeData.elementAt(0);
}
public Node getNextHead() {
Node node = (Node) snakeData.elementAt(0);
node = new Node(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() {
Node node= (Node)snakeData.elementAt(0);
Node newNode = this.getNextHead();
for (int i =snakeData.size()-1 ; i>0; i--) {
Node node1 = (Node) snakeData.elementAt(i);
Node node2 = (Node) snakeData.elementAt(i-1);
node1.x = node2.x;
node1.y = node2.y;
}
node.x = newNode.x;
node.y = newNode.y;
}
public void addNode() {
Node node = (Node) snakeData.lastElement();
Node newNode = new Node(node.x,node.y);
snakeData.addElement(newNode);
}
public void paint(Graphics g) {
int SnakeColor= 0xff0000;
int gn = GreedSnake.NODE_SIZE;
Enumeration e = snakeData.elements() ;
while(e.hasMoreElements()){
Node node = (Node)e.nextElement() ;
g.setColor(SnakeColor);
g.fillRect(node.x * gn, node.y * gn, gn, gn);
}
}
public void eatFood(Food food) {
this.addNode();
}
public boolean ptInSnake(Node node) {
for (int i = 1; i<snakeData.size(); i++) {
Node nodeInSnake = (Node) snakeData.elementAt(i);
if ((nodeInSnake.x == node.x)&&(nodeInSnake.y == node.y)) {
return true;
}
}
return false;
}
}
//食物對象類
package greedSnake;
import java.util.Random;
import com.nttdocomo.ui.Graphics;
public class Food {
private int x;
private int y;
private static Random rnd = new Random();
private Food(int x,int y) {
this.x = x;
this.y = y;
}
public static Food createRandomFood(int width,int height) {
return createFood( getRandomInt(width),getRandomInt(height));
}
private static int getRandomInt(int limit) {
return Math.abs(rnd.nextInt() % limit);
}
private static Food createFood(int x,int y) {
return new Food(x,y);
}
/**
* Get the x coordinate of the base
* location of this instance.
*/
public int getX() {
return x;
}
/**
* Get the y coordinate of the base
* location of this instance.
*/
public int getY() {
return y;
}
/** Paint this instance onto the specified Graphics context. */
public synchronized void paint(Graphics g) {
int gn = GreedSnake.NODE_SIZE;
int FoodColor= 0x0000ff;
g.setColor(FoodColor);
g.fillRect(this.getX()* gn,this.getY()* gn,gn,gn);
}
}
//節點對象類
/package greedSnake;
public class Node {
public int x;
public int y;
/** Create a new instance of this class. */
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}