2013-07-12 2 views
1

Я относительно новичок в Java и пытаюсь имитировать движение объекта (скажем, автомобиля) по прямому пути. Я хочу, чтобы мой объект двигался по шагам на выходе, вместо того, чтобы появляться только в последней точке строки.Использование прямоугольников для моделирования движения прямой линии объекта

Я использовал 2 класса: Veh.java - объект транспортного средства и SimuFrame.java - для создания имитационной среды.

я упомянул некоторые электронные учебники для идей: http://www.newthinktank.com/2012/07/java-video-tutorial-52/ (Это имитирует игру астероиды Howeer Я хочу, чтобы мой объект двигаться по прямой линии, а не в случайном направлении.)

Пожалуйста, помогите мне понять, где я я ошибаюсь и что делать дальше ..

Большое спасибо.

Вот мой код:

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); 

    } 
} 

}

ответ

2

У вас есть целый ряд проблем в коде:

  • У вас есть (проглатывание) NullPointerException (NPE) в RepaintTheFrame.run(), что приводит к ScheduledThreadPoolExecutor.scheduleAtFixedRate() запустить только один раз, за scheduleAtFixedRate()'s javadoc.

  • Вы перемещаете свой автомобиль в JComponent.paint().

    В любой графической структуре перерисовка будет вызываться автоматически каркасом, как правило, в событии ОС, например. перемещение окна, перемещение мыши над окном и т. д.

    Ваш метод paint() должен только рисовать. Он должен не изменить свою модель домена.

  • Ваш метод move() всегда заканчивается транспортным средством в конце. Возможно, это не ваше намерение. Вероятно, вы хотите, чтобы ваш метод move() просто увеличивал положение автомобиля.

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; 
} 

Не знаю, почему вы клонировать массив там. Это, вероятно, не нужно.