用户可在主界面进行注册、登录、查看排行榜;登录成功后,可选择ShootGame(飞机大战游戏)或CarGame(道路狂飙游戏)。
2.1 package Flyings:
该包以Flying的飞行类为父类,分Shoot,Collision接口,Flying中定义飞行物的固有特性,以及飞行物的共有方法,Hero,Boss,Bee,Enemy,Bullet为Flying的子类,继承Flying中的变量和方法,提高了代码的复用性,也提高了代码的鲁棒性。
2.2 package User:
User包中包含User类与存放配置文件位置的Info接口,User类主要包含用户与后端数据库连接、登录、注册和保存等方法。
2.3 Run类:
包含项目主界面,用户登录注册和游戏入口的图形界面。
2.4 package Games
该包包含ShootGame与CarGame游戏主界面与游戏运行逻辑方法。
2.5 package Car:
该包包含CarGame游戏的所有组件,以Car为父类,UserCar,PcCar为子类。
1.1 JDBC连接数据库:实现账号密码验证、注册,和用户信息的检索、插入、更新、删除等操作,统一对数据进行管理,保证了数据的安全性和完整性。
1.2 exe文件封装:把代码实现成软件,摆脱增强jdk等开发环境,了项目传播以及用户使用的可能性,降低了用户的使用成本。增强了项目的安全性,预防了因为失误而导致的代码上的缺失或错误,也防止了用户在游戏中进行不正当的竞争行为。
1.3 GUI图形界面设计:利用GUI构建鼠标键盘的监听(AWT)、登入界面、主界面、游戏界面、提示界面等,实现可视化的界面。
1.4继承、封装、多肽以及接口等都可以在代码中体现。
用户账号:不可使用空格,无字数限制且支持汉英文;
用户密码:6-11位字符,无特殊符号限制;
为每个用户设定一个索引值,通过索引值来对用户信息进行精确修改,实现端到端数据连接。
可实现多个用户同时在线,用户与用户之间互不干扰。
采用写回策略,设置了写缓冲器,减少了访问主存的次数,即更新缓存时只有在需要将缓存里面的脏数据交换出去的时候再把数据同步到主内存里,在缓存经常会命中的情况下,性能更好,更流畅。
在异常和危险情况下系统生存的关键。本项目具有异常处理功能,能够捕获并响应意外情况以保证程序能稳妥地结束,计算机不会崩溃。
本项目通过定时器设置进度,可以指定想要delay(开始执行的等待时间)时间,在实现时Timer类可以调度任务,TimerTask则是通过在run()方法里实现具体任务。Timer实例可以调度多任务,它是线程安全的。当Timer的构造器被调用时,它创建一个线程,这个线程可以用来调度任务。
按计划完成原定飞机大战项目功能目标,实现英雄机射击,加血,减血清屏等功能,并且拥有BOSS,小蜜蜂奖励机制。利用数据库存放用户数据,可以联机实现不同用户端共享数据,并且达到较好的用户体验。同时利用飞机大战定时器,碰撞,随机等机制,实现小汽车碰撞小游戏。
按照原定计划按时完成项目,并在完成原定的飞机大战计 划上制作了一个汽车游戏。
3.1其他用户只有与主机连接同一局域网时才可正常登入账号。
3.2游戏方式单一,用户粘性不强。
3.3缺乏多感官的游戏体验。
4.1实现“全网通”,在用户连接不同网络时也可以正常登入账号。
4.2开发多种玩法,比如关卡模式、联机模式等。
4.3实现声音特效的嵌入。
4.4实现用户间的交流平台(聊天室)。
4.5添加更多的游戏项目。
1.游戏难度随时间增加,5%的概率生成小蜜蜂
2.定时器定时任务,每1秒保存1次用户信息,既能保持适度流畅的游戏体验,也能及时保存用户信息。
3.碰撞逻辑
user类:
public void setPassword(String password) {
this.password = password;
}
public int getMax_score() {
return max_score;
}
/**
* 判断是否登录成功
*/
public boolean sign_in(String name, String password) {
String sql = "select user_id,user_name,user_password,user_score from user";//查询user表中的所有信息
try {
initParam(Sql_filename);
Connection connection = DriverManager.getConnection(url, user, pass);//连接数据库
Statement statement = connection.createStatement();//创建statement对象
ResultSet resultSet = statement.executeQuery(sql);//执行sql语句
while (resultSet.next()) {
this.id = resultSet.getInt(1);
this.name = resultSet.getString(2);
this.password = resultSet.getString(3);
this.score = 0;
this.max_score = resultSet.getInt(4);
if (this.name.equals(name) && this.password.equals(password))
return true;
}
connection.close();
statement.close();
resultSet.close();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 判断是否注册成功
*/
public boolean register(String name, String password) {
if (password.length() > 11 || password.length() < 6) {
//System.out.println(password);
return false;
}
if (name.contains(" "))
return false;
if (in(name))
return false;
getCount();
String sql = "insert into user(user_id,user_name,user_password,user_score) values(" +
(COUNT + 1) + " , '" + name + "' , '" + password + "' , " + 0 + ")";
try {
initParam(Sql_filename);
Connection connection = DriverManager.getConnection(url, user, pass);
Statement statement = connection.createStatement();
statement.executeUpdate(sql);//插入信息
connection.close();
statement.close();
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 判断用户是否已存在于配置文件中
*/
public boolean in(String name) {
String sql = "select user_id,user_name,user_password,user_score from user";//查询user表中的所有信息
try {
initParam(Sql_filename);
Connection connection = DriverManager.getConnection(url, user, pass);//连接数据库
Statement statement = connection.createStatement();//创建statement对象
ResultSet resultSet = statement.executeQuery(sql);//执行sql语句
while (resultSet.next()) {
int id = resultSet.getInt(1);
this.name = resultSet.getString(2);
this.password = resultSet.getString(3);
this.score = resultSet.getInt(4);
if (this.name.equals(name))
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 给用户临时增加分数
*/
public void add_score(int score) {
this.score += score;
}
/**
* 保存用户信息
*/
public void save() {
set_score();
}
public void copyFrom(User user) {
this.setScore(user.getScore());
this.setId(user.getId());
this.setName(user.getName());
this.setAttribute(user.getAttribute());
this.setPassword(user.getPassword());
}
public void set_score() {
String sql = "update user set user_score=" + score + " where user_id=" + this.id;
if (score <= max_score)
return;
try {
//System.out.println(score);
initParam(Sql_filename);
Connection connection = DriverManager.getConnection(url, user, pass);//连接数据库
Statement statement = connection.createStatement();//创建statement对象
statement.executeUpdate(sql);//执行sql语句
connection.close();
statement.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public ArrayList<User> getRank() {
String sql = "select user_id,user_name,user_password,user_score from user";//查询user表中的所有信息
ArrayList<Integer> score_rank = new ArrayList<>();
ArrayList<User> user_rank = new ArrayList<>();
try {
initParam(Sql_filename);
Connection connection = DriverManager.getConnection(url, user, pass);//连接数据库
Statement statement = connection.createStatement();//创建statement对象
ResultSet resultSet = statement.executeQuery(sql);//执行sql语句
while (resultSet.next()) {
int temp_id = resultSet.getInt(1);
String temp_name = resultSet.getString(2);
String temp_password = resultSet.getString(3);
int temp_score = resultSet.getInt(4);
score_rank.add(temp_score);
}
connection.close();
statement.close();
resultSet.close();
} catch (Exception e) {
e.printStackTrace();
}
for (int j = 0; j < score_rank.size(); j++) {
int maxIndex = 0;
for (int k = 0; k < score_rank.size(); k++) {
if (score_rank.get(maxIndex) < score_rank.get(k))
maxIndex = k;
}
String temp_name = id_to_account(maxIndex);
int temp_score = score_rank.get(maxIndex);
User user = new User(temp_name, temp_score, maxIndex);
user_rank.add(user);
score_rank.add(maxIndex, -1);
score_rank.remove(maxIndex + 1);
}
class MyComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
Integer score1 = ((User) o1).getScore();
Integer score2 = ((User) o2).getScore();
return score1.compareTo(score2);
}
}
//Arrays.sort(rank,new MyComparator());
return user_rank;
}
//按指定行读取用户名称
public String id_to_account(int id) {
String sql = "select user_id,user_name,user_password,user_score from user";//查询user表中的所有信息
try {
initParam(Sql_filename);
Connection connection = DriverManager.getConnection(url, user, pass);//连接数据库
Statement statement = connection.createStatement();//创建statement对象
ResultSet resultSet = statement.executeQuery(sql);//执行sql语句
while (resultSet.next()) {
int temp_id = resultSet.getInt(1);
String temp_name = resultSet.getString(2);
if (id == temp_id)
return temp_name;
}
connection.close();
statement.close();
resultSet.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public int id_to_score(int id) {
String sql = "select user_id,user_name,user_password,user_score from user";//查询user表中的所有信息
try {
initParam(Sql_filename);
Connection connection = DriverManager.getConnection(url, user, pass);//连接数据库
Statement statement = connection.createStatement();//创建statement对象
ResultSet resultSet = statement.executeQuery(sql);//执行sql语句
while (resultSet.next()) {
int temp_id = resultSet.getInt(1);
String temp_name = resultSet.getString(2);
String temp_password = resultSet.getString(3);
int temp_score = resultSet.getInt(4);
if (id == temp_id) {
this.max_score = temp_score;
return temp_score;
}
}
connection.close();
statement.close();
resultSet.close();
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
}
Test类:
Test类
public class Test {
public static void main(String[] args) {
Run run = new Run();
run.main();
}
}
run类:
import Games.CarGame;
import Games.ShootGame;
import Users.User;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
public class Run extends JPanel {
public static final int WIDTH = 600; // 宽
public static final int HEIGHT = 800; // 高
private static int state; //游戏状态
public static final int SIGN = 0;//登录
public static final int HOME = 1;//家
public static final int EMAIL = 2;//邮箱
public static final int RANK = 3;//排行榜
public static BufferedImage background; //生成的图片在内存里有一个图像缓冲区
public static User user = new User();//一个游戏对应一个User
static {
//加载图片资源
try {
background = ImageIO.read(ShootGame.class.getResource("imgs/background(1).jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
ImageIcon img = new ImageIcon(background);
g.drawImage(img.getImage(), 0, 0, null);
}
JFrame jf_main = new JFrame("ShootGame");
JButton jb_sign = new JButton();//登录按钮
JButton jb_register = new JButton();//注册按钮
JButton jb_rank = new JButton();//排行榜按钮
JButton jb_cancel = new JButton();//取消按钮
JLabel jl_name = new JLabel("用户名:");//用户名标签
JLabel jl_password = new JLabel("密码:");//密码标签
String name_tip = "注意不要输入空格哦。";
String password_tip = "请输入6到11位的密码";
JTextField jt_name = new JTextField(name_tip, 10);//用户名文本框
JPasswordField jp_password = new JPasswordField();//密码文本框
class JTextFieldHintListener implements FocusListener {
private String hintText;
private JTextField textField;
public JTextFieldHintListener(JTextField jTextField, String hintText) {
this.textField = jTextField;
this.hintText = hintText;
jTextField.setText(hintText); //默认直接显示
jTextField.setForeground(Color.GRAY);
}
@Override
public void focusGained(FocusEvent e) {
//获取焦点时,清空提示内容
String temp = textField.getText();
if (temp.equals(hintText)) {
textField.setText("");
textField.setForeground(Color.BLACK);
}
}
@Override
public void focusLost(FocusEvent e) {
//失去焦点时,没有输入内容,显示提示内容
String temp = textField.getText();
if (temp.equals("")) {
textField.setForeground(Color.GRAY);
textField.setText(hintText);
}
}
}
public void signIn() {
this.setLayout(null);//默认流布局,null设置为空布局可以进行自定义操作
jb_sign.setBounds(180, 450, 100, 40);//自定义位置和大小
jb_sign.setText("登录");
jb_register.setBounds(320, 450, 100, 40);//自定义位置和大小
jb_register.setText("注册");
jb_rank.setBounds(180, 500, 100, 40);//自定义位置和大小
jb_rank.setText("排行榜");
jb_cancel.setBounds(320, 500, 100, 40);
jb_cancel.setText("取消");
this.add(jb_sign);
this.add(jb_register);
this.add(jb_rank);
this.add(jb_cancel);
jl_name.setBounds(100, 250, 150, 30);
jl_name.setFont(new Font("楷体", Font.BOLD, 25));
jl_name.requestFocus();//使name标签获取焦点
this.add(jl_name);
jt_name.setBounds(250, 250, 150, 30);
jt_name.addFocusListener(new JTextFieldHintListener(jt_name, name_tip));
this.add(jt_name);
jl_password.setBounds(100, 350, 150, 30);
jl_password.setFont(new Font("楷体", Font.BOLD, 25));
this.add(jl_password);
jp_password.setBounds(250, 350, 150, 30);
//jp_password.addFocusListener(new JTextFieldHintListener(jp_password, password_tip));
this.add(jp_password);
MyActionListener myActionListener = new MyActionListener();
jb_sign.addActionListener(myActionListener);
jb_register.addActionListener(myActionListener);
jb_rank.addActionListener(myActionListener);
jb_cancel.addActionListener(myActionListener);
//jf_main.add(this);
}
public void action() {
// 创建鼠标适配器对象,监听鼠标事件,并且重写鼠标点击、移动的方法
MouseAdapter mAdapter = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
}
};
}
class MyActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String name = jt_name.getText();
String password = String.valueOf(jp_password.getPassword());
JLabel jl_email_tip = new JLabel();//Email提示信息
JTextArea jt_email_out = new JTextArea();
jt_email_out.setLineWrap(true);//Email发送的信息
JTextField jt_email_in = new JTextField();//Email输入的信息
Run email = new Run();
JFrame jf_email = new JFrame(name + "的邮箱");
jf_email.setSize(WIDTH, HEIGHT);//设置窗体的宽高
jf_email.setLocationRelativeTo(null);//默认显示在屏幕的中间
String message = new String();
email.setLayout(null);//默认流布局,null设置为空布局可以进行自定义操作
if (e.getActionCommand() == "登录") {
Run game = new Run();//创建该用户的子游戏
if (user.sign_in(name, password)) {
JFrame jf_house = new JFrame(name + "的房子");
jf_house.setSize(WIDTH, HEIGHT);//设置窗体的宽高
jf_house.setLocationRelativeTo(null);//默认显示在屏幕的中间
game.state = HOME;
game.setLayout(null);//默认流布局,null设置为空布局可以进行自定义操作
JButton jb_email = new JButton();//Email按钮
JButton jb_shootGame = new JButton();//shootGame按钮
JButton jb_carGame = new JButton(); //carGame按钮
jb_email.setBounds(250, 180, 90, 40);//自定义位置和大小
jb_email.setText("Email");
jb_shootGame.setBounds(245, 300, 100, 40);//自定义位置和大小
jb_shootGame.setText("ShootGame");
jb_carGame.setBounds(250, 420, 90, 40);//自定义位置和大小
jb_carGame.setText("CarGame");
game.add(jb_email);
game.add(jb_shootGame);
game.add(jb_carGame);
MyActionListener myActionListener = new MyActionListener();
jb_email.addActionListener(myActionListener);
jb_shootGame.addActionListener(myActionListener);
jb_carGame.addActionListener(myActionListener);
jf_house.add(game);
jf_house.setVisible(true); //将窗体显示出来
} else {
JFrame jframe = new JFrame("登陆失败"); //创建窗体并未窗体设置标题
jframe.add(game);
jframe.setSize(WIDTH + 100, HEIGHT - 500);//设置窗体的宽高
jframe.setLocationRelativeTo(null);//默认显示在屏幕的中间
JPanel jp = new JPanel();
jp.setLayout(null);
JLabel jl = new JLabel();
jl.setText("用户名不存在或密码错误!!!");
jl.setBounds(100, 50, 600, 100);
jl.setFont(new Font("楷体", Font.BOLD, 30));
jp.add(jl);
jframe.add(jp);
jframe.setVisible(true); //将窗体显示出来
}
} else if (e.getActionCommand() == "注册") {
if (user.register(name, password)) {
JFrame jframe = new JFrame("注册成功");
jframe.setSize(WIDTH + 100, HEIGHT - 500);
jframe.setLocationRelativeTo(null);
JPanel jp = new JPanel();
jp.setLayout(null);
JLabel jl = new JLabel();
jl.setText("恭喜你注册成功!");
jl.setBounds(220, 50, 400, 100);
jl.setFont(new Font("楷体", Font.BOLD, 30));
jp.add(jl);
jframe.add(jp);
jframe.setVisible(true);
} else {
JFrame jframe = new JFrame("注册失败"); //创建窗体并未窗体设置标题
jframe.setSize(WIDTH + 100, HEIGHT - 500);//设置窗体的宽高
jframe.setLocationRelativeTo(null);//默认显示在屏幕的中间
JPanel jp = new JPanel();
jp.setLayout(null);
JLabel jl = new JLabel();
jl.setText("密码要求6~11位、用户名输入有误或账户已存在!!!");
jl.setBounds(50, 50, 550, 100);
jl.setFont(new Font("楷体", Font.BOLD, 20));
jp.add(jl);
jframe.add(jp);
jframe.setVisible(true); //将窗体显示出来
}
} else if (e.getActionCommand() == "Email") {
email.state = HOME;
JButton jb_send = new JButton();//发送按钮
jl_email_tip.setText("目前仅是发送测试。");
jl_email_tip.setBounds(120, 100, 200, 100);
jt_email_in.setBounds(50, 300, 300, 50);
jb_send.setBounds(80, 450, 80, 30);
jb_send.setText("发送");
//jTextArea_out.setBounds(0, 200, 654, 100);
//jTextArea_out.setText("你好");
message = jt_email_in.getText();
email.add(jl_email_tip);
email.add(jt_email_in);
email.add(jb_send);
//jf_email.add(jTextArea_out);
jf_email.add(email);
jf_email.setVisible(true); //将窗体显示出来
MyActionListener myActionListener = new MyActionListener();//给发送按钮添加监控
jb_send.addActionListener(myActionListener);
} else if (e.getActionCommand() == "发送") {
jt_email_out.setBounds(0, 200, 654, 100);
jt_email_out.setText("");
jt_email_out.append(message);
jf_email.add(jt_email_out);
jf_email.add(email);
jf_email.repaint();
//jf_email.setVisible(true); //将窗体显示出来
} else if (e.getActionCommand() == "ShootGame") {
ShootGame.shoot_game(user);
// System.out.println(user.getName());
} else if (e.getActionCommand() == "CarGame") {
CarGame.car_game();
} else if (e.getActionCommand() == "排行榜") {
JFrame jf_rank = new JFrame("排行榜"); //创建窗体并未窗体设置标题
JPanel jp_rank = new JPanel();
jp_rank.setLayout(null);//默认流布局,null设置为空布局可以进行自定义操作
jf_rank.setSize(WIDTH, HEIGHT);//设置窗体的宽高
jf_rank.setLocationRelativeTo(null);//默认显示在屏幕的中间
JLabel jl_rank = new JLabel();
jl_rank.setText("排行榜");
jl_rank.setBounds(120, 100, 300, 100);
jl_rank.setFont(new Font("楷体", Font.BOLD, 50));
ArrayList<User> rank = user.getRank();
String temp_name = new String();
int temp_score;
user.getCount();
for (int i = 0; i < user.COUNT + 1 && i < user.RANK; i++) {
temp_name = rank.get(i).getName();
temp_score = rank.get(i).getScore();
//System.out.println(name);
JLabel jl = new JLabel();
jl.setText("NO." + (i + 1) + ":" + temp_name + " " + temp_score);
jl.setBounds(80, 100 + (i + 1) * 50, 300, 100);
jl.setFont(new Font("楷体", Font.BOLD, 30));
jp_rank.add(jl);
jf_rank.add(jp_rank);
}
jp_rank.add(jl_rank);
jf_rank.setVisible(true); //将窗体显示出来
}
}
}
public void main() {
Run game = new Run();
jf_main.add(game);
jf_main.setSize(WIDTH, HEIGHT);
jf_main.setLocationRelativeTo(null);//默认显示在屏幕中间
jf_main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口进程结束
game.signIn();
jf_main.setVisible(true); //将窗体显示出来
}
}
Info接口:
Info接口
package Users;
public interface Info {
String Sql_filename = "res\\Info\\mysql.ini";
}
ShootGame类:
ShootGame类
package Games;
import Flyings.*;
import Users.User;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import static java.lang.Math.max;
public class ShootGame extends JPanel {
public static final int WIDTH = 600; // 宽
public static final int HEIGHT = 800; // 高
public static BufferedImage background; //生成的图片在内存里有一个图像缓冲区
public static BufferedImage start;
public static BufferedImage gameover;
public static BufferedImage enemy;
public static BufferedImage pause;
public static BufferedImage bee;
public static BufferedImage hero_bullet;
public static BufferedImage boss_bullet;
public static BufferedImage hero0;
public static BufferedImage hero1;
public static BufferedImage boss0;
public static BufferedImage boss1;
public Hero hero = new Hero(300, 700);//声明主机对象
public static ArrayList<Enemy> enemies = new ArrayList<>(); //敌机
public static ArrayList<Boss> bosses = new ArrayList<>(); //Boss集合类
public static ArrayList<Bee> bees = new ArrayList<>(); //小蜜蜂集合类
public static User user = new User();
static JFrame frame = new JFrame("飞机大战"); //创建窗体并未窗体设置标题
public ShootGame(User user) {
this.user.copyFrom(user);
}
// 静态代码块,在类加载的时候就执行,只执行一次
static {
//加载图片资源
try {
background = ImageIO.read(ShootGame.class.getResource("imgs/background(2).jpg"));
start = ImageIO.read(ShootGame.class.getResource("imgs/start.png"));
gameover = ImageIO.read(ShootGame.class.getResource("imgs/gameOver.png"));
enemy = ImageIO.read(ShootGame.class.getResource("imgs/enemy.png"));
pause = ImageIO.read(ShootGame.class.getResource("imgs/pause.png"));
bee = ImageIO.read(ShootGame.class.getResource("imgs/bee.png"));
hero_bullet = ImageIO.read(ShootGame.class.getResource("imgs/hero_bullet.png"));
boss_bullet = ImageIO.read(ShootGame.class.getResource("imgs/boss_bullet.png"));
hero0 = ImageIO.read(ShootGame.class.getResource("imgs/hero0.png"));
hero1 = ImageIO.read(ShootGame.class.getResource("imgs/hero1.png"));
boss0 = ImageIO.read(ShootGame.class.getResource("imgs/boss0.png"));
boss1 = ImageIO.read(ShootGame.class.getResource("imgs/boss1.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private Timer timer; //定时器
private int intervel = 10; //时间间隔(毫秒)
private static int state;//游戏状态
private int score = 0;//声明变量得分
// public static final int SIGN = 0;//登录
public static final int START = 1;//开始
public static final int RUNNING = 2;//游戏中
public static final int PAUSE = 3;//暂停
public static final int GAME_OVER = 4;//游戏结束
/**
* 飞机大战游戏
*/
public static void shoot_game(User user) {
ShootGame shootGame = new ShootGame(user);
JFrame jf_shootGame = new JFrame("飞机大战"); //创建窗体并未窗体设置标题
jf_shootGame.add(shootGame);
jf_shootGame.setSize(WIDTH, HEIGHT);//设置窗体的宽高
jf_shootGame.setLocationRelativeTo(null);//默认显示在屏幕的中间
shootGame.action();
shootGame.state = START;
jf_shootGame.add(shootGame);
jf_shootGame.setVisible(true); //将窗体显示出来
}
int safeIndex = 0;
// 创建方法,处理逻辑
private void action() {
// repaint();
// 创建鼠标适配器对象,监听鼠标事件,并且重写鼠标点击、移动的方法
MouseAdapter mAdapter = new MouseAdapter() {
//重写鼠标移出
@Override
public void mouseExited(MouseEvent e) {
super.mouseExited(e);
if (state == RUNNING)
state = PAUSE;
}
//重写鼠标点击
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
switch (state) {
case PAUSE: {
state = RUNNING;
break;
}
case START: {
state = RUNNING;
safeIndex = 0;//保存进度清零
speedIndex = 0;//速度清零
flyEnteredIndex = 0;//时间清零
shootIndex = 0;//时间清零
bees.clear();//清理小蜜蜂
bosses.clear();//清理boss
enemies.clear();//清理小敌机
hero = new Hero(300, 700);
score = 0;
MaxScore = max(user.getScore(), user.id_to_score(user.getId()));
break;
}
case GAME_OVER: {
score = 0;
state = START; //游戏的状态改为起始状态
break;
}
case RUNNING: {
for (int i = 0; i < bosses.size(); i++) {
bosses.get(i).addLife(-50);
int num = hero.clear(bosses.get(i).getBullets(), enemies);
user.add_score(num * Enemy.enemyScore);
if (bosses.get(i).BossHeartless()) {
bosses.remove(i);
if (i > 0)
i--;
}
}
break;
}
default:
break;
}
}
//重写鼠标移动
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
super.mouseMoved(e);
if (state == RUNNING) {
int x = e.getX();
int y = e.getY();
hero.step(x, y);
}
}
};
this.addMouseListener(mAdapter); //添加鼠标点击事件的监听
this.addMouseMotionListener(mAdapter); //添加鼠标移动事件的监听
timer = new Timer();
// 给定时器设置进度
/*
* 参数一:被定时器执行的任务
* 参数二:延时多少毫秒去执行run()里面的内容
* 参数三:定时器执行的周期
*/
/*
* 没有名字的内部类:
* new 父类构造器(){
* 匿名内部类的类体部分
* }
* 不能反复使用
* 消除坠余代码
*/
timer.schedule(new TimerTask() {
@Override
public void run() {
if (state == RUNNING) {
safeIndex++;
int safeMod = 1000;//每10秒保存一次信息
if (safeIndex % safeMod == 0) {
user.save();
}
enterAction(); //在定时器中,如果游戏处于运行,
stepAction();
shootAction();
bangAction();
checkGameOverAction(user);
}
repaint(); //重新绘制(提供的)
}
}, intervel, intervel);
}
static int speedIndex = 0;
//生成一个飞行物
public static Flying nextOne() {
speedIndex++;
int speedMod = 300;//每3秒速度+1
int speed;
speed = 1 + speedIndex / speedMod;
Random r = new Random();
int type = r.nextInt(20);// 0--19
if (type == 0) {//5%小蜜蜂,95%敌机
return new Bee(speed);
}
return new Enemy(speed);
}
//实例化 一个入场倒计时变量
int flyEnteredIndex = 0;
//飞行物入场的方法,进入画面
public void enterAction() {
int flyMod = 40;//到40毫秒生成1个飞行物
int bossMod = 1500;//到15秒生成1个boss
flyEnteredIndex++;
//到40毫秒,生成一个飞行物
if (flyEnteredIndex % flyMod == 0) {
Flying fly = nextOne();
if (fly instanceof Bee) {
Bee bee = (Bee) fly;
this.bees.add(bee);
} else {
Enemy enemy = (Enemy) fly;
this.enemies.add(enemy);
}
}
if (flyEnteredIndex % bossMod == 0) {
int bossHeart = flyEnteredIndex / bossMod * 50;//boss的生命值每生成1次加50
int bossEnergy = 10;//boss的能量值每生成1次加10
int bossScore = flyEnteredIndex / bossMod * 10;//boss的分数值每生成1次加50
if (bosses.size() < 2) {
Boss boss = new Boss(3, bossHeart, bossEnergy, bossScore);
this.bosses.add(boss);
}
}
}
//飞行物走步
public void stepAction() {
//boss及其子弹走步
for (int i = 0; i < bosses.size(); i++) {
bosses.get(i).step();//boss移动
for (int j = 0; j < bosses.get(i).getBullets().size(); j++)
bosses.get(i).getBullets().get(j).step();//子弹移动
}
//bee走步
for (int i = 0; i < bees.size(); i++) {
bees.get(i).step();
}
//小敌机走步
for (int i = 0; i < enemies.size(); i++) {
enemies.get(i).step();
}
//主机子弹走步
for (int i = 0; i < hero.getBullets().size(); i++) {
hero.getBullets().get(i).step();
}
}
//射击时间间隔
int shootIndex = 0;
//飞行物射击的方法
public void shootAction() {
int shootMod = 10;//每10毫秒生成一颗子弹
int boss_shootMod = 50;//boss每50毫秒生成一颗子弹
shootIndex++;
//boss射击
if (shootIndex % boss_shootMod == 0) {
//boss射击
for (int i = 0; i < bosses.size(); i++) {
bosses.get(i).shooting();
}
}
if (shootIndex % shootMod == 0) {
//主机射击
hero.shooting();
}
}
//各类飞行物碰撞方法
public void bangAction() {
//Hero机碰撞到Boss机和Boss机子弹,和Boss机碰到Hero机
for (int i = 0; i < bosses.size(); i++) {
Boss boss = bosses.get(i);
hero.hit(boss);//Hero机碰到Boss机
boss.hit(hero);//Boss机碰到Hero机
for (int j = 0; j < boss.getBullets().size(); j++) {
Bullet bullet = boss.getBullets().get(j);
if (hero.hit(bullet)) {
boss.getBullets().remove(bullet);
//System.out.println(bullet.getHurt());
hero.addLife(-bullet.getHurt());
j--;
}
if (boss.BossHeartless()) {
bosses.remove(boss);
boss.AwardUser(user);
score++;//界面显示的分数++
boss.AwardHero(hero);
if (i > 0)
i--;
break;
}
}
}
//Hero机碰撞到enemy小敌机
for (int i = 0; i < enemies.size(); i++) {
Enemy enemy = enemies.get(i);
if (hero.hit(enemy)) {
hero.addLife(-1);
enemies.remove(enemy);
if (i > 0)
i--;
}
}
//Hero机碰撞到Bee小蜜蜂
for (int i = 0; i < bees.size(); i++) {
Bee bee = bees.get(i);
if (hero.hit(bee)) {
bees.remove(bee);
if (i > 0)
i--;
}
}
//enemy小敌机,Boss机被Hero机的子弹打中
for (int i = 0; i < hero.getBullets().size(); i++) {
Bullet bullet = hero.getBullets().get(i);
for (int j = 0; j < bosses.size(); j++) {
Boss boss = bosses.get(j);
if (boss.hit(bullet)) {
boss.addLife(-bullet.getHurt());
hero.getBullets().remove(bullet);
if (i > 0)
i--;
}
}
for (int k = 0; k < enemies.size(); k++) {
Enemy enemy = enemies.get(k);
if (enemy.hit(bullet)) {
enemy.AwardUser(user);
score++;//界面显示的分数++
enemy.AwardHero(hero);
hero.getBullets().remove(bullet);
if (i > 0)
i--;
enemies.remove(enemy);
k--;
}
}
}
}
//游戏结束
public void checkGameOverAction(User user) {
if (hero.getLife() <= 0) {
user.save();
user.setScore(0);//游戏结束分值清零
state = GAME_OVER;
}
}
//绘制状态
public void paintState(Graphics g) {
switch (state) {
//开始状态
case START:
g.drawImage(start, 50, 300, null);
break;
//游戏状态
case RUNNING:
g.drawImage(background, 0, 0, null);
break;
//暂停状态
case PAUSE:
g.drawImage(pause, 50, 300, null);
break;
//游戏结束状态
case GAME_OVER:
g.drawImage(gameover, 50, 300, null);
break;
default:
break;
}
}
//绘制小蜜蜂
public void paintBee(Graphics g) {
for (int i = 0; i < bees.size(); i++) {
Bee bee = bees.get(i);
int x = bee.getX() - bee.getWidth() / 2;
int y = bee.getY() - bee.getHigh() / 2;
g.drawImage((bee.getImages())[0], x, y, null);
}
}
//绘制小敌机
public void paintEnemy(Graphics g) {
for (int i = 0; i < enemies.size(); i++) {
Enemy enemy = enemies.get(i);
int x = enemy.getX() - enemy.getWidth() / 2;
int y = enemy.getY() - enemy.getHigh() / 2;
g.drawImage((enemy.getImages())[0], x, y, null);
}
}
//绘制Boss机
public void paintBoss(Graphics g) {
for (int i = 0; i < bosses.size(); i++) {
//实例化一个boss
Boss boss = bosses.get(i);
int x = boss.getX() - boss.getWidth() / 2;
int y = boss.getY() - boss.getHigh() / 2;
g.drawImage((boss.getImages())[0], x, y, null);
Font font = new Font(Font.SANS_SERIF, Font.BOLD, 20);//设置字体类型
g.setColor(Color.red);//设置字体颜色
g.setFont(font);//将字体设置到画笔上
g.drawString("BossHeart:" + boss.getBossHeart(), x + boss.getWidth() / 3, y + boss.getHigh()); //在画笔上绘制
for (int j = 0; j < bosses.get(i).getBullets().size(); j++) {
Bullet bullet = boss.getBullets().get(j);
x = bullet.getX() - bullet.getWidth() / 2;
y = bullet.getY() - bullet.getHigh() / 2;
g.drawImage((bullet.getImages())[0], x, y, null);
}
}
}
//绘制英雄机
public void paintHero(Graphics g) {
hero.change();
for (int i = 0; i < hero.getBullets().size(); i++) {
Bullet bullet = hero.getBullets().get(i);
int x = bullet.getX() - bullet.getWidth() / 2;
int y = bullet.getY() - bullet.getHigh() / 2;
g.drawImage((bullet.getImages())[0], x, y, null);
}
int x = hero.getX() - hero.getWidth() / 2;
int y = hero.getY() - hero.getHigh() / 2;
g.drawImage(hero.getImage(), x, y, null);
}
//最高分
int MaxScore = user.id_to_score(user.getId());
//绘制分数方法
public void paintScore(Graphics g) {
// 得分的x , y坐标
int x = 10;
int y = 25;
Font font = new Font(Font.SANS_SERIF, Font.BOLD, 14);//设置字体类型
g.setColor(Color.white);//设置字体颜色
g.setFont(font);//将字体设置到画笔上
g.drawString("Score:" + score, x, y); //在画笔上绘制
y += 20; //修改y的坐标
MaxScore = user.getMax_score();
g.drawString("MaxScore:" + MaxScore, x, y);
//绘制主机的生命数
y += 20;
g.drawString("Life:" + hero.getLife(), x, y);
//绘制主机能量值
y += 20;
g.drawString("Energy:" + hero.getEnergy(), x, y);
}
//绘制背景
public void paintBackground(Graphics g) {
g.drawImage(background, 0, 0, null);
}
// 重写paint方法,并且传入画笔参数(提供的)
@Override
public void paint(Graphics g) {
paintBackground(g);
paintState(g);
paintScore(g);
paintHero(g);
paintBoss(g);
paintEnemy(g);
paintBee(g);
}
}
CarGame类
package Games;
import Car.Car;
import Car.PcCar;
import Car.UserCar;
import Users.User;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
public class CarGame extends JPanel{
public static final int pccarNumber = 4;//对方车辆数量
public static final int WIDTH = 600; // 宽
public static final int HEIGHT = 800; // 高
public static BufferedImage background_Car; //生成的图片在内存里有一个图像缓冲区
public static BufferedImage start;
public static BufferedImage gameover;
public static BufferedImage usercar0;
public static BufferedImage usercar1;
public static BufferedImage pause;
public static BufferedImage pccar0;
public static BufferedImage pccar1;
public static BufferedImage pccar2;
public static BufferedImage pccar3;
public static BufferedImage pccar4;
public UserCar usercar = new UserCar(300, 700);//声明玩家汽车对象
public static ArrayList<PcCar> pcCars = new ArrayList<>(); //对方汽车
static User user = new User();
static JFrame frame = new JFrame("道路狂飙"); //创建窗体并未窗体设置标题
// 静态代码块,在类加载的时候就执行,只执行一次
static {
//加载图片资源
try {
background_Car = ImageIO.read(CarGame.class.getResource("car_imgs/background_car.png"));
start = ImageIO.read(CarGame.class.getResource("car_imgs/start.png"));
gameover = ImageIO.read(CarGame.class.getResource("car_imgs/gameOver.png"));
pccar0 = ImageIO.read(CarGame.class.getResource("car_imgs/pccar0.png"));
pccar1 = ImageIO.read(CarGame.class.getResource("car_imgs/pccar1.png"));
pccar2 = ImageIO.read(CarGame.class.getResource("car_imgs/pccar2.png"));
pccar3 = ImageIO.read(CarGame.class.getResource("car_imgs/pccar3.png"));
pccar4 = ImageIO.read(CarGame.class.getResource("car_imgs/pccar4.png"));
pause = ImageIO.read(CarGame.class.getResource("car_imgs/pause.png"));
usercar0 = ImageIO.read(CarGame.class.getResource("car_imgs/usercar0.png"));
usercar1 = ImageIO.read(CarGame.class.getResource("car_imgs/usercar1.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private Timer timer; //定时器
private int intervel = 10; //时间间隔(毫秒)
private static int state;//游戏状态
private int score = 0;//声明变量得分
// public static final int SIGN = 0;//登录
public static final int START = 1;//开始
public static final int RUNNING = 2;//游戏中
public static final int PAUSE = 3;//暂停
public static final int GAME_OVER = 4;//游戏结束
/**
* 道路狂飙游戏
*/
public static void car_game() {
CarGame carGame = new CarGame();
JFrame jf_carGame = new JFrame("道路狂飙"); //创建窗体并未窗体设置标题
jf_carGame.add(carGame);
jf_carGame.setSize(WIDTH, HEIGHT);//设置窗体的宽高
jf_carGame.setLocationRelativeTo(null);//默认显示在屏幕的中间
carGame.action();
carGame.state = START;
jf_carGame.add(carGame);
jf_carGame.setVisible(true); //将窗体显示出来
}
/**
* 增加对方汽车
*/
public void Create_enemies() {
PcCar pccar = new PcCar(0);
this.pcCars.add(pccar);
}
// 创建方法,处理逻辑
private void action() {
// repaint();
// 创建鼠标适配器对象,监听鼠标事件,并且重写鼠标点击、移动的方法
MouseAdapter mAdapter = new MouseAdapter() {
//重写鼠标移出
@Override
public void mouseExited(MouseEvent e) {
super.mouseExited(e);
if (state == RUNNING)
state = PAUSE;
}
//重写鼠标点击
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
switch (state) {
case PAUSE:
case START: {
state = RUNNING;
break;
}
case GAME_OVER: { //游戏结束,清理现场
//hero = new Hero(300, 600); //玩家汽车显示出来
score = 0;
state = START; //游戏的状态改为起始状态
break;
}
case RUNNING: {
break;
}
default:
break;
}
}
//重写鼠标移动
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
super.mouseMoved(e);
if (state == RUNNING) {
int x = e.getX();
int y = e.getY();
usercar.position(x, y);
}
}
};
this.addMouseListener(mAdapter); //添加鼠标点击事件的监听
this.addMouseMotionListener(mAdapter); //添加鼠标移动事件的监听
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (state == RUNNING) {
enterAction(); //在定时器中,如果游戏处于运行,
moveAction();
checkGameOverAction(user);
}
repaint(); //重新绘制(提供的)
}
}, intervel, intervel);
}
static int speedIndex = 0;
static int y_speed = 3;//汽车的初始速度
//生成一辆车
public static Car nextOne() {
speedIndex++;
if (speedIndex>2){
y_speed+=1;//每生成两辆车增加一点基础速度
}
return new PcCar(y_speed);
}
//实例化 一个入场倒计时变量
int carEnteredIndex = 0;
//汽车入场的方法,进入画面
public void enterAction() {
int Mod = 150;//到Mod毫秒生成1辆车
carEnteredIndex++;
//到Mod毫秒,生成一辆车
if (carEnteredIndex % Mod == 0) {
Car car= nextOne();
PcCar pccar=(PcCar)car;
this.pcCars.add(pccar);
}
}
//对方汽车移动
public void moveAction() {
for (int i = 0; i < pcCars.size(); i++) {
pcCars.get(i).move();
if(pcCars.get(i).outOfBounds()) {
user.add_score(pcCars.get(i).getScore());
pcCars.remove(i);
}
}
}
//游戏结束
public void checkGameOverAction(User user) {
for(int i = 0; i< pcCars.size(); i++){
if (usercar.hitBy(pcCars.get(i))){
user.save();//保存用户记录
carEnteredIndex = 0;//时间清零
pcCars.clear();//清理对方汽车
usercar= new UserCar(300,700);
state = GAME_OVER;
}
}
}
//绘制状态
public void paintState(Graphics g) {
switch (state) {
//开始状态
case START:
g.drawImage(start, 100, 0, null);
break;
//游戏状态
case RUNNING:
g.drawImage(background_Car, 0, 0, null);
break;
//暂停状态
case PAUSE:
g.drawImage(pause, 0, 0, null);
break;
//游戏结束状态
case GAME_OVER:
g.drawImage(gameover, 0, 0, null);
break;
default:
break;
}
}
//绘制UesrCar
public void paintUsercar(Graphics g){
int x = usercar.getX()-usercar.getWidth()/2;
int y = usercar.getY()-usercar.getHigh()/2;
g.drawImage(usercar.getImage(),x,y,null);
}
//绘制PcCar
public void paintPccar(Graphics g){
for(int i = 0; i< pcCars.size(); i++){
PcCar pccar = pcCars.get(i);
int x = pccar.getX() - pccar.getHigh()/2;
int y = pccar.getY() - pccar.getWidth()/2;
g.drawImage((pccar.getImages())[0],x,y,null);
}
}
//绘制背景
public void paintBackground(Graphics g){
g.drawImage(background_Car,0,0,null);
}
//最高分
int MaxScore = user.id_to_score(user.getId());
//绘制分数方法
public void paintScore(Graphics g) {
// 得分的x , y坐标
int x = 10;
int y = 25;
Font font = new Font(Font.SANS_SERIF, Font.BOLD, 14);//设置字体类型
g.setColor(Color.blue);//设置字体颜色
g.setFont(font);//将字体设置到画笔上
g.drawString("Score:" + user.getScore(), x, y); //在画笔上绘制
y += 20; //修改y的坐标
g.drawString("MaxScore:" + MaxScore, x, y);//个人最高分
}
// 重写paint方法,并且传入画笔参数(提供的)
@Override
public void paint(Graphics g) {
paintBackground(g);
paintState(g);
paintScore(g);
paintUsercar(g);
paintPccar(g);
}
}
package Flyings;
public interface Shoot {
public abstract void shooting();
}
Hero类
package Flyings;
import Games.ShootGame;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
public class Hero extends Flying implements Shoot {
public static final int FULL = 50;//清屏所需能量值
private int indexBullet; //射击交换计数
private int indexImage; // 图片交换计数
private int doubleFire; // 双倍火力
private int life; // 命
private int energy;//能量值
private Image image; //当前的图片
private ArrayList<Bullet> bullets = new ArrayList<>(); //子弹类
public Hero(int x, int y) {
super(x, y);
life = 3; //初始化生命
indexImage = 0; //英雄机图片交换
indexBullet = 0; //
images = new BufferedImage[2];
images[0] = ShootGame.hero0;
images[1] = ShootGame.hero1;
image = images[0];
this.width = images[0].getWidth(); //英雄机图片长宽
this.high = images[0].getHeight();
}
public int getIndex() {
return indexImage;
}
public void setIndex(int index) {
this.indexImage = index;
}
public int getDoubleFire() {
return doubleFire;
}
public void setDoubleFire(int doubleFire) {
this.doubleFire = doubleFire;
}
public int getLife() {
return life;
}
public void setLife(int life) {
this.life = life;
}
public int getEnergy() {
return energy;
}
public void setEnergy(int energy) {
this.energy = energy;
}
public ArrayList<Bullet> getBullets() {
return bullets;
}
public Image getImage() {
return image;
}
public void skill_clear() {
System.out.println("Clear!!!");
}
//交换图片
public void change() {
indexImage++; //每调用一次加一,用来标志英雄机当前图片
int num = indexImage / 10 % images.length;//
image = images[num];//当前图片为英雄机图片集第num张图片
}
//Hero当前中点坐标
public void step(int x, int y) {
this.x = x;
this.y = y;
}
// 英雄机加生命方法
public void addLife(int life) {
this.life += life;
}
//检测碰撞及其种类
public boolean hit(Flying flying) {
if (hitBy(flying)) {//判断有碰撞
if (!(flying instanceof Bee)) {//判断是否碰撞小蜜蜂
if (!((flying instanceof Bullet) && (flying.getY_speed() < 0))) {//判断不是自己的子弹
if (doubleFire == 1) {//若是碰撞boss,boss子弹,敌机,而且当前为双倍火力,就取消双倍火力
doubleFire = 0;
}
}
} else { //碰撞到小蜜蜂
if (((Bee) flying).getType() == 1) { //若小蜜蜂Type为1,英雄机生命加一
addLife(1);
}
if (((Bee) flying).getType() == 0) { 若小蜜蜂Type为0,而且当前为单倍火力,置为双倍火力
indexBullet = 0;
doubleFire = 1;
}
}
return true;
}
return false;
}
//清屏函数
public int clear(ArrayList<Bullet> bullets, ArrayList<Enemy> enemies) {
int temp = enemies.size(); //当前小敌机集合的长度
if (energy >= FULL) {
bullets.clear(); //清理子弹以及小敌机
enemies.clear();
energy -= 50;
}
return temp; //返回清理的小敌机数量,用来加用户分数
}
int indexShoot = 0;//每50毫秒增加子弹伤害
//添加子弹
public void shooting() {
indexBullet++; //每调用一次,标志加一
indexShoot++;
int shootMod = 300;//每10毫秒
if (doubleFire == 0) { //单倍火力
Bullet bullet = new Bullet(x, y, 0, indexShoot / shootMod);
bullets.add(bullet);
}
if (doubleFire == 1) { //双倍火力
Bullet bullet0 = new Bullet(x - width / 5, y, 0, indexShoot / shootMod);
Bullet bullet1 = new Bullet(x + width / 5, y, 0, indexShoot / shootMod);
bullets.add(bullet0);
bullets.add(bullet1);
if (indexBullet % 150 == 0) { //双倍火力时间限制为15秒
doubleFire = 0;
}
}
}
//判断出界条件
public boolean outOfBounds() {
return false;
}
}
package Flyings;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;
public class Flying {
protected int high;//飞行物对应的高度
protected int width;//飞行物对应的宽度
protected int x;//飞行物中心点的x值
protected int y;//飞行物中心点的y值
protected BufferedImage[] images; // 声明图片数组
protected int x_speed;//x轴方向上的速度
protected int y_speed;//y轴方向上的速度
protected Rectangle rectangle= new Rectangle(x-width/2, y-high/2, width, high);//飞行物的矩形范围
public int getHigh() {return high;}
public void setHigh(int high) {this.high = high;}
public int getWidth() {return width;}
public void setWidth(int width) {this.width = width;}
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[] getImages() {return images;}
/*
public void setImages(BufferedImage[] images) {this.images = images;}
public int getX_speed() {return x_speed;}
public void setX_speed(int x_speed) {this.x_speed = x_speed;}
public void setY_speed(int y_speed) {this.y_speed = y_speed;}
*/
public int getY_speed() {return y_speed;}
public Flying() {
}//无参构造器
public Flying(int x, int y) {
this.x = x;
this.y = y;
}
/*走步(运行轨迹)*/
public void step(){
}
/*飞行物越界处理 */
public boolean outOfBounds() {
return false;
}
//判断是否与fly发生碰撞
public boolean hitBy(Flying fly){
return x+width/4> fly.getX()-fly.getWidth()/4&&
x-width/4< fly.getX()+fly.getWidth()/4&&
y+high/4>fly.getY()-fly.getHigh()/4&&
y-high/4<fly.getY()+ fly.getHigh()/4;
}
}
package Flyings;
import Games.ShootGame;
import Users.User;
import java.awt.image.BufferedImage;
import java.util.Random;
public class Enemy extends Flying implements Collision {
public static int enemyEnergy = 1;
public static int enemyScore = 1;
//构造器
public Enemy(int y_speed) {
this.images = new BufferedImage[1];
images[0] = ShootGame.enemy;
width = images[0].getWidth();
high = images[0].getHeight();
this.y_speed = y_speed;
//小敌机任意位置产生
Random random = new Random();
this.x = random.nextInt(ShootGame.WIDTH - width) + width / 2;
this.y = 0;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHigh() {
return high;
}
public void setHigh(int high) {
this.high = high;
}
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;
}
//重写走步
@Override
public void step() {
y += y_speed;
}
//越界
@Override
public boolean outOfBounds() {
return y >= ShootGame.HEIGHT + high / 2;
}
//碰撞
public boolean hit(Flying fly) {
if (hitBy(fly)) {
if (fly instanceof Hero) {
return true;
} else if ((fly instanceof Bullet) && (fly.getY_speed() < 0)) {
return true;
}
}
return false;
}
//打到小敌机给hero加能量
public void AwardHero(Hero hero) {
hero.setEnergy(hero.getEnergy() + enemyEnergy);
}
//打到小敌机给user加分
public void AwardUser(User user) {
user.add_score(enemyScore);
}
}
Collision接口
package Flyings;
public interface Collision {
// 碰撞检测
public boolean hit(Flying fly);
// public boolean hit();
}
Bullet类
package Flyings;
import Games.ShootGame;
import java.awt.image.BufferedImage;
public class Bullet extends Flying {
private int hurt; //子弹造成的伤害
private int type; //0为英雄机的子弹,1为boss机的子弹
public int getHurt() {
return hurt;
}
public void setHurt(int hurt) {
this.hurt = hurt;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
//构造器
public Bullet(int x,int y,int type,int hurt){
this.images = new BufferedImage[1];
if (type==0) {
this.images[0] = ShootGame.hero_bullet;
this.y_speed = -3;
}else{
this.images[0] = ShootGame.boss_bullet;
this.y_speed = 3;
}
width = images[0].getWidth();
high = images[0].getHeight();
this.x = x;
this.y = y;
this.hurt = hurt;
}
//重写走步 子弹从下往上走(Hero用)
@Override
public void step() {
y+=y_speed;
}
//子弹从上往下走(Boss用)
public void step_down(){
y+=y_speed;
}
//越界
@Override
public boolean outOfBounds() {
return (y<=-high/2 || y>=ShootGame.HEIGHT+high/2);
}
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 int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHigh() {
return high;
}
public void setHigh(int high) {
this.high = high;
}
}
Boss类
package Flyings;
import Games.ShootGame;
import Users.User;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;
public class Boss extends Flying implements Shoot,Collision {
private ArrayList<Bullet> bullets = new ArrayList<>();//子弹类
private int BossHeart;//Boss机的血量
private int BossEnergy;//Boss机爆炸后给Hero机加的能量
private int BossScore;//Boss机爆炸后加的分数
/* 传入Boss机的x,y,能量,分数,还有移动速度,将Boss机的图片传入获得Boss机的长,宽 */
public Boss(int x_speed, int BossHeart, int BossEnergy, int BossScore) {
images = new BufferedImage[2];
Random r = new Random(); //随机生成
int img = r.nextInt(100);
//通过随机值与100取模,余数小于50选择第一张图片
if (img % 100 < 50)
images[0] = ShootGame.boss0;
else
images[0] = ShootGame.boss1;
width = images[0].getWidth();
//从图片中获得Boss机的宽度
high = images[0].getHeight();
//从图片中获得Boss机的高度
Random random = new Random();
//随机生成一个位置范围在(界面的左右边界)
this.x = random.nextInt(ShootGame.WIDTH - width) + width / 2;
//让生成的Boss机高度固定
this.y = high / 2;
//传入Boss机x轴的速度
this.x_speed = x_speed;
//传入Boss机的血量
this.BossHeart = BossHeart;
//传入Boss机被消灭后给Hero机加的能量
this.BossEnergy = BossEnergy;
//传入Boss机被消灭后给Hero机加的分数
this.BossScore = BossScore;
}
/* 利用公有方法设置和获得类的私有成员变量 */
public void setBossEnergy(int BossEnergy) {
this.BossEnergy = BossEnergy;
}
public int getBossEnergy() {
return BossEnergy;
}
public ArrayList<Bullet> getBullets() {
return bullets;
}
public void setBossScore(int BossScore) {
this.BossScore = BossScore;
}
public int getBossScore() {
return BossScore;
}
public int getBossHeart() {
return BossHeart;
}
public void setBossHeart(int life) {
this.BossHeart = BossHeart;
}
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 int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHigh() {
return high;
}
public void setHigh(int high) {
this.high = high;
}
public int getX_speed() {
return x_speed;
}
public void setX_speed(int x_speed) {
this.x_speed = x_speed;
}
public int getY_speed() {
return y_speed;
}
public void setY_speed(int y_speed) {
this.y_speed = y_speed;
}
/* Boss机生成子弹并装入数组中发射多排子弹 */
@Override
public void shooting() {
int BossBullet = 1;
Bullet bullet0 = new Bullet(x, y, 1, BossBullet);
Bullet bullet1 = new Bullet(x + width / 5, y, 1, BossBullet);
Bullet bullet2 = new Bullet(x - width / 5, y, 1, BossBullet);
bullets.add(bullet0);
bullets.add(bullet1);
bullets.add(bullet2);
}
/*Boss机越界判断 */
@Override
public boolean outOfBounds() {
//如果Boss机越出游戏界面的判断条件
if (x < width / 2 || x > ShootGame.WIDTH - width / 2)
return true;
else
return false;
}
/*Boss飞机结合越界方法判断飞行的状态*/
@Override
public void step() {
if (this.outOfBounds() == true)
//如果越界,速度相反
x_speed = -x_speed;
x += x_speed;
//加上移动的距离实时改变Boss机的坐标
}
/* Boss机生成子弹并装入数组中 */
// public void CreateBullet(){
// Bullet bullet0=new Bullet(x,y);
// Bullet bullet1=new Bullet(x+width/5,y);
// Bullet bullet2=new Bullet(x-width/5,y);
// bullets.add(bullet0);
// bullets.add(bullet1);
// bullets.add(bullet2);
// }
/* Boss机将生成的子弹装入数组中 */
public void ArraryBullet() {
}
/* 碰撞函数 */
@Override
public boolean hit(Flying fly) {
if (hitBy(fly)) {//判断是否碰撞
//当传入参数为子弹,且子弹速度小于0即为Hero机的子弹
if ((fly instanceof Bullet) && (fly.getY_speed() < 0)) {
BossHeart--;
}
if (fly instanceof Hero) {
BossHeart--;
}
return true;
}
return false;
}
//boss扣血
public void addLife(int life) {
this.BossHeart += life;
}
/* 判断Boss机的血量是否为0 */
public boolean BossHeartless() {
if (this.BossHeart <= 0)
return true;
else
return false;
}
/* 当Boss机血量为0时奖励Hero机能量 */
public void AwardHero(Hero hero) {
if (this.BossHeartless() == true) {
//将目前的能量加上Boss机的能量为参数传给Hero机的setEnergy()
hero.setEnergy(hero.getEnergy() + this.getBossEnergy());
}
}
/* 当Boss机的血量为0时给User加相应的得分 */
public void AwardUser(User user) {
if (this.BossHeartless() == true) {
user.add_score(this.getBossScore());
}
}
}
Bee类
package Flyings;
import Games.ShootGame;
import java.awt.image.BufferedImage;
import java.util.Random;
public class Bee extends Flying implements Collision {
private int AwardType; //奖励类型:0表示双倍火力,1表示生命值+1
private int x_speed = 1; //x坐标移动
private int y_speed = 2; //y坐标移动
//小蜜蜂构造器
public Bee(int y_speed) {
images = new BufferedImage[1];
images[0] = ShootGame.bee;
width = images[0].getWidth();
high = images[0].getHeight();
this.y_speed = y_speed;
//Bee任意位置产生
Random random = new Random();
this.x = random.nextInt(ShootGame.WIDTH - width) + width / 2;
this.y = 0;
AwardType = (int) (Math.random() * 2);
}
//获取奖励类型
public int getType() {
return AwardType;
}
//判断小蜜蜂是否被碰撞
public boolean hit(Flying fly) {
if (hitBy(fly) && (fly instanceof Hero)) {//撞击英雄机
AwardType = (int) (Math.random() * 2);
return true;
}
return false;
}
//小蜜蜂走步
@Override
public void step() {
x += x_speed;
y += y_speed;
//如果不做这样的判断,小蜜蜂就会飞出窗体
//如果小蜜蜂飞出左侧窗体,重新为x坐标移动赋值为1,向右飞
if (x < 0) {
x_speed = 1;
} else if (x > ShootGame.WIDTH - width) { //如果小蜜蜂飞出右侧窗体,为x坐标的移动赋值为 -1,向左飞
x_speed = -1;
}
}
//小蜜蜂越界处理
@Override
public boolean outOfBounds() {
// 飞出下边框就飞出边界了
return y > ShootGame.HEIGHT + high / 2;
}
}
UserCar类
package Car;
import Games.CarGame;
import java.awt.*;
import java.awt.image.BufferedImage;
public class UserCar extends Car{
private int speed; //汽车当前速度
private int index; //图片交换次数
private Image image; //当前的图片
public UserCar(int x, int y){
super(x, y);
index = 0;
images = new BufferedImage[2]; //两张用户汽车图片,交替显示,动图效果
images[0] = CarGame.usercar0; //无尾气图
images[1] = CarGame.usercar1; //有尾气图
image = images[0]; // 初始无尾气
this.width = images[0].getWidth(); //汽车图片长宽
this.high = images[0].getHeight();
}
//交换图片
public void change(){
index++;
int num=index/10%images.length;
image = images[num];
}
//汽车当前中点位置
public void position(int x,int y){
this.x = x;
this.y = y;
}
//碰撞到对面汽车
public boolean hitBy(Car car){
if(hit(car)&&(car instanceof PcCar)){
return true;
}
return false;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
PcCar类
PcCar类
package Car;
import Games.CarGame;
import Users.User;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
public class PcCar extends Car{
private int index;
public static int getScore() {
return score;
}
public static int score=1;
private Image image; //当前的图片
int speedIndex = 0;
//构造器
public PcCar(int y_speed){
this.y_speed = y_speed;
this.images = new BufferedImage[1];
Random r = new Random();
int rInt=r.nextInt(5);
if(rInt == 0)images[0]=CarGame.pccar0;
else if(rInt == 1)images[0]=CarGame.pccar1;
else if(rInt == 2)images[0]=CarGame.pccar2;
else if(rInt == 3)images[0]=CarGame.pccar3;
else images[0]=CarGame.pccar4;
width = images[0].getWidth();
high = images[0].getHeight();
//对面汽车4车道中的任意车道产生
Random random = new Random();
int yInt=random.nextInt(4);
if(yInt==0)
this.x = CarGame.WIDTH/2-width;
else if (yInt==1)
this.x = CarGame.WIDTH/2;
else if(yInt==2)
this.x = CarGame.WIDTH/2+width;
else this.x = CarGame.WIDTH/2+2*width;
this.y = -high;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHigh() {
return high;
}
public void setHigh(int high) {
this.high = high;
}
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;
}
//重写移动
@Override
public void move(){
y+=y_speed;
}
//越界
@Override
public boolean outOfBounds() {
return y>=CarGame.HEIGHT;
}
//给user加分
public void AwardUser(User user){
user.add_score(score);
}
}
Car类
package Car;
import java.awt.image.BufferedImage;
public class Car {
protected int high;//汽车对应的高度
protected int width;//汽车对应的宽度
protected int x;//汽车中心点的x值
protected int y;//汽车中心点的y值
protected BufferedImage[] images; // 声明图片数组
protected int x_speed;//x轴方向上的速度
protected int y_speed;//y轴方向上的速度
//无参构造器
public Car(){
}
//两参构造器
public Car(int x,int y){
this.x = x;
this.y = y;
}
/*移动(运行轨迹)*/
public void move(){
}
/*汽车越界处理 */
public boolean outOfBounds() {
return false;
}
//判断是否与car发生碰撞
public boolean hit(Car car){
return x+width/4> car.getX()-car.getWidth()/4&&
x-width/4< car.getX()+car.getWidth()/4&&
y+high/4>car.getY()-car.getHigh()/4&&
y-high/4<car.getY()+ car.getHigh()/4;
}
public int getHigh() {
return high;
}
public void setHigh(int high) {
this.high = high;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
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[] getImages() {
return images;
}
public void setImages(BufferedImage[] images) {
this.images = images;
}
public int getX_speed() {
return x_speed;
}
public void setX_speed(int x_speed) {
this.x_speed = x_speed;
}
public int getY_speed() {
return y_speed;
}
public void setY_speed(int y_speed) {
this.y_speed = y_speed;
}
}
本项目的开发环境是IntelliJ IDEA,jdk1.8.0,Navicat Premium 15。