我对Java相对较新,并且一直试图在直线路径上模拟物体(比如汽车)的运动。 我希望我的对象在输出中逐步移动,而不是仅仅出现在该行的最后一点。
我使用了2个类:Veh.java - 车辆对象和SimuFrame.java - 来创建模拟环境。
我已经提到了一些想法的在线教程:http://www.newthinktank.com/2012/07/java-video-tutorial-52/(这模拟了小行星游戏。我希望我的对象能够以直线而不是随机方向移动)
请帮助我了解我错在哪里以及接下来要做什么..
非常感谢。
这是我的代码:
import java.awt.*;
import java.awt.event.*;
public class Veh extends Rectangle{
int uLeftX, uLeftY; //upper LH Position for Rectangle
static int height = 20;
static int width = 20;
int[] pathCoords=new int[1000];
int startPosY; // start position of the objet - anywhere on the left bounday of the frame.
int goalPosY; // end position of the objet - anywhere on the right boundary of the frame.
//Constructor to Create a new Veh
public Veh(int startPosY,int goalPosY){
//Create a new rectangle vehicle from super class constructor
super(0, startPosY, height, width);
this.startPosY=startPosY;
this.goalPosY=goalPosY;
this.pathCoords = Pathmove();
}
//Calculating the 1000 points on the line joining (0,startPosY) and (goalPosY,999)
int[] Pathmove(){
//Slope calculation
float s=(float)(this.goalPosY-this.startPosY)/999;
pathCoords[0]=this.startPosY;
System.out.println("First xy pair is: 0," +this.pathCoords[0]);
for(int m=1; m<1000; m++){
pathCoords[m]= (int)(m*s)-(int)((m-1)*s)+ pathCoords[m-1];
}
return pathCoords;
}
//Function to move the Reactangular object along the line using the Y coordinate values from Pathmove()
void move(){
int[] a = (int[])this.pathCoords.clone();
for (int c=0; c<a.length;c++){
this.setLocation(c,a[c]);
}
}
}
这是创建模拟环境的代码。
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class SimuFrame extends JFrame{
public static int frameWidth=1000;
public static int frameHeight=1000;
public static void main(String[] args){
new SimuFrame();
}
public SimuFrame(){
this.setSize(frameWidth,frameHeight);
this.setTitle("Path Planning Results");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SimuObject SO=new SimuObject();
this.add(SO);
// Used to execute code after a given delay
// The attribute is corePoolSize - the number of threads to keep in
// the pool, even if they are idle
ScheduledThreadPoolExecutor executor= new ScheduledThreadPoolExecutor(5);
executor.scheduleAtFixedRate(new RepaintTheFrame(this), 0L, 20L, TimeUnit.MILLISECONDS);
this.setVisible(true);
}
}
// Class implements the runnable interface
// By creating this thread I want to continually redraw the screen
// while other code continues to execute
class RepaintTheFrame implements Runnable{
SimuFrame theFrame;
public RepaintTheFrame(SimuFrame theFrame){
}
@Override
public void run() {
theFrame.repaint();
}
}
class SimuObject extends JComponent{
//Holds every Veh created
public ArrayList<Veh> vehs=new ArrayList<Veh>();
public SimuObject(){
int startPosY = (int)(Math.random()*999);
int goalPosY = (int)(Math.random()*999);
vehs.add(new Veh(startPosY,goalPosY));
}
public void paint(Graphics g){
// Allows me to make many settings changes in regards to graphics
Graphics2D graphicSettings = (Graphics2D)g;
// Draw a background that is as big as the Simu board
graphicSettings.setColor(Color.WHITE);
graphicSettings.fillRect(0, 0, getWidth(), getHeight());
// Set rendering rules
graphicSettings.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Set the drawing color to red
graphicSettings.setPaint( Color.RED);
// Cycle through all of the Rock objects
for(Veh veh : vehs){
// Move the vehicle
veh.move();
graphicSettings.draw(veh);
}
}
}
答案 0 :(得分:2)
您的代码中存在许多问题:
NullPointerException
中有(吞下)RepaintTheFrame.run()
(NPE),导致ScheduledThreadPoolExecutor.scheduleAtFixedRate()
每scheduleAtFixedRate()
's javadoc只运行一次。
您正在JComponent.paint()
移动您的汽车。
在任何图形框架中,重绘将由框架自动调用,通常在OS事件上,例如,移动窗口,将鼠标移到窗口上等等。
您的paint()
方法只能绘制。它应不修改您的域模型。
你的move()方法最终会以车辆结束。这可能不是你的意图。你可能希望你的move()方法只是增加汽车的位置。
答案 1 :(得分:1)
将步骤中的起始值移动到结束值称为interpolation。你想在这里专门进行线性插值。它是最容易掌握的一种。
This page对您有很大的帮助。
如果没有插入幻想,你可以像这样改变你的移动程序:
int index =0;
void move(){
//int[] a = (int[])this.pathCoords.clone();
if(index<this.pathCoords.length)
this.setLocation(c,pathCoords[index]);
index+=1;
}
不确定为什么要在那里克隆数组。这可能没有必要。