📄 map.java
字号:
import javax.microedition.lcdui.*;
import java.io.*;
public class Map {
public Map() {
}
public static int leftTopX;//屏幕视窗在地图中的位置
public static int leftTopY;
//以下4项,可以根据具体的大小获得具体的数值。这里的例子中为固定大小。
public static final int cellWidth = 16; //地图元素组成的单元格大小
public static final int cellHeight = 16; //地图元素组成的单元格大小
public static final int mapWNum = 40; //地图中x方向单元格的个数
public static final int mapHNum = 13; //地图中y方向单元格的个数
public static final byte[] mapInfo = {
4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4
};
Image backGround;
/**
* 地图类的初始化信息
*/
void init(){
leftTopX = 0;//初始化视窗的位置
leftTopY = 0;
try
{
backGround = Image.createImage("/background.png");
}
catch (IOException ex)
{
}
}
/**
* 显示地图
*/
protected final void drawMap(Graphics g){
int tempX = - (leftTopX%backGround.getWidth());
for(int i = 0;i < 2;i ++){//背景用两张图片滚动填充
g.drawImage(backGround, i*backGround.getWidth()+ tempX, 0, 0);
}
drawAllMap(g);
drawBuild(g);
}
/**
* 显示所有在屏幕内的地图块元素
* @param g Graphics
*/
protected final void drawAllMap(Graphics g)//绘制地图
{
int[][] MapData = Data.MapData;
/*计算y方向(纵向)的起始地图单元格*/
int iStart = leftTopY / cellHeight;
/*计算x方向(横向)的起始地图单元格*/
int jStart = leftTopX / cellWidth;
/*纵向(y方向)可以显示的地图单元格数目*/
int iNum = GameCanvas.SCREEN_HEIGHT / cellHeight + 1;
/*横向(x方向)可以显示的地图单元格数目*/
int jNum = GameCanvas.SCREEN_WIDTH / cellWidth + 1;
/*限制地图块的显示部分超过地图纵向的总数量的部分*/
if (iStart + iNum >= MapData.length) {
iNum = MapData.length - 1 - iStart; //超出了地图纵向边界则Y轴可以显示的格子数则设置成为地图的高减去起始绘制位置的格
}
/*限制地图块的显示部分超过地图横向的总数量的部分*/
if (jStart + jNum >= MapData[0].length) {
jNum = MapData[0].length - 1 - jStart; //超出了地图横向边界则X轴可以显示的格子数则设置成为地图的宽减去起始绘制位置的格
}
/*根据计算结果显示*/
for (int i = iStart; i <= iStart + iNum; i++)
for (int j = jStart; j <= jStart + jNum; j++) { //循环整个地图
if (MapData[i][j] >= 0) { //地图数组中元素大于等于0表示存在图块
g.drawImage(Data.allImage[MapData[i][j]], //资源图片
j * cellWidth - leftTopX, //屏幕坐标X
i * cellHeight - leftTopY, //屏幕坐标Y
0);
}
}
}
protected final void drawBuild(Graphics g) {
int[][] buildData = Data.buildData;
/*获得建筑层的数量*/
int length = buildData.length;
/*绘制所有的建筑层的元素*/
for (int i = 0; i < length; i++) {
/*判断第i个建筑元素是否在屏幕内,在屏幕内则显示,否则不显示,为了节省绘制时间,增加游戏运行速度*/
if (buildData[i][1] + Data.allItemData[buildData[i][0]][3] >= leftTopX && //此建筑元素的x坐标+宽度大于屏幕左侧在地图中的坐标
buildData[i][1] <= leftTopX + GameCanvas.SCREEN_WIDTH &&
//此建筑元素的x坐标 < 屏 幕右侧在地图中的坐标
buildData[i][2] + Data.allItemData[buildData[i][0]][4] >= leftTopY && //同理y坐标的判定
buildData[i][2] <= leftTopY + GameCanvas.SCREEN_HEIGHT) {
/*绘制此建筑元素*/
g.drawImage(Data.allImage[buildData[i][0]],
buildData[i][1] - leftTopX, //相对屏幕的x坐标
buildData[i][2] - leftTopY, //相对屏幕的y坐标
Graphics.HCENTER|Graphics.VCENTER);
}
}
}
/**
* 根据主角的位置、方向等信息进而确定屏幕的坐标
* @param x short主角的位置
* @param y short
* @param isLeft boolean 主角的方向,是否向左
*/
protected final void setScreenMode(int x, int y, boolean isLeft) {
/**
* 设定主角在屏幕内的显示位置(postionX,postionY)(定义为屏幕的预设点)
* 屏幕中的此位置(postionX,postionY)无限地接近主角,即主角在屏幕中的位置
*/
/*注:这里设定主角在屏幕中的位置不是完全居中显示,因为考虑到游戏主角的可视范围更宽广,所以通常设定会在主角的前方视野大于主角的背后视野,但是以下方法对于主角完全居中显示的情况同样适用。*/
final int postionX = 30;
final int postionY = 60;
if (!isLeft) {
/*主角的方向向右时,主角的显示位置应该为(postionX,postionY),此时主角的前方视野为:屏幕的宽度 - 主角的X方向的坐标(以屏幕宽度为176像素为例,即176 - 30);主角的背后方视野为:主角的X方向的坐标(即30),此数值说明主角的前方视野大于背后方的视野,所以我们这里的目标是将主角的位置显示在屏幕的这个位置(postionX,postionY)。*/
/*定义了主角的目标显示位置为(postionX,postionY),但是在游戏中的主角位置是主角相对于游戏地图的绝对位置(前面章节已经讲过主角的位置),所以这里目标显示位置(postionX,postionY)相对于屏幕的位置为(leftTopX+postionX,leftTopY+postionY)
这里改变主角的显示位置以达到目标显示位置只需要判断目标显示位置相对于地图的位置与主角的位置是否发生了偏离即可*/
/**
*当屏幕的位置与主角的位置相差10像素以上
* 屏幕将以每帧10个像素的速度靠近主角
* 当屏幕的位置与主角的位置相差小于10像素则使屏幕的预设点直接设定为主角的位置
*/
if (leftTopX + postionX - x > 10) { // 当目标显示位置相对于地图的位置与主角的位置相差10像素以上
leftTopX -= 10; //调整手机屏幕相对于地图的坐标,则目标显示位置也改变为leftTopX+postionX。(注意此时leftTopX发生改变,leftTopX+postionX也发生改变),后面部分同理。
}
else if (leftTopX + postionX - x < -10) { // 当目标显示位置相对于地图的位置与主角的位置相差10像素以上
leftTopX += 10;
}
else leftTopX = (short) (x - postionX); // 当目标显示位置相对于地图的位置与主角的位置相差小于10像素
}
else {
//方向向左的计算方式
/*,这里主角的目标显示位置为(GameCanvas.SCREEN_WIDTH \u2013 postionX,postionY),因为主角方向向左,所以主角的前方视野为主角的左侧,固主角的X方向的目标为屏幕右侧边缘坐标-初始设定的目标位置。*/
if (leftTopX + GameCanvas.SCREEN_WIDTH - postionX - x > 10) { //此处以屏幕的右测边缘计算
leftTopX -= 10;
}
else if (leftTopX + (GameCanvas.SCREEN_WIDTH) - postionX - x < -10) {
leftTopX += 10;
}
else leftTopX = (short) (x - (GameCanvas.SCREEN_WIDTH) + postionX);
}
/**y方向的计算*/
if (leftTopY + (GameCanvas.SCREEN_HEIGHT >>> 1) + postionY - y > 10) {
leftTopY -= 10;
}
else if (leftTopY + (GameCanvas.SCREEN_HEIGHT >>> 1) + postionY - y < -10) {
leftTopY += 10;
}
else leftTopY = (short) (y - (GameCanvas.SCREEN_HEIGHT >>> 1) - postionY);
//当屏幕的左边小于地图时,取地图最左边即0
leftTopX = (short) Math.max(0, leftTopX);
//当屏幕的右侧大于地图的总宽度时,取地图的最右变的坐标为屏幕的最右变
leftTopX = (short) (Math.min(mapWNum * cellWidth,
leftTopX + GameCanvas.SCREEN_WIDTH) - GameCanvas.SCREEN_WIDTH);
//当屏幕的顶部小于地图顶部时,取地图最顶边即0
leftTopY = (short) Math.max(0, leftTopY);
/*当屏幕的底部大于地图的最底部时(即屏幕超出了整个地图),
取屏幕的最低端为地图的最低端,可以计算屏幕的顶端
leftTopY = 地图的最底部 - 屏幕的高度*/
leftTopY = (short) (Math.min(mapHNum * cellHeight,
leftTopY + GameCanvas.SCREEN_HEIGHT) - GameCanvas.SCREEN_HEIGHT);
}
protected static final boolean isFall(int x, int y)
{
int j = x / cellWidth;
int i = y / cellHeight;
if (i < 0 || j < 0 || i >= Data.MapData.length || j >= Data.MapData[i].length)return false;
if (Data.MapData[i][j] < 0)return true;
byte temp = mapInfo[Data.MapData[i][j]];
temp = (byte) ( (temp) & 0x1);//注意这里没有移位
if (temp == 0)
return false;
else
return true;
}
protected static final boolean isRun(int x, int y)
{
int j = x / cellWidth;
int i = y / cellHeight;
if (i < 0 || j < 0 || i >= Data.MapData.length || j >= Data.MapData[i].length)return false;
if (Data.MapData[i][j] < 0)return true;
byte temp = mapInfo[Data.MapData[i][j]];
temp = (byte) ( (temp >> 1) & 0x1);//注意这里右移1位
if (temp == 0)
return false;
else
return true;
}
protected static final boolean isUp(int x, int y)
{
int j = x / cellWidth;
int i = y / cellHeight;
if (x < 0 || y < 0 || i >= Data.MapData.length || j >= Data.MapData[i].length)return false;
if (Data.MapData[i][j] < 0)return true;
byte temp = mapInfo[Data.MapData[i][j]];
temp = (byte) ( (temp >> 2) & 0x1);//注意这里右移2位
if (temp == 0)
return false;
else
return true;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -