多线程几乎是所有游戏都要用到的技术(当然除了五子棋等等)因为很多大型游戏在一个线程的运行下是非常的缓慢的,那我们要想知道如何利用线程做事,那就首先要知道线程是什么,首先,线程不是进程,在多进程OS中,通常是在一个进程中包括多个线程,每个线程都是作为利用CPU的基本单位,是花费最小开销的实体。也就是说,一个进程是由一个或者多个进程来运行的,这样我们开始用线程来写进程程序。
这一次我们先来做一个简单的东西,就是让一个图片在一个窗体中平行的动起来,要想让它动起来,我们就要不停的改变它的位置,这里面有一个类,类名叫Thread,这个类就是我们主要用到的,从源代码上可以看到,它是继承超级父类Objiect的,我们在使用这个类的时候,不需要导入,
从API上我们可以看到最后一句话,清清楚楚的告诉了我们怎么去用这个类,我这里是用所提供的方法,用一个子类来继承Thread,然后重写里面的run方法,这个方法里面要写上我们要做的事情,见代码:
public class MyThread extends Thread{
private JLabel j;
int x = 1 ,y = 1;
private int speedx = 1;
private int speedy = 1;
//构造方法,传入放了图片的label
public MyThread(JLabel j){
this.j =j;
}
public void run()
{
j.setBounds(x+=speedx, y+=speedy, 50, 50);
}
}
下一步就是如何启动线程呢?Thread有一个start方法,就是启动线程的,所以我们在frame类中实例化MyThread类后,调用start方法就可以了。
在启动线程后,我们会发现图片位置变换的非常快,几乎看不到影子,如何让它慢下来呢?这里面还有一个方法 sleep 方法,方法的参数是以毫秒为单位的时间,这个方法的用处就是让线程睡眠一段时间,这段时间由参数决定,这样我们就可以在run方法里面用到这个方法,让它适当的睡眠就可以让图片慢下来,小伙伴们可以试试。
这里面有三个方法要提到一下,stop、suspend和resume,这三个方法在API上都可以查到,但是上面明显的表明的三个字:已过时。这三个方法都有缺点,具体的原因API上面有,我在用前两种方法的时候是会有bug但是第三个暂时没测出来,小伙伴们可以自己去试一下,一般简单的暂停、停止可以用if、contimue、break搭配完成,下面展示一个完整的线程代码,虽然简单、不精细,但是小伙伴们也可以拿去测试理解一下。
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Random;
public class Ball extends Thread{
private int Radius = 20;
private int xSpeed = 5;
private int ySpeed = 5;
private int xLocate = 1;
private int yLocate = 1;
private boolean stopFlag = false;
private boolean pauseFalg = false;
private Color colo = new Color(new Random().nextInt(256),new Random().nextInt(256),new Random().nextInt(256));
private Graphics g ;
private MainFrame frame;
private ArrayList<Ball> arr;
public Ball(MainFrame frame){
this.frame = frame;
}
public void run(){
initData();
while(true){
g = frame.getEast().getGraphics();
try {
this.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
isHit();isHitBall();
g.setColor(frame.getEast().getBackground());
if(pauseFalg){
continue;
}
g.fillOval(xLocate, yLocate, Radius*2, Radius*2);
xLocate += xSpeed;
yLocate += ySpeed;
if(stopFlag){
break;
}
g.setColor(colo);
g.fillOval(xLocate, yLocate, Radius*2, Radius*2);
}
}
public void isHit(){
if(xLocate > frame.getEast().getWidth()){
xSpeed = -xSpeed;
//colo = new Color(new Random().nextInt(256),new Random().nextInt(256),new Random().nextInt(256));
}
if(yLocate > frame.getEast().getHeight()){
ySpeed = -ySpeed;
//colo = new Color(new Random().nextInt(256),new Random().nextInt(256),new Random().nextInt(256));
}
if(xLocate <= 0 && xSpeed < 0){
xSpeed = -xSpeed;
//colo = new Color(new Random().nextInt(256),new Random().nextInt(256),new Random().nextInt(256));
}
if(yLocate <= 0 && ySpeed < 0){
ySpeed = -ySpeed;
//colo = new Color(new Random().nextInt(256),new Random().nextInt(256),new Random().nextInt(256));
}
}
public void initData(){
Random i = new Random();
xSpeed = i.nextInt(2)+5;
i = new Random();
ySpeed = i.nextInt(2)+5;
i = new Random();
Radius = i.nextInt(10)+20;
}
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainFrame {
private Ball ball;
private static MainFrame mf = new MainFrame();
private ArrayList<Ball> ballArray = new ArrayList<Ball>();
public static void main(String[] args) {
mf.initUI();
}
JPanel jp = new JPanel();
public void initUI(){
JFrame frame = new JFrame();
frame.setSize(600, 500);
frame.setDefaultCloseOperation(3);
frame.setLayout(new BorderLayout());
JPanel west = new JPanel();
west.setPreferredSize(new Dimension(100,100));
west.setBackground(Color.black);
String[] buttonName = {"开始一个球","暂停","停止","继续"} ;
for(int i = 0;i<4;i++){
JButton jbu = new JButton(buttonName[i]);
west.add(jbu);
jbu.addActionListener(l);
}
//jp.setPreferredSize(new Dimension(500,500));
frame.add(jp,BorderLayout.CENTER);
//jp.setBackground(Color.black);
frame.add(west,BorderLayout.WEST);
frame.setVisible(true);
}
//东边面板
public JPanel getEast(){
return jp;
}
ActionListener l = new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
String name = e.getActionCommand();
if(name.equals("开始一个球")){
ball = new Ball(mf);
ballArray.add(ball);
ball.start();
}
else if(name.equals("暂停")){
for(int i = 0;i<ballArray.size();++i){
Ball b = ballArray.get(i);
b.setPauseFalg(true);
}
}
else if(name.equals("停止")){
for(int i = 0;i<ballArray.size();++i){
Ball b = ballArray.get(i);
b.setStopFlag(true);
}
}else if(name.equals("继续")){
for(int i = 0;i<ballArray.size();++i){
Ball b = ballArray.get(i);
b.setPauseFalg(false);
}
}
}
};
public ArrayList<Ball> getBallArray() {
return ballArray;
}
}