51testing 发表于 2007-11-16 17:28:07

J2me MIDlet 手机游戏入门开发:贪吃蛇

这个游戏有一个类,用来显示动画,也是蛇要吃的物品类,也有了代码包,图片包,结构清晰,代码量500行,地图生成的简单算法,和播放动画的简单算法!有矩形碰撞,升级就是增加蛇的移动速度,简单做法就是把刷新速度提高了,每次刷新蛇要移动一个格子,出现的物品有的是增加蛇长度的,有的是减少蛇长度的。

  本文给出的是程序代码,需要图片才能编译程序,工程文件已经打包上传到csdn,地址如下:download.csdn.net/user/kome2000/

Gif.java 这个类是绘制动画的类,也是蛇的食物类

package code;

import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;

public class Gif
...{
public String name = "gif";
public int life = 1;
public int pos_x = 0;
public int pos_y = 0;
public int w = 10;
public int h = 10;
public int form = 1;

private int allTime;
private int currForm;
private long startTime;

public boolean isShow=true;
public int[] formTime=...{100};

private Image[] img;

public Gif( String _name, int _form, int _w, int _h )
...{
w = _w;
h = _h;
setGif( _name, _form );
startTime = System.currentTimeMillis();
setPos();
}

public void setGif( String _name, int _form )
...{
try
...{
name = _name;
form = _form;
formTime= new int;
img = new Image;

for( int i=0; i<form; i++ )
...{
formTime = 100;
allTime += formTime;
img = Image.createImage("/pics/"+name+"_"+i+".png");
}

// Image temp = Image.createImage("/pics/"+name+".png");
// form = temp.getWidth()/w;
// formTime = new int;
// img = new Image;
// Graphics gn;
// for( int i=0; i<img.length; i++ )
// {
// formTime = 100;
// allTime +=formTime;
// img = Image.createImage(w, h);
// gn = img.getGraphics();
// gn.drawImage(temp, -i*w, 0, gn.LEFT|gn.TOP);
// }
// gn = null;
// temp = null;
// System.gc();

}catch(Exception e)...{ e.printStackTrace(); }
}

public void setPos()
...{
pos_x = cGame.rand.nextInt(cGame.s_width-w) + ( w>>1 );
pos_y = cGame.rand.nextInt(cGame.s_height-h) + ( h>>1 );
startTime = System.currentTimeMillis();
}

public void setFormTime(int[] _formTime)
...{
formTime = _formTime;
allTime = 0;
for( int i=0; i<formTime.length; i++ )
...{
allTime +=formTime;
}
startTime = System.currentTimeMillis();
}

public void paint(Graphics g)
...{
if( isShow )
...{
long now = System.currentTimeMillis();
long time= (now-startTime)%allTime;
for(int i=0; i<form; i++)
...{
time -= formTime;
if( time<=0 )
...{
g.drawImage(img, pos_x, pos_y, g.HCENTER|g.VCENTER);
break;
}
}
}
}
}



cGame.java 这个类已经不陌生了, 作用功能和上一个游戏雷同////////////////////////////////////////////////////////////////////////////////
//
// cGame.java
//
// Project: Minesweeper
// Author(s): Gao Lei
// Create: 2007-10-12
////////////////////////////////////////////////////////////////////////////////
package code;

import java.util.Random;
import javax.microedition.lcdui.*;

////////////////////////////////////////////////////////////////////////////////

