📄 navigatecanvas.java
字号:
import javax.microedition.lcdui.*;
import java.util.*;
public class NavigateCanvas extends Canvas implements CommandListener, Runnable {
TripMate main;
Trip trip;
int currX;
int currY;
int currDirection;
int[] pointX;
int[] pointY;
int[] intervals;
byte[] directions;
int duration;
Timer timer;
TripTask task;
boolean endOfTrip;
Displayable parent;
static final int ARROW_SIZE = 4;
static final int SCALE = 8;
static final int RED = 0xFF0000;
static final int GREEN = 0x00FF00;
static final int BLUE = 0x0000FF;
static final int WHITE = 0xFFFFFF;
static final int BLACK = 0x000000;
public void run() {
int prevX = currX;
int prevY = currY;
int currTime = main.state.suspendTime != 0
? main.state.suspendTime - main.state.startTime
: (int)(System.currentTimeMillis()/1000) - main.state.startTime;
if (currTime >= duration) {
if (main.state.tripState == TripState.NAVIGATE_FORWARD) {
currX = pointX[pointX.length-1];
currY = pointY[pointY.length-1];
} else {
currX = pointX[0];
currY = pointY[0];
}
if (!endOfTrip) {
stopTimer();
endOfTrip = true;
removeCommand(TripMate.STOP_CMD);
removeCommand(TripMate.SUSPEND_CMD);
removeCommand(TripMate.NEXT_CMD);
addCommand(TripMate.BACK_CMD);
}
} else {
if (main.state.suspendTime != 0 && currX != 0) {
currDirection = (currDirection + 1) & 3;
} else {
if (main.state.tripState == TripState.NAVIGATE_FORWARD) {
for (int i = 0; i < intervals.length; i++) {
int delta = intervals[i];
if (currTime <= delta) {
currX = pointX[i] + (pointX[i+1] - pointX[i]) * currTime / delta;
currY = pointY[i] + (pointY[i+1] - pointY[i]) * currTime / delta;
currDirection = directions[i];
break;
}
currTime -= delta;
}
} else {
for (int i = intervals.length; --i >= 0;) {
int delta = intervals[i];
if (currTime <= delta) {
currX = pointX[i+1] + (pointX[i] - pointX[i+1]) * currTime / delta;
currY = pointY[i+1] + (pointY[i] - pointY[i+1]) * currTime / delta;
currDirection = directions[i] ^ TripMate.CHANGE_DIRECTION_MASK;
break;
}
currTime -= delta;
}
}
}
}
int top, left, width, height;
if (currX < prevX) {
left = currX;
width = prevX - currX;
} else {
left = prevX;
width = currX - prevX;
}
if (currY < prevY) {
top = currY;
height = prevY - currY;
} else {
top = prevY;
height = currY - prevY;
}
repaint(left-ARROW_SIZE, top-ARROW_SIZE, width+ARROW_SIZE*2, height+ARROW_SIZE*2);
}
NavigateCanvas(Trip trip, TripMate main, Displayable parent) {
this.main = main;
this.trip = trip;
this.parent = parent;
int x = 0;
int y = 0;
int maxX = 0;
int minX = 0;
int maxY = 0;
int minY = 0;
int prev = trip.time;
int direction = TripMate.FORWARD;
for (int i = 0; i < trip.points.length; i++) {
int delta = trip.points[i].time - prev;
direction = (direction + trip.points[i].direction) & 3;
switch (direction) {
case TripMate.LEFT:
if ((x -= delta) < minX) {
minX = x;
}
break;
case TripMate.RIGHT:
if ((x += delta) > maxX) {
maxX = x;
}
break;
case TripMate.FORWARD:
if ((y -= delta) < minY) {
minY = y;
}
break;
case TripMate.BACKWARD:
if ((y += delta) > maxX) {
maxY = y;
}
break;
}
prev += delta;
}
int width = maxX - minX + 1;
int height = maxY - minY + 1;
int screenWidth = getWidth();
int screenHeight = getHeight();
int scaleX = ((screenWidth - ARROW_SIZE*2) << SCALE) / width;
int scaleY = ((screenHeight - ARROW_SIZE*2) << SCALE) / height;
int scale = scaleX < scaleY ? scaleX : scaleY;
int startX = width == 1 ? screenWidth/2 : ARROW_SIZE - ((minX * scale) >> SCALE);
int startY = height == 1 ? screenHeight/2 : ARROW_SIZE - ((minY * scale) >> SCALE);
pointX = new int[trip.points.length+1];
pointY = new int[trip.points.length+1];
intervals = new int[trip.points.length];
directions = new byte[trip.points.length];
duration = trip.duration();
direction = TripMate.FORWARD;
prev = trip.time;
x = y = 0;
pointX[0] = startX;
pointY[0] = startY;
for (int i = 0; i < trip.points.length; i++) {
int delta = trip.points[i].time - prev;
direction = (direction + trip.points[i].direction) & 3;
directions[i] = (byte)direction;
intervals[i] = delta;
switch (directions[i]) {
case TripMate.LEFT:
x -= delta;
break;
case TripMate.RIGHT:
x += delta;
break;
case TripMate.FORWARD:
y -= delta;
break;
case TripMate.BACKWARD:
y += delta;
break;
}
prev += delta;
pointX[i+1] = startX + ((x*scale)>>SCALE);
pointY[i+1] = startY + ((y*scale)>>SCALE);
}
timer = new Timer();
task = new TripTask();
task.is(this);
timer.schedule(task, 0, TripMate.FREQUENCY);
setCommandListener(this);
if (main.state.suspendTime == 0) {
int currTime = (int)(System.currentTimeMillis()/1000) - main.state.startTime;
if (currTime < duration) {
addCommand(TripMate.SUSPEND_CMD);
addCommand(TripMate.NEXT_CMD);
}
} else {
addCommand(TripMate.RESUME_CMD);
}
addCommand(TripMate.TEXT_CMD);
addCommand(TripMate.STOP_CMD);
addCommand(TripMate.QUIT_CMD);
Display.getDisplay(main).setCurrent(this);
}
void stopTimer() {
if (timer != null) {
timer.cancel();
timer = null;
}
}
protected void paint(Graphics g) {
g.setColor(WHITE);
g.fillRect(g.getClipX(), g.getClipY(), g.getClipWidth(), g.getClipHeight());
g.setColor(BLUE);
for (int i = 1; i < pointX.length; i++) {
g.drawLine(pointX[i-1], pointY[i-1], pointX[i], pointY[i]);
}
if (endOfTrip) {
g.setColor(RED);
g.fillArc(currX-ARROW_SIZE+1, currY-ARROW_SIZE+1, (ARROW_SIZE-1)*2, (ARROW_SIZE-1)*2, 0, 360);
} else {
int x, y, direction;
if (main.state.tripState == TripState.NAVIGATE_FORWARD) {
x = pointX[pointX.length-1];
y = pointY[pointY.length-1];
direction = directions[directions.length-1];
} else {
x = pointX[0];
y = pointY[0];
direction = directions[0] ^ TripMate.CHANGE_DIRECTION_MASK;
}
switch (direction) {
case TripMate.LEFT:
g.drawLine(x, y, x+3, y-3);
g.drawLine(x, y, x+3, y+3);
break;
case TripMate.RIGHT:
g.drawLine(x, y, x-3, y-3);
g.drawLine(x, y, x-3, y+3);
break;
case TripMate.FORWARD:
g.drawLine(x, y, x-3, y+3);
g.drawLine(x, y, x+3, y+3);
break;
case TripMate.BACKWARD:
g.drawLine(x, y, x-3, y-3);
g.drawLine(x, y, x+3, y-3);
break;
}
g.drawImage(TripMate.arrows[currDirection], currX, currY, Graphics.HCENTER|Graphics.VCENTER);
}
}
public void commandAction(Command c, Displayable d)
{
if (c == TripMate.QUIT_CMD) {
main.quit();
} else if (c == TripMate.STOP_CMD || c == TripMate.BACK_CMD) {
main.state.tripState = TripState.FINISHED;
main.state.suspendTime = 0;
main.updateState();
stopTimer();
Display.getDisplay(main).setCurrent(main.mainMenu);
} else if (c == TripMate.SUSPEND_CMD) {
main.state.suspendTime = (int)(System.currentTimeMillis()/1000);
main.updateState();
removeCommand(TripMate.SUSPEND_CMD);
removeCommand(TripMate.NEXT_CMD);
addCommand(TripMate.RESUME_CMD);
} else if (c == TripMate.RESUME_CMD) {
main.state.startTime += (int)(System.currentTimeMillis()/1000) - main.state.suspendTime;
main.state.suspendTime = 0;
main.updateState();
removeCommand(TripMate.RESUME_CMD);
addCommand(TripMate.SUSPEND_CMD);
addCommand(TripMate.NEXT_CMD);
} else if (c == TripMate.NEXT_CMD) {
int currTime = (int)(System.currentTimeMillis()/1000) - main.state.startTime;
if (main.state.tripState == TripState.NAVIGATE_FORWARD) {
for (int i = 0; i < intervals.length; i++) {
int delta = intervals[i];
if (currTime <= delta) {
main.state.startTime -= delta - currTime;
main.updateState();
break;
}
currTime -= delta;
}
} else {
for (int i = intervals.length; --i >= 0;) {
int delta = intervals[i];
if (currTime <= delta) {
main.state.startTime -= delta - currTime;
main.updateState();
break;
}
currTime -= delta;
}
}
} else if (c == TripMate.TEXT_CMD) {
new NavigateForm(this);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -