一般来说,当运行一个应用程序的时候,就启动了一个进程,当然有些会启动多个进程。启动进程的时候,操作系统会为进程分配资源,其中最主要的资源是内存空间,因为程序是在内存中运行的。
在进程中,有些程序流程块是可以乱序执行的,并且这个代码块可以同时被多次执行。实际上,这样的代码块就是线程体。线程是进程中乱序执行的代码流程。当多个线程同时运行的时候,这样的执行模式成为并发执行。
Java语言对多线程的支持通过类Thread
// 主线程其它代码段
ThreadClass subThread = new ThreadClass();
subThread.start();
// 主线程其它代码段
subThread.sleep(1000);
前些天用线程打算做一个打飞机的游戏,苦于技术限制,还没做好,只做了飞机在天上飞的效果。
定义一个主类MainWindow,用来实现窗体和调用主函数
package cn.gyw.study0412;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JFrame;
public class MainWindow extends JFrame {
public void initUI() {
this.setTitle("sss");
this.setSize(1000, 800);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
this.setVisible(true);
final Graphics g = this.getGraphics();
final ArrayList<Animle> shapes = new ArrayList<Animle>();
AnSky as = new AnSky(g, 0, 0, "images/sky.png");
shapes.add(as);
AnPlane ap_1 = new AnPlane(g, 50, 100, "images/plane.png");
AnPlane ap_2 = new AnPlane(g, 50, 200, "images/plane.png");
AnPlane ap_3 = new AnPlane(g, 50, 300, "images/plane.png");
AnPlane ap_4 = new AnPlane(g, 50, 400, "images/plane.png");
shapes.add(ap_1);
shapes.add(ap_2);
shapes.add(ap_3);
shapes.add(ap_4);
ThreadDraw td = new ThreadDraw(shapes);
td.start();
MouseListener ml = new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
AnBullet ab = new AnBullet(g, x, y);
shapes.add(ab);
}
};
this.addMouseListener(ml);
}
public static void main(String[] args) {
MainWindow mw = new MainWindow();
mw.initUI();
}
}
以为打飞机游戏的时候会出现很多飞机、子弹之类的图形元素,但是他们大都数都具有一样的特点,比如形状和如何移动,所以在做项目的时候可以定义一个接口Animel,方便管理
package cn.gyw.study0412;
public interface Animle {
public void draw();
public void move();
}
这样在实现时就可以根据需要定义一个类来继承接口,比如我要实现飞机类,就可以定义AnPlane类
package cn.gyw.study0412;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
public class AnPlane implements Animle {
private int x, y;
private Graphics g;
private Image imPng;
public AnPlane(Graphics g,int x, int y,String pngFileName){
this.g=g;
this.x=x;
this.y=y;
ImageIcon ic= new ImageIcon(pngFileName);
imPng=ic.getImage();
}
public void draw() {
g.drawImage(imPng, x, y, 80, 80, null);
}
public void move() {
x = x + 50;
}
}
构造方法传入画笔对象和需要画一架飞机的坐标,同时我们可以把需要画的对象的地址以字符串的形式存储在构造方法中,这样初始化对象的时候就更方便了。
这样还不行,画出的飞机和子弹都是连续的,看不出飞机子弹什么的在天上飞行的场景,为了解决这个问题,我们可以让背景图片也休眠,这样看起来就有了动态的感觉。
为了存储我们需要加上的图形元素,我们可以用系统自带的链表来存储,当然也可以用自己以前写的链表队列,在MainWindow类中已经贴出来了。