class cGame extends Canvas implements Runnable
...{
private static final int STATEPLAY = 0;
private static final int STATELOST = 1;
private static final int STATEWIN = 2;

private static final int KEY_UP = 1;
private static final int KEY_DOWN = 2;
private static final int KEY_LEFT = 3;
private static final int KEY_RIGHT = 4;
private static final int KEY_FIRE = 5;

public static int s_width = 0;
public static int s_height = 0;
public static long updates = 0;
public static Random rand;

private int maxRand = 1000;
private int map_x = 10;
private int map_y = 10;
private int map_w = 16;
private int map_h = 16;


private int key_x = map_x / 2;
private int key_y = map_y / 2;
private int snake_w = 8;
private int snake_h = 8;
private int pos_x = map_x / 2;
private int pos_y = map_y / 2;
private int aspect_x= 0;
private int aspect_y= 1;
private int snake_max = 100;
private int snake_n = 5;
private int gameState = STATEPLAY;
private int level = 1;
private long sleepTime =160;

private int[] snake_x = new int[ snake_max ];
private int[] snake_y = new int[ snake_max ];

private int[][] map;
private boolean isShowInfo = false;

private Font font = Font.getFont( Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE );
private Thread thread;
private Image[] imgGameBg = new Image;
private Image[] imgItem = new Image;
private Gif[] gold = new Gif;
private Gif[] dung = new Gif;
private Gif fungus;

cGame()
...{
setFullScreenMode(true);
s_width = getWidth();
s_height= getHeight();
rand = new Random( System.currentTimeMillis() );
try
...{
for( int i=0; i<gold.length; i++ )
...{
gold= new Gif("gold", 5, 19, 15 );
}
for( int i=0; i<dung.length; i++ )
...{
dung= new Gif("dung", 6, 21, 30 );
dung.life = -2; // --life
}

fungus = new Gif("fungus", 12, 25, 23 );
fungus.setFormTime
(
new int[] ...{ 2000, 150, 150, 150,
150, 200, 100, 100,
200, 150, 200, 200
}
);
fungus.life = 5; // --life +5

for( int i=0; i<imgItem.length; i++ )
...{
imgItem=Image.createImage("/pics/item_16_"+i+".png");
}

Image temp = Image.createImage("/pics/bg_tile_0.png");
Graphics gn;
for( int i=0; i<imgGameBg.length; i++ )
...{
imgGameBg = Image.createImage(16, 16);
gn = imgGameBg.getGraphics();
gn.drawImage(temp, -i*16, 0, gn.LEFT|gn.TOP);
}
gn = null;
temp = null;
System.gc();
}catch(Exception e)...{ e.printStackTrace(); }

rePlay( level );
thread = new Thread(this);
thread.start();
}

public void run()
...{
while( true )
...{
try
...{
updates++;
repaint();
serviceRepaints();
thread.sleep(sleepTime);
}catch(Exception e)
...{
e.printStackTrace();
}
}
}


public void paint(Graphics g)
...{
g.setClip(0, 0, s_width, s_height);
g.setColor(0x000000);
g.fillRect(0, 0, s_width, s_height);

for( int i=0; i<map_x; i++ )
...{
for( int j=0; j<map_y; j++ )
...{
g.drawImage(imgGameBg[ map ], j*map_h, i*map_w, g.LEFT|g.TOP);
}
}

for( int i=0; i<gold.length; i++ )
...{
gold.paint(g);
}
for( int i=0; i<dung.length; i++ )
...{
dung.paint(g);
}
if( snake_n>20 )
fungus.paint( g );

paintSnake( g );

if( isShowInfo || gameState != STATEPLAY )
...{
g.setColor(0xFFFFFF);
for( int i=0; i<=map_y; i++ ) // |||
...{
g.drawLine(i*map_w, 0, i*map_w, map_h*map_x);
}
for( int i=0; i<=map_x; i++ ) // ===
...{
g.drawLine(0, i*map_h, map_y*map_w, i*map_h);
}
g.setFont( font );
}
g.setColor( 0xff0000 );
g.setFont( font );
g.drawString( "life:"+snake_n, 2, 2, 0 );
g.drawString( "level:"+level, 2, 18, 0 );
}


void paintSnake( Graphics g )
...{
g.setColor(0x0000FF);
for( int i=snake_n; i>0; i-- )
...{
snake_x = snake_x;
snake_y = snake_y;
g.fillRect(snake_x-snake_w/2, snake_y-snake_h/2, snake_w, snake_h);
}
snake_x += aspect_x*8;
snake_y += aspect_y*8;
g.setColor(0x6666FF);
g.fillRect(snake_x-snake_w/2, snake_y-snake_h/2, snake_w, snake_h);

if( snake_x<0 || snake_x>s_width || snake_y<0 ||snake_y>s_height )
...{
rePlay(level);
}

for( int i=snake_n; i<snake_n; i++ )
...{
if( isIntersect(snake_x, snake_y, snake_w, snake_h,
snake_x, snake_y, snake_w, snake_h )
)
...{
rePlay(level);
}

}

for( int i=0; i<gold.length; i++ )
...{
if( isIntersect(snake_x, snake_y, snake_w, snake_h,
gold.pos_x, gold.pos_y, gold.w, gold.h )
)
...{
addSnake( gold.life );
gold.setPos();
}
}
for( int i=0; i<dung.length; i++ )
...{
if( isIntersect(snake_x, snake_y, snake_w, snake_h,
dung.pos_x, dung.pos_y, dung.w, dung.h )
)
...{
addSnake( dung.life );
dung.setPos();
}
}

if( isIntersect(snake_x, snake_y, snake_w, snake_h,
fungus.pos_x, fungus.pos_y, fungus.w, fungus.h )
)
...{
addSnake( fungus.life );
// fungus.isShow =false;
fungus.setPos();
}

}

boolean isIntersect(int x1,int y1, int w1, int h1, int x2, int y2, int w2, int h2)
...{
if( Math.abs(x2-x1) < (w1+w2)/2 && Math.abs(y2-y1) < (h1+h2)/2 )
...{
return true;
}
else
return false;
}

public void keyPressed(int key)
...{
key = Math.abs(key);
System.out.println("key="+key);

switch( key )
...{
case KEY_NUM2:
case KEY_UP:
if( gameState != STATEPLAY )
break;
else
...{
if( aspect_y <= 0)
...{
aspect_x = 0;
aspect_y = -1;
}
}
break;

case KEY_NUM8:
case KEY_DOWN:
if( gameState != STATEPLAY )
break;
else
...{
if( aspect_y >= 0)
...{
aspect_x = 0;
aspect_y = +1;
}
}
break;

case KEY_NUM4:
case KEY_LEFT:
if( gameState != STATEPLAY )
break;
else
...{
if( aspect_x <= 0)
...{
aspect_y = 0;
aspect_x = -1;
}
}
break;

case KEY_NUM6:
case KEY_RIGHT:
if( gameState != STATEPLAY )
break;
else
...{
if( aspect_x >= 0)
...{
aspect_y = 0;
aspect_x = +1;
}
}
break;

case KEY_FIRE:
case KEY_NUM5:
if( gameState == STATEPLAY )
...{
// addSnake();
// System.out.println("snake_n="+snake_n);
}
break;

case KEY_NUM1:

break;
case KEY_NUM3:
isShowInfo = !isShowInfo;
break;
case KEY_NUM0:
rePlay( level );
break;
}
this.repaint();
}

private void addSnake(int life)
...{
snake_n += life;
if( snake_n > snake_max )
...{
snake_n = snake_max;
level++;
rePlay(level);
}
if( snake_n < snake_n ) //game over
...{
rePlay(level);
snake_n = snake_n;
}
}

public void rePlay( int level )
...{
sleepTime = 150-level*20;
map_x = s_height/16;
map_y = s_width/16;
key_x = map_x>>1;
key_y = map_y>>1;
gameState = STATEPLAY;
map = new int;
isShowInfo = false;
snake_n = 5;
aspect_x = 0;
aspect_y = 0;
for( int i=0; i<map_x; i++ ) //draw bg
...{
for( int j=0; j<map_y; j++ )
...{
int r = rand.nextInt(maxRand);
for( int k=0; k<imgGameBg.length; k++ )
...{
if( r < maxRand>>k+1 )
...{
map = k;
}
}
}
}

for( int i=0; i<snake_n; i++ ) //init snake
...{
snake_x = s_width>>1;
snake_y = (s_height>>1)-(i*snake_h);
}
}
}



Snake.java这个类是之前的 Minesweeper.java这个类 基本上就该个名字,其他什么都不用改!



///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Snake.java
//
// Project: Snake
// Author(s): Gao Lei
// Create: 2007-10-08
///////////////////////////////////////////////////////////////////////////////////////////////////
package code;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

///////////////////////////////////////////////////////////////////////////////////////////////////

public class Snake extends MIDlet
...{
static Snake s_midlet;
static Display s_display = null;
static cGame s_game = null;

public Snake()
...{
s_midlet = this;
}

public void startApp()
...{
if (s_display == null)
...{
s_display = Display.getDisplay(this);
}

if (s_game == null)
...{
s_game = new cGame();
s_display.setCurrent(s_game);
}
else
...{
s_display.setCurrent(s_game);
}
}

public void pauseApp()
...{

}

public void destroyApp(boolean unconditional)
...{
notifyDestroyed();
}
}

  这次代码上的注释比较少的原因是我的IDE不支持中文输入!所以即便是加注释也是英文的!就没加了大多数函数方法和上个游戏没多大变化!
页: [1]
查看完整版本: J2me MIDlet 手机游戏入门开发:贪吃蛇