import javax.microedition.lcdui.Canvas;
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.Sprite;
import javax.microedition.lcdui.game.TiledLayer;
public class AppCanvas extends GameCanvas implements Runnable{
private Graphics g;
private Image roleImg,groundImg;
private TiledLayer barrierLayer,groundLayer;
private Sprite hero;
private LayerManager layerManager;
private int WORLD_WIDTH,WORLD_HEIGHT;//地图宽高
private int[] view = new int[4];//可视窗口大小
private static final int X = 0;
private static final int Y = 1;
private static final int WIDTH = 2;
private static final int HEIGHT = 3;
private static int STEP = 12;
private int direction = -1;
private int CELL_WIDTH=24,CELL_HEIGHT=35;
protected AppCanvas() {
super(true);
// TODO Auto-generated constructor stub
setFullScreenMode(true);
g=this.getGraphics();
roleImg=Tools.getImage("/hero.png");
groundImg=Tools.getImage("/map.png");
layerManager=new LayerManager();
hero = new Sprite(roleImg, 24, 29);
barrierLayer = new TiledLayer(12, 12, groundImg, CELL_WIDTH, CELL_HEIGHT);
groundLayer = new TiledLayer(12, 12, groundImg, CELL_WIDTH, CELL_HEIGHT);
hero.defineCollisionRectangle(4,4,hero.getWidth()-8,hero.getHeight()-8);
hero.setPosition(CELL_WIDTH*2, CELL_HEIGHT*6);
Tools.fillCells(groundLayer, Consts.groundLayer_cells);
Tools.fillCells(barrierLayer, Consts.barrierLayer_cells);
//获得地图大小
WORLD_WIDTH=groundLayer.getWidth();
WORLD_HEIGHT=groundLayer.getHeight();
//添加到图层
layerManager.append(hero);
layerManager.append(barrierLayer);
layerManager.append(groundLayer);
view[X] = 0;
view[Y] = 0;
view[WIDTH] = 240;//getWidth();//240
view[HEIGHT] = 320;//getHeight();//320
layerManager.setViewWindow(view[X], view[Y], view[WIDTH], view[HEIGHT]);
new Thread(this).start();
}
public void run() {
// TODO Auto-generated method stub
while (true){
long start=System.currentTimeMillis();
input();
draw(g);
long end=System.currentTimeMillis();
if(end-start<100){
try {
Thread.sleep(100-(end-start));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void draw(Graphics g){
layerManager.paint(g, 0, 0);
this.flushGraphics();
}
public void input() {
int keyState=getKeyStates();
if ((keyState & DOWN_PRESSED) != 0) {
if (direction != DOWN_PRESSED) {
direction = DOWN_PRESSED;
hero.setFrameSequence(new int[] { 6, 7, 8 });
} else {
hero.nextFrame();
}
if (hero.getY() + hero.getHeight() < WORLD_HEIGHT)
hero.move(0, STEP);
else
hero.setPosition(hero.getX(), WORLD_HEIGHT - hero.getHeight());
} else if ((keyState & UP_PRESSED) != 0) {
if (direction != UP_PRESSED) {
direction = UP_PRESSED;
hero.setFrameSequence(new int[] { 0, 1, 2 });
} else {
hero.nextFrame();
}
if (hero.getY() - STEP >= 0)
hero.move(0, -STEP);
else
hero.setPosition(hero.getX(), 0);
} else if ((keyState & LEFT_PRESSED) != 0) {
if (direction != LEFT_PRESSED) {
direction = LEFT_PRESSED;
hero.setFrameSequence(new int[] { 9, 10, 11 });
} else {
hero.nextFrame();
}
if (hero.getX() - STEP >= 0)
hero.move(-STEP, 0);
else
hero.setPosition(0, hero.getY());
} else if ((keyState & RIGHT_PRESSED) != 0) {
if (direction != RIGHT_PRESSED) {
direction = RIGHT_PRESSED;
hero.setFrameSequence(new int[] { 3, 4, 5 });
} else {
hero.nextFrame();
}
if (hero.getX() + hero.getWidth() < WORLD_WIDTH)
hero.move(STEP, 0);
else
hero.setPosition(WORLD_WIDTH - hero.getWidth(), hero.getY());
}
checkCollision(direction);
// Next scroll the view if needed
//地图滚动
if (hero.getX() < view[X] +view[WIDTH]/2){//左,+ hero.getWidth()
int dx = view[X] +view[WIDTH]/2 - hero.getX() ;
if (view[X] - dx >= 0){
view[X] -= dx;
}
}else if(hero.getX() > view[X] + view[WIDTH]/2){//右- hero.getWidth()
int dx = hero.getX()- view[X] - view[WIDTH]/2;
if(view[X] + view[WIDTH] <= WORLD_WIDTH){
view[X] += dx;
}
}
if (hero.getY() < view[Y] + view[HEIGHT]/2){ // scoll up,+hero.getHeight()
int dy = view[Y] + view[HEIGHT]/2 - hero.getY();
if (view[Y] - dy >= 0){
view[Y] -= dy;
}
}else if(hero.getY()> view[Y] + view[HEIGHT]/2){ // scroll down
int dy =hero.getY() - view[Y] - view[HEIGHT]/2;
if(view[Y] + view[HEIGHT] <= WORLD_HEIGHT){
view[Y] += dy;
}
}
layerManager.setViewWindow(view[X],view[Y],view[WIDTH],view[HEIGHT]);
}
private void checkCollision(int direction) {
if (hero.collidesWith(barrierLayer, false)) {
switch (direction) {
case LEFT_PRESSED:
hero.move(STEP, 0);
break;
case RIGHT_PRESSED:
hero.move(-STEP, 0);
break;
case UP_PRESSED:
hero.move(0, STEP);
break;
case DOWN_PRESSED:
hero.move(0, -STEP);
break;
}
positionAtWorld();
//障碍物的值
byte arrayValue=Consts.barrierLayer_cells[indexY*barrierLayer.getColumns()+indexX];
System.out.println("arrayValue="+arrayValue);
switch (arrayValue) {
case 5:
case 14:
case 15:
case 16:
case 17:
case 19:
//根据障碍物的值一一处理事件
break;
}
}
}
//障碍物在地图上的列,行坐标索引(根据人物当前位置和方向推算)
private int indexX,indexY;//角色碰撞的障碍物在地图上的列,行坐标索引
private void positionAtWorld() {
int x=hero.getX()/CELL_WIDTH;//24,这样不精确,不能整除的话可能要+1
int y=hero.getY()/CELL_HEIGHT;//35
System.out.println("x========"+x);
System.out.println("y========"+y);
switch (direction) {
case UP_PRESSED:// 上
indexX = x;
indexY = y - 1;
break;
case DOWN_PRESSED:// 下
indexX = x;
indexY = y + 1;
break;
case LEFT_PRESSED:// 左
indexX = x - 1;
indexY = y;
break;
case RIGHT_PRESSED:// 右
indexX = x + 1;
indexY = y;
break;
}
}
}
import java.io.IOException;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.TiledLayer;
public class Tools {
public static Image getImage(String name){
Image image=null;
try {
image=Image.createImage(name);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return image;
}
public static final boolean isCollideWith(int ax,int ay,int aw,int ah,int bx,int by,int bw,int bh){
if(ay-by>bh||ax-bx>bw||by-ay>ah||bx-ax>aw){
return false;
}
return true;
}
public static void fillCells(TiledLayer tl,byte[][] map){
//二维数组
for(int i=0;i<tl.getColumns();i++)
for(int j=0;j<tl.getRows();j++)
tl.setCell(i, j, map[j][i]);
}
public static void fillCells(TiledLayer tl,byte[] map){
//一维数组
for(int i=0;i<map.length;i++){
int col=i%tl.getColumns();
int row=(i-col)/tl.getColumns();
tl.setCell(col,row,map[i]);
}
}
}
public class Consts {
//键值 Nokia,SE机型
public final static int KEY_UP = -1;
public final static int KEY_DOWN = -2;
public final static int KEY_LEFT = -3;
public final static int KEY_RIGHT = -4;
public final static int KEY_LS = -6;
public final static int KEY_RS = -7;
public final static int KEY_OK = -5;
public final static int KEY_BACK = -11;
public final static byte KEY_0 = 48;
public final static byte KEY_1 = 49;
public final static byte KEY_2 = 50;
public final static byte KEY_3 = 51;
public final static byte KEY_4 = 52;
public final static byte KEY_5 = 53;
public final static byte KEY_6 = 54;
public final static byte KEY_7 = 55;
public final static byte KEY_8 = 56;
public final static byte KEY_9 = 57;
public final static byte KEY_STAR = 42;
public final static byte KEY_SHARP = 35;
public static byte[] groundLayer_cells = new byte[] {
1, 1, 2, 3, 3, 3, 4, 3, 3, 3, 3, 3,
3, 3, 6, 3, 3, 7, 8,3, 3, 3, 3, 3,
3, 3, 6, 3, 3, 3, 3, 8,3, 3, 3, 3,
3, 3, 6, 3, 3, 3, 3, 7, 8, 9,3, 3,
3, 3, 6, 3, 3, 3, 3, 3, 7, 3,3, 3,
3, 3, 6, 3, 3, 3, 3, 3, 3, 3,3, 3,
11,11,10,11,11,11,11,11,11,11,3, 3,
3, 3, 6, 3, 3, 18, 3, 7, 3, 3,3, 3,
3, 3, 12, 1, 1, 1, 1, 13, 3, 3,3, 3,
3, 3, 3, 3, 3, 3, 3, 18, 3, 3,3, 3,
3, 3, 3, 3, 3, 3, 3, 18, 3, 3,3, 3,
3, 3, 3, 3, 3, 3, 3, 18, 3, 3,3, 3
};
public static byte[] barrierLayer_cells = new byte[] {
0, 0, 0, 14, 0, 0, 8, 5, 5, 5,5, 5,
0, 15, 0, 0, 0, 0, 0, 8, 5, 5,5, 5,
0, 0, 0, 15, 0, 0, 14, 8, 9, 5,5, 5,
0, 19, 0, 0, 15, 0, 14, 0, 8, 9,5, 5,
0, 0, 0, 20, 0, 14, 0, 0, 8, 9,5, 5,
0, 0, 0, 16, 14, 16, 0, 0, 0, 0,5, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,5, 5,
15, 0, 0, 16, 0, 0, 0, 0, 0, 0,5, 5,
19, 15, 0, 0, 0, 0, 0, 0, 17, 0,5, 5,
0, 15, 16, 0, 0, 15, 0, 0, 0, 0,5, 5,
0, 15, 16, 0, 0, 15, 0, 0, 0, 0,0, 0,
0, 15, 16, 0, 0, 15, 0, 0, 0, 0,0, 0
};
}
- 大小: 36.3 KB
- 大小: 51.7 KB
- 大小: 11.2 KB
分享到:
相关推荐
在这个背景下,"J2ME开发RPG,ACT游戏的地图缓存类,卡马克卷轴算法封装类"是一个专门解决此类问题的资源。 地图缓存是游戏开发中的一个关键概念,它涉及到如何存储和快速访问游戏地图的数据。在J2ME平台上,由于...
### 卡马克卷轴算法研究 #### 概述与背景 在J2ME框架下的手机游戏开发中,尤其是在资源受限的环境下,如何高效地处理地图滚动重绘成为了提升游戏体验的关键技术之一。针对这一问题,“卡马克卷轴算法”作为一种...
总之,卡马克卷轴算法是Android游戏开发中的一个重要优化手段,通过巧妙地处理地图滚动,可以在有限的硬件资源下实现流畅的游戏体验。理解和掌握这一算法,对于提升游戏开发技能,优化游戏性能具有重要的意义。
它将二维空间分成四个相等的部分,每个部分可以进一步细分,形成一个四叉树结构。在渲染场景时,四叉树可以帮助我们高效地组织和筛选对象,比如在3D游戏中,只对玩家视线范围内的物体进行渲染,从而减少计算量,提高...
Java Micro Edition(JME)是Java平台的一个轻量级版本,主要用于嵌入式设备和移动设备的游戏开发。卡马克地图缓冲卷轴算法是由著名游戏程序员约翰·卡马克(John Carmack)开发的一种优化2D滚动地图的技术。这个...
【卡马克卷轴算法】是地图滚动渲染的一种高效优化技术,尤其在资源有限的环境,如J2ME框架下的手机游戏中,它能显著提升游戏体验。卡马克卷轴算法通过利用缓冲区,解决了屏幕闪烁和帧率过低的问题,使得地图滚动更加...
《ActionScript3游戏开发:深入理解卡马克卷轴算法》 在Flash ActionScript3(AS3)游戏开发中,卡马克卷轴算法是一项至关重要的技术,尤其在制作横版过关游戏中,它为背景滚动提供了流畅且高效的解决方案。...
3. 实现DEMO:在J2ME平台上,可以编写一个DEMO来演示卡马克卷轴算法的效果,包括加载地图数据,计算更新区域,以及在缓冲区和屏幕之间的数据转移。 4. 项目应用与优化:在实际项目中,需要对卡马克卷轴算法的实际...
最后,卡马克卷轴算法的灵活性也是一大优势。通过调整缓冲区的大小和更新策略,开发者可以针对不同游戏的需求进行优化,使得这一技术能够适用于多种不同的游戏类型和场景。 然而,任何技术都不是完美无缺的。卡马克...
Flash中实现卡马克卷轴算法.doc
卡马克算法android版本底层封装(使用android游戏开发中地图基于Title块的绘制)
综上所述,这个压缩包文件集合提供了一个学习和实践卡马克滚屏技术的全面资源,包括基本算法、特定实现以及可能的优化策略。对于想要深入理解游戏开发,特别是2D卷轴游戏的开发者来说,这些都是非常宝贵的资料。通过...
而卡马克卷轴,作为一个经典的游戏概念,通常涉及到滚动背景和游戏对象的动态处理,这在移动游戏开发中是不可或缺的技术。本文将深入探讨Java ME中的卡马克卷轴实现,并结合SDL(Simple DirectMedia Layer)在桌面...
本篇文章将深入解析J2ME平台下的卡马克算法源码,为初学者提供一份详尽的学习资料。 卡马克算法的核心在于提高图形渲染效率,通过优化内存管理和渲染流程,使得有限的计算资源能够在移动设备上实现流畅的游戏体验。...
卡马克缓冲算法,又称双缓冲技术,是游戏开发和图形编程中的一个重要概念,尤其在早期的移动设备如J2ME平台上的应用十分广泛。这个算法由著名的游戏开发者约翰·卡马克提出,它解决了屏幕更新时闪烁和不连续显示的...
`CramackmapbufferImageview`很可能是一个自定义的视图组件,专门用于实现卡马克地图缓冲功能。 - 使用Bitmap对象存储和渲染地图块,Bitmap的创建和复用是性能的关键,需要优化解码过程,减少内存占用。 - 与...