用面向对象的编程方式实现飞机大战小游戏,java版 - 沙和尚-
用面向对象的编程方式实现飞机大战小游戏,java版
概述
本文将使用java语言以面向对象的编程方式一步一步实现飞机大战这个小游戏
本篇文章仅供参考,如有写的不好的地方或者各位读者哪里没看懂可以在评论区给我留言
或者邮件8274551712@qq.com
源码地址 :https://github.com/sc2885112/AircraftWars.git
项目结构分析
在这个游戏中,所有的物体都是飞行物所以有一个总的抽象类类:飞行物体类(FlyingObject)
飞行物的子级划分:奖励飞行物(*Prize),飞机(Plane),武器(Bullet)
飞机的子级划分:敌人飞机(enemy),英雄机(hero)
敌人的飞机又分普通敌人和特殊敌人,武器又分普通武器和特殊武器,英雄机又分a,b,c。。。等英雄机
话不多说上代码。。。。。。。
飞行物体类FlyingObject
public abstract class FlyingObject implements Flying{ private int x; private int y; private BufferedImage img; private int imgWidth; private int imgHeight; private int flySpeed; //移动速度 public FlyingObject(int x, int y, int flySpeed,BufferedImage img) { this.x = x; this.y = y; this.flySpeed = flySpeed; this.img = img; } public FlyingObject(int x, int y, int flySpeed) { this.x = x; this.y = y; this.flySpeed = flySpeed; } public FlyingObject() {} @Override public void fly(int x,int y) { this.setX(x); this.setY(y); } /** * 走一步 * @return */ public void step(){ this.setY(this.getY() + this.getFlySpeed()); } /** * 越界检查 */ public boolean isTransboundary(){ return this.y > PlayMain.GAME_HEIGHT; }
/**
* 碰撞检查
* 这个碰撞算法是我拷贝的别人的
* 有些许误差
* @return
*/
public boolean inspectCollision(FlyingObject flyObj){ int x1 = flyObj.x - this.getImgWidth()/2; //x坐标最小距离 int x2 = flyObj.x + this.getImgWidth()/2 + flyObj.getImgWidth(); //x坐标最大距离 int y1 = flyObj.y - this.getImgHeight()/2; //y坐标最小距离 int y2 = flyObj.y + this.getImgHeight()/2 + flyObj.getImgHeight(); //y坐标最大距离 int herox = this.x + this.getImgWidth()/2; //英雄机x坐标中心点距离 int heroy = this.y + this.getImgHeight()/2; //英雄机y坐标中心点距离 return herox>x1 && herox<x2 && heroy>y1 && heroy<y2; //区间范围内为撞上了 } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public BufferedImage getImg() { return img; } public void setImg(String imgPath){ try { this.img = ImageIO.read(FlyingObject.class.getResource(imgPath)); this.imgWidth = this.getImg().getWidth(); this.imgHeight = this.getImg().getHeight(); } catch (IOException e) { System.out.println("读取图片出错!"); e.printStackTrace(); } } public int getFlySpeed() { return flySpeed; } public void setFlySpeed(int flySpeed) { this.flySpeed = flySpeed; } public int getImgWidth() { return imgWidth; } public void setImgWidth(int imgWidth) { this.imgWidth = imgWidth; } public int getImgHeight() { return imgHeight; } public void setImgHeight(int imgHeight) { this.imgHeight = imgHeight; } }
飞机类(Plane)
public abstract class Plane extends FlyingObject implements Attack{ private int attackSpeed; //攻击速度 private int life; //生命值 private Bullet bullet; //装载的武器 private int firepower; //火力值 public Plane() {} @Override public ArrayList<Bullet> launch() { return bullet.getBullet(this.getX() + this.getImgWidth() / 2 - 8 ,this.getY() - 10,firepower); } public int getAttackSpeed() { return attackSpeed; } public void setAttackSpeed(int attackSpeed) { this.attackSpeed = attackSpeed; } public int getLife() { return life; } public void setLife(int life) { this.life = life; } public Bullet getBullet() { return bullet; } public void setBullet(Bullet bullet) { this.bullet = bullet; } public int getFirepower() { return firepower; } public void setFirepower(int firepower) { this.firepower = firepower; } }
生命奖励类(LifePrize)
public class LifePrize extends FlyingObject implements Prize{ public LifePrize(){ this.setFlySpeed(3); this.setImg("../img/prize/bee.png"); } @Override public PrizeCategory getCategory() { // TODO Auto-generated method stub return PrizeCategory.Life; } }
火力加成奖励类(FirePrize)
public class FirePrize extends FlyingObject implements Prize{ public FirePrize(){ this.setFlySpeed(3); this.setImg("../img/prize/fire.png"); } @Override public PrizeCategory getCategory() { // TODO Auto-generated method stub return PrizeCategory.Fire; } }
武器类(Bullet)
/** * 武器总类 * 依赖在飞机类的属性上 * @author sand monk */ public abstract class Bullet extends FlyingObject{ private int hurt; //伤害值 private boolean type; //武器的类别,是敌机发出还是英雄机发出 public Bullet(int x, int y, int flySpeed,int hurt,BufferedImage img, boolean type) { super(x, y, flySpeed, img); this.hurt = hurt; this.type = type; } public Bullet(int x, int y, int flySpeed,int hurt,boolean type) { super(x, y, flySpeed); this.hurt = hurt; this.type = type; } public Bullet() {} /** * 生成子弹 * 留给子类覆盖 * @return */ public abstract ArrayList<Bullet> getBullet(int x , int y ,int firepower); @Override public void step() { if(this.getType()) this.setY(this.getY() - this.getFlySpeed()); else this.setY(this.getY() + this.getFlySpeed()); }; @Override public boolean isTransboundary() { if(type) return this.getY() < 0; else return this.getY() > PlayMain.GAME_HEIGHT; }; public int getHurt() { return hurt; } public void setHurt(int hurt) { this.hurt = hurt; } public boolean getType() { return type; } public void setType(boolean type) { this.type = type; } }
敌人总类(Enemy)
/** * 敌人的总类 * 有一个获取分数的方法 * @author lenovo */ public abstract class Enemy extends Plane{ public abstract int getScope(); }
敌人小兵(CommonEnemy)
/** * 普通的敌机 0号机 * @author sand monk */ public class CommonEnemy extends Enemy{ public CommonEnemy(){ this.setBullet(new CommonBullet(false,"../img/bullet/bullet2.png",6)); this.setAttackSpeed(1); this.setFlySpeed(3); this.setLife(1); this.setFirepower(1); this.setImg("../img/enemy/enemy11.png"); } @Override public int getScope() { // TODO Auto-generated method stub return 10; } }
中级敌人(EnemyThree)
/** * 敌机三号 * @author sand monk * */ public class EnemyThree extends Enemy{ public EnemyThree(){ this.setBullet(new CommonBullet(false,"../img/bullet/bullet2.png",6)); this.setAttackSpeed(1); this.setFlySpeed(1); this.setLife(20); this.setFirepower(2); this.setImg("../img/enemy/enemy3.png"); } @Override public int getScope() { return 100; } }
普通的武器类(CommonBullet)
/** * 普通的子弹 * @author sand monk */ public class CommonBullet extends Bullet{ public CommonBullet(int x, int y, int flySpeed, int hurt, BufferedImage img, boolean type) { super(x, y, flySpeed, hurt , img , type); } public CommonBullet(boolean type ,String imagePath,int flySpeed){ this.setFlySpeed(flySpeed); this.setHurt(1); this.setImg(imagePath); this.setType(type); } @Override public ArrayList<Bullet> getBullet(int x, int y ,int firepower) { ArrayList<Bullet> result = new ArrayList<Bullet>(); if(!this.getType()){ y = y + this.getImgHeight(); } if( firepower >= 3){ result.add(new CommonBullet((x - 15),y,this.getFlySpeed(),this.getHurt(),this.getImg(),this.getType())); result.add(new CommonBullet((x),y,this.getFlySpeed(),this.getHurt(),this.getImg(),this.getType())); result.add(new CommonBullet((x + 15),y,this.getFlySpeed(),this.getHurt(),this.getImg(),this.getType())); } if( firepower == 2){ result.add(new CommonBullet((x + 15),y,this.getFlySpeed(),this.getHurt(),this.getImg(),this.getType())); result.add(new CommonBullet((x - 15),y,this.getFlySpeed(),this.getHurt(),this.getImg(),this.getType())); } if(firepower == 1){ result.add(new CommonBullet(x,y,this.getFlySpeed(),this.getHurt(),this.getImg(),this.getType())); } return result; } }
英雄机(ZeroRedHero)这个名字是根据我找的素材图片取的。。。。。。。。
/** * 零号红色机 * @author sand monk * */ public class ZeroRedHero extends Plane{ /** * 初始化零号机 */ public ZeroRedHero(){ this.setImg("../img/hero/ship-Common.png"); this.setLife(3); // 设置生命值 this.setFlySpeed(999); // 设置飞行速度 this.setAttackSpeed(5);// 设置攻击速度 this.setFirepower(1); // 设置火力值 上限为3 this.setBullet(new CommonBullet(true,"../img/bullet/bullet.png",3)); // 设置武器 this.setX(PlayMain.GAME_WIDTH / 2 / this.getImgWidth() * this.getImgWidth()); this.setY(PlayMain.GAME_HEIGHT - this.getImgHeight()); } }
主方法
@SuppressWarnings("serial") public class PlayMain extends JPanel { // 游戏主界面尺寸 public static final int GAME_WIDTH = 700; public static final int GAME_HEIGHT = 900; private GameStatus gameStatus; // 记录游戏状态 private HeroStatus heroStatus = HeroStatus.Common; // 英雄状态 public static BufferedImage backgroundImg; // 游戏界面背景图 public static BufferedImage pushImg; // 游戏界面背景图 public static BufferedImage gameOverImg; // 游戏界面背景图 private static int heroImgWidth; // 英雄机图片的宽,用来计算画笔的角度 private static int heroImgHeight; // 英雄机图片的高,用来计算画笔的角度 private ArrayList<Bullet> bullets ; // 全图子弹集合 private ArrayList<FlyingObject> flyObjList ; // 飞行物集合 private Plane hero; // 英雄飞机 private Timer timer = new Timer(); // 定时器 public static int intervel = 10; // 界面运动定时器间隔 单位毫秒 10毫秒运动一次,相当于一秒100帧 private int enemyPlanInterver = 0;// 生成敌人飞机定时器 private int launchInterver = 1; // 射击间隔定时器 private int garbageRecoveryInterver = 1000; // 垃圾清理定时器 private long heroVirtualStart = 0; // 英雄虚化状态的开始时间 private int heroAttSpeed = 0;// 英雄的攻击速度 private int score = 0; // 得分 private Random random = new Random(); private JFrame frame; // 窗口框架 private JMenuBar bar; // 菜单 private JMenu game; // 菜单项 private JMenuItem[] items; // 菜单下拉项 private JTextArea textArea; // 右边框 // 初始化背景图在类加载的时候执行一次 static { try { backgroundImg = ImageIO.read(PlayMain.class.getResource("../img/backgrand/back2.jpg")); pushImg = ImageIO.read(PlayMain.class.getResource("../img/status/push.png")); gameOverImg = ImageIO.read(PlayMain.class.getResource("../img/status/gameOver.png")); } catch (IOException e) { e.printStackTrace(); } } public PlayMain() throws IOException { init(); } /** * 初始化所有数据 * @throws IOException */ public void init() throws IOException { // 初始化英雄机 initHeroPlan(); // 初始化UI initUI(); // 游戏状态为启动 gameStatus = GameStatus.Runing; bullets = new ArrayList<Bullet>(); flyObjList = new ArrayList<FlyingObject>(); score = 0; } /** * 初始化UI组件 */ public void initUI() { frame = new JFrame("飞机大战怀旧版"); // 实现窗口框架 textArea = new JTextArea(); bar = new JMenuBar(); // 建立菜单栏 game = new JMenu("菜单"); // 建立名为“游戏”的菜单 items = new JMenuItem[2]; // game菜单下创建2个子菜单项 game.add(items[0] = new JMenuItem("重新开始"));// 第一个子菜单为“重新开始” game.add(items[1] = new JMenuItem("退出")); // 第二个子菜单为“退出” } /** * 初始化英雄机参数 * @throws IOException */ public void initHeroPlan() throws IOException { hero = new ZeroRedHero(); heroImgWidth = hero.getImgWidth(); heroImgHeight = hero.getImgHeight(); heroAttSpeed = hero.getAttackSpeed(); } /** * 画 */ @Override public void paint(Graphics g) { try { drawMainView(g); // 画主界面 drawHero(g); // 画英雄机 drawBullet(g); // 画子弹 drawFlyObject(g); // 画飞行物 drawScore(g); // 画分数 drawGameStatus(g);//画状态 } catch (IOException e) { e.printStackTrace(); } } public void drawMainView(Graphics g) throws IOException { g.drawImage(backgroundImg, 0, 0, null); } public void drawGameStatus(Graphics g){ if(gameStatus == GameStatus.End){ g.drawImage(gameOverImg, 0, 0, null); } if(gameStatus == GameStatus.Suspend){ g.drawImage(pushImg, 0, 0, null); } } public void drawHero(Graphics g) { // 判断是否是虚化状态 boolean commen = true; if (heroStatus != HeroStatus.Common) { // 判断是否是虚化状态 if (heroStatus == HeroStatus.Virtual) { //判断时间有没有超过三秒 if (System.currentTimeMillis() - heroVirtualStart < 3000) { hero.setImg("../img/hero/ship-Virtual.png"); commen = false; } } // 判断是否是无敌状态 if (heroStatus == HeroStatus.Virtual) { if (System.currentTimeMillis() - heroVirtualStart < 3000) { hero.setImg("../img/hero/ship-Virtual.png"); commen = false; } } } if (commen) { heroStatus = HeroStatus.Common; hero.setImg("../img/hero/ship-Common.png"); } g.drawImage(hero.getImg(), hero.getX(), hero.getY(), null); } public void drawBullet(Graphics g) { Bullet bullet; for (int i = 0; i < bullets.size(); i++) { bullet = bullets.get(i); g.drawImage(bullet.getImg(), bullet.getX(), bullet.getY(), null); } } public void drawFlyObject(Graphics g) { FlyingObject flyObj; for (int i = 0; i < flyObjList.size(); i++) { flyObj = flyObjList.get(i); g.drawImage(flyObj.getImg(), flyObj.getX(), flyObj.getY(), null); } } public void drawScore(Graphics g) { int x = 10; // x坐标 int y = 25; // y坐标 Font font = new Font(Font.SANS_SERIF, Font.BOLD, 16); // 字体 g.setColor(Color.RED); g.setFont(font); // 设置字体 g.drawString("得分:" + score, x, y += 20); // 画分数 g.drawString("生命:" + hero.getLife(), x, y += 20); // 画命 g.drawString("攻击速度 :" + heroAttSpeed , x, y += 20); g.drawString("火力值 :" + hero.getFirepower(), x, y += 20); } //打开窗口开始游戏 public void startFrame() { // 鼠标移动事件 addMouseMotionListener(new MouseMotionListener() { @Override public void mouseMoved(MouseEvent e) { int x = e.getX(); int y = e.getY(); textArea.setText(null); textArea.append("PX: ( X:" + x + ", Y:" + y + ")\n"); hero.setX(x - heroImgWidth / 2); hero.setY(y - heroImgHeight / 2); repaint(); } @Override public void mouseDragged(MouseEvent e) { } }); //鼠标移入移出事件 addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { // 鼠标进入 if(gameStatus != GameStatus.End){ gameStatus = GameStatus.Runing; } } @Override public void mouseExited(MouseEvent e) { // 鼠标退出 if(gameStatus != GameStatus.End){ gameStatus = GameStatus.Suspend; } } }); // 点关闭按钮事件 frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { String str = "是否要退出游戏?"; // 添加消息对话框 if (JOptionPane.showConfirmDialog(null, str, "退出游戏", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { System.exit(0); // 退出 } } }); // 点击重新开始事件 items[0].addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String str = "是否要重新开始游戏?"; // 添加消息对话框 if (JOptionPane.showConfirmDialog(null, str, "重新开始", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { try { init(); } catch (IOException e1) { e1.printStackTrace(); } } } }); // 点击退出事件 items[1].addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String str = "是否要退出游戏?"; // 添加消息对话框 if (JOptionPane.showConfirmDialog(null, str, "退出游戏", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { System.exit(0); // 退出 } } }); // 界面运动定时器 timer.schedule(new TimerTask() { @Override public void run() { nextStep(); // 开始运动 randomEnemyPlany(); // 生成敌机 heroShooting(); // 英雄射击 garbageRecovery(); // 垃圾清理 duangGG();// 子弹的碰撞检查 isGameOver();// 检查游戏是否结束 repaint(); // 重绘,调用paint()方法 } }, intervel, intervel); this.setPreferredSize(new Dimension(GAME_WIDTH, GAME_HEIGHT)); // 设置游戏界面的宽高 // 设置右边文本框 textArea.setEditable(false); // 不可编辑 JScrollPane scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrollPane.setPreferredSize(new Dimension(200, GAME_HEIGHT)); scrollPane.setVisible(true); frame.setLayout(new BorderLayout());// 设置布局方式为流式布局 frame.add(this, BorderLayout.WEST); frame.add(scrollPane, BorderLayout.EAST); bar.add(game); frame.setJMenuBar(bar); frame.pack(); frame.setLocation(0, 0); // 电脑窗口的定位 frame.setResizable(false);// 设置此窗口是否可由用户调整大小 frame.setVisible(true); // 设置窗口显示状态 frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); } /** * 随机生成飞行物 */ public void randomEnemyPlany() { if(gameStatus != GameStatus.Runing) return; if (enemyPlanInterver % 50 == 0) { int ran = random.nextInt(20); if (ran == 1) { FlyingObject prize = new LifePrize(); prize.setX(random.nextInt(GAME_WIDTH - prize.getImgWidth())); prize.setY(0); flyObjList.add(prize); } else if (ran == 2) { FlyingObject prize = new FirePrize(); prize.setX(random.nextInt(GAME_WIDTH - prize.getImgWidth())); prize.setY(0); flyObjList.add(prize); } else if (ran > 17) { EnemyThree eplane = new EnemyThree(); eplane.setX(random.nextInt(GAME_WIDTH - eplane.getImgWidth())); eplane.setY(0); flyObjList.add(eplane); } else { CommonEnemy eplane = new CommonEnemy(); eplane.setX(random.nextInt(GAME_WIDTH - eplane.getImgWidth())); eplane.setY(0); flyObjList.add(eplane); } } enemyPlanInterver++; } /** * 运动一步 */ public void nextStep() { if(gameStatus != GameStatus.Runing) return; // 子弹运动 for (int i = 0; i < bullets.size(); i++) bullets.get(i).step(); // 飞行物运动 for (int i = 0; i < flyObjList.size(); i++) flyObjList.get(i).step(); } /** * 射击 */ public void heroShooting() { if(gameStatus != GameStatus.Runing) return; /** * 英雄机射击 */ if (launchInterver % ((1000 / PlayMain.intervel) / heroAttSpeed) == 0) { bullets.addAll(hero.launch()); } /** * 敌机射击 */ Enemy enemy; for (int i = 0; i < flyObjList.size(); i++) { if (flyObjList.get(i) instanceof Enemy) { enemy = (Enemy) flyObjList.get(i); if (launchInterver % ((1000 / PlayMain.intervel) / enemy.getAttackSpeed()) == 0) { bullets.addAll(enemy.launch()); } } } launchInterver++; } /** * 移除越界的飞行物和子弹 */ public void garbageRecovery() { //一秒执行一次 if (garbageRecoveryInterver % (1000 / intervel) == 0) { ArrayList<Bullet> bulletsBak = new ArrayList<Bullet>(); ArrayList<FlyingObject> flyObjListBak = new ArrayList<FlyingObject>(); // 遍历所有子弹 Bullet bullet; for (int i = 0; i < bullets.size(); i++) { bullet = bullets.get(i); if (!bullet.isTransboundary()) bulletsBak.add(bullet); } // 遍历所有飞行物 FlyingObject flyObj; for (int i = 0; i < flyObjList.size(); i++) { flyObj = flyObjList.get(i); if (!flyObj.isTransboundary()) flyObjListBak.add(flyObj); } // 替换集合 bullets = bulletsBak; flyObjList = flyObjListBak; } garbageRecoveryInterver++; } /** * 检查游戏是否结束 */ public void isGameOver(){ if(collision()) gameStatus = GameStatus.End; } /** * 英雄机碰撞检测 * 如果命数为1则游戏结束返回true * @return */ public boolean collision() { /** * 如果是普通状态则进行碰撞检测,碰撞检测成功后,检查命数 如果命数不为0则进入虚化状态,如果为0则游戏结束 */ if (heroStatus == HeroStatus.Common) { //与敌机和奖励的碰撞检查 for (int i = 0; i < flyObjList.size(); i++) { if (flyObjList.get(i).inspectCollision(hero)) { if (flyObjList.get(i) instanceof Prize) { Prize prize = (Prize) flyObjList.get(i); setPrize(prize); // 设置奖励 // 移除飞行物 removeEnemy(i); } else { if (hero.getLife() == 1) { return true; } else { Plane enemy = (Plane) flyObjList.get(i); hero.setLife(hero.getLife() - enemy.getBullet().getHurt()); heroStatus = HeroStatus.Virtual; heroVirtualStart = System.currentTimeMillis(); } } } } //与子弹的碰撞检查 for (int i = 0; i < bullets.size(); i++) { if(!bullets.get(i).getType()){ if (bullets.get(i).inspectCollision(hero)) { if (hero.getLife() == 1) { return true; } else { hero.setLife(hero.getLife() - bullets.get(i).getHurt()); heroStatus = HeroStatus.Virtual; heroVirtualStart = System.currentTimeMillis(); removeBullet(i); } } } } } return false; } /** * 子弹与敌机的碰撞检查 */ public void duangGG() { Bullet bullet; Enemy enemy; Prize prize; // ArrayList<FlyingObject> flyObjBak; // ArrayList<Bullet> bulletsBak; if (!bullets.isEmpty()) { for (int i = 0; i < bullets.size(); i++) { bullet = bullets.get(i); if (!flyObjList.isEmpty()) { flyObj: for (int j = 0; j < flyObjList.size(); j++) { // 如果子弹是英雄机发出 if (bullet.getType()) { if (bullet.inspectCollision(flyObjList.get(j))) { if (flyObjList.get(j) instanceof Prize) {// 判断敌机是伤害敌机还是奖励 /** * 获取奖励内容 设置对应奖励 */ prize = (Prize) flyObjList.get(j); setPrize(prize);// 设置奖励 removeEnemy(j); } else { /** * 用子弹的伤害值与敌机生命值相减 如果敌机生命值为0,删除敌机 */ enemy = (Enemy) flyObjList.get(j); enemy.setLife(enemy.getLife() - bullet.getHurt()); if (enemy.getLife() <= 0) { removeEnemy(j); score += enemy.getScope(); } } // 移除子弹 removeBullet(i); break flyObj; } } } } } } } /** * 设置对应奖励 */ public void setPrize(Prize prize) { if (prize.getCategory() == PrizeCategory.Life) { hero.setLife(hero.getLife() + 1); } if (prize.getCategory() == PrizeCategory.Fire) { hero.setFirepower(hero.getFirepower() + 1); } //懒得写了 - - if (prize.getCategory() == PrizeCategory.Attackspeed) { } if (prize.getCategory() == PrizeCategory.Invincible) { } } /** * 移除飞行物 */ public void removeEnemy(int index) { ArrayList<FlyingObject> listBak = new ArrayList<>(); flyObjList.set(index, flyObjList.get(flyObjList.size() - 1)); for (int i = 0; i < flyObjList.size() - 1; i++) listBak.add(flyObjList.get(i)); flyObjList = listBak; } /** * 移除子弹 */ public void removeBullet(int index){ ArrayList<Bullet> listBak = new ArrayList<>(); bullets.set(index, bullets.get(bullets.size() - 1)); for (int i = 0; i < bullets.size() - 1; i++) listBak.add(bullets.get(i)); bullets = listBak; } public static void main(String[] args) throws IOException { PlayMain plMain = new PlayMain(); plMain.startFrame(); } }