java开发的小游戏 恐龙在奔跑

项目名称是Dinosaur

 在src文件中,建立了4个包,依次是com.mr.main,com.mr.modle,com.mr.service,com.mr.view。

 代码文件分别是Start.java,Dinosaur.java,Obstacle.java,FreshThread.java,MusicPlayer.java,ScoreRecorder.java,sound.java,BackgroundImage.java,GamePanel.java,MainFrame.java,ScoreDialog.java。

 上图是其他文件夹的结构,我会把图片文件和音乐文件也上传。

那个data文件夹的source,里面的内容是

870,1160,1970

 下面开始上代码:

Start.java

package com.mr.main; //入口包

import com.mr.view.MainFrame;

//启动类
public class Start
{

	public static void main(String[] args)
	{
		MainFrame m1 = new MainFrame();
		m1.setVisible(true);

	}

}

Dinosaur.java

package com.mr.modle;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.xml.crypto.dsig.keyinfo.RetrievalMethod;

import com.mr.service.FreshThread;
import com.mr.service.Sound;

//模型包
//恐龙类
public class Dinosaur
{
	public BufferedImage image; 						//主图片
	private BufferedImage image1,image2,image3; 		//跑步图片
	public int x,y; 									//坐标
	private int jumpValue = 0; 							//跳跃的增变量
	private boolean jumpState = false; 					//跳跃状态
	private int stepTimer = 0; 							//踏步计时器
	private final int JUMP_HEIGHT = 105;				//跳起最大高度
	private final int LOWEST_Y = 120; 					//落地最低坐标
	private final int FREASH = FreshThread.FREASH; 		//刷新时间

