java项目练习
介绍
一、游戏界面
二、项目目录
使用说明
- 在services中的sound中可切换游戏背景音乐
- 在view包下的mainframe中修改窗体大小
- 在view包下的backgroundimage中可修改背景图片的运动速度
3、代码
main包
package com.xxxde.main;
import com.xxxde.view.MainFrame;
// 游戏开始类
public class Start {
public static void main(String[] args) {
MainFrame frame = new MainFrame();// 创建主窗体
frame.setVisible(true);// 显示主窗体
}
}
model包
1.dinosaur
package com.xxxde.modle;
import com.xxxde.service.FreshThread;
import com.xxxde.service.Sound;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
// 恐龙类
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_HIGHT = 100; // 跳起最大高度
private final int LOWEST_Y = 120; // 落地最低坐标
private final int FREASH = FreshThread.FREASH; // 刷新时间--刷新帧线程
public Dinosaur() {
x = 50; // 恐龙的横坐标
y = LOWEST_Y; // 恐龙的纵坐标
try {
image1 = ImageIO.read(new File("image/恐龙1.png")); // 读取恐龙的图片
image2 = ImageIO.read(new File("image/恐龙2.png"));
image3 = ImageIO.read(new File("image/恐龙3.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
// 踏步
private void step() {
// 每过250毫秒,更换一张图片。因为共有3图片,所以除以3取余,轮流展示这三张
int tmp = stepTimer / 250 % 3;
switch (tmp) {
case 1 :
image = image1;
break;
case 2 :
image = image2;
break;
default :
image = image3;
}
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_HIGHT) {// 如果跳过最高点
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);
}
}
2.Obstacle
package com.xxxde.modle;
import com.xxxde.view.BackgroundImage;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
public class Obstacle {
public int x;
public int y;
public BufferedImage image;
private BufferedImage stone;
private BufferedImage cacti;
private int speed;
public Obstacle() {
try {
this.stone = ImageIO.read(new File("image/石头.png"));
this.cacti = ImageIO.read(new File("image/仙人掌.png"));
} catch (IOException var2) {
var2.printStackTrace();
}
Random r = new Random();
if (r.nextInt(2) == 0) {
this.image = this.cacti;
} else {
this.image = this.stone;
}
this.x = 800;
this.y = 200 - this.image.getHeight();
this.speed = BackgroundImage.SPEED;
}
//移动
public void move() {
this.x -= this.speed;
}
//消除
public boolean isLive() {
if(x<=-image.getWidth()) return false;
return true;
}
public Rectangle getBounds() {
return this.image == this.cacti ? new Rectangle(this.x + 7, this.y, 15, this.image.getHeight()) : new Rectangle(this.x + 5, this.y + 4, 23, 21);
}
}
services包
1.FreshThread
package com.xxxde.service;
import com.xxxde.view.GamePanel;
import com.xxxde.view.MainFrame;
import com.xxxde.view.ScoreDialog;
import java.awt.*;
public class FreshThread extends Thread {
public static final int FREASH = 20;
GamePanel p;
public FreshThread(GamePanel p) {
this.p = p;
}
public void run() {
while(!this.p.isFinish()) {
this.p.repaint();
try {
Thread.sleep(FREASH);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Container c=p.getParent();
while (!(c instanceof MainFrame)){c = c.getParent();}
MainFrame frame = (MainFrame)c;
new ScoreDialog(frame);
frame.restart();
}
}
2.MusicPlayer
package com.xxxde.service;
import javax.sound.sampled.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class MusicPlayer implements Runnable {
File soundFile;
Thread thread;
boolean circulate;
public MusicPlayer(String filepath, boolean circulate) throws FileNotFoundException {
this.circulate = circulate;
this.soundFile = new File(filepath);
if (!this.soundFile.exists()) {
throw new FileNotFoundException(filepath + "未找到");
}
}
public void run() {
byte[] auBuffer = new byte[1024*128];//创建一个128KB缓冲区
do {
AudioInputStream audioInputStream = null;
SourceDataLine auline = null;
try {
audioInputStream = AudioSystem.getAudioInputStream(this.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(this.circulate);
}
public void play() {
this.thread = new Thread(this);
this.thread.start();
}
public void stop() {
this.thread.stop();
}
}
3.ScoreRecorder
package com.xxxde.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[] scores = new int[3];
public ScoreRecorder() {
}
public static void init() {
File f = new File(SCOREFILE);
if (!f.exists()) {
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
fis = new FileInputStream(f);
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
String value = br.readLine();
if (value != null && !"".equals(value)) {
String[] vs = value.split(",");
if (vs.length < 3) {
Arrays.fill(scores, 0);
} else {
for(int i = 0; i < 3; ++i) {
scores[i] = Integer.parseInt(vs[i]);
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void saveScore() {
String value = scores[0] + "," + scores[1] + "," + scores[2];
FileOutputStream fos = null;
OutputStreamWriter osw = null;
BufferedWriter bw = null;
try {
fos = new FileOutputStream(SCOREFILE);
osw = new OutputStreamWriter(fos);
bw = new BufferedWriter(osw);
bw.write(value);
bw.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void addNewScore(int score) {
int[] tmp = Arrays.copyOf(scores, 4);
tmp[3] = score;
Arrays.sort(tmp);
scores = Arrays.copyOfRange(tmp, 1, 4);
}
public static int[] getScores() {
return scores;
}
}