java小游戏-java小游戏-大鱼吃小鱼
- 1 创建窗口
- 2 添加背景图
- 3 启动封面
- 4 启动页面的点击事件
- 5 游戏开始时的背景添加
- 6 双缓存解决闪屏问题
- 7 地方第一条小鱼的添加
- 8 敌方左方小鱼批量添加
- 9 我方鱼生成
- 10 我方鱼吃敌方小鱼的碰撞检测
- 11 游戏积分的实现
- 12 关卡的设置
- 13 界面绘制
- 14 右侧敌方鱼的生成和多种鱼的生成
- 15 boss鱼的添加
- 16 暂停功能和重新开始功能实现
连接视频
1 创建窗口
创建GameApp类
public class GameApp extends JFrame {//宽高int width = 1440;int height = 900;void launch(){this.setVisible(true);this.setSize(width,height);this.setLocationRelativeTo(null);//设置游戏窗口不可改变this.setResizable(false);this.setTitle("大鱼吃小鱼");this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {GameApp gameApp = new GameApp();gameApp.launch();}}
2 添加背景图
先上传准备的图片
创建GameUtils类
/*** 工具类*/
public class GameUtils {//背景图片public static Image bjimg = Toolkit.getDefaultToolkit().createImage("img/bj.jpg");}
在GameApp类重写paint方法
@Override
public void paint(Graphics g) {g.drawImage(GameUtils.bjimg,0,0,null);
}
3 启动封面
在GameApp类添加参数,修改paint方法
//游戏状态 0 未开始 1 游戏中 2 通关失败 3 通关完成 4 暂停
static int state = 0;@Override
public void paint(Graphics g) {g.drawImage(GameUtils.bjimg,0,0,null);switch (state){case 0:g.drawImage(GameUtils.bjimg,0,0,null);g.setColor(Color.pink);g.setFont(new Font("仿宋",Font.BOLD,80));g.drawString("开始",700,500);break;case 1:break;case 2:break;case 3:break;case 4:break;}}
4 启动页面的点击事件
在GameApp类添加鼠标监听事件
void launch(){...this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//鼠标监听事件this.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {super.mouseClicked(e);if(e.getButton() == 1 && state == 0){//鼠标左键点击state = 1;repaint();}}});
}
5 游戏开始时的背景添加
创建Bj类
/*** 背景类*/
public class Bj {void paintSelf(Graphics g){g.drawImage(GameUtils.bjimg,0,0,null);}}
在GameApp类中引用
Bj bj = new Bj();void launch(){...while (true){repaint();try {Thread.sleep(40);} catch (InterruptedException e) {e.printStackTrace();}}
}@Override
public void paint(Graphics g) {g.drawImage(GameUtils.bjimg,0,0,null);switch (state){case 0:g.drawImage(GameUtils.bjimg,0,0,null);g.setColor(Color.pink);g.setFont(new Font("仿宋",Font.BOLD,80));g.drawString("开始",700,500);break;case 1:bj.paintSelf(g);break;case 2:break;case 3:break;case 4:break;}}
6 双缓存解决闪屏问题
在GameApp类添加画屏
Image offScreenImage = null;@Override
public void paint(Graphics g) {//懒加载模式初始化对象offScreenImage = createImage(width,height);Graphics graphics = offScreenImage.getGraphics();switch (state){case 0:graphics.drawImage(GameUtils.bjimg,0,0,null);graphics.setColor(Color.pink);graphics.setFont(new Font("仿宋",Font.BOLD,80));graphics.drawString("开始",700,500);break;case 1:bj.paintSelf(graphics);break;case 2:break;case 3:break;case 4:break;}g.drawImage(offScreenImage,0,0,null);
}
7 地方第一条小鱼的添加
在GameUtils类添加敌方小鱼图片
//敌方鱼类
public static Image enemy1_img = Toolkit.getDefaultToolkit().createImage("img/finsh1_r.gif");
创建Enemy类
/*** 敌方类*/
public class Enemy {//定义图片Image image;//定义物体坐标int x,y;int width,height;//移动速度int speed;//方向 1 从左到右 -1 从右到左int dir = 1;//类型int type;//分值int count;//绘制自身方法public void paintSelf(Graphics g){g.drawImage(image,x,y,width,height,null);}//获取自身矩形用于碰撞检测public Rectangle getRec(){return new Rectangle(x,y,width,height);}
}
创建Enemy_1_L类
/*** 敌方鱼的左类*/
public class Enemy_1_L extends Enemy{public Enemy_1_L(){this.x = -45;this.y = (int)(Math.random()*700 + 100);this.width = 45;this.height = 69;this.speed = 10;this.count = 1;this.type = 1;this.image = GameUtils.enemy1_img;}}
在GameApp类创建敌方鱼类对象,修改paint方法
//敌方鱼类
Enemy enemy = new Enemy_1_L();public void paint(Graphics g) {...switch (state){...case 1:bj.paintSelf(graphics);enemy.x += enemy.speed;enemy.paintSelf(graphics);break;case 2:...
}
8 敌方左方小鱼批量添加
在GameUtils类创建敌方鱼集合
//敌方鱼类集合
public static List<Enemy> enemyList = new ArrayList<>();
修改GameApp类添加方法
double random;
//计数器
int time = 0;void launch() {...while (true) {repaint();time++;try {Thread.sleep(40);} catch (InterruptedException e) {e.printStackTrace();}}
}public void paint(Graphics g) {...switch (state){...case 1:bj.paintSelf(graphics);logic();for (Enemy e : GameUtils.enemyList) {e.paintSelf(graphics);}break;case 2:...
}void logic() {//敌方鱼生成if (time % 10 == 0) {enemy = new Enemy_1_L();GameUtils.enemyList.add(enemy);}//移动方向for (Enemy e : GameUtils.enemyList) {e.x = e.x + e.dir * e.speed;}
}
9 我方鱼生成
在GameUtils添加参数
//我方鱼类
public static Image myFishimg_l = Toolkit.getDefaultToolkit().createImage("img/myfishimg_l.gif");
public static Image myFishimg_r = Toolkit.getDefaultToolkit().createImage("img/myfishimg_r.gif");//我方鱼方向
static boolean UP = false;
static boolean DOWN = false;
static boolean LEFT = false;
static boolean RIGHT = false;
创建MyFish类
/*** 我方鱼类*/
public class MyFish {//图片Image image;//坐标int x = 700, y = 500;int width = 50, height = 50;//移动速度int speed = 20;//等级int level = 1;void logic() {if (GameUtils.UP) {y = y - speed;}if (GameUtils.DOWN) {y = y + speed;}if (GameUtils.LEFT) {x = x - speed;image = GameUtils.myFishimg_l;}if (GameUtils.RIGHT) {x = x + speed;image = GameUtils.myFishimg_r;}}//绘制自身方法public void paintSelf(Graphics g) {logic();g.drawImage(image, x, y, width, height, null);}//获取自身矩形方法,用于碰撞判断public Rectangle getRec() {return new Rectangle(x, y, width, height);}
}
在GameApp类引用对象
//我方鱼
MyFish myFish = new MyFish();void launch() {...@Overridepublic void keyReleased(KeyEvent e) {//键抬起super.keyReleased(e);if(e.getKeyCode() == KeyEvent.VK_UP){//↑GameUtils.UP = false;}if(e.getKeyCode() == KeyEvent.VK_DOWN){//↓GameUtils.DOWN = false;}if(e.getKeyCode() == KeyEvent.VK_LEFT){//←GameUtils.LEFT = false;}if(e.getKeyCode() == KeyEvent.VK_RIGHT){//→GameUtils.RIGHT = false;}}});while (true) {...@Override
public void paint(Graphics g) {...case 1:bj.paintSelf(graphics);myFish.paintSelf(graphics);logic();for (Enemy e : GameUtils.enemyList) {e.paintSelf(graphics);}break;case 2:break;case 3:break;case 4:break;}g.drawImage(offScreenImage, 0, 0, null);
}
10 我方鱼吃敌方小鱼的碰撞检测
在GameApp类修改logic方法
void logic() {//敌方鱼生成if (time % 10 == 0) {enemy = new Enemy_1_L();GameUtils.enemyList.add(enemy);}//移动方向for (Enemy e : GameUtils.enemyList) {e.x = e.x + e.dir * e.speed;//我方鱼与敌方鱼碰撞检测if(myFish.getRec().intersects(e.getRec())){System.out.println("碰撞了");e.x = -200;e.y = -200;}}
}
11 游戏积分的实现
在GameUtils类添加常量
//分数
static int count = 0;
在MyFish类修改方法
//绘制自身方法
public void paintSelf(Graphics g) {logic();g.drawImage(image, x, y, width + GameUtils.count, height+ GameUtils.count, null);
}//获取自身矩形方法,用于碰撞判断
public Rectangle getRec() {return new Rectangle(x, y, width + GameUtils.count, height + GameUtils.count);
}
在GameApp类修改相关方法
@Override
public void paint(Graphics g) {...case 1:bj.paintSelf(graphics);//打印积分graphics.setColor(Color.ORANGE);graphics.setFont(new Font("仿宋", Font.BOLD, 50));graphics.drawString("积分" + GameUtils.count,200,120);myFish.paintSelf(graphics);logic();for (Enemy e : GameUtils.enemyList) {e.paintSelf(graphics);}break;case 2:break;case 3:break;case 4:break;}g.drawImage(offScreenImage, 0, 0, null);
}void logic() {...//移动方向for (Enemy e : GameUtils.enemyList) {e.x = e.x + e.dir * e.speed;//我方鱼与敌方鱼碰撞检测if(myFish.getRec().intersects(e.getRec())){System.out.println("碰撞了");e.x = -200;e.y = -200;GameUtils.count = GameUtils.count+e.count;}}
}
12 关卡的设置
在GameUtils类添加常量
//关卡的等级
static int level = 0;
在GameApp类修改相关方法
@Override
public void paint(Graphics g) {....case 3:myFish.paintSelf(graphics);graphics.setColor(Color.orange);graphics.setFont(new Font("仿宋", Font.BOLD, 80));graphics.drawString("积分" + GameUtils.count,200,120);graphics.drawString("胜利",400,500);break;case 4:break;}g.drawImage(offScreenImage, 0, 0, null);
}void logic() {//关卡的难度if (GameUtils.count < 5) {GameUtils.level = 0;myFish.level = 1;}else if(GameUtils.count <= 15){GameUtils.level = 1;}else if(GameUtils.count <= 50){GameUtils.level = 2;myFish.level = 2;}else if(GameUtils.count <= 150){GameUtils.level = 3;myFish.level = 3;}else if(GameUtils.count <= 300){GameUtils.level = 4;myFish.level = 3;}else if(GameUtils.count > 300){state = 3;}//敌方鱼生成...
}
13 界面绘制
在GameUtils类添加方法
//绘制文字的工具方法
public static void drawWord(Graphics g,String str,Color color,int size,int x,int y){g.setColor(color);g.setFont(new Font("仿宋", Font.BOLD, size));g.drawString(str,x,y);
}
在GameApp类修改相关方法
@Override
public void paint(Graphics g) {//懒加载模式初始化对象offScreenImage = createImage(width, height);Graphics graphics = offScreenImage.getGraphics();bj.paintSelf(graphics,myFish.level);switch (state) {case 0:break;case 1:myFish.paintSelf(graphics);logic();for (Enemy e : GameUtils.enemyList) {e.paintSelf(graphics);}break;case 2:break;case 3:myFish.paintSelf(graphics);break;case 4:break;}g.drawImage(offScreenImage, 0, 0, null);
}
在Bj类修改paintSelf方法
void paintSelf(Graphics g, int fishLevel) {g.drawImage(GameUtils.bjimg, 0, 0, null);switch (GameApp.state) {case 0:GameUtils.drawWord(g, "开始", Color.red, 80, 700, 500);break;case 1:GameUtils.drawWord(g, "积分" + GameUtils.count, Color.orange, 50, 200, 120);GameUtils.drawWord(g, "难度" + GameUtils.level, Color.orange, 50, 600, 120);GameUtils.drawWord(g, "等级" + fishLevel, Color.orange, 50, 1000, 120);break;case 2:break;case 3:GameUtils.drawWord(g, "积分" + GameUtils.count, Color.orange, 50, 200, 120);GameUtils.drawWord(g, "难度" + GameUtils.level, Color.orange, 50, 600, 120);GameUtils.drawWord(g, "等级" + fishLevel, Color.orange, 50, 1000, 120);GameUtils.drawWord(g, "胜利", Color.orange, 80, 700, 500);break;case 4:break;default:}
}
14 右侧敌方鱼的生成和多种鱼的生成
在GameUtils类添加参数
//敌方鱼类
public static Image enemy1_img = Toolkit.getDefaultToolkit().createImage("img/finsh1_r.gif");
public static Image enemyr_img = Toolkit.getDefaultToolkit().createImage("img/finsh1_l.gif");public static Image enemyl_2img = Toolkit.getDefaultToolkit().createImage("img/finsh2_r.png");
public static Image enemyr_2img = Toolkit.getDefaultToolkit().createImage("img/finsh2_l.png");
public static Image enemyl_3img = Toolkit.getDefaultToolkit().createImage("img/finsh3_r.png");
public static Image enemyr_3img = Toolkit.getDefaultToolkit().createImage("img/finsh3_l.png");
创建Enemy_1_R类,Enemy_2_L类,Enemy_2_R类,Enemy_3_L类,Enemy_3_R类
public class Enemy_1_R extends Enemy_1_L {public Enemy_1_R(){this.x = 1400;dir = -1;this.image = GameUtils.enemyr_img;}
}public class Enemy_2_L extends Enemy{public Enemy_2_L(){this.x = -100;this.y = (int)(Math.random()*700 + 100);this.width = 100;this.height = 100;this.speed = 5;this.count = 2;this.type = 2;this.image = GameUtils.enemyl_2img;}
}public class Enemy_2_R extends Enemy_2_L{public Enemy_2_R(){this.x = 1400;dir = -1;this.image = GameUtils.enemyr_2img;}
}public class Enemy_3_L extends Enemy{public Enemy_3_L(){this.x = -300;this.y = (int)(Math.random()*700 + 100);this.width = 300;this.height = 150;this.speed = 15;this.type = 3;this.image = GameUtils.enemyl_3img;}@Overridepublic Rectangle getRec() {return new Rectangle(x+40,y+30,width-80,height-60);}
}public class Enemy_3_R extends Enemy_3_L{public Enemy_3_R(){this.x = 1400;dir = -1;this.image = GameUtils.enemyr_3img;}
}
在GameApp类修改相关方法
@Override
public void paint(Graphics g) {//懒加载模式初始化对象offScreenImage = createImage(width, height);Graphics graphics = offScreenImage.getGraphics();bj.paintSelf(graphics, myFish.level);switch (state) {case 0:break;case 1:myFish.paintSelf(graphics);logic();for (Enemy e : GameUtils.enemyList) {e.paintSelf(graphics);}break;case 2:for (Enemy e : GameUtils.enemyList) {e.paintSelf(graphics);}break;case 3:myFish.paintSelf(graphics);break;case 4:break;}g.drawImage(offScreenImage, 0, 0, null);
}void logic() {....random = Math.random();//敌方鱼生成switch (GameUtils.level) {case 4:case 3:case 2:if (time % 30 == 0) {if (random > 0.5) {enemy = new Enemy_3_L();} else {enemy = new Enemy_3_R();}GameUtils.enemyList.add(enemy);}case 1:if (time % 20 == 0) {if (random > 0.5) {enemy = new Enemy_2_L();} else {enemy = new Enemy_2_R();}GameUtils.enemyList.add(enemy);}case 0:if (time % 10 == 0) {if (random > 0.5) {enemy = new Enemy_1_L();} else {enemy = new Enemy_1_R();}GameUtils.enemyList.add(enemy);}break;default:}//移动方向for (Enemy e : GameUtils.enemyList) {e.x = e.x + e.dir * e.speed;//我方鱼与敌方鱼碰撞检测if (myFish.getRec().intersects(e.getRec())) {if (myFish.level >= e.type) {System.out.println("碰撞了");e.x = -200;e.y = -200;GameUtils.count = GameUtils.count + e.count;} else {state = 2;}}}
}
在Bj类添加失败绘制
void paintSelf(Graphics g, int fishLevel) {g.drawImage(GameUtils.bjimg, 0, 0, null);switch (GameApp.state) {...case 2:GameUtils.drawWord(g, "积分" + GameUtils.count, Color.orange, 50, 200, 120);GameUtils.drawWord(g, "难度" + GameUtils.level, Color.orange, 50, 600, 120);GameUtils.drawWord(g, "等级" + fishLevel, Color.orange, 50, 1000, 120);GameUtils.drawWord(g, "失败", Color.orange, 80, 700, 500);break;case 3:...}
}
15 boss鱼的添加
在GameUtils类添加参数
public static Image bossimg = Toolkit.getDefaultToolkit().createImage("img/boss.gif");
创建BossEnemy类
public class BossEnemy extends Enemy{public BossEnemy(){this.x = -1000;this.y = (int)(Math.random()*700 + 100);this.width = 340;this.height = 340;this.speed = 100;this.count = 0;this.type = 10;this.image = GameUtils.bossimg;}
}
在GameApp类修改相关方法
//boss鱼
BossEnemy boss;
//是否生成boss
boolean isBoss = false;@Override
public void paint(Graphics g) {//懒加载模式初始化对象offScreenImage = createImage(width, height);Graphics graphics = offScreenImage.getGraphics();bj.paintSelf(graphics, myFish.level);switch (state) {case 0:break;case 1:myFish.paintSelf(graphics);logic();for (Enemy e : GameUtils.enemyList) {e.paintSelf(graphics);}if(isBoss){boss.x = boss.x + boss.dir*boss.speed;boss.paintSelf(graphics);if(boss.x < 0){graphics.setColor(Color.red);graphics.fillRect(boss.x,boss.y,2400,boss.height/30);}}break;case 2:for (Enemy e : GameUtils.enemyList) {e.paintSelf(graphics);}if(isBoss){boss.paintSelf(graphics);}break;case 3:myFish.paintSelf(graphics);break;case 4:break;}g.drawImage(offScreenImage, 0, 0, null);
}void logic() {...random = Math.random();//敌方鱼生成switch (GameUtils.level) {case 4:if(time%60==0){if(random > 0){boss = new BossEnemy();isBoss = true;}}case 3:case 2:if (time % 30 == 0) {if (random > 0.5) {enemy = new Enemy_3_L();} else {enemy = new Enemy_3_R();}GameUtils.enemyList.add(enemy);}case 1:if (time % 20 == 0) {if (random > 0.5) {enemy = new Enemy_2_L();} else {enemy = new Enemy_2_R();}GameUtils.enemyList.add(enemy);}case 0:if (time % 10 == 0) {if (random > 0.5) {enemy = new Enemy_1_L();} else {enemy = new Enemy_1_R();}GameUtils.enemyList.add(enemy);}break;default:}//移动方向for (Enemy e : GameUtils.enemyList) {e.x = e.x + e.dir * e.speed;if(isBoss){if(boss.getRec().intersects(e.getRec())){e.x = -200;e.y = -200;}if(boss.getRec().intersects(myFish.getRec())){state =2;}}//我方鱼与敌方鱼碰撞检测if (myFish.getRec().intersects(e.getRec())) {if (myFish.level >= e.type) {System.out.println("碰撞了");e.x = -200;e.y = -200;GameUtils.count = GameUtils.count + e.count;} else {state = 2;}}}
}
16 暂停功能和重新开始功能实现
在GameApp类修改相关方法
void launch() {...//鼠标监听事件this.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {super.mouseClicked(e);if (e.getButton() == 1 && state == 0) {//鼠标左键点击state = 1;repaint();}if (e.getButton() == 1 && (state == 2 || state == 3)) {reGame();state =1;}}});//键盘移动this.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {//键按压super.keyPressed(e);....if (e.getKeyCode() == KeyEvent.VK_SPACE) {//空格键switch (state){case 1:state =4;GameUtils.drawWord(getGraphics(),"游戏暂停!!!",Color.red,50,600,400);break;case 4:state =1;break;}}}...
}@Override
public void paint(Graphics g) {...switch (state) {case 0:break;case 1:myFish.paintSelf(graphics);logic();for (Enemy e : GameUtils.enemyList) {e.paintSelf(graphics);}if(isBoss){boss.x = boss.x + boss.dir*boss.speed;boss.paintSelf(graphics);if(boss.x < 0){graphics.setColor(Color.red);graphics.fillRect(boss.x,boss.y,2400,boss.height/30);}}break;case 2:for (Enemy e : GameUtils.enemyList) {e.paintSelf(graphics);}if(isBoss){boss.paintSelf(graphics);}break;case 3:myFish.paintSelf(graphics);break;case 4:return;default:}g.drawImage(offScreenImage, 0, 0, null);
}//重新开始
void reGame(){GameUtils.enemyList.clear();time = 0;myFish.level = 1;GameUtils.count = 0;myFish.x = 700;myFish.y = 500;myFish.width = 50;myFish.height = 50;boss = null;isBoss = false;
}