坦克大战—day 9

 

子弹的效率问题

1.问题的引入

子弹飞到屏幕外或者击中敌人坦克,应该怎么处理?

子弹生成后放在容器中,子弹会不会将容器撑爆?

解决方案:使用对象池来解决:提前创建好若干个子弹对象,放到一个容器中。

                  需要的时候从对象池中拿一个出来使用,当子弹需要被销毁时,放到原来的对象池中。

                  类似于线程池。

2.创建子弹对象池

在util包中创建BulletPool类。

package util;

import game.Bullet;

import java.util.ArrayList;
import java.util.List;

/**
 * 子弹对象池
 */
public class BulletPool {
    public static  final int DEFAULT_POOL_SIZE=200;
    public static  final int DEFAULT_POOL_MAX_SIZE=300;
    //用于保存所有子弹的容器
    private static List<Bullet> pool =new ArrayList<>();

    //在类加载的时候创建200个子弹对象添加到容器中
    static {
        for(int i=0;i<DEFAULT_POOL_SIZE;i++)
            pool.add(new Bullet());
    }

    /**
     * 从对象池中获取一个子弹对象
     * @return
     */
    public static Bullet get()
    {
        Bullet bullet=null;
        //判断对象池是否为空
        if(pool.size()==0){
            //生成子弹对象
            bullet=new Bullet();
        }
       else  {
           //拿走第一个位置上的子弹对象
           bullet= pool.remove(0);
        }
       return bullet;
    }
    //归还子弹
    public static void theReturn(Bullet bullet){
        if(pool.size()==DEFAULT_POOL_MAX_SIZE)
            return;
        pool.add(bullet);
    }
}

3.修改子弹生成方法

由于子弹对象池中保存不仅仅我方的坦克,还有敌人的坦克。所以原先子弹类中有参构造方法,改为默认构造方法,不确定属性。

在tank类中修改方法。

    /**
     *坦克发射子弹方法
     */
    public void fire()
    {
        int bulletX=x;
        int bulletY=y;
        switch (dir){
            case DIR_UP:
               bulletY-=2*RADIUS;
                break;
            case DIR_DOWN:
                bulletY+=2*RADIUS;
                break;
            case DIR_LEFT:
                bulletX-=2*RADIUS;
                break;
            case DIR_RIGHT:
                bulletX+=2*RADIUS;
                break;
        }
        Bullet bullet = BulletPool.get();
        bullet.setX(bulletX);
        bullet.setY(bulletY);
        bullet.setAtk(atk);
        bullet.setDir(dir);
        bullet.setColor(color);
        //Bullet bullet=new Bullet(bulletX,bulletY,dir,atk,color);
        bullets.add(bullet);
    }

4.子弹归还对象池的方法

处理飞出屏幕的子弹。在子弹类新建一个变量visible。如果子弹飞出屏幕,visible为false。

 private void move()
    {
        switch (dir){
            case Tank.DIR_UP:
                y-=speed;
                if(y<=0)
                    visible=false;
                break;
            case Tank.DIR_DOWN:
                y+=speed;
                if(y>=Constant.FRAME_HEIGHT)
                    visible=false;
                break;
            case Tank.DIR_LEFT:
                x-=speed;
                if(x<=0)
                    visible=false;
                break;
            case Tank.DIR_RIGHT:
                x+=speed;
                if(y>=Constant.FRAME_WIDTH)
                    visible=false;
                break;
        }
    }

如果子弹的visible为false。那么就不画这个子弹。

    public void draw(Graphics g)
    {
        if(visible==false)return;
        logic();
        g.setColor(color);
        g.fillOval(x-RADIUS,y-RADIUS,RADIUS<<1,RADIUS<<1);

    }

归还子弹。

​
/**
     * 绘制子弹
     */
    private void drawBullet(Graphics g){
         for(Bullet bullet:bullets)
             bullet.draw(g);
         //判断是否归还子弹
        for (int i = 0; i <bullets.size(); i++) {
            Bullet bullet=bullets.get(i);
            if(!bullet.isVisible())
            {
                BulletPool.theReturn(bullets.remove(i));
            }
        }

    }

​

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值