注:此为小游戏最终版本 代码做到最优最简
基于之前发表的文章详情可见
点击查看前文
回顾之前的代码我们可以看到很多的固定常量值或是属性我们都会大量的重复使用,这并不符合我们代码简洁易懂的特点
所以我们可以把重复出现的量或是属性或是方法使用面向对象的思想,减少代码的冗余使代码简单明了
public class GameClient extends Frame{
}
关于Farme类:
1.Farme类是Java自带的一个系统类
2.Farme类的作用是可以制作出带有标题和边框的顶层窗口
//窗体宽度
public static final int CLIENT_WIDTH = 700;
//窗体高度
public static final int CLIENT_HEIGHT = 500;
使用static定义 以便在其他类调用属性
// 运行游戏方法
public void start() {
//开始游戏时在控制台输出显示内容
System.out.println("游戏马上开始,请玩家做好准备");
//设置窗体标题
this.setTitle("原谅帽带战");
//设置窗体的大小以及位置
this.setBounds(0, 0, SuperSoulEntity.CLIENT_WIDTH, SuperSoulEntity.CLIENT_HEIGHT);
// 让窗体显示出来
this.setVisible(true);
//点击窗口x关闭键响应关闭
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent windowEvent) {
//点击X退出游戏后在控制台输出显示内容
System.out.println("Game Over!!!");
//调用System类中的exit方法以实现窗口关闭按钮(X)的生效
System.exit(0);
}
});
//定义main方法以开始运行游戏
public static void main(String[] args) {
GameClient gameClient = new GameClient();
gameClient.start();
}
//读取图片方法getImage
public static Image getImage(String imgPath) {
//参数为图片路径地址
ImageIcon imageIcon = new ImageIcon(imgPath);
return imageIcon.getImage();
}
// 常量 定义背景图片的路径
public static final String BG_PATH = "images/bg.png";
// 定义一个图片的静态变量
private static Image image;
// 把路径的值给静态变量,所有资源(图片,音频,视频)只需要加载一次
static {
image = SuperSoulEntity.getImage(BG_PATH);
}
//重写父类Frame类的paint方法以实现插入各种图片
@Override
public void paint(Graphics g) {
// 画背景图
g.drawImage(image, 0, 0, SuperSoulEntity.CLIENT_WIDTH, SuperSoulEntity.CLIENT_HEIGHT, this);
}
//x坐标
protected int x;
//y坐标
protected int y;
//宽
protected int width;
//高
protected int height;
//移动速度
protected int speed;
//游戏窗体属性 使图片在窗体中显示
protected GameClient gameClient;
//全参构造 给图片属性赋初始值
public SuperSoulEntity (int x,int y,int width,int height,int speed,GameClient gameClient) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speed = speed;
this.gameClient = gameClient;
}
// 人物图片属性
public static Image buffoonImage = SuperSoulEntity.getImage("images/body/s-left.png");
//带参构造
public Buffoon(int x, int y, GameClient gameClient) {
super(x, y, 50, 50, 5, gameClient);
}
//小丑有自己的画画方法
public void paint(Graphics g) {
g.drawImage(buffoonImage, this.x, this.y, this.width, this.height, this.gameClient);
}
//重写父类Frame类的paint方法以实现插入各种图片
@Override
public void paint(Graphics g) {
// 将人物插入窗口
buffoon.paint(g);
}
// 人物-状态(初始值为静止)
private String dir = "STOP";
// 人物-方向
private String dir1 = "UP";
//判断方向按键是否同时按下了两个组合键(斜方向移动)默认四个方向都没有被按下
boolean up = false;
boolean right = false;
boolean left = false;
boolean down = false;
//get set方法
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
/**
* 线程类(重新绘制画图的线程)
*/
public class RepaintThread implements Runnable{
public RepaintThread(GameClient gameClient) {
this.gameClient = gameClient;
}
// 游戏窗体
private GameClient gameClient;
@Override
public void run() {
while (true){
// 每50毫秒执行一次
try {
Thread.sleep(50);
// 重新绘制图像
gameClient.repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 确定键盘按下时的人物移动方向
public void okDirPrssed(int keyCode) {
// 确定方向
switch (keyCode) {
case KeyEvent.VK_UP:
System.out.println("向上走!");
// 按向上箭头,给人物的方向设置为向上
this.setDir("UP");
// 当按住下方向键时,监听为true(已按下)
up = true;
break;
case KeyEvent.VK_DOWN:
System.out.println("向下走!");
// 按向下箭头,给人物的方向设置为向下
this.setDir("DOWN");
// 当按住下方向键时,监听为true(已按下)
down = true;
break;
case KeyEvent.VK_LEFT:
System.out.println("向左走!");
// 按向左箭头,给人物的方向设置为向左
this.setDir("LEFT");
// 当按住下方向键时,监听为true(已按下)
left = true;
break;
case KeyEvent.VK_RIGHT:
System.out.println("向右走!");
// 按向右箭头,给人物的方向设置为向右
this.setDir("RIGHT");
// 当按住下方向键时,监听为true(已按下)
right = true;
break;
}
//判断用户到底按了那些键
//东北
if (up && right) {
this.setDir("UR");
}
//东南
if (right && down) {
this.setDir("DR");
}
//西北
if (left && up) {
this.setDir("LU");
}
//西南
if (left && down) {
this.setDir("LD");
}
}
/**
* 键盘松开,确定人物移动方向
*/
public void okDirReleased(int keyCode) {
switch (keyCode) {
//上
case KeyEvent.VK_UP:
up = false;
break;
//下
case KeyEvent.VK_DOWN:
down = false;
break;
//左
case KeyEvent.VK_LEFT:
left = false;
buffoonImage = SuperSoulEntity.getImage("images/body/s-left.png");
break;
//右
case KeyEvent.VK_RIGHT:
right = false;
buffoonImage = SuperSoulEntity.getImage("images/body/s-right.png");
break;
}
if (!up&&!down&&!left&&!right){
this.setDir("STOP");
}
}
/**
* 人物移动
*/
public void move(String dir) {
if ("UP".equals(dir)) {
this.y -= this.speed;
dir1="UP";
}
if ("RIGHT".equals(dir)) {
this.x += this.speed;
dir1="RIGHT";
}
if ("DOWN".equals(dir)) {
this.y += this.speed;
dir1="DOWN";
}
if ("LEFT".equals(dir)) {
this.x -= this.speed;
dir1="LEFT";
}
if ("UR".equals(dir)) {
this.x += this.speed;
this.y -= this.speed;
dir1="UR";
}
if ("DR".equals(dir)) {
this.x += this.speed;
this.y += this.speed;
dir1="DR";
}
if ("LD".equals(dir)) {
this.x -= this.speed;
this.y += this.speed;
dir1="LD";
}
if ("LU".equals(dir)) {
this.x -= this.speed;
this.y -= this.speed;
dir1="LU";
}
}
// 运行游戏方法
public void start() {
//开始游戏时在控制台输出显示内容
System.out.println("游戏马上开始,请玩家做好准备");
//设置窗体标题
this.setTitle("原谅帽带战");
//设置窗体的大小以及位置
this.setBounds(0, 0, SuperSoulEntity.CLIENT_WIDTH, SuperSoulEntity.CLIENT_HEIGHT);
// 让窗体显示出来
this.setVisible(true);
//点击窗口x关闭键响应关闭
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent windowEvent) {
//点击X退出游戏后在控制台输出显示内容
System.out.println("Game Over!!!");
//调用System类中的exit方法以实现窗口关闭按钮(X)的生效
System.exit(0);
}
});
// 监听键盘事件
this.addKeyListener(new KeyAdapter() {
//当键盘按下时触发
@Override
public void keyPressed(KeyEvent e) {
// 获取被按下的键的对应数值 如:A-67,B-68
int keyCode = e.getKeyCode();
// 调用人物确定方向的方法okDir
buffoon.okDirPrssed(keyCode);
buffoon.move(buffoon.getDir());
}
//当键盘松开时触发
@Override
public void keyReleased(KeyEvent e) {
//获取松开的按键的值
int keyCode = e.getKeyCode();
buffoon.okDirReleased(keyCode);
}
});
//开启重新绘制线程
RepaintThread repaintThread = new RepaintThread(this);
// 创建车间工人
Thread thread = new Thread(repaintThread);
// 工人听候调度
thread.start();
}