www.pudn.com > HitBrick.rar > HitBrick.java
import javax.microedition.midlet.* ;
import javax.microedition.lcdui.* ;
import java.util.Random ;
//主类
public class HitBrick extends MIDlet
{
//成员变量 //////////////////////////////////////////////////////////////////
//主类
//主Display 对象及根据需要重载的canvas对象
private Display display ;
private MyCanvas canvas ;
//调试开关,置为true后可输出调试信息
private boolean debug ;
//主类
//成员变量 END////////////////////////////////////////////////////////////////
//成员函数 //////////////////////////////////////////////////////////////////
//主类
public HitBrick()
{
display = Display.getDisplay(this);
canvas = new MyCanvas(this) ;
}
protected void startApp()
{
display.setCurrent(canvas) ;
}
protected void pauseApp()
{
}
protected void destroyApp(boolean unconditional)
{
}
public void exitMIDlet()
{
destroyApp(true) ;
notifyDestroyed() ;
}
//主类
//成员函数 END////////////////////////////////////////////////////////////////
//嵌套类 //////////////////////////////////////////////////////////////////
//主类
//实用Canvas类包含图形控制及游戏逻辑
class MyCanvas extends Canvas implements CommandListener
{
//成员变量 //////////////////////////////////////////////////////////////////
//class MyCanvas
//界面中所用的命令
private Command exit ;
private Command start ;
//外层的主类的引用
private HitBrick hitBrick ;
//需绘制的对象列表
private NormalObject paintList[] ;
private int listCount = 0 ;
//砖块列表_1
private NormalObject Bricks_1[][] = new NormalObject[6][3] ;
//private NormalObject
//游戏中撞球和击球板的实例
private Ball ball ;
private Plate plate ;
//让砖块的多个实例共享的图像对象
private Image brick ;
private Image brick_1 ;
private Image loss ;
private Image win ;
//游戏区屏幕尺寸
private int width, height ;
//玩家积分及砖块计数,当前级别
private int mark, brickCount, layer ;
private int dieLine ;
private boolean getWin ;
//键盘按下标志
private boolean left, right, up, down, fire ;
//调试文本输出
private Ticker ticker ;
//随机数发生器
private RandomG randomG = new RandomG() ;
//class MyCanvas
//成员变量 END////////////////////////////////////////////////////////////////
//成员函数 //////////////////////////////////////////////////////////////////
//class MyCanvas
public MyCanvas(HitBrick hitBrick)
{
if(debug)
{
ticker = new Ticker(" ");
setTicker(ticker) ;
}
//引入主类的实例
this.hitBrick = hitBrick ;
//初始化玩家的分,及砖块计数
mark = 0 ;
brickCount = 3* 6 ;
layer = 0 ;
dieLine = 10;
//初始化命令并加载
exit = new Command("Exit", Command.EXIT, 1) ;
start = new Command("Start", Command.SCREEN, 2) ;
addCommand(exit) ;
addCommand(start) ;
setCommandListener(this) ;
//初始化游戏区屏幕尺寸
width = getWidth() ;
height = getHeight() - 15 ;
//初始化击球板及球
plate = new Plate("/pic/j6.png", 20, 100, 0.0f, 0.0f, false) ;
ball = new Ball("/pic/j5.png", width/2 - 40 + (randomG.nextG(10) % 80) , 3* 18,
( randomG.nextG(5) > 15 ? -1.5f : 1.5f), 1.5f, false) ;
//载入砖块图像
try
{
brick = Image.createImage("/pic/j8.png") ;
brick_1 = Image.createImage("/pic/j9.png") ;
loss = Image.createImage("/pic/j10.png") ;
win = Image.createImage("/pic/j11.png") ;
}
catch(Exception e)
{
}
//初始化每个砖块
for(int y = 0 ;y < 3 ;y++)
for(int x = 0 ;x < 6 ;x ++)
{
Bricks_1[x][y] = new Brick(x * 32 , 18 * y, 32, 18, 1 , 1, 0) ;
}
//将击球板定位到游戏区底部
plate.setPos( (width - plate.cx)/2, height - plate.cy) ;
//初始化移动对象的绘制列表
paintList = new NormalObject[10] ;
paintList[0] = ball ;
paintList[1] = plate ;
listCount = 2 ;
if(debug)
{
ticker.setString("width is " + width + "height is " + height) ;
}
}
protected void changeLevel(int level)
{
switch(level)
{
case 1:
//重置每个砖块
for(int y = 0 ;y < 3 ;y++)
for(int x = 0 ;x < 6 ;x ++)
{
if(y == 2)
((Brick)Bricks_1[x][y]).set(2 , 2, 1) ;
else
((Brick)Bricks_1[x][y]).set(1 , 1, 0) ;
}
brickCount = 18 ;
ball.x = (randomG.nextG(10) % 80) ;
ball.y = 3 * 18 ;
ball.vx = ( randomG.nextG(5) > 15 ? -1.5f : 1.5f) ;
ball.vy = 1.5f ;
break;
case 2:
//重置每个砖块
for(int y = 0 ;y < 3 ;y++)
for(int x = 0 ;x < 6 ;x ++)
{
((Brick)Bricks_1[x][y]).set(2 , 2, 1) ;
}
brickCount = 18 ;
ball.x = (randomG.nextG(10) % 80) ;
ball.y = 3 * 18 ;
ball.vx = ( randomG.nextG(5) > 15 ? -1.5f : 1.5f) ;
ball.vy = 1.5f ;
break;
}
}
protected void paint(Graphics g)
{
if(dieLine <= 0)
{
g.drawImage(loss, 0,0, Graphics.TOP | Graphics.LEFT) ;
return ;
}
if(getWin)
{
g.drawImage(win, 0,0, Graphics.TOP | Graphics.LEFT) ;
return ;
}
//清屏
g.setColor(255,255,255) ;
g.fillRect(0,0,getWidth(), getHeight()) ;
//按移动物体表依次绘制
for(int index = 0 ; index < listCount ; index ++)
{
paintList[index].paint(g) ;
}
//绘制砖块
for(int y = 0 ;y < 3 ;y++)
for(int x = 0 ;x < 6 ;x ++)
{
if(((Brick)Bricks_1[x][y]).pictureNum == 0)
Bricks_1[x][y].paint(g, brick, Bricks_1[x][y].strong > 0) ;
else if(((Brick)Bricks_1[x][y]).pictureNum == 1)
Bricks_1[x][y].paint(g, brick_1, Bricks_1[x][y].strong > 0) ;
}
//在信息输出栏输出游戏信息
g.setColor(255,0,0) ;
g.drawString("M: " + mark, 5, height + 1, Graphics.LEFT | Graphics.TOP) ;
g.drawString("Your lives: " + dieLine, width, height + 1, Graphics.RIGHT | Graphics.TOP) ;
if(brickCount <= 0)
{
g.drawString("Game Over", width, height + 1, Graphics.RIGHT | Graphics.TOP) ;
}
//划分出信息输出栏
g.drawLine(0,getHeight() - 15,getWidth(), getHeight() - 15) ;
}
public void commandAction(Command command, Displayable displayable)
{
if(command == exit)
{
hitBrick.exitMIDlet() ;
}
else if(command == start)
{
new Thread(new ImageMover()).start() ;
removeCommand(start) ;
}
}
//键按下事件函数,设置各按下键标志
protected void keyPressed(int _key)
{
switch(getGameAction(_key))
{
case Canvas.UP:
up = true ;
break ;
case Canvas.DOWN:
down = true ;
break ;
case Canvas.LEFT:
left = true ;
break ;
case Canvas.RIGHT:
right = true ;
break ;
case Canvas.FIRE:
fire = true ;
break ;
}
}
//键释放事件函数,设置各释放键标志
protected void keyReleased(int _key)
{
switch(getGameAction(_key))
{
case Canvas.UP:
up = false ;
break ;
case Canvas.DOWN:
down = false ;
break ;
case Canvas.LEFT:
left = false ;
break ;
case Canvas.RIGHT:
right = false ;
break ;
case Canvas.FIRE:
fire = false ;
break ;
}
}
//class MyCanvas
//成员函数 END///////////////////////////////////////////////////////////////
//嵌套类 //////////////////////////////////////////////////////////////////
//class MyCanvas
//撞球类,由MoveObject派生
class Ball extends MoveObject
{
//成员变量 //////////////////////////////////////////////////////////////////
//class Ball
//球的旋转标志
private float right_r, left_r ;
private float acc_r = 0.5f ;
//球的碰撞标志
private boolean collisioned ;
//class Ball
//成员变量 END////////////////////////////////////////////////////////////////
//成员函数 //////////////////////////////////////////////////////////////////
//class Ball
public Ball(String path, int x, int y, float vx, float vy, boolean special)
{
super(path, x, y, vx, vy, special) ;
}
//计算并移动球
public void move()
{
//根据参数计算速度值
getV() ;
//运动约束
moveLimit() ;
//产生位移
if((vx - (int)vx) > 0.5f)
x += ((int) vx + 1);
else
x += (int)vx ;
if((vy - (int)vy) > 0.5f)
y += ((int)vy + 1) ;
else
y += (int) vy ;
}
//计算速度值
private void getV()
{
}
//运动约束
private void moveLimit()
{
//边界约束
if(vx < 0 && x <= 0)
vx *= -1.0f ;
else if(x + cx >= width && vx > 0)
vx *= -1.0f ;
if(vy < 0 && y <= 0)
vy *= -1.0f ;
else if(vy > 0 && y + cy >= height)
{
vy *= -1.0f ;
dieLine -= 1 ;
}
//边界约束 END
//碰撞检测
Collisioned() ;
//速度约束
if(vx > 2.0f)
vx = 2.0f ;
if(vx < -2.0f)
vx = -2.0f ;
if(vy > 2.0f)
vy = 2.0f ;
if(vy < -2.0f)
vy = -2.0f ;
if((int)vx == 0)
{
vx = ((float)(randomG.nextG(7) - 64)) / 50.0f ;
}
//速度约束 END
}
private void Collisioned()
{
//先检测与击球板的碰撞
CollisionWithObject(plate) ;
//检测还存在的砖块
for(int y = 0 ;y < 3 ;y++)
for(int x = 0 ;x < 6 ;x ++)
{
if(Bricks_1[x][y].strong > 0)
{
if(CollisionWithObject(Bricks_1[x][y]))
{
//如果球与砖块碰撞
//该砖块强度减一
if((Bricks_1[x][y].strong -= 1) <= 0)
{
//如果强度变为0 ,减砖块计数,按砖块分值加玩家分数
brickCount -- ;
mark += ((Brick)Bricks_1[x][y]).count ;
if(brickCount <= 0)
{
layer ++ ;
if(layer < 3)
changeLevel(layer) ;
else
getWin = true ;
}
}
//如果球与击球板碰撞 END
}
}
}
}
//检测球与NormalObject对象及其派生类的碰撞
public boolean CollisionWithObject(NormalObject ob)
{
float temp ;
collisioned = false ;
if((ob.x - this.x - this.cx) < 3 && (ob.x - this.x - this.cx) > -1)
{
if((this.y + this.cy >= ob.y) && (this.y <= ob.y+ob.cy))
{
if(this.vx - ob.vx > 0.0f)
{
collisioned = true ;
this.vx = -1.0f * (this.vx - ob.vx) ;
ob.vx = -0.4f * ob.vx ;
}
}
}
else
if((this.x - (ob.x + ob.cx)) < 3 && (this.x - (ob.x + ob.cx)) > -1)
{
if((this.y + this.cy >= ob.y) && (this.y <= ob.y+ob.cy))
{
if(ob.vx - this.vx > 0.0f)
{
collisioned = true ;
this.vx = 1.0f * (ob.vx - this.vx) ;
ob.vx = -0.4f * ob.vx ;
}
}
}
else
if((ob.y - this.y - this.cy) < 2 && (ob.y - this.y - this.cy) > 0)
{
if((this.x + this.cx >= ob.x) && (this.x <= ob.x + ob.cx))
{
if(this.vy - ob.vy > 0.0f)
{
collisioned = true ;
this.vy = -1.0f * (this.vy - ob.vy) ;
this.vx += ((float)(randomG.nextG(5) % 30 -15)) / 80.0f ;
this.vx += ob.vx * 0.6 ;
}
}
}
else
if((this.y - (ob.y + ob.cy)) < 2 && (this.y - (ob.y + ob.cy)) > 0)
{
if((this.x + this.cx >= ob.x) && (this.x < ob.x + ob.cx))
{
if(ob.vy - this.vy > 0.0f)
{
collisioned = true ;
this.vy = 1.0f * (ob.vy - this.vy) ;
this.vx += ((float)(randomG.nextG(5) % 30 -15)) / 80.0f ;
this.vx += ob.vx * 0.6 ;
}
}
}
return collisioned ;
}
//class Ball
//成员函数 END////////////////////////////////////////////////////////////////
}
//击球板类,由MoveObject派生
class Plate extends MoveObject
{
//成员变量 //////////////////////////////////////////////////////////////////
//class Plate
//静止界限
private float restLimit = 0.1f ;
//粘滞界限
private float stickykey = 1.0f ;
//衰减系数
private float attenuation = -0.7f ;
//摩擦系数
private float resistance = 0.03f ;
//正向加速度与逆向加速度
private float acceleration = 0.05f, antiAcceleration = 0.03f ;
//class Plate
//成员变量 END///////////////////////////////////////////////////////////////
//成员函数 //////////////////////////////////////////////////////////////////
//class Plate
public Plate(String path, int x, int y, float vx, float vy, boolean special)
{
super(path, x, y, vx, vy, special) ;
//if(suc)
//{
//}
}
//计算并移动击球板
public void move()
{
//根据参数计算击球板的速度
getV() ;
moveLimit() ;
if(!ball.CollisionWithObject(this))
{
//产生位移
if((vx - (int)vx) > 0.5f)
x += ((int) vx + 1);
else
x += (int)vx ;
}
}
//运动约束
private void moveLimit()
{
//边界约束
//击球板碰撞边界后反弹并带有速度衰减
if(vx < 0 && x <= 0)
vx *= attenuation ;
else if(x + cx >= width && vx > 0)
vx *= attenuation ;
//边界约束 END
}
//计算速度
private void getV(boolean left, boolean right)
{
//按下左右键时,
if(left)
{
//当速度降至静止界限下,就迫使击球板以一定初速运动
//其他情况按恒加速度运动计
if(vx < restLimit && vx > -restLimit)
{
vx = -1.0f ;
}
else if(vx < 0.0f)
{
vx -=antiAcceleration ;
}
else if(vx > 0.0f)
{
vx -= acceleration ;
}
}
if(right)
{
//当速度降至静止界限下,就迫使击球板以一定初速运动
//其他情况按恒加速度运动计
if(vx < restLimit && vx > -restLimit)
{
vx = 1.0f ;
}
else if(vx > 0.0f)
{
vx +=antiAcceleration ;
}
else if(vx < 0.0f)
{
vx +=acceleration ;
}
}
if(!left && !right)
{
//当移动键未按下,且速度降至粘滞界限下(1像素/帧以下),就迫使击球板停下来
//其他情况按恒加速度运动计
if((vx < stickykey && vx > 0.0f) || (vx > -stickykey && vx < 0.0f) )
vx = 0.0f ;
else if(vx > 0.0f)
{
vx -= resistance ;
}
else if(vx < 0.0f)
{
vx += resistance ;
}
}
}
private void getV()
{
//按下左右键时,
if(left)
{
//当速度降至静止界限下,就迫使击球板以一定初速运动
//其他情况按恒加速度运动计
if(vx < restLimit && vx > -restLimit)
{
vx = -1.0f ;
}
else if(vx < 0.0f)
{
vx -=antiAcceleration ;
}
else if(vx > 0.0f)
{
vx -= acceleration ;
}
}
if(right)
{
//当速度降至静止界限下,就迫使击球板以一定初速运动
//其他情况按恒加速度运动计
if(vx < restLimit && vx > -restLimit)
{
vx = 1.0f ;
}
else if(vx > 0.0f)
{
vx +=antiAcceleration ;
}
else if(vx < 0.0f)
{
vx +=acceleration ;
}
}
if(!left && !right)
{
//当移动键未按下,且速度降至粘滞界限下(1像素/帧以下),就迫使击球板停下来
//其他情况按恒加速度运动计
if((vx < stickykey && vx > 0.0f) || (vx > -stickykey && vx < 0.0f) )
vx = 0.0f ;
else if(vx > 0.0f)
{
vx -= resistance ;
}
else if(vx < 0.0f)
{
vx += resistance ;
}
}
}
//class Plate
//成员函数 END////////////////////////////////////////////////////////////////
}
}
//class MyCanvas
//嵌套类 END///////////////////////////////////////////////////////////////
//砖块类
class Brick extends NormalObject
{
public int count;
public int pictureNum ;
public Brick(int x , int y , int cx, int cy, int count , int strong, int pictureNum)
{
this.x = x ;
this.y = y ;
this.cx= cx ;
this.cy= cy ;
this.count = count ;
this.strong = strong ;
this.pictureNum = pictureNum ;
}
public void set(int count , int strong, int pictureNum)
{
this.count = count ;
this.strong = strong ;
this.pictureNum = pictureNum ;
}
}
//代表物体的基类
class NormalObject
{
//成员变量 //////////////////////////////////////////////////////////////////
//class NormalObject
public int x, y, cx, cy ;
public float vx = 0.0f, vy=0.0f ;
public int strong ;
//class NormalObject
//成员变量 END///////////////////////////////////////////////////////////////
//成员函数 //////////////////////////////////////////////////////////////////
//class NormalObject
public NormalObject(int x, int y,Image objectImage )
{
//成员初始化
this.x = x ;
this.y = y ;
this.cx = objectImage.getWidth() ;
this.cy = objectImage.getHeight() ;
}
public NormalObject()
{
}
//设置位置
public void setPos(int x, int y)
{
this.x = x ;
this.y = y ;
}
//绘制
public void paint(Graphics g,Image objectImage, boolean draw)
{
if(objectImage != null && draw)
{
g.drawImage(objectImage, x,y, Graphics.TOP | Graphics.LEFT) ;
}
}
public void paint(Graphics g)
{
}
//class NormalObject
//成员函数 END///////////////////////////////////////////////////////////////
}
//代表移动物体的基类
class MoveObject extends NormalObject
{
//成员变量 //////////////////////////////////////////////////////////////////
//class MoveObject
//public int x, y, cx, cy ;
//public float vx, vy ;
public boolean special, suc = true ;
public Image moveObject ;
//class MoveObject
//成员变量 END///////////////////////////////////////////////////////////////
//成员函数 //////////////////////////////////////////////////////////////////
//class MoveObject
public MoveObject(String path, int x, int y, float vx, float vy, boolean special)
{
super() ;
//图像载入几成员初始化
try
{
moveObject = Image.createImage(path) ;
this.x = x ;
this.y = y ;
this.cx = moveObject.getWidth() ;
this.cy = moveObject.getHeight() ;
this.vx = vx ;
this.vy = vy ;
}
catch(Exception error)
{
suc = false ;
}
}
//移动
public void move()
{
}
//设置位置
public void setPos(int x, int y)
{
this.x = x ;
this.y = y ;
}
//绘制
public void paint(Graphics graphics)
{
//super() ;
if(suc)
{
graphics.drawImage(moveObject, x,y, Graphics.TOP | Graphics.LEFT) ;
}
}
//class MoveObject
//成员函数 END///////////////////////////////////////////////////////////////
}
class RandomG extends Random
{
public RandomG()
{
super() ;
}
public int nextG(int bits)
{
return next(bits) ;
}
}
//动画线程类
class ImageMover implements Runnable
{
ImageMover()
{
}
public void run()
{
long ss =System.currentTimeMillis() ;
//帧定时
while (true)
{
if(canvas.dieLine <= 0)
break ;
long time = System.currentTimeMillis();
if((time - ss) > 10000)
{
ss = time ;
if(debug)
canvas.ticker.setString("dieline is " + canvas.dieLine) ;
}
//动画逻辑
{
canvas.plate.move() ;
canvas.ball.move() ;
//canvas.enemy.move(true) ;
}
time = System.currentTimeMillis() - time;
if (time >= 1) continue;
try
{
Thread.sleep(1 - time);
}
catch (Exception e){};
//重绘帧
canvas.repaint() ;
}
}
}
//主类
//嵌套类 END////////////////////////////////////////////////////////////////
}