📄 sprite.java
字号:
//Source file: d:/MyProjects/Java/eatbean/eatbean/Sprite.java
package eatbean;
import java.util.Hashtable;
import java.awt.*;
//
import eatbean.util.*;
import eatbean.util.algorithm.PathFinder;
import eatbean.util.algorithm.Node;
import eatbean.conf.*;
public class Sprite extends Actor {
public static final int MAX_FRAME = 2;
public static final int MIN_FRAME = 0;
public static final int MAX_SIZE = 16;
private Rect bakR = null;
private Pos[] bakP = null;
private Image img = null;
private boolean keepRunning = true;
private boolean stepSucc = false; // nextstep()是否成功
private PathManager pathManager = null;
private static Hashtable frameTable = new Hashtable();
private static Hashtable imgBuffTable = new Hashtable();
private int currFrame = MIN_FRAME;
private long lastChangeFrameTime = -1;
static {
for(int i = MIN_FRAME; i <= MAX_FRAME; i++)
frameTable.put(new Integer(i), "sprite"+i+".gif");
}
public Sprite(Mediator mediator) {
super(mediator);
init();
}
private void init() {
mapPos = mediator.getSpriteBornPos();
MapElement e = mediator.getElement(mapPos);
rect.width = MAX_SIZE;
rect.height = MAX_SIZE;
rect.x = adjustX(e.getLeft(), e.getWidth(), rect.width);
rect.y = adjustY(e.getTop(), e.getHeight(), rect.height);
currCoveredPos = mediator.getCoveredElementsMapPos(this);
mapPos = mediator.getCurrMapPos(currCoveredPos, rect);
direction = DIR_EAST; // 初始方向
pathManager = new PathManager(mediator.getMapIntElements());
currFrame = MIN_FRAME;
img = getImage(currFrame);
}
public void run() {
nextDirection = DIR_WEST;
while(keepRunning) {
if(!mediator.getPaused()) {
stepSucc = nextstep();
//if(!nextstep() || Math.random()*10 > 9.8)
choiceNextDirection();
//mediator.flushScreen(this);
} else
if(thread != null) thread.yield();
mediator.flushScreen(this);
nextframe();
}
}
public void die() {
keepRunning = false;
}
public boolean nextstep() {
boolean result = false;
boolean flag = true;
backup();
/*
if(Debug.ON) Debug.println("mapPos: " + mapPos);
if(Debug.ON) Debug.println("rect: " + rect);
if(Debug.ON) Debug.println("nextDirection: " + nextDirection);
*/
if(nextDirection == getReverse())
direction = nextDirection;
else if(nextDirection != direction) { //nextDirection 与 direction 互相垂直
if(mediator.acceptable(getMapPos(), nextDirection)) {
MapElement e = mediator.getElement(mapPos);
rect.x = adjustX(e.getLeft(), e.getWidth(), rect.width);
rect.y = adjustY(e.getTop(), e.getHeight(), rect.height);
direction = nextDirection;
flag = false;
}
}
if(flag) {
switch(direction) {
case DIR_WEST :
rect.x = rect.x - step;
break;
case DIR_EAST :
rect.x = rect.x + step;
break;
case DIR_NORTH :
rect.y = rect.y - step;
break;
case DIR_SOUTH :
rect.y = rect.y + step;
break;
}
}
currCoveredPos = mediator.getCoveredElementsMapPos(this);
//下一步是否有效
if(!flag || mediator.acceptable(this)) { //有效
if(!mediator.hasIntersectSprite(this)) {
clear(bakP);
//paint();
Pos p = mediator.getCurrMapPos(currCoveredPos, rect);
if(p != null)
mapPos = p;
result = true;
}
} else {
restore();
}
return result;
}
private void nextframe() {
long currTime = System.currentTimeMillis();
if(currTime - lastChangeFrameTime < SysParam.CHANGE_FRAME_TIME) return;
currFrame++;
if(currFrame > MAX_FRAME || currFrame < MIN_FRAME) currFrame = MIN_FRAME;
img = getImage(currFrame);
lastChangeFrameTime = currTime;
}
public void clear(Pos[] p) {
if(p == null) {
if(Debug.ON)System.out.println("Sprite.clear(): p == null!!!!");
} else
mediator.repaintBg(this, p);
}
public void clear() {
clear(currCoveredPos);
}
private void draw() {
OffScreen offScreen = mediator.getOffScreen();
offScreen.drawImage(img, rect.x, rect.y);
}
public boolean act() {
if(thread == null) {
thread = new Thread(this);
thread.start();
}
return true;
}
public void paint() {
draw();
}
private int adjustX(int x, int w1, int w2) {
return x + (w1-w2)/2;
}
private int adjustY(int y, int h1, int h2) {
return y + (h1-h2)/2;
}
private void backup() {
bakR = getRect(); //backup rect
//if(currCoveredPos == null) currCoveredPos = mediator.getCoveredElementsMapPos(this);
if(currCoveredPos != null) {
bakP = new Pos[currCoveredPos.length];
for(int i = 0; i < currCoveredPos.length; i ++)
bakP[i] = (Pos)currCoveredPos[i].clone();
}
}
private void restore() {
rect = bakR;
currCoveredPos = bakP;
}
private Image getImage(int imgIndex) {
Image result = null;
synchronized(imgBuffTable) { // 同步,保证同一Image仅被调入内存一次
result = super.getImage(imgBuffTable, frameTable, imgIndex);
}
return result;
}
private void choiceNextDirection() {
nextDirection = pathManager.choiceNextDirection();
}
class PathManager {
private Node path = null;
private Node currNode = null;
private int[][] map = null;
private boolean reFind = true;
PathManager(int[][] map) {
this.map = map;
}
public int choiceNextDirection() {
int result = getDirection();
if(Math.random()*100 > 99) reFind = true;
if(reFind) { // 寻找路径
reFind = false;
path = null;
currNode = null;
Pos fairyMapPos = mediator.getFairyMapPos();
if(fairyMapPos != null) {
Node spriteNode = new Node(mapPos.x, mapPos.y); // start node
Node fairyNode = new Node(fairyMapPos.x, fairyMapPos.y); // target node
PathFinder pathFinder = new PathFinder(map);
path = pathFinder.findPath(fairyNode, spriteNode);
currNode = path;
//printPath();
}
}
if(currNode == null)
result = choiceRandomDirection();
else {
if(mapPos.equals(currNode)) { // 按路径往下走
currNode = currNode.parent;
if(currNode != null) result = compare(mapPos, currNode);
}
if(Math.random()*10>9) { // 放弃已找到的路径
path = null;
currNode = null;
}
}
return result;
}
private int compare(Pos spriteMapPos, Pos nextNode) {
int result = getDirection();
if(spriteMapPos.x < nextNode.x)
result = Actor.DIR_EAST;
else if(spriteMapPos.x > nextNode.x)
result = Actor.DIR_WEST;
else if(spriteMapPos.y < nextNode.y)
result = Actor.DIR_SOUTH;
else if(spriteMapPos.y > nextNode.y)
result = Actor.DIR_NORTH;
return result;
}
private int choiceRandomDirection() {
int result = getDirection();
if(!stepSucc || Math.random()*10 > 9.9) {
int r = (int)(Math.random()*12);
if(r < 3)
result = Actor.DIR_WEST;
else if(r < 6)
result = Actor.DIR_EAST;
else if(r < 9)
result = Actor.DIR_NORTH;
else if(r < 12)
result = Actor.DIR_SOUTH;
}
return result;
}
private void printPath() {
if(path == null)
System.out.println("无可用路径!");
else {
Node tmp = path;
while(tmp != null) {
System.out.println(tmp.toString() + "\n");
tmp = tmp.parent;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -