大球吃小球项目完成

项目需求:

  • 屏幕中出现100个小球进行碰撞运动,完全覆盖的话就吃掉小球。

小球类,Ball.java:

  • 小球类中包含小球的属性,初始化构造器,移动方法,绘制方法,和大球吃小球的方法。
  • 小球的位置,大小直径都是随机的
  • 移动速度,offsetx 和 offsety 也都是随机的,小于0.5就往上移动,大于0.5往下移动。
public class Ball {
    
    
    double x; //x坐标
    double y; //y坐标
    int d; //直径
    int r;  //rgb颜色
    int g;
    int b;
    Color color; // 红黄蓝取颜色的值
    double offsetX;  //移动的值
    double offsetY;  //移动的值

	//构造器,调用小球类自动执行,初始化小球数据
    public Ball(){
    
    
        d = (int)(Math.random()*(40-2)+2);
        x = Math.random()*800-d;
        y = Math.random()*600-d;
        r = (int)(Math.random()*256);
        g = (int)(Math.random()*256);
        b = (int)(Math.random()*256);
        color = new Color(r,g,b);
        offsetX = Math.random()*(6-1)+1;
        offsetY = Math.random()*(6-1)+1;
        offsetX = Math.random()< 0.5 ? offsetX : -offsetX;
        offsetY = Math.random()< 0.5 ? offsetY : -offsetY;
    }

    public void paint(Graphics2D g){
    
    
        g.setColor(color);
        g.fillOval((int)x,(int)y,d,d);
    }

}

移动方法

public void move(){
    
    
        x += offsetX;
        y += offsetY;
        if(x>800-d){
    
    
            offsetX = -offsetX;
            x = 800-d;
        }else if(y>600-d){
    
    
            offsetY = -offsetY;
            y = 600-d;
        }else if(x<0){
    
    
            offsetX = -offsetX;
            x=0;
        }else if (y<0){
    
    
            offsetY = -offsetY;
            y=0;
        }
    }
  • 800*600为宽高,大于800就反弹回来。
  • 因为double数据有差值,可能会出现溜边的情况,x=800-d就是强行扳回来

吃小球类

  • 通过两个球的圆心距来判断是否为包含关系,如果包含就吃掉。
public boolean eaten(Ball ball){
    
    
        double X = x, Y = y, D = this.d;  //大球
        double x=ball.x, y=ball.y, d=ball.d; //小球
//        int red=ball.r,green = ball.g, blue = ball.b;
        Color newColor = ball.color;
        //检查球的直径是否合理
        if(d > D){
    
    
            return false; //直径不合理,不进行进一步比较
        }
        //利用勾股定理计算两个球之间的距离
        double a = (X+D/2) - (x+d/2);
        double b = (Y+D/2) - (y+d/2);
        double c = Math.sqrt(a*a + b*b);
        boolean eaten = c < D/2-d/2;
        //如果发生吃了,就进行合并
        if(eaten){
    
    
            //计算合并后的圆面积
            double R = D/2,r = d/2;
            double area = Math.PI*R*R + Math.PI*r*r;
            double rx = Math.sqrt(area/Math.PI);
            this.d = (int) rx*2;  //替换当前圆的直径
            this.color = newColor;
        }
        return eaten;
    }

执行方法类 BallApp.java

public class BallApp extends App {
    
    
    Ball[] balls = new Ball[100];

    public BallApp(){
    
    
        for (int i = 0;i<balls.length;i++){
    
    
            balls[i] = new Ball();
        }
    }

    @Override
    public void painting(Graphics2D g) {
    
    
        for (int i =0;i<balls.length;i++){
    
    
            balls[i].move();
            balls[i].paint(g);
        }
        eating();
//        g.drawOval(22,60,10,10);  圆圈
    }

    public void eating(){
    
    
        //大球和小球
        Ball[] big = balls;
        Ball[] small = balls;
        boolean[] eaten = new boolean[small.length]; //创建了吃掉标志,默认都是false,表示没吃掉。boolean默认false
        int n = 0; //记录有几个球被吃掉了
        for (int i = 0;i<big.length;i++){
    
       //每一个大球
            //如果大球已经被吃掉了,就忽略
            if(eaten[i]){
    
    
                continue;
            }
            for (int j=0;j<small.length;j++){
    
       //每一个小球
                //球不能吃自己
                if(big[i]==small[j]){
    
    
                    continue;
                }
                //如果小球被吃掉就忽略
                if(eaten[j]){
    
    
                    continue;
                }
                if(big[i].eaten(small[j])){
    
    
                    System.out.println("吃...");
                    System.out.println(big[i].x+ ","+big[i].y+ ","+big[i].d);
                    System.out.println(small[j].x+ ","+small[j].y+ ","+small[j].d);
                    //把小球的位置设置为true
                    eaten[j] = true;
                    n++;
                }
            }
        }
        System.out.println(Arrays.toString(eaten));
        System.out.println(n);
        if(n==0){
    
     //什么都没吃掉
            return;
        }
        //缩容处理
        Ball[] arr = new Ball[small.length]; //此时为新数组,但都为空
        int index = 0;
        for (int i =0;i<small.length; i++){
    
    
            if (!eaten[i]){
    
      //如果index不为true
                arr[index++] = small[i]; //就放入arr中,不为true的元素都放进了数组,后面的部分为0
               // index++;
            }
        }
        System.out.println(Arrays.toString(arr));
       balls =  Arrays.copyOf(arr,arr.length-n); //缩容处理,并替换原数组
    }

    public static void main(String[] args) {
    
    
        BallApp app = new BallApp();
        app.start();
    }
}
  • 给小球数组创建eaten被吃的标志,然后把没被吃的小球放在新数组,被吃的小球就变成了最后的0,在进行缩容处理,把这些0去掉。

おすすめ

転載: blog.csdn.net/sinat_33940108/article/details/119995911