📄 mapcanvas.java
字号:
package mobileRPG.client;
import javax.microedition.lcdui.*;
import java.util.Date;
public class MapCanvas extends Canvas implements Runnable {
private Main main;
private Thread thread;
private int backgroundcolor = 0xFFFFFF;
private int foregroundcolor = 0x000000;
private Entity entityPlayer;
private Entity[] entityNPC;
private ImageSet imageset;
private Image[][] layer;
private boolean[][] needsRefresh, passable;
public int xSize, ySize, xOffset, yOffset;
private boolean refresh, scrollWithCharacter;
public long time;
public MapCanvas(Main main, String mapfile) {
this.main = main;
xOffset = 0;
yOffset = 0;
scrollWithCharacter = true;
// First load the map info
loadConfigFile(mapfile);
// Next load the character info
loadEntity("/res/BlackMage.ent");
// Start the refresh thread
refresh = true;
thread = new Thread(this);
thread.start();
}
public boolean isScrollWithCharacter() {
return scrollWithCharacter;
}
public boolean isPassable(int xTile, int yTile) {
if (xTile < 0 || xTile >= passable.length) {return false;}
if (yTile < 0 || yTile >= passable[xTile].length) {return false;}
if (xTile == entityPlayer.xTileStart && yTile == entityPlayer.yTileStart) {
return false;
}
if (xTile == entityPlayer.xTileTarget && yTile == entityPlayer.yTileTarget) {
return false;
}
// Make sure the character isn't running into any npcs
for (int n = 0; n < entityNPC.length; n++) {
// If the current tile that the entity is in or moving from
if (xTile == entityNPC[n].xTileStart && yTile == entityNPC[n].yTileStart) {
return false;
}
// The tile that this npc in stopped in or is moving to
if (xTile == entityNPC[n].xTileTarget && yTile == entityNPC[n].yTileTarget) {
return false;
}
}
return passable[xTile][yTile];
}
public void loadEntity(String entFile) {
int x = 16*26;
int y = 16*34;
if (entityPlayer != null) {
x = entityPlayer.getXPosition();
y = entityPlayer.getYPosition();
}
Entity e = new Entity(16, 16, x, y, main, entFile, this);
entityPlayer = e;
}
public void loadConfigFile(String mapfile) {
ConfigFile cf = new ConfigFile(mapfile);
// 1. load the image set
imageset = main.imageSetLoader.loadImages(cf, "Map", true);
// 2. Load tile info
loadMapInfo(cf);
// 3. Load the npc entities and their scripts
loadEntities(cf);
cf.close();
}
public void loadMapInfo(ConfigFile cf) {
int x, y;
// Next load the size of the map and position of the tiles
int[] d = cf.readIntArrayLine();
xSize = d[0];
ySize = d[1];
layer = new Image[xSize][ySize];
needsRefresh = new boolean[xSize][ySize];
for (y = 0; y < ySize; y++) {
d = cf.readIntArrayLine();
for (x = 0; x < xSize; x++) {
layer[x][y] = imageset.getImage(d[x]);
needsRefresh[x][y] = true;
}
}
// Clear the Blank line
cf.readLine();
// Now read in the Passable info
passable = new boolean[xSize][ySize];
for (y = 0; y < ySize; y++) {
d = cf.readIntArrayLine();
for (x = 0; x < xSize; x++) {
if (d[x] == 0) {
passable[x][y] = true;
} else {
passable[x][y] = false;
}
}
}
// Clear the Blank line
cf.readLine();
}
public void loadEntities(ConfigFile cf) {
// File format:
// 1 Count
// + x|y|entFileName|entScriptFileName
int count, n, x, y;
String entFilename, entScriptFilename;
String[] s;
Entity e;
count = cf.readIntLine();
entityNPC = new Entity[count];
for (n = 0; n < entityNPC.length; n++) {
// Read the line
s = cf.readArrayLine('|');
// Load variables
x = Integer.parseInt(s[0]);
y = Integer.parseInt(s[1]);
entFilename = s[2];
entScriptFilename = s[3];
// Instatiate the Entity
e = new ScriptedEntity(16, 16, x, y, main, entFilename, this, entScriptFilename);
entityNPC[n] = e;
}
}
public void run() {
long nowTime, startTime, frameCount, fps, delay, fpsA, seconds, fpsV;
long[] frameTime;
int frameTimeIndex, targetFPS, i, averageOver;
targetFPS = 30;
averageOver = 5;
fpsV = 2;
frameTime = new long[averageOver];
frameTimeIndex = 0;
startTime = (new Date()).getTime();
frameCount = 0;
// 31 = 30 fps
delay = 30;
while (true) {
// ****** Start Modify Delay ******
frameCount++;
nowTime = (new Date()).getTime();
time = nowTime - startTime;
if (time > 0) {
fps = (frameCount*1000);
fps = fps/time;
//time = fps;
// Adjust delay
frameTime[frameTimeIndex] = time;
i = frameTimeIndex - (averageOver-1);
if (i < 0) {i += averageOver;}
seconds = frameTime[frameTimeIndex] - frameTime[i];
frameTimeIndex++;
if (frameTimeIndex >= frameTime.length) {
frameTimeIndex = 0;
}
if (frameCount > averageOver) {
fpsA = (averageOver*1000) / seconds;
if (frameTimeIndex == 0) {
//if (fpsA > targetFPS+fpsV) {delay++;}
//if (fpsA < targetFPS-fpsV) {delay--;}
}
time = fpsA;
//time = delay;
}
}
// ****** End Modify Delay ******
for (int n = 0; n < entityNPC.length; n++) {
entityNPC[n].run();
}
entityPlayer.run();
repaint();
try {
Thread.sleep(delay);
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
public void setNeedsRefresh(int x, int y) {
needsRefresh[x][y] = true;
}
protected void update(Graphics g) {
g.drawString("update", 16,16,Graphics.TOP|Graphics.LEFT);
paint(g);
}
protected void paint(Graphics g) {
if (refresh) {
paintBGFull(g);
refresh = false;
}
if (scrollWithCharacter) {
xOffset = entityPlayer.getXPosition() - (getWidth() / 2);
yOffset = entityPlayer.getYPosition() - (getHeight() / 2);
// Do all tiles on screen
int xTileStart, yTileStart, xTileEnd, yTileEnd;
xTileStart = xOffset / 16;
yTileStart = yOffset / 16;
xTileEnd = xTileStart + getWidth() / 16 + 1;
yTileEnd = yTileStart + getHeight() / 16 + 1;
g.setColor(foregroundcolor);
for (int y = yTileStart; y <= yTileEnd; y++) {
for (int x = xTileStart; x <= xTileEnd; x++) {
paintTile(g, x, y);
}
}
} else {
// Just do two tiles
g.setColor(foregroundcolor);
for (int y = 0; y < ySize; y++) {
for (int x = 0; x < xSize; x++) {
if (needsRefresh[x][y]) {
paintTile(g, x, y);
}
}
}
}
for (int n = 0; n < entityNPC.length; n++) {
paintEntity(g, entityNPC[n]);
}
paintEntity(g, entityPlayer);
// Paint the time
String timeMessage = time + " T";
g.drawString(timeMessage, 2, 2, Graphics.TOP|Graphics.LEFT);
if (!scrollWithCharacter) {
needsRefresh[0][0] = true;
needsRefresh[1][0] = true;
needsRefresh[2][0] = true;
needsRefresh[3][0] = true;
}
}
protected void paintEntity(Graphics g, Entity e) {
Image image;
int x, y;
image = e.getCurrentImage();
x = e.getXPosition() - xOffset;
y = e.getYPosition() - yOffset;
if (image != null) {
g.drawImage(image, x, y-3, Graphics.TOP|Graphics.LEFT);
}
}
protected void paintTile(Graphics g, int x, int y) {
if (x < 0 || x >= layer.length) {
g.drawImage(ImageSetLoader.defaultImage, x*16-xOffset, y*16-yOffset, Graphics.TOP|Graphics.LEFT);
} else if (y < 0 || y >= layer[x].length) {
g.drawImage(ImageSetLoader.defaultImage, x*16-xOffset, y*16-yOffset, Graphics.TOP|Graphics.LEFT);
} else {
g.drawImage(layer[x][y], x*16-xOffset, y*16-yOffset, Graphics.TOP|Graphics.LEFT);
needsRefresh[x][y] = false;
}
}
protected void paintBGFull(Graphics g) {
g.setColor(backgroundcolor);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(foregroundcolor);
for (int y = 0; y < ySize; y++) {
for (int x = 0; x < xSize; x++) {
paintTile(g, x, y);
}
}
}
protected void keyPressed(int keyCode) {
entityPlayer.move(keyCode);
}
public void checkForScrolling() {
boolean needs = false;
// This function is not needed if the screen is scrolling with the character
if (scrollWithCharacter) {return;}
int xSize = getWidth();
int ySize = getHeight();
int xPosition = entityPlayer.getXPosition();
int yPosition = entityPlayer.getYPosition();
if (xPosition + 16 - xOffset > xSize) {
xOffset = xPosition;
needs = true;
} else if (yPosition + 16 - yOffset > ySize) {
yOffset = yPosition;
needs = true;
} else if (xPosition < xOffset) {
xOffset = xPosition - xSize+16;
needs = true;
} else if (yPosition < yOffset) {
yOffset = yPosition - ySize+16;
needs = true;
}
if (needs) {
for (int y = 0; y < this.ySize; y++) {
for (int x = 0; x < this.xSize; x++) {
needsRefresh[x][y] = true;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -