在J2ME游戏开发中怎样实现地图的滚屏?
发布网友
发布时间:2022-04-29 22:50
我来回答
共2个回答
热心网友
时间:2022-06-25 01:14
/**
* <p>Title: CarmackMIDlet</p>
*
* <p>Description: Carmack Buffer </p>
*
* <p>Copyright: Copyright (c) 2009</p>
*
* <p>Company: sharejoy CD</p>
*
* @author fengsheng.yang
* @version 1.0
*/
import javax.microedition.lci.Graphics;
import javax.microedition.lci.Image;
public class CarmackMapBuffer {
/** 缓冲区宽高,命名方式为:Carmack width or height */
private final int carWidth, carHeight;
/** 缓冲区宽的图块数,与高的图块数,命名方式为:Carmack title width or height num*/
private final int carTitleWidthNum, carTitleHeightNum;
/** 屏幕宽高命名方式为:screen width or height */
private final int scrWidth, scrHeight;
/** 缓冲区增大的大小(上下大小是一样的) */
private final int buffSize;
/** 图块大小,宽高一致 */
private int titleSize;
/** 缓冲区,命名方式为:Carmack buffer */
private Image carBuffer;
/** 缓冲区画笔,命名方式为:Carmack Graphics */
private Graphics carGp;
/** 图片宽度的所切割的图块数量。 */
private int imageTitleWidthNum;
/** 缓冲区的宽度图块数量,与高度图块数量 */
private int bufWNum, bufHNum;
/** 地图的宽高 */
private int bufW, bufH;
/** 地图在缓冲区的X 、Y偏移量,命名方式为:map offset x or y */
private int mapOffx, mapOffy;
/** 缓冲切割线,命名方式为:Carmack x or y */
private int carx, cary;
//////////////////////////////////////////////////////////////
//临时数据
/** 地图图片 */
private Image mapImage;
/** 地图数组 */
private byte mapArray[][];
/***************************************************************************/
/***************************************************************************/
/***************************************************************************/
/**
* 创建缓冲区
*
* @param scrW
* 屏幕宽度
* @param scrH
* 屏幕高度
* @param titleSize
* 图块大小
*/
public CarmackMapBuffer(int scrW, int scrH, int titleSize) {
scrWidth = scrW;
scrHeight = scrH;
this.titleSize = titleSize;
buffSize = titleSize * 2;
int temp = 0;
while (temp < scrWidth) {
temp += titleSize;
}
carWidth = buffSize + temp;
temp = 0;
while (temp < scrHeight) {
temp += titleSize;
}
carHeight = buffSize + temp;
carTitleWidthNum = carWidth / titleSize;
carTitleHeightNum = carHeight / titleSize;
carBuffer = Image.createImage(carWidth, carHeight);
carGp = carBuffer.getGraphics();
}
/**
* 设置地图片数据
*
* @param image
* 地图图片
* @param map
* 地图的二维数组
*/
public void setMap(Image image, byte[][] map) {
this.mapImage = image;
this.mapArray = map;
this.bufHNum = mapArray.length;
this.bufWNum = mapArray[0].length;
bufW = bufWNum * titleSize - scrWidth;
bufH = bufHNum * titleSize - scrHeight;
imageTitleWidthNum = image.getWidth() / titleSize;
initBuffer();
}
/**
* 初始化Buffer
*
*/
private void initBuffer() {
int x, y, cx, cy;
for (int i = 0; i < carTitleHeightNum; i++) {
for (int j = 0; j < carTitleWidthNum; j++) {
x = getMapX(i, j);
y = getMapY(i, j);
cx = j * titleSize;
cy = i * titleSize;
carGp.setClip(cx, cy, titleSize, titleSize);
carGp.drawImage(mapImage, cx - x, cy - y, 0);
}
}
}
/**
* 绘制地图
*
*/
public void darwMap(Graphics g, int x, int y) {
// 地图在缓冲中的坐标
int tempx = mapOffx % carWidth;
int tempy = mapOffy % carHeight;
// 切割线右下角的宽与高
int rightWidth = carWidth - tempx;
int rightHeight = carHeight - tempy;
drawRegion(g, carBuffer, tempx, tempy, rightWidth, rightHeight, 0, x,
y, 0);
drawRegion(g, carBuffer, 0, tempy, scrWidth - rightWidth, rightHeight,
0, x + rightWidth, y, 0);
drawRegion(g, carBuffer, tempx, 0, rightWidth, scrHeight - rightHeight,
0, x, y + rightHeight, 0);
drawRegion(g, carBuffer, 0, 0, scrWidth - rightWidth, scrHeight
- rightHeight, 0, x + rightWidth, y + rightHeight, 0);
}
/**
* 卷轴滚动
*
* @param x
* X轴滚动
* @param y
* Y轴滚动
*/
public void scroll(int x, int y) {
x += mapOffx;
y += mapOffy;
if (x < 0 || y < 0) {
return;
}
if (x > bufW) {
mapOffx = bufW;
return;
}
if (y > bufH) {
mapOffy = bufH;
return;
}
updateBuffer(x, y);
}
/**
* 更新缓冲区
*
* @param x
* 缓冲区新的地图X坐标
* @param y
* 缓冲区新的地图Y坐标
*/
private void updateBuffer(int x, int y) {
/** 改变偏移量*/
mapOffx = x;
mapOffy = y;
// 右移
if (x > carx + buffSize) {
int indexMapLastX = getIndexBuffLastX();
if (indexMapLastX < bufWNum) {
copyBufferX(indexMapLastX, getIndexCarY(), getTitleHeight(),
getBufferCarX(), getBufferCarY());
carx += titleSize;
}
}
// 左移
if (x < carx) {
carx -= titleSize;
copyBufferX(getIndexCarX(), getIndexCarY(), getTitleHeight(),
getBufferCarX(), getBufferCarY());
}
// 下移
if (y > cary + buffSize) {
int indexMapLastY = getIndexBuffLastY();
if (indexMapLastY < bufHNum) {
copyBufferY(getIndexCarX(), indexMapLastY, getTitelWidth(),
getBufferCarX(), getBufferCarY());
cary += titleSize;
}
}
// 上移
if (y < cary) {
cary -= titleSize;
copyBufferY(getIndexCarX(), getIndexCarY(), getTitelWidth(),
getBufferCarX(), getBufferCarY());
}
}
/**
* 获得地图图片的X坐标
*
* @param row
* map数组的横坐标
* @param col
* map数组的纵坐标
* @return 地图图片的X坐标
*/
private int getMapX(int row, int col) {
return (mapArray[row][col] % imageTitleWidthNum) * titleSize;
}
/**
* 获得地图图片的Y坐标
*
* @param row
* map数组的横坐标
* @param col
* map数组的纵坐标
* @return 地图图片的Y坐标
*/
private int getMapY(int row, int col) {
return (mapArray[row][col] / imageTitleWidthNum) * titleSize;
}
/**
* 获得缓冲画笔。
*
* @return 缓冲画笔
*/
public Graphics getGraphics() {
return carGp;
}
/**
* 获得缓冲区
*
* @return 缓冲
*/
public Image getImage() {
return carBuffer;
}
/**
* 画图
*
* @param g
* 目标屏幕的画笔
* @param img
* 原图片
* @param x_src
* 原图片X坐标
* @param y_src
* 原图片Y坐标
* @param width
* 原图片宽度
* @param height
* 原图片高度
* @param transform
* 旋转角度
* @param x_dest
* 目标屏幕的X坐标
* @param y_dest
* 目标屏幕的Y坐标
* @param anchor
* 画笔的锚点
*/
private void drawRegion(Graphics g, Image img, int x_src, int y_src,
int width, int height, int transform, int x_dest,
int y_dest,
int anchor) {
// 作宽度检测
if (width <= 0 || height <= 0) {
return;
}
// 作超屏幕宽度检测
if (width > scrWidth) {
width = scrWidth;
// 作超屏幕高度检测
}
if (height > scrHeight) {
height = scrHeight;
}
g.drawRegion(img, x_src, y_src, width, height, transform, x_dest,
y_dest, anchor);
}
private void copyBufferX(int indexMapx, int indexMapy, int titleHeight,
int destx, int desty) {
int mapImagex, mapImagey, vy;
// 拷贝地图上面到缓冲的下面
for (int j = 0; j < titleHeight; j++) {
mapImagex = getMapX(indexMapy + j, indexMapx);
mapImagey = getMapY(indexMapy + j, indexMapx);
vy = j * titleSize + desty;
carGp.setClip(destx, vy, titleSize, titleSize);
carGp.drawImage(mapImage, destx - mapImagex, vy - mapImagey, 0);
}
// 拷贝地图下面到缓冲的上面
for (int k = titleHeight; k < carTitleHeightNum; k++) {
mapImagex = getMapX(indexMapy + k, indexMapx);
mapImagey = getMapY(indexMapy + k, indexMapx);
vy = (k - titleHeight) * titleSize;
carGp.setClip(destx, vy, titleSize, titleSize);
carGp.drawImage(mapImage, destx - mapImagex, vy - mapImagey, 0);
}
}
private void copyBufferY(int indexMapx, int indexMapy, int titleWidth,
int destx, int desty) {
int mapImagex, mapImagey, vx;
// 拷贝地图左面到缓冲的右面
for (int i = 0; i < titleWidth; i++) {
mapImagex = getMapX(indexMapy, indexMapx + i);
mapImagey = getMapY(indexMapy, indexMapx + i);
vx = i * titleSize + destx;
carGp.setClip(vx, desty, titleSize, titleSize);
carGp.drawImage(mapImage, vx - mapImagex, desty - mapImagey, 0);
}
// 拷贝地图右面到缓冲的左面
for (int k = titleWidth; k < carTitleWidthNum; k++) {
mapImagex = getMapX(indexMapy, indexMapx + k);
mapImagey = getMapY(indexMapy, indexMapx + k);
vx = (k - titleWidth) * titleSize;
carGp.setClip(vx, desty, titleSize, titleSize);
carGp.drawImage(mapImage, vx - mapImagex, desty - mapImagey, 0);
}
}
/**
* 获得切割线所在的索引X
*
* @return 索引X
*/
private int getIndexCarX() {
return carx / titleSize;
}
/**
* 获得切割线所在的索引Y
*
* @return 索引Y
*/
private int getIndexCarY() {
return cary / titleSize;
}
/**
* 获得切割线在Buffer中的X位置
*
* @return 切割线在Buffer中的X位置
*/
private int getBufferCarX() {
return carx % carWidth;
}
/**
* 获得切割线在Buffer中的Y位置
*
* @return 切割线在Buffer中的Y位置
*/
private int getBufferCarY() {
return cary % carHeight;
}
/**
* 获得缓冲区后面的X索引
*
* @return 后面的X索引
*/
private int getIndexBuffLastX() {
return (carx + carWidth) / titleSize;
}
/**
* 获得缓冲区后面的Y索引
*
* @return 缓冲区后面的Y索引
*/
private int getIndexBuffLastY() {
return (cary + carHeight) / titleSize;
}
/**
* 获得当前图块高度的数量
*
* @return 当前图块高度的数量
*/
private int getTitleHeight() {
return (carHeight - cary % carHeight) / titleSize;
}
/**
* 获得当前图块宽度的数量
*
* @return 当前图块宽度的数量
*/
private int getTitelWidth() {
return (carWidth - carx % carWidth) / titleSize;
}
}
热心网友
时间:2022-06-25 01:14
需要知道你怎么显示地图的,不然还真不好说怎么实现滚屏。