GameAPI

游戏画布,图层和游戏精灵
简介
javax.microedition.lcdui.game 包,提高Java 游戏的性能
GameCanvas:游戏画布,比普通画布更加适合游戏开发
Layer:图层,可以表示画布上的某个可视的物体,是抽象类
Sprite:可以充当游戏中的具体角色,一般用于运动角色,如子弹,汽车等
TiledLayer:可以充当游戏中的具体角色,一般用于环境角色,如地图等
LayerManager:管理图层的变换
GameCanvas
基本结构
classMyGameCanvasextendsGameCanvasimplementsRunnable{
publicMyGameCanvas(){
super(true);
}
publicvoidrun(){
}
}

构造函数传入参数,可以控制特殊键是否被禁用,为true时,可以通过getKeyStates查询状态,一般写法(getKeyStates&相应键值)!=0表示某键

被按下
可以通过getGraphics直接操作画布,不用写paint函数,不用重画开销,flushGraphics()将缓冲画布画到屏幕上
Sprite
Layer的子类,Layer中的重要方法:
int getHeight() /int getWidth()
int getX() /int getY()
boolean isVisible() /voidsetVisible(booleanvisible)
void move(int dx,int dy) /voidsetPosition(intx,inty)
Sprite(Image image) :传入一幅图片/Sprite(Image image,int frameWidth,int frameHeight) :传入图片,设置帧宽度和高度
Sprite.paint(g):将精灵画在界面上
Sprite知识点:旋转和悬挂点
voiddefineReferencePixel(intx,inty) :定义悬挂点
voidsetRefPixelPosition(intx,inty) :将悬挂点定位到某个坐标
int getRefPixelX() :得到悬挂点的横坐标
int getRefPixelY() :得到悬挂点的纵坐标
voidsetTransform(inttransform) :旋转
案例:图像不断旋转并且在界面位置不断变化
package prj;

import java.util.Random;

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
//让图片绕着左上角旋转
public class MIDlet6 extends MIDlet {
private MyGameCanvas mgc = new MyGameCanvas();
private Display dis;
protected void startApp() throws MIDletStateChangeException {
dis = Display.getDisplay(this);
dis.setCurrent(mgc);

}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {


}

protected void pauseApp() {


}

class MyGameCanvas extends GameCanvas implements Runnable{
private boolean RUN = true;
private Random rnd = new Random();
private Graphics gra;
private Sprite s1;
private Image img;
private int STATE = Sprite.TRANS_NONE;
public MyGameCanvas(){
super(true);
gra = this.getGraphics();
try{
img = Image.createImage("/img1.png");
}catch(Exception ex){ex.printStackTrace();}
s1 = new Sprite(img);
//定义悬挂点
//s1.defineReferencePixel(s1.getWidth()/2,s1.getHeight()/2);//坐标是图像上的坐标
s1.defineReferencePixel(0,0);
s1.setRefPixelPosition(100,100);//悬挂点在界面上的坐标

new Thread(this).start();
}
public void run(){
while(RUN){
try{
s1.setTransform(STATE);
gra.setColor(255,255,255);
gra.fillRect(0,0,this.getWidth(),this.getHeight());
gra.setColor(255,0,0);
gra.drawLine(100,100, 150,200);
s1.paint(gra);
this.flushGraphics();
switch(STATE){
case Sprite.TRANS_NONE: STATE=Sprite.TRANS_ROT90; break;
case Sprite.TRANS_ROT90: STATE=Sprite.TRANS_ROT180; break;
case Sprite.TRANS_ROT180: STATE=Sprite.TRANS_ROT270; break;
case Sprite.TRANS_ROT270: STATE=Sprite.TRANS_NONE; break;
}
Thread.currentThread().sleep(100);
}catch(Exception ex){}
}
}

}


}

SpriteSprite碰撞检测和动画
Sprite知识点:碰撞检测
voiddefineCollisionRectangle(intx,inty,intwidth,intheight) :定义一个矩形的不可碰撞的区域
boolean collidesWith(Sprite s,boolean pixelLevel):判断是否和另一个Sprite发生了碰撞;参数2为true,则认为不透明点发生了碰撞才算

碰撞,否则认为矩形发生了碰撞就算碰撞
boolean collidesWith(TiledLayert,boolean pixelLevel) :判断是否和TiledLayer发生碰撞,TiledLayer后面会讲
boolean collidesWith(Image image,intx,inty,boolean pixelLevel):判断是否和另一个图片碰撞,用的较少,大家可以去查询文档
Sprite知识点:带动画的角色
能否让一个角色本身就含有动画?
切割图片原则:首先走行,一行走完,取下一行,编号从0开始
int getRawFrameCount():得到帧数
voidnextFrame()/voidprevFrame()/voidsetFrame(int sequenceIndex):设置显示某一帧,号码从0开始算
voidsetFrameSequence(int[] sequence)/int getFrameSequenceLength() :设置/得到帧的顺序
int[]seq= newint[]{0,3,2,1};
voidsetImage(Imageimg,int frameWidth,int frameHeight) :改变图片
package prj;

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class MIDlet5 extends MIDlet {
private MyGameCanvas mgc = new MyGameCanvas();
private Display dis;
protected void startApp() throws MIDletStateChangeException {
dis = Display.getDisplay(this);
dis.setCurrent(mgc);
}

protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
// TODO Auto-generated method stub

}

