Я имитирую людей, идущих по графу связанных узлов. Чтобы отобразить его визуально, я использую объект холста. Я делаю это, сначала визуализируя граф с его узлами и связями между ними, после этого я начинаю рисовать человека, который представлен небольшим квадратом, движущимся по графу.
Моя проблема в том, что после того, как я рисую карту (или график), анимация человека удаляет метки, а иногда и линии графика. Я знаю, что это потому, что я визуализирую движение человека на том же холсте, который содержит карту (и из-за вызова метода clearRect()
).
Как я могу избежать очистки графика? Сначала я посмотрел на JLayeredPane
, но холсты перекрываются, и на самом верхнем холсте нет прозрачности (без прозрачности человека). Второй вариант, который я придумал, — это скопировать область перед рисованием человека, а затем восстановить область, когда человек движется, но я не уверен, как этого добиться, поэтому руководство приветствуется, поскольку я не использовал swing
или awt
, которые много, и я думаю, что это может быть общей проблемой.
Я прикрепил изображение, чтобы показать мою проблему и мой код рендеринга для каждого человека
public class Person extends Thread {
public Person(String name, Spot location, World world, Graphics g) {
this.name= name;
this.location= location;
this.world= world;
this.g= g;
}
private void move() {
Set<Link> links= world.getLinksFrom(location.getId());
Link route= CollectionUtil.getRandomElement(links);
Spot destination= route.getOriginX() == location.getX() &&
route.getOriginY() == location.getY() ?
route.getTheTarget(): route.getTheOrigin();
try {
double deltaX= (destination.getX() - location.getX()) / route.distance();
double deltaY= (destination.getY() - location.getY()) / route.distance();
double w2= (PERSON_WIDTH / 2);
for(double i=location.getX(), j=location.getY(), d= route.distance();
d > 5;
i+=deltaX, j+= deltaY,
d=Point2D.distance(i, j, destination.getX(), destination.getY())) {
g.clearRect((int)(i - w2 - deltaX), (int)(j - w2 - deltaY),
PERSON_WIDTH, PERSON_WIDTH);
g.drawRect((int)(i-w2), (int)(j-w2),
PERSON_WIDTH-1, PERSON_WIDTH-1);
Thread.sleep(50);
}
this.location= destination;
// Stay ath the new location for a while
Thread.sleep(new Random(System.currentTimeMillis()).nextInt(Person.MAX_SPOT_MILLIS));
} catch(InterruptedException e) {
throw new RuntimeException(e);
}
@Override
public void run() {
while(!isInterrupted()) {
this.move();
}
}
}