	public Dinosaur()
	{
		this.x = 50;
		this.y = LOWEST_Y;
		try
		{
			image1 = ImageIO.read(new File("image/konglong1.png"));
			image2 = ImageIO.read(new File("image/konglong2.png"));
			image3 = ImageIO.read(new File("image/konglong3.png"));
			
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	private void step()
	{
		//每过250毫秒,更换一张图片。因为有3张,所以除以3取余,轮流
		
		int temp = (stepTimer / 250) % 3;
		switch (temp)
		{
		case 1:
			image = this.image1;
			break;
		case 2:
			image = this.image2;
			break;
		default:
			image = this.image3;
			break;
		}
		
		stepTimer += FREASH;
	}
	
	public void jump()
	{
		if (!jumpState)
		{
			Sound.jump();  //播放跳跃的音效
		}
		jumpState = true; //处于跳跃状态
	}

	public void move()
	{
		step();
		if (jumpState)
		{
			if (y >= LOWEST_Y)
			{
				jumpValue = -4;  //如果纵坐标大于等于最低点
			}
			if (y <= LOWEST_Y - JUMP_HEIGHT)
			{
				jumpValue = 4; //如果跳过最高点
			}
			y+= jumpValue;
			if (y >= LOWEST_Y)
			{
				jumpState = false; //如果再次落地
			}
		}
	}
	
	public Rectangle getFootBounds()
	{
		return new Rectangle(x+30,y+59,29,18);
	}
	
	public Rectangle getHeadBounds()
	{
		return new Rectangle(x+66,y+25,32,22);
	}
}

Obstacle.java

package com.mr.modle;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;

import com.mr.view.BackgroundImage;

//障碍类
public class Obstacle
{
	public int x,y; 
	public BufferedImage image;
	private BufferedImage stone; //石头
	private BufferedImage cacti; //仙人掌
	private int speed; //移动速度
	
	public Obstacle()
	{
		try
		{
			stone = ImageIO.read(new File("image/stone.jpg"));
			cacti = ImageIO.read(new File("image/cacti.jpg"));
			
		} catch (IOException e)
		{
			e.printStackTrace();
		}
		Random r1 = new Random();
		if (r1.nextInt(2) == 0)
		{
			image = cacti; //为0,仙人掌
		}
		else 
		{
			image = stone; //为1,石头
		}
		x = 800;
		y = 220 - image.getHeight();
		speed = BackgroundImage.SPEED;  // 移动速度与背景速度一致
	}
	
	public void move()
	{
		x -= speed;
	}
	
	public boolean isLive()
	{
		if (x <= -image.getWidth())
		{
			return false;
		}
		return true;
	}
	
	public Rectangle getBounds()
	{
		if (image == cacti)
		{
			return new Rectangle(x+7,y,15,image.getHeight()); //仙人掌
		}
		return new Rectangle(x+5,y+4,23,21); //石头
	}
}

FreshThread.java

package com.mr.service;

import java.awt.Container;

import com.mr.view.GamePanel;
import com.mr.view.MainFrame;
import com.mr.view.ScoreDialog;

//服务包
//刷新帧线程
public class FreshThread extends Thread
{
	public static final int FREASH = 20; //刷新时间
	GamePanel panel; //游戏面板
	
	public FreshThread(GamePanel p)
	{
		this.panel = p;
	}
	
	public void run()
	{
		while (!panel.isFinish())
		{
			panel.repaint();
			try
			{
				Thread.sleep(FREASH);
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
		Container container1 = panel.getParent();
		while (!(container1 instanceof MainFrame))
		{
			container1 = container1.getParent();
		}
		MainFrame frame = (MainFrame)container1;
		new ScoreDialog(frame);
		frame.restart();
	}
	

}

MusicPlayer.java

package com.mr.service;

import java.io.File;
import java.io.FileNotFoundException;
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.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

//音乐播放器类
public class MusicPlayer implements Runnable
{
	File soundFile; //音乐文件
	Thread thread;  //父线程
	boolean circulate; //循环播放
	
	public MusicPlayer(String filePath,boolean circulate) throws FileNotFoundException
	{
		this.circulate = circulate;
		soundFile  = new File(filePath);
		if (!soundFile.exists())
		{
			throw new FileNotFoundException(filePath + "未找到");
		}
	}

	public void run()
	{
		byte[] auBuffer = new byte[1024 * 128]; //128k缓冲区
		do
		{
			AudioInputStream audioInputStream = null; //音频输入流
			SourceDataLine auLine = null; //混频器数据行
			try
			{
				audioInputStream = AudioSystem.getAudioInputStream(soundFile);
				AudioFormat format = audioInputStream.getFormat();
				DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
				auLine = (SourceDataLine)AudioSystem.getLine(info);
				auLine.open(format);
				auLine.start();
				int byteCount = 0;
				while (byteCount != -1)
				{
					byteCount = audioInputStream.read(auBuffer,0,auBuffer.length);
					if (byteCount >= 0)
					{
						auLine.write(auBuffer, 0, byteCount);
					}
				}
			}catch (IOException e)
			{
				e.printStackTrace();
			}
			catch (UnsupportedAudioFileException e) 
			{
				e.printStackTrace();
			}
			catch (LineUnavailableException e) 
			{
				e.printStackTrace();
			}finally
			{
				auLine.drain();
				auLine.close();
			}
		} while (circulate);
	}

	public void play()
	{
		thread = new Thread(this);
		thread.start();
	}
	
	public void stop()
	{
		thread.stop();
	}
}

ScoreRecorder.java

package com.mr.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;

//分数记录器类
public class ScoreRecorder
{
	private static final String SCOREFILE = "data/source"; //成绩记录文件
	private static int scroes[] = new int[3]; //前三名
	
	public static void init()
	{
		File file1 = new File(SCOREFILE);
		if (!file1.exists())
		{
			try
			{
				file1.createNewFile();
			} catch (IOException e)
			{
				e.printStackTrace();
			}
			return;
		}
		
		FileInputStream fileInputStream1 = null;
		InputStreamReader inputStreamReader1 = null;
		BufferedReader bufferedReader1 = null;
		try
		{
			fileInputStream1 = new FileInputStream(file1); //文件字节输入流
			inputStreamReader1 = new InputStreamReader(fileInputStream1); //字节流转字符流
			bufferedReader1 = new BufferedReader(inputStreamReader1); //缓冲字节流
			String value = bufferedReader1.readLine(); //读取一行
			if (!(value ==null || "".equals(value))) //如果不为空
			{
				String vs[] = value.split(","); //分隔字符串
				if (vs.length < 3) //小于3
				{
					Arrays.fill(scroes, 0); //成绩填充0
				}
				else 
				{
					for (int i = 0; i < 3; i++)
					{
						scroes[i] = Integer.parseInt(vs[i]);
					}
				}
			}
		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		finally 
		{
			try
			{
				bufferedReader1.close();
			} catch (IOException e2)
			{
				e2.printStackTrace();
			}
			try
			{
				inputStreamReader1.close();
			} catch (IOException e2)
			{
				e2.printStackTrace();
			}
			try
			{
				fileInputStream1.close();
			} catch (IOException e2)
			{
				e2.printStackTrace();
			}
		}
	}
	
	public static void saveScore()
	{
		String value = scroes[0] + "," + scroes[1] + "," + scroes[2]; //
		FileOutputStream fileOutputStream1 = null;
		OutputStreamWriter outputStreamWriter1 = null;
		BufferedWriter bufferedWriter1 = null;
		try
		{
			fileOutputStream1 = new FileOutputStream(SCOREFILE);
			outputStreamWriter1 = new OutputStreamWriter(fileOutputStream1);
			bufferedWriter1 = new BufferedWriter(outputStreamWriter1);
			bufferedWriter1.write(value);
			bufferedWriter1.flush();
		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		finally 
		{
			try
			{
				bufferedWriter1.close();
			} catch (IOException e2)
			{
				e2.printStackTrace();
			}
			
			try
			{
				outputStreamWriter1.close();
			} catch (IOException e2)
			{
				e2.printStackTrace();
			}
			
			try
			{
				fileOutputStream1.close();
			} catch (IOException e2)
			{
				e2.printStackTrace();
			}
		}
	}

	static public void addNewScore(int score)
	{
		int temp[] = Arrays.copyOf(scroes, 4);
		temp[3] = score;
		Arrays.sort(temp);
		scroes = Arrays.copyOfRange(temp, 1, 4);
	}

	static public int[] getScores()
	{
		return scroes;
	}
}

Sound.java

package com.mr.service;

import java.io.FileNotFoundException;

//音效类
public class Sound
{
	static final String DIR = "music/";
	static final String BACKGROUD = "background.wav";
	static final String JUMP = "jump.wav";
	static final String HIT = "hit.wav";
	
	//播放声音,参数1,文件名称,参数2,是否循环播放
	private static void play(String file,boolean circulate)
	{
		try
		{
			MusicPlayer player = new MusicPlayer(file, circulate);
			player.play();
		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
	}
	
	//播放跳跃音效
	static public void jump()
	{
		play(DIR+JUMP, false);
	}
	
	//播放撞击音效
	static public void hit()
	{
		play(DIR+HIT, false);
	}
	
	//播放背景音乐
	static public void backgroud()
	{
		play(DIR+BACKGROUD, true);
	}
	
	
}

BackgroundImage.java

package com.mr.view;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

//视图包
//滚动背景
public class BackgroundImage
{
	public BufferedImage image;
	private BufferedImage image1,image2;
	private Graphics2D g2d;
	public int x1,x2;
	public static final int SPEED = 4;
	
	public BackgroundImage()
	{
		try
		{
			image1 = ImageIO.read(new File("image/beijing.png"));
			image2 = ImageIO.read(new File("image/beijing.png"));
			
		} catch (IOException e)
		{
			e.printStackTrace();
		}
		
		image = new BufferedImage(800, 300, BufferedImage.TYPE_INT_RGB);
		g2d = image.createGraphics(); //
		x1 = 0; //第一幅图横坐标
		x2 = 800; //第二副图坐标
		g2d.drawImage(image1, x1, 0, null);
	}

	public void roll()
	{
		x1 -= SPEED;
		x2 -= SPEED;
		if (x1 <= -800)
		{
			x1 = 800;
		}
		if (x2 <= -800)
		{
			x2 = 800;
		}
		g2d.drawImage(image1, x1, 0, null);
		g2d.drawImage(image2, x2, 0, null);
	}
}

GamePanel.java

package com.mr.view;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;
import javax.xml.crypto.dsig.keyinfo.RetrievalMethod;

import com.mr.modle.Dinosaur;
import com.mr.modle.Obstacle;
import com.mr.service.FreshThread;
import com.mr.service.ScoreRecorder;
import com.mr.service.Sound;

//游戏面板
public class GamePanel extends JPanel implements KeyListener
{
	private BufferedImage image1; //主图片
	private BackgroundImage background1;//背景图片
	private Dinosaur golden1; //恐龙
	private Graphics2D g2d; //主图片绘图对象
	private int addObstacleTimer = 0; //障碍计时器
	private boolean finish = false; //游戏结束标志
	private List<Obstacle> list1 = new ArrayList<>(); //障碍集合
	private final int FREASH = FreshThread.FREASH; //刷新时间
	int score = 0; //得分
	int scoreTimer = 0; //分数计时器
	
	
	public GamePanel()
	{
		image1 = new BufferedImage(800, 300, BufferedImage.TYPE_INT_BGR);
		g2d = image1.createGraphics();
		background1 = new BackgroundImage();
		golden1 = new Dinosaur();
		list1.add(new Obstacle());
		FreshThread thread1 = new FreshThread(this);
		thread1.start();
	}


	private void paintImage()
	{
		background1.roll();
		golden1.move();
		g2d.drawImage(background1.image, 0, 0, this);
		if (addObstacleTimer == 1300)
		{
			if (Math.random() * 100 > 40)
			{
				list1.add(new Obstacle());
			}
			addObstacleTimer = 0;
		}
		
		for (int i = 0; i < list1.size(); i++)
		{
			Obstacle o1 = list1.get(i);
			if (o1.isLive())
			{
				o1.move();
				g2d.drawImage(o1.image, o1.x, o1.y, this);
				if (o1.getBounds().intersects(golden1.getFootBounds())|| o1.getBounds().intersects(golden1.getHeadBounds()))
				{
					Sound.hit();
					gameOver();
				}
			}
			else 
			{
				list1.remove(i);
				i--;
			}
		}
		g2d.drawImage(golden1.image, golden1.x, golden1.y, this);
		if (scoreTimer >= 500)
		{
			score += 10;
			scoreTimer = 0;
		}
		g2d.setColor(Color.BLACK);
		g2d.setFont(new Font("黑体",Font.BOLD,24));
		g2d.drawString(String.format("%06d", score), 700, 30);
		addObstacleTimer += FREASH;
		scoreTimer += FREASH;
	}
	
	public void paint(Graphics g)
	{
		paintImage();
		g.drawImage(image1, 0, 0, this);
		
	}
	
	public void gameOver()
	{
		ScoreRecorder.addNewScore(score);
		finish = true;
	}
	
	public boolean isFinish()
	{
		return finish;
	}
	
	public void keyPressed(KeyEvent e)
	{
		int code = e.getKeyCode();
		if (code == KeyEvent.VK_SPACE)
		{
			golden1.jump();
		}
	}
	
	@Override
	public void keyTyped(KeyEvent e)
	{
		
	}


	@Override
	public void keyReleased(KeyEvent e)
	{
		// TODO Auto-generated method stub
		
	}
}

MainFrame.java

package com.mr.view;

import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.WindowConstants;

import com.mr.service.ScoreRecorder;
import com.mr.service.Sound;

//主窗体
public class MainFrame extends JFrame
{

	public MainFrame()
	{
		restart(); //开始
		this.setBounds(340,150,820,260);
		this.setTitle("奔跑吧,虾米大王");
		Sound.backgroud(); //播放背景音乐
		ScoreRecorder.init(); //读取得分记录
		addListener(); //添加监听
		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
	}

	public void restart()
	{
		Container container1 = this.getContentPane();
		container1.removeAll(); //删除容器中所有组件
		GamePanel panel1 = new GamePanel(); //创建游戏面板
		container1.add(panel1);
		addKeyListener(panel1); //添加键盘事件
		container1.validate(); //验证组件
	}
	
	private void addListener()
	{
		addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				ScoreRecorder.saveScore();
			}
		});
	}
}

ScoreDialog.java

package com.mr.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.mr.service.ScoreRecorder;

//成绩对话框
public class ScoreDialog extends JDialog
{

	public ScoreDialog(JFrame frame)
	{
		super(frame,true);
		int scores[] = ScoreRecorder.getScores();
		JPanel scorePanel = new JPanel(new GridLayout(4,1));
		scorePanel.setBackground(Color.WHITE);
		JLabel label1 = new JLabel("得分排行榜",JLabel.CENTER);
		label1.setFont(new Font("黑体",Font.BOLD,20));
		label1.setForeground(Color.RED);
		
		JLabel label2 = new JLabel("第1名:" + scores[2],JLabel.CENTER);
		JLabel label3 = new JLabel("第2名:" + scores[1],JLabel.CENTER);
		JLabel label4 = new JLabel("第3名:" + scores[0],JLabel.CENTER);
		JButton button1 = new JButton("重新开始");
		button1.addActionListener(new ActionListener()
		{
			
			@Override
			public void actionPerformed(ActionEvent e)
			{
				dispose();
				
			}
		});
		
		scorePanel.add(label1);
		scorePanel.add(label2);
		scorePanel.add(label3);
		scorePanel.add(label4);
		
		Container container1 = this.getContentPane();
		container1.setLayout(new BorderLayout());
		container1.add(scorePanel,BorderLayout.CENTER);
		container1.add(button1,BorderLayout.SOUTH);
		
		this.setTitle("游戏结束");
		int width,height;
		width = 200;
		height = 200;
		int x = frame.getX() + (frame.getWidth() - width)/2;
		int y = frame.getY() + (frame.getHeight() - height)/2;
		setBounds(x,y,width,height);
		setVisible(true);
	}

}

代码结束了。

image文件夹的

beijing.png

 cacti.png

 

konglong1.png

 

 konglong2.png

 konglong3.png

 konglong.png

 stone.png

 music文件的

background.wav

hit.wav

jump.wav

我试过了,上传不上来,你们只好自己去下载wav类型的声音,名称改为一致的。

放个运行结果上来看看吧。

 另外提一句,我下载的wav声音是超级玛丽的游戏音乐,玩起来挺有意思的。

 

  • 7
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虾米大王

有你的支持,我会更有动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值