public class CarGame extends JFrame {
class MyThread extends Thread{
private JLabel label;
private int x, y;
public MyThread(String fname, int x, int y) {
this.x = x;
this.y = y;
label = new JLabel();
label.setIcon(new ImageIcon(fname));
label.setBounds(x, y, 100, 100);
add(label);
}
public void run() {
for (int i=0; i<200; i++) {
x += 10 * Math.random();
label.setBounds(x, y, 100, 100);
repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public CarGame() {
setTitle("Car Race");
setSize(600, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
(new MyThread("car1.gif", 100, 0)).start();
(new MyThread("car2.gif", 100, 50)).start();
(new MyThread("car3.gif", 100, 100)).start();
setVisible(true);
}
public static void main(String[] args) {
CarGame t = new CarGame();
}
}
Hi, I'm a university student and I got a question while studying JAVA. I want to make this Car Game works without using any thread. Please help me! Thank you :)
Create an object for every car which holds its state. Put all cars in a list and iterate over it 200 times:
import java.util.Arrays;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class CarGame extends JFrame {
class Car {
private JLabel label;
private int x, y;
public Car(String fname, int x, int y) {
this.x = x;
this.y = y;
label = new JLabel();
label.setIcon(new ImageIcon(fname));
label.setBounds(x, y, 100, 100);
add(label);
}
public void move()
{
x += 10 * Math.random();
label.setBounds(x, y, 100, 100);
repaint();
}
}
public CarGame() {
setTitle("Car Race");
setSize(600, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
List<Car> cars=Arrays.asList(new Car("car1.gif", 100, 0),new Car("car2.gif", 100, 50),new Car("car3.gif", 100, 100));
setVisible(true);
for(int i=0;i<200;i++)
{
cars.forEach(car->car.move());
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
CarGame t = new CarGame();
}
}
You will always have one thread.
Remark: using Thread.sleep() for this purpose is not such a good idea as it will block the thread from doing other work. Better would be to use a timer which is triggered every 100ms and calls the cars.foreach(…)
. Off course this would result in a second thread. The timer can be canceled once the first (or last) car reaches the finish. (thanks to @JoopEggen for the valid comment)
For completeness (and because it was fun to do): a version without threads but with :
import java.util.Arrays;
import java.util.List;
import javax.swing.Timer;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class CarGame extends JFrame {
int width = 600;
int position=1;
class Car {
private JLabel label;
private int x, y;
public Car(String fname, int x, int y) {
this.x = x;
this.y = y;
label = new JLabel(fname+">");
label.setIcon(new ImageIcon(fname+".gif"));
label.setBounds(x, y, 100, 100);
add(label);
}
public boolean move() {
if (!finished()) {
x += 10 * Math.random();
label.setBounds(x, y, 100, 100);
if(finished())
label.setText(label.getText()+"["+(position++)+"]");
}
return finished();
}
public boolean finished() {
return x > width;
}
}
public CarGame() {
setTitle("Car Race");
setSize(width+100, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
List<Car> cars = Arrays.asList(new Car("car1", 100, 0), new Car("car2", 100, 50),
new Car("car3", 100, 100));
setVisible(true);
Timer timer=new Timer(100,null);
timer.addActionListener(e-> {
// count the number of non-finished cars
if(cars.stream().map(car -> car.move()).filter(b->!b).count()==0)
timer.stop();
});
timer.start();
}
public static void main(String[] args) {
new CarGame();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.