线程之小球的运动

---恢复内容开始---

线程之小球的运动

     线程这个知识点我写了将近三天,而且现在还在完善阶段,写线程也暴露了我写程序时的很多缺点,下面就来看看写线程时烦的那些傻吧!

一:当我是用一个线程控制一个球的时候:(即点击一下按钮就启动一个线程)

基本思路是:

1.第一步:设置好窗体,给按钮加上监听器;

2.创建一个类实现按钮的监听;

3.创建一个线程类,实现Run()方法。

     第一个越不过的坎:画小球时小球会闪动:

原因:我画小球的步骤是:改变小球颜色,改变坐标,画小球,暂停,擦除;但是线程一启动它的速度是很快的,所以先要暂停,然后擦除,改颜色和坐标,最后画小球。

    //暂停
            try {
                Thread.sleep(60);// 休眠0.01秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }//方法一:暂停时的循环休眠
        //    System.out.println();//空循环方法二
            if (stateFlag) {// 若stateFlag为true,执行continue,进行空循环或者是循环休眠的状态,不执行下面的语句;否则,执行下面的语句
                continue;
            }
            //擦除
            g.drawImage(img, 0, 70, 700, 700, null);
            //改变坐标
            x += movex;
            y += movey;
            //改颜色
            g.setColor(new Color(a, b, c));
            //画小球
            g.fillOval(x, y, size, size);

第二个越不过的坎:小球的创建,暂停,启动,删除;

/*
     * 先前把小球的创建,启动和暂停想的太复杂了,其实可以把问题简单化:
     * 创建的时候就启动线程,暂停的话就是持续休眠,启动就是让已经创建的小球继续移动,删除就是清空画图板
     * 
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        String str = e.getActionCommand();
         System.out.println("al" +"   "+ al);
        if (str.equals("创建")) {
            System.out.println("=======================" + str);
            //实例化一个线程类
            BallThread ball = new BallThread(rand.nextInt(700),
                    rand.nextInt(600)+100, 40, 10, 10, bf, al);
            ball.start();//启动线程
            al.add(ball);
        } else if (str.equals("启动")) {
            for (int i = 0; i < al.size(); i++) {
                BallThread ball = al.get(i);//获得已经创建的小球
                ball.stateFlag = false;//让已经创建的小球继续移动
            }

        } else if (str.equals("暂停")) {
            for (int i = 0; i < al.size(); i++) {
                BallThread ball = al.get(i);
                ball.stateFlag = true;//让已经创建的小球进入无限休眠的循环状态
            }
        }
        else if (str.equals("删除")) {
            for (int i = 0; i < al.size(); i++) {
        ball = al.get(i);
        ball.flag = true;
        ball.stateFlag=false;
        ball.drawwhiterecrt();
            }
        }    
    }

第三个越不过的坎:小球运动的处理方法;

难点是:当两个小球碰撞时是要互相弹开时,其实是两个小球移动的方向是往回退的,机两个小球的移动方向互换

// 碰撞处理,比较圆心之间距离,遍历数组队列,找出当前球与其他球的圆心距离
            for (int i = 0; i < al.size(); i++) {
                ball = al.get(i);//获得其他的球
                if (this == ball) {//如果找出的球是和自己一样的,就继续找球,否则就继续下面的程序
                    continue;
                }
                int xx = Math.abs(this.x - ball.x);
                int yy = Math.abs(this.y - ball.y);
                int xy = (int) Math.sqrt(xx * xx + yy * yy);//求两个球的圆心距
                int tempx = 0;
                int tempy = 0;
               //如果两个球碰撞了,两个球交换坐标(移动的方向);
                if (xy <= (this.size / 2 + ball.size / 2 )) {
                    tempx = this.movex;
                    tempy = this.movey;
                    this.movex = ball.movex;
                    this.movey = ball.movey;
                    ball.movex = tempx;
                    ball.movey = tempy;

                }
            }

第四个越不过去的坎:不要让小球把按钮擦掉了;

用随机数控制小球移动的坐标就好了:

BallThread ball = new BallThread(rand.nextInt(700),
rand.nextInt(600)+100, 40, 10, 10, bf, al);

运行的结果:

二:用一个线程控制多个小球的运动:(方法更优)

思路:

1.首先画窗体;

2.创建一个小球类,把小球的属性和方法都写上去;

属性:坐标,颜色,速度,直径

方法:画小球,移动,碰撞

3.创建一个类实现监听和Runable()和actionListener();

 要注意的问题是:小球队列的存储问题,要在点击一下“创建”的时候存小球

运行的结果:

用一个线程控制多个小球的好处:

1.解决加入背景图片时小球的闪动的问题(因为背景图片带替了擦除的功能,它不停地画就会出现不断地闪动);

2.节省内存,提高程序运行的速度(时间复杂度&&空间复杂度);

因为线程没有自己独立的内存空间(运行空间),所以每次启动一个线程都需要向进程申请运行空间,多个线程就需要更多的运行空间,从而在积累到一定数量的时候,会影响到CPU的运行速度。如图所示:

三 背景图片的移动

 思路:把背景图片也当作一个小球,在画小球的方法中加入背景图片的移动方法。

// 画小球的方法:暂停,擦除,换坐标,画小球
    public void drawOval() {
        background(img);
        //小球的移动
        move();    
        // 改变坐标
        x += movex;
        y += movey;
        // 改颜色
        g.setColor(new Color(a, b, c));        
        // 画小球
        g.fillOval(x, y, size, size);
        
    }
    //背景移动的方法
    public void background(Image img){    
        y1+=1;
        if(y1==0){
            y1=-100;
        }
        g.drawImage(img,0,y1,700,700,null);
    }

线程进一步的设想:

1.在小球上再添加一个线程,发射子弹;

2.小猪冒险的游戏;

---恢复内容结束---

原文地址:https://www.cnblogs.com/java-7/p/5807720.html