1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Java小游戏之《大鱼吃小鱼》

Java小游戏之《大鱼吃小鱼》

时间:2023-09-22 19:04:18

相关推荐

Java小游戏之《大鱼吃小鱼》

1.GameWin(主类):GameWin extends JFrame, 子类继承父类,创建窗口,设置窗口的变量参数width, heigth ,用于设置窗口大小,在主类中创建launch()方法,用组件类Component的方法设置窗口相关参数并添加窗口图标

public void launch() {Image logo=(new ImageIcon("img/enemyFish/logo.png")).getImage();this.setVisible(true);//设置窗口是否可见this.setSize( width, height);//设置窗口大小this.setLocationRelativeTo(null);//设置窗口在屏幕居中位置this.setIconImage(logo);this.setTitle("大鱼吃小鱼");//设置窗口标题this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //设置关闭窗口按钮

在main()函数中创建GameWin类的对象再调用launch()方法

public static void main(String[] args){GameWin gameWin=new GameWin();gameWin.launch();}

2、创建GameUtils类:在写小游戏的根目录下新建一个文件夹(与游戏时同一级别)

在GameUtils类中为游戏添加背景图(sea.jpg);创建我方鱼的对象以及敌方鱼对象

public static Image beijing = Toolkit.getDefaultToolkit().getImage("img/enemyFish/sea.jpg");//敌方鱼类public static Image enamyl_img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish4_l.png");public static Image enamyr_img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish4_r.png");public static Image enamyl_2img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish1_r.gif");public static Image enamyr_2img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish1_l.gif");public static Image enamyl_3img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish2_r.png");public static Image enamyr_3img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish2_l.png");public static Image enamyl_4img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish3_r.png");public static Image enamyr_4img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish3_l.png ");public static Image bossing =Toolkit.getDefaultToolkit().getImage("img/enemyFish/boss.gif");//我方鱼类public static Image MyFishimg_L =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish_left.gif");public static Image MyFishimg_R =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish_right.gif");public static Image MyFishimg2_L =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish1_l.png");public static Image MyFishimg2_R =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish1_r.png");public static Image MyFishimg3_L =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish3_left.png");public static Image MyFishimg3_R =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish3_right.png");

在GameWin中创建GameUtils对象,重写paint()方法,画出背景图

public void paint(Graphic g){g.drawImage(GameUtils.bgimg,0,0,null);}

由于游戏有5种状态:0未开始,1游戏中,2通关失败,3通关成功,4暂停

在GameWin类中定义游戏默认状态,在launch()方法中用switch()语句定义游戏的五种状态

static int state=0;

在paint方法中用switch语句来定义方法状态创建一个启动方法用来创建窗口信息将背景绘制自身的方法放到游戏状态为1的语句下,在0状态下设置启动页面的背景图,用画笔绘制开始界面文字并设置颜色字体样式大小和坐标;

创建一个背景图的实体类Bg,编写绘制背景的方法,在类中设置游戏五种状态中背景文字

import java.awt.*;//新建一个背景图的实体类public class Bg {void paint(Graphics g,int fishLevel) {//编写绘制背景的方法g.drawImage(GameUtils.beijing,0,0,null);//在绘制背景的方法中定义所需参数switch(GameWin.state) {case 0:GameUtils.drawWord(g,"开始",Color.pink,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.red, 80, 700,500);break;case 4:break;default:}}}

在launch()方法中添加鼠标监听事件,当鼠标点击开始文字时,启动页面消失游戏进入运行状态

//添加鼠标监听事件(匿名内部类:存在于方法区内,执行一瞬间,执行完之后消失)this.addMouseListener(new MouseAdapter(){//启动页面是在游戏最开始的时候显示,此时游戏的状态码为0,当点击启动页面窗口后,进入游戏状态,然后游戏状态码为1启动页面文字消失@Overridepublic void mouseClicked(MouseEvent e) {super.mouseClicked(e);if(e.getButton()==1&&state==0) {//用if判断鼠标左键是否点击并且进入游戏运行状态。鼠标左键state=1;//在鼠标左键点击代码块中将游戏状态改为1并调用paint方法,repaint(); //因为repaint方法会再次调用paint方法,这样才能将改变后的窗口绘制出来 }if(e.getButton()==1&&(state==2||state==3)) {reGame();state=1;}}});

在GameWin中获取Bg类的对象,将背景绘制自身的方法放置在游戏状态为1 的语句下,由于背景需要不断地调用,在launch()方法中添加一个while循环,每间隔40毫秒重复调用repaint()方法(因为repaint()方法会再次调用paint()方法),并在GameWin类中声明一个成员变量time,用于记录repaint()调用次数。

while (true) {repaint();time++;try {Thread.sleep(40);//Thread线程类(Thread类常用方法:public static void sleep(long millis)为当前执行的线程指定睡眠时间。参数millils是线程睡眠的毫秒数。)}catch (InterruptedException e){//sleep()方法必须写在try-catch块内e.printStackTrace();//当try语句中出现异常是时,会执行catch 中的语句,java运行时系统会自动将catch括号中的Exception e 初始化,//也就是实例化Exception类型的对象。e是此对象异常名称。然后e(引用)会自动调用Exception类中指定的方法,也就出现了e.printStackTrace();} //printStackTrace()方法的意思是:在命令行打印异常信息在程序中出错的位置及原因。}

运行程序,查看结果。发现有闪屏现象。

!!!双缓冲解决闪屏现象

使用缓存的方式解决闪屏问题,思路是重新创建一个空的图片,把所有的组件绘制到空的图片上,然后把绘制好的图片一次性绘制到主窗口上

定义一个成员变量offScreenImage,在paint函数中懒加载模式初始化对象

public void paint(Graphics g) {//懒加载模式初始化对象offScreenImage=createImage(width,height);Graphics gImage=offScreenImage.getGraphics();//获取图片对应的画笔对象,把组件绘制到新的图片当中bg.paint(gImage,myFish.level);}

创建Enamy类用于敌方鱼的添加

import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import javax.swing.ImageIcon;//编写敌方鱼的父类public class Enamy {//定义图片Image enamyFish;//定义物体坐标int x, y, width, height;//移动速度int speed;//定义方向用,用于计算敌方鱼的移动方向,从左向右则是1,从右向左则是-1int dir=1;//敌方鱼类型int type;//敌方鱼分值int count;//编写元素绘制自身的方法public void paintSelf(Graphics g) {g.drawImage(enamyFish, x, y, width, height, null);}//和获取自身矩形的方法 用于碰撞检测public Rectangle getRec() {return new Rectangle(x,y,width,height);}}//敌方鱼左类(创建敌方鱼左类,继承敌方鱼父类)class Enamy_1_L extends Enamy{//小鱼左Enamy_1_L(){this.x=-45;this.y=(int)(Math.random()*700+100);this.width=45;this.height=80;this.speed=12;this.count=1;this.type=1;this.enamyFish= GameUtils.enamyl_img;}}//敌方鱼右类class Enamy_1_R extends Enamy_1_L{//小鱼右Enamy_1_R(){this.x=1400;dir=-1;this.enamyFish=GameUtils.enamyr_img;}}class Enamy_2_L extends Enamy{//海马鱼Enamy_2_L(){this.x=-100;this.y=(int)(Math.random()*700+100);this.width=45;this.height=80;this.speed=18;this.count=5;this.type=2;this.enamyFish=GameUtils.enamyl_2img;}}class Enamy_2_R extends Enamy_2_L{Enamy_2_R(){this.x=1400;dir=-1;this.enamyFish=GameUtils.enamyr_2img;}}class Enamy_3_L extends Enamy{//蓝带Enamy_3_L(){this.x=-100;this.y=(int)(Math.random()*700+100);this.width=100;this.height=150; this.speed=18;this.count=8;this.type=3;this.enamyFish=GameUtils.enamyl_3img;}}class Enamy_3_R extends Enamy_3_L{Enamy_3_R(){this.x=1400;dir=-1;this.enamyFish=GameUtils.enamyr_3img; }}class Enamy_4_L extends Enamy{//剑鱼Enamy_4_L(){this.x=-300;this.y=(int)(Math.random()*700+100);this.width=300;this.height=150;this.speed=20;this.count=20;this.type=4;this.enamyFish=GameUtils.enamyl_4img;}public Rectangle getRec() {return new Rectangle(x+40,y+30,width-80,height-60);}}class Enamy_4_R extends Enamy_4_L{Enamy_4_R(){this.x=1400;dir=-1;this.enamyFish=GameUtils.enamyr_4img;}}class Enamy_Boss extends Enamy{Enamy_Boss(){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.enamyFish=GameUtils.bossing;}}

在GameWin中获取Enamy类的对象,在paint()方法中用画笔gImage画出敌方鱼

接下来进行敌方鱼的批量添加,在GameUtils中创建敌方鱼类集合

//创建敌方鱼类集合,实现敌方小鱼的批量添加public static List<Enamy>EnamyList=new ArrayList<>();//在GameWin类中创建logic()方法用于批量添加敌方鱼类

在GameWin类中创建logic()方法用于批量添加敌方鱼类并设置关卡难度

void logic() {//关卡难度if(GameUtils.count<15) {GameUtils.level=0;myFish.level=1;}else if(GameUtils.count<=30) {GameUtils.level=1;}else if(GameUtils.count<=50) {GameUtils.level=2;myFish.level=2;}else if(GameUtils.count<=80) {GameUtils.level=3;myFish.level=3;}else if(GameUtils.count<=100) {GameUtils.level=4;myFish.level=4;}else if(GameUtils.count>300) {state=3;}random=Math.random();//用关卡等级限制敌方鱼的生成:等级0生成敌方第一种鱼;等级1生成敌方第一种鱼和敌方第二种鱼;等级2生成敌方switch(GameUtils.level) {//游戏难度等级case 4: //由于paint()每40毫秒调用一次,生成1条鱼,生成速度过快,所以用time%来限制生成速度if(time%60==0) {if(random>0) { boss=new Enamy_Boss();isboss=true;}}case 3:if(time%50==0) {if(random>0.5) { //random>0.5,让敌方左鱼和敌方右鱼都有一半的概率出现enamy=new Enamy_4_L();}else {enamy=new Enamy_4_R();}GameUtils.EnamyList.add(enamy);}case 2:if(time%30==0) {if(random>0.5) {enamy=new Enamy_3_L();}else {enamy=new Enamy_3_R();}GameUtils.EnamyList.add(enamy);}case 1:if(time%20==0) {if(random>0.5) {enamy=new Enamy_2_L();}else {enamy=new Enamy_2_R();}GameUtils.EnamyList.add(enamy);}case 0://由于敌方鱼需要不断地添加,所以将方法添加到游戏运行状态为1的代码块中//敌方鱼生成if(time%10==0) {if(random>0.5) {enamy=new Enamy_1_L();//将敌方鱼添加到敌方鱼物体的集合中} else {enamy =new Enamy_1_R();}GameUtils.EnamyList.add(enamy);} break;default:}//移动方向for(Enamy enamy:GameUtils.EnamyList) {enamy.x=enamy.x+enamy.dir*enamy.speed;if(isboss) {//boss鱼与敌方鱼的碰撞检测if(boss.getRec().intersects(enamy.getRec())) {enamy.x=-200;enamy.y=-200;}if(boss.getRec().intersects(myFish.getRec())) {state=2;}}//我方鱼与敌方鱼碰撞检测if(myFish.getRec().intersects(enamy.getRec())) {if(myFish.level>=enamy.type) {//把敌方鱼进行移除操作enamy.x=-200;enamy.y=-200;GameUtils.count=GameUtils.count+enamy.count;}else {state=2;}}}}

在GameWin中的launch()方法中添加键盘监听事件

//键盘监听事件this.addKeyListener(new KeyAdapter(){@Overridepublic void keyPressed(KeyEvent e) {super.keyPressed(e);//方向键控制键盘移动if(e.getKeyCode()==KeyEvent.VK_UP) {GameUtils.UP=true;}if(e.getKeyCode()==KeyEvent.VK_DOWN) {GameUtils.DOWN=true;}if(e.getKeyCode()==KeyEvent.VK_LEFT) {GameUtils.LEFT=true;}if(e.getKeyCode()==KeyEvent.VK_RIGHT) {GameUtils.RIGHT=true;}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 keyReleased(KeyEvent 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;}}});

创建我方鱼类MyFish

import java.awt.*;public class MyFish {//图片Image myfish;//坐标int x=700;int y=500;int width=60;int height=60;//移动速度int speed=20;//我方鱼等级int level=1;//添加我方鱼对键盘的控制void logic() {if((GameUtils.UP)&&(y>=30)){//对我方鱼进行边界限制y=y-speed;}if((GameUtils.DOWN)&&(y<=770)) {y=y+speed;}if((GameUtils.LEFT)&&(x>=0)) {x=x-speed;if(GameUtils.level<=1) { //在每一个等级中设定我方鱼的形态myfish=GameUtils.MyFishimg2_L;}else if(GameUtils.level<=3) {myfish=GameUtils.MyFishimg3_L;}else myfish=GameUtils.MyFishimg_L;}if((GameUtils.RIGHT)&&(x<=1377)) {x=x+speed;if(GameUtils.level<=1) {myfish=GameUtils.MyFishimg2_R;}else if(GameUtils.level<=3) {myfish=GameUtils.MyFishimg3_R;}else myfish=GameUtils.MyFishimg_R;}}//绘制自身的方法public void paint(Graphics g) {logic();g.drawImage(myfish, x, y, width+GameUtils.count,height+GameUtils.count, null);}//获取自身矩形的方法,用于碰撞检测 public Rectangle getRec() {return new Rectangle(x,y,width+GameUtils.count,height+GameUtils.count);}}

在GameUtils中定义积分变量和关卡,当我方鱼与敌方鱼碰撞检测后积分增加,并将积分绘制在状态为1的语句下,在GameWin中添加游戏重写方法

void reGame() {GameUtils.EnamyList.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;}

最后为游戏添加背景音乐

创建Test类

import java.io.File;import java.io.IOException;import javax.sound.sampled.AudioFormat;import javax.sound.sampled.AudioInputStream;import javax.sound.sampled.AudioSystem;import javax.sound.sampled.DataLine;import javax.sound.sampled.FloatControl;import javax.sound.sampled.LineUnavailableException;import javax.sound.sampled.SourceDataLine;import javax.sound.sampled.UnsupportedAudioFileException;public class Test extends Thread {private String fileName;private final int EXTERNAL_BUFFER_SIZE = 524288;public Test(String wavFile) {this.fileName = wavFile;}@SuppressWarnings("unused")public void run() {//1.获取要播放的音乐文件名File soundFile = new File(fileName); // 播放音乐的文件名if (!soundFile.exists()) { //用于检查指定的文件在目录中是否存在System.err.println("Wave file not found:" + fileName);return;}while (true) { // 设置循环播放//2.定义 AudioInputStream 用于接收输入的音频数据AudioInputStream audioInputStream = null; // 创建音频输入流对象try {audioInputStream = AudioSystem.getAudioInputStream(soundFile); //3. 创建音频对象,使用AudioSystem来获取音频的输入流(处理(抛出)异常);} catch (UnsupportedAudioFileException e1) {e1.printStackTrace();return;} catch (IOException e1) {e1.printStackTrace();return;}//4.使用AudioFormat来获取AudioInputStream的格式AudioFormat format = audioInputStream.getFormat(); // 音频格式SourceDataLine auline = null; // 5.源数据线DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);//6.获取受数据行支持的音频格式try {auline = (SourceDataLine) AudioSystem.getLine(info);//7、获取与上面类型相匹配的行 写到源数据行里 auline.open(format);8、打开具有指定格式的行,这样可以使行获得资源并进行操作} catch (LineUnavailableException e) {e.printStackTrace();return;} catch (Exception e) {e.printStackTrace();return;}if (auline.isControlSupported(FloatControl.Type.PAN)) {FloatControl pan = (FloatControl) auline.getControl(FloatControl.Type.PAN);}auline.start(); 9、允许某个数据行执行数据i/o//10、写数据int nBytesRead = 0; //读取的总字节数byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];//设置字节数组大小try {//11、从音频流读取指定的最大数量的数据字节,并将其放入给定的字节数组中。while (nBytesRead != -1) { //-1代表没有 不等于-1时就无限读取nBytesRead = audioInputStream.read(abData, 0, abData.length);//12、读取哪个数组if (nBytesRead >= 0) //13、读取了之后将数据写入混频器,开始播放auline.write(abData, 0, nBytesRead);}} catch (IOException e) {e.printStackTrace();return;} finally {//关闭auline.drain();auline.close();}}}}

在main()方法中调用

public static void main(String[] args) throws UnsupportedAudioFileException, IOException, LineUnavailableException {Test audioPlayWave = new Test("img/music/11.wav");// 开音乐 音樂名audioPlayWave.start();@SuppressWarnings("unused")int musicOpenLab = 1;GameWin gameWin=new GameWin();gameWin.launch();}

以上是写游戏的思路仅供参考,在修改和完善之后代码顺序有些乱,下面附上源码

GameWin类

package 游戏; import javax.sound.sampled.LineUnavailableException;import javax.sound.sampled.UnsupportedAudioFileException;import javax.swing.*;import java.awt.Graphics;import java.awt.Color;import java.awt.Font;import java.awt.Image;import java.awt.Toolkit;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.image.ImageObserver;import java.io.IOException;@SuppressWarnings("serial")public class GameWin extends JFrame {/**游戏状态 0未开始,1游戏中,2通关失败,3通关成功,4暂停*/static int state=0;//定义游戏默认状态,在paint方法中用switch语句来定义方法状态//创建一个启动方法用来创建窗口信息//将背景绘制自身的方法放到游戏状态为1的语句下Image offScreenImage;int width=1440;int height=900;double random;//计数器:用于记录游戏的重绘次数和paint()调用次数int time=0;Bg bg=new Bg();//在窗口类中获取背景类的对象,将背景绘制的方法放在游戏状态为1的语句下-case1//敌方鱼类Enamy enamy;//boss类Enamy boss;//是否生成bossboolean isboss=false;//定义一个布尔型用于判断boss是否生成,初始为未生成//我方鱼类MyFish myFish=new MyFish();GameUtils bgimg=new GameUtils();//double random;//使用缓存的方式解决闪屏问题,思路是重新创建一个空的图片,把所有的组件绘制到空的图片上,然后把绘制好的图片一次性绘制到主窗口上//定义一个成员变量offScreenImage,在paint函数中懒加载模式初始化对象/*** */public void launch() {Image logo=(new ImageIcon("img/enemyFish/logo.png")).getImage();this.setVisible(true);//设置窗口是否可见this.setSize( width, height);//设置窗口大小this.setLocationRelativeTo(null);//设置窗口在屏幕居中位置this.setIconImage(logo);this.setTitle("大鱼吃小鱼");//设置窗口标题this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //设置关闭窗口按钮//添加鼠标监听事件(匿名内部类:存在于方法区内,执行一瞬间,执行完之后消失)this.addMouseListener(new MouseAdapter(){//启动页面是在游戏最开始的时候显示,此时游戏的状态码为0,当点击启动页面窗口后,进入游戏状态,然后游戏状态码为1启动页面文字消失@Overridepublic void mouseClicked(MouseEvent e) {super.mouseClicked(e);if(e.getButton()==1&&state==0) {//用if判断鼠标左键是否点击并且进入游戏运行状态。鼠标左键state=1;//在鼠标左键点击代码块中将游戏状态改为1并调用paint方法,repaint(); //因为repaint方法会再次调用paint方法,这样才能将改变后的窗口绘制出来 }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_UP) {GameUtils.UP=true;}if(e.getKeyCode()==KeyEvent.VK_DOWN) {GameUtils.DOWN=true;}if(e.getKeyCode()==KeyEvent.VK_LEFT) {GameUtils.LEFT=true;}if(e.getKeyCode()==KeyEvent.VK_RIGHT) {GameUtils.RIGHT=true;}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 keyReleased(KeyEvent 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) {repaint();time++;try {Thread.sleep(40);//Thread线程类(Thread类常用方法:public static void sleep(long millis)为当前执行的线程指定睡眠时间。参数millils是线程睡眠的毫秒数。)}catch (InterruptedException e){//sleep()方法必须写在try-catch块内e.printStackTrace();//当try语句中出现异常是时,会执行catch 中的语句,java运行时系统会自动将catch括号中的Exception e 初始化,//也就是实例化Exception类型的对象。e是此对象异常名称。然后e(引用)会自动调用Exception类中指定的方法,也就出现了e.printStackTrace();} //printStackTrace()方法的意思是:在命令行打印异常信息在程序中出错的位置及原因。}} public void paint(Graphics g) {//懒加载模式初始化对象offScreenImage=createImage(width,height);Graphics gImage=offScreenImage.getGraphics();//获取图片对应的画笔对象,把组件绘制到新的图片当中bg.paint(gImage,myFish.level);switch(state) {case 0://在状态为0的语句中设置启动页面的背景图break;case 1:myFish.paint(gImage);logic();for(Enamy enamy:GameUtils.EnamyList) {enamy.paintSelf(gImage);}if(isboss) { //boss鱼的移动方向boss.x=boss.x+boss.dir*boss.speed;boss.paintSelf(gImage);if(boss.x<0) {//boss出现预警红线gImage.setColor(Color.red);gImage.fillRect(boss.x, boss.y, 2400,boss.height/30);}}break;case 2:for(Enamy enamy:GameUtils.EnamyList) {enamy.paintSelf(gImage);}if(isboss) {boss.paintSelf(gImage);}break;case 3:myFish.paint(gImage);break;case 4:return;default:}g.drawImage(offScreenImage, 0, 0, null);//将内存当中绘制好的新图片一次性绘制到主窗口中//用画笔g绘制背景图片}//用于批量添加敌方鱼类void logic() {//关卡难度if(GameUtils.count<15) {GameUtils.level=0;myFish.level=1;}else if(GameUtils.count<=30) {GameUtils.level=1;}else if(GameUtils.count<=50) {GameUtils.level=2;myFish.level=2;}else if(GameUtils.count<=80) {GameUtils.level=3;myFish.level=3;}else if(GameUtils.count<=100) {GameUtils.level=4;myFish.level=4;}else if(GameUtils.count>300) {state=3;}random=Math.random();//用关卡等级限制敌方鱼的生成:等级0生成敌方第一种鱼;等级1生成敌方第一种鱼和敌方第二种鱼;等级2生成敌方switch(GameUtils.level) {//游戏难度等级case 4: //由于paint()每40毫秒调用一次,生成1条鱼,生成速度过快,所以用time%来限制生成速度if(time%60==0) {if(random>0) { boss=new Enamy_Boss();isboss=true;}}case 3:if(time%50==0) {if(random>0.5) { //random>0.5,让敌方左鱼和敌方右鱼都有一半的概率出现enamy=new Enamy_4_L();}else {enamy=new Enamy_4_R();}GameUtils.EnamyList.add(enamy);}case 2:if(time%30==0) {if(random>0.5) {enamy=new Enamy_3_L();}else {enamy=new Enamy_3_R();}GameUtils.EnamyList.add(enamy);}case 1:if(time%20==0) {if(random>0.5) {enamy=new Enamy_2_L();}else {enamy=new Enamy_2_R();}GameUtils.EnamyList.add(enamy);}case 0://由于敌方鱼需要不断地添加,所以将方法添加到游戏运行状态为1的代码块中//敌方鱼生成if(time%10==0) {if(random>0.5) {enamy=new Enamy_1_L();//将敌方鱼添加到敌方鱼物体的集合中} else {enamy =new Enamy_1_R();}GameUtils.EnamyList.add(enamy);} break;default:}//移动方向for(Enamy enamy:GameUtils.EnamyList) {enamy.x=enamy.x+enamy.dir*enamy.speed;if(isboss) { //boss鱼与敌方鱼的碰撞检测if(boss.getRec().intersects(enamy.getRec())) {enamy.x=-200; //将敌方鱼的移除操作enamy.y=-200;}if(boss.getRec().intersects(myFish.getRec())) {state=2;}}//我方鱼与敌方鱼碰撞检测if(myFish.getRec().intersects(enamy.getRec())) {if(myFish.level>=enamy.type) {//把敌方鱼进行移除操作enamy.x=-200;enamy.y=-200;GameUtils.count=GameUtils.count+enamy.count;}else {state=2;}}}}void reGame() {GameUtils.EnamyList.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;}//创建main()方法运行launch()方法public static void main(String[] args) throws UnsupportedAudioFileException, IOException, LineUnavailableException {Test audioPlayWave = new Test("img/music/11.wav");// 开音乐 音樂名audioPlayWave.start();@SuppressWarnings("unused")int musicOpenLab = 1;GameWin gameWin=new GameWin();gameWin.launch();}}

GameUtils类

import java.awt.*;import java.util.ArrayList;import java.util.List;import javax.swing.ImageIcon;//创建一个工具类,让工具类定义一个静态类的背景图片public class GameUtils {//添加方向判定,用于对我方鱼移动的控制static boolean UP=false;static boolean DOWN=false;static boolean LEFT=false;static boolean RIGHT=false;//分数static int count=0;//当我方鱼与敌方小鱼碰撞检测后积分加1//关卡等级static int level=0;//创建敌方鱼类集合,实现敌方小鱼的批量添加public static List<Enamy>EnamyList=new ArrayList<>();//在GameWin类中创建logic()方法用于批量添加敌方鱼类//背景图public static Image beijing = Toolkit.getDefaultToolkit().getImage("img/enemyFish/sea.jpg");//敌方鱼类public static Image enamyl_img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish4_l.png");public static Image enamyr_img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish4_r.png");public static Image enamyl_2img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish1_r.gif");public static Image enamyr_2img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish1_l.gif");public static Image enamyl_3img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish2_r.png");public static Image enamyr_3img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish2_l.png");public static Image enamyl_4img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish3_r.png");public static Image enamyr_4img =Toolkit.getDefaultToolkit().getImage("img/enemyFish/fish3_l.png ");public static Image bossing =Toolkit.getDefaultToolkit().getImage("img/enemyFish/boss.gif");//我方鱼类public static Image MyFishimg_L =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish_left.gif");public static Image MyFishimg_R =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish_right.gif");public static Image MyFishimg2_L =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish1_l.png");public static Image MyFishimg2_R =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish1_r.png");public static Image MyFishimg3_L =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish3_left.png");public static Image MyFishimg3_R =Toolkit.getDefaultToolkit().getImage("img/enemyFish/myfish3_right.png");//绘制文字工具类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);}}

Bg类

import java.awt.*;//新建一个背景图的实体类public class Bg {void paint(Graphics g,int fishLevel) {//编写绘制背景的方法g.drawImage(GameUtils.beijing,0,0,null);//在绘制背景的方法中定义所需参数switch(GameWin.state) {case 0:GameUtils.drawWord(g,"开始",Color.pink,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.red, 80, 700,500);break;case 4:break;default:}}}

Enamy类

import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import javax.swing.ImageIcon;//编写敌方鱼的父类public class Enamy {//定义图片Image enamyFish;//定义物体坐标int x, y, width, height;//移动速度int speed;//定义方向用,用于计算敌方鱼的移动方向,从左向右则是1,从右向左则是-1int dir=1;//敌方鱼类型int type;//敌方鱼分值int count;//编写元素绘制自身的方法public void paintSelf(Graphics g) {g.drawImage(enamyFish, x, y, width, height, null);}//和获取自身矩形的方法 用于碰撞检测public Rectangle getRec() {return new Rectangle(x,y,width,height);}}//敌方鱼左类(创建敌方鱼左类,继承敌方鱼父类)class Enamy_1_L extends Enamy{//小鱼左Enamy_1_L(){this.x=-45;this.y=(int)(Math.random()*700+100);this.width=45;this.height=80;this.speed=12;this.count=1;this.type=1;this.enamyFish= GameUtils.enamyl_img;}}//敌方鱼右类class Enamy_1_R extends Enamy_1_L{//小鱼右Enamy_1_R(){this.x=1400;dir=-1;this.enamyFish=GameUtils.enamyr_img;}}class Enamy_2_L extends Enamy{//海马鱼Enamy_2_L(){this.x=-100;this.y=(int)(Math.random()*700+100);this.width=45;this.height=80;this.speed=18;this.count=5;this.type=2;this.enamyFish=GameUtils.enamyl_2img;}}class Enamy_2_R extends Enamy_2_L{Enamy_2_R(){this.x=1400;dir=-1;this.enamyFish=GameUtils.enamyr_2img;}}class Enamy_3_L extends Enamy{//蓝带Enamy_3_L(){this.x=-100;this.y=(int)(Math.random()*700+100);this.width=100;this.height=150; this.speed=18;this.count=8;this.type=3;this.enamyFish=GameUtils.enamyl_3img;}}class Enamy_3_R extends Enamy_3_L{Enamy_3_R(){this.x=1400;dir=-1;this.enamyFish=GameUtils.enamyr_3img; }}class Enamy_4_L extends Enamy{//剑鱼Enamy_4_L(){this.x=-300;this.y=(int)(Math.random()*700+100);this.width=300;this.height=150;this.speed=20;this.count=20;this.type=4;this.enamyFish=GameUtils.enamyl_4img;}public Rectangle getRec() {return new Rectangle(x+40,y+30,width-80,height-60);}}class Enamy_4_R extends Enamy_4_L{Enamy_4_R(){this.x=1400;dir=-1;this.enamyFish=GameUtils.enamyr_4img;}}class Enamy_Boss extends Enamy{Enamy_Boss(){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.enamyFish=GameUtils.bossing;}}

MyFish类

import java.awt.*;public class MyFish {//图片Image myfish;//坐标int x=700;int y=500;int width=60;int height=60;//移动速度int speed=20;//我方鱼等级int level=1;//添加我方鱼对键盘的控制void logic() {if((GameUtils.UP)&&(y>=30)){//对我方鱼进行边界限制y=y-speed;}if((GameUtils.DOWN)&&(y<=770)) {y=y+speed;}if((GameUtils.LEFT)&&(x>=0)) {x=x-speed;if(GameUtils.level<=1) { //在每一个等级中设定我方鱼的形态myfish=GameUtils.MyFishimg2_L;}else if(GameUtils.level<=3) {myfish=GameUtils.MyFishimg3_L;}else myfish=GameUtils.MyFishimg_L;}if((GameUtils.RIGHT)&&(x<=1377)) {x=x+speed;if(GameUtils.level<=1) {myfish=GameUtils.MyFishimg2_R;}else if(GameUtils.level<=3) {myfish=GameUtils.MyFishimg3_R;}else myfish=GameUtils.MyFishimg_R;}}//绘制自身的方法public void paint(Graphics g) {logic();g.drawImage(myfish, x, y, width+GameUtils.count,height+GameUtils.count, null);}//获取自身矩形的方法,用于碰撞检测 public Rectangle getRec() {return new Rectangle(x,y,width+GameUtils.count,height+GameUtils.count);}}

Test类同上方Test

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。