以打砖块游戏来理解多线程(四)

2014-11-24 01:45:30 · 作者: · 浏览: 2

try{

Thread.sleep(1);

}catch(Exception ef){

ef.printStackTrace();

}

}

}

//画球的方法

public void createBall(Graphics g,int x,int y){

javax.swing.ImageIcon icon = new javax.swing.ImageIcon("src\\netjava\\wxh0807pm1\\image\\6.png");

g.drawImage(icon.getImage(), x, y, null);

}

/**

* 判断输赢的方法

* @param chars

*/

public void isWin(int[][]array){

int count=0;

for(int m=0;m

for(int n=0;n

if(array[m][n]!=0){

count++;

}

}

}

System.out.println(count);

if(count==0){

JOptionPane.showMessageDialog(null, "YOU WIN!!!");

stopThread();

}

}

}

然后再在小球类里面定义暂停、继续等的方法来控制小球的线程,具体代码如下所示:

//暂停的方法

public static void pauseThread(){

isPause=true;

}

//继续的方法

public static void resumeThread(){

isPause=false;

}

//停止的方法

public static void stopThread(){

isPause=true;

isStop=true;

}

//初始的方法

public static void initThread(){

isPause=false;

isStop=false;

}

然后再在初始化窗体的方法里面定义一个内部匿名类,来启动线程,但是在这个类里面用到的不在此类里的变量都要定义成final,具体代码如下:

//匿名内部类

ActionListener alt = new ActionListener(){

public void actionPerformed(ActionEvent e){

String command = e.getActionCommand();

if (command.equals("开始")){

//读取文件

int[][] array = MapTest.readMap("src\\netjava\\wxh0807pm1\\image\\map");

arr = array;

//画图片

createMap(array,g);

Ball b = new Ball(panel,fd);

b.start();

bt.setText("暂停");

}

if (command.equals("暂停")){

Ball.pauseThread();

bt.setText("继续");

}

if (command.equals("继续")){

Ball.resumeThread();

bt.setText("暂停");

}

if (command.equals("停止")){

Ball.stopThread();

bt.setText("开始");

}

}

};

//添加监听器

bt.addActionListener(alt);

bt1.addActionListener(alt);

Fender fd = new Fender(panel);

panel.addMouseMotionListener(fd);

然后再重绘挡板、小球以及砖块就可以了,重绘代码如下所示:

//重绘

class mypanel extends JPanel{

public void paint(Graphics g){

//重写父类的方法

super.paint(g);

//遍历砖块数组,实现重绘

for(int i=0;i

for(int j=0;j

if(arr[i][j]!=0){

int num=arr[i][j];

String path = "image/"+num+".png";

ImageIcon icon = MapTest.createImageIcon(path);

g.drawImage(icon.getImage(), 35*j, 15*i, 35, 15, null);

}

}

}

//重绘挡板

Fender f=new Fender(this);

f.createFender(g,Fender.x,630,100,20);

//重绘小球

Ball ball=new Ball();

ball.createBall(g, Ball.x0 , Ball.y0);

}

}

到这里基本的游戏已成型了,但是发现砖块消掉不完全或则还没被碰到的砖块已经被擦掉了,所以要重新启动一个线程来不停的对画图区域进行刷新,具体代码如下所示:

//刷新画布监听线程

class PaintThread extends Thread{

public void run(){

while(!Ball.isStop){

while(!Ball.isPause){

//重绘

repaint();

try{

Thread.sleep(1);

}catch(Exception ef){

ef.printStackTrace();

}

}

try{

Thread.sleep(1);

}catch(Exception ef){

ef.printStackTrace();

}

}

}

}

这样弄之后把上面的问题解决了,但是又发现挡板 、小球在不停的闪动,这时就需要根据双缓冲原理在swing中实现消除闪烁,所以上面重绘的代码改动如下:

//重绘

class mypanel extends JPanel{

public void paint(Graphics g){

//重写双缓冲机制

offSreenImage = this.createImage(495, 650);

//获得截取图片的画布

Graphics gImage = offSreenImage.getGraphics();

//获取画布的底色并且使用这种颜色填充画布,如果没有填充效果的话,则会出现拖动的效果

gImage.setColor(gImage.getColor());

//有清楚上一步图像的功能,相当于gImage.clearRect(0, 0, WIDTH, HEIGHT)

gImage.fillRect(0, 0, 495, 650);

//重写父类的方法

super.paint(gImage);

//遍历砖块数组,实现重绘

for(int i=0;i

for(int j=0;j

if(arr[i][j]!=0){

int num=arr[i][j];

String path = "image/"+num+".png";

ImageIcon icon = MapTest.createImageIcon(path);