protected void pauseApp() {
// TODO Auto-generated method stub

}

class MyGameCanvas extends GameCanvas implements Runnable{
private Image img;
private Sprite sp1;
private Graphics gra;
private boolean RUN = true;
public MyGameCanvas(){
super(true);
try{
img = Image.createImage("/donghua.png");
//sp1 = new Sprite(img);
//你可以将img分割成几个图片小块,每个小块有一定的宽度和高度
//以下代码将图片分为4帧,
sp1 = new Sprite(img,img.getWidth()/4,img.getHeight());
gra = this.getGraphics();
}catch(Exception ex){
ex.printStackTrace();
}
new Thread(this).start();
}
public void run(){
while(RUN){
gra.setColor(0,255,0);
gra.fillRect(0,0,this.getWidth(),this.getHeight());
sp1.paint(gra);
this.flushGraphics();
sp1.move(1, 1);
sp1.nextFrame();
try{
Thread.currentThread().sleep(100);
}catch(Exception ex){}
}
}
}


}

TiledLayerTiledLayer和图层管理
TiledLayer
TiledLayer(intcolumns,introws, Image image,int tileWidth,int tileHeight):将图片用tileWidth,tileHeight分割,指定将要填充的列数和

行数,注意,图片小块index从1开始
以下例子中,左边图片分为2个图片小块,填充右边的地图,四行四列
TiledLayer
void paint(Graphics g) :画出TiledLayer
voidsetCell(int col,introw,int tileIndex) :将某个图片小块填入相应位置
int getCell(int col,introw) :得到某行某列的图片小块Index
int getCellHeight() /int getCellWidth()
int getColumns() /int getRows()
voidfillCells(int col,introw,int numCols,int numRows,int tileIndex) :用一个图片小块填充整个网格
voidsetStaticTileSet(Image image,int tileWidth,int tileHeight) :修改图片
实际游戏中的技巧
应该将不同的物体弄成不同的图层
右图的地图应该是两个图层:墙壁一个,草地一个,为什么?
便于碰撞检测
图层管理器:LayerManager
有一种更好的方法来在界面上画图,不用针对一个个图层来画图了
void append(Layer l) :添加图层
void remove(Layer l) :去掉图层
voidsetViewWindow(intx,inty,intwidth,intheight) ,设置窗口的可视部分
void paint(Graphics g,intx,inty),将所有图层画统一画出来
package prj;

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.TiledLayer;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class MIDlet6 extends MIDlet {
private MyGameCanvas mgc = new MyGameCanvas();
private Display dis;
protected void startApp() throws MIDletStateChangeException {
dis = Display.getDisplay(this);
dis.setCurrent(mgc);
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
// TODO Auto-generated method stub

}
protected void pauseApp() {
// TODO Auto-generated method stub

}

class MyGameCanvas extends GameCanvas implements Runnable{
private Image map;
private TiledLayer tlRoad;
private TiledLayer tlWall;

private Graphics gra;
private LayerManager lm;//图层管理器
private boolean RUN = true;
private int Y = 0;
public MyGameCanvas(){
super(true);
try{
map = Image.createImage("/map.png");
gra = this.getGraphics();
tlRoad = new TiledLayer(4,4,map,map.getWidth()/2,map.getHeight());
tlWall = new TiledLayer(4,4,map,map.getWidth()/2,map.getHeight());

lm = new LayerManager();
lm.append(tlRoad);
lm.append(tlWall);


int[][] cells = new int[][]{
{1,2,1,2},
{1,2,2,2},
{1,2,1,2},
{1,2,1,2}
};
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(cells[j][i]==1){
tlRoad.setCell(j, i, cells[i][j]);
}
else{
tlWall.setCell(j, i, cells[i][j]);
}
}
}
}catch(Exception ex){
ex.printStackTrace();
}
new Thread(this).start();

}
public void run(){
while(RUN){
gra.setColor(255,255,255);
gra.fillRect(0,0,this.getWidth(),this.getHeight());
//通过LayerManager显示
lm.setViewWindow(0,Y,80,30);
lm.paint(gra, 30,25); //将图层管理器内的图层画到界面的左上角30,25位置
this.flushGraphics();
Y++;
try{
Thread.currentThread().sleep(100);
}catch(Exception ex){}
}
}
}

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值