讲了那么多python的知识,今天我们换一下口味,讲解一个java实例,就是著名的坦克大战游戏。

准备工作:

(1)安装eclipse

(2)JDK1.8版本以上


这里我用到的是eclipse中文版,主要面向非官方用户。

一:建立一个工作空间

1.先在桌面上创建一个tanke命名的文件夹,然后我们把工作空间切换过去,方法如下:

java坦克大战实例讲解(一)_工作空间

这是我们来切换工作空间:

java坦克大战实例讲解(一)_java_02

之后eclipse会重启,我们等待一下,就会看到已经切换到我们的工作空间了。

这时我们想要验证下,就可以新建一个java项目,然后在建立我们需要的类:

java坦克大战实例讲解(一)_java_03

然后我们输出一些东西,可以看到我们创建成功了:

java坦克大战实例讲解(一)_工作空间_04


2.我们还需要一些修改:

(1)修改码表为utf-8:我们点击窗口(Windows)->首选项(Preference)->工作空间进入设置:

java坦克大战实例讲解(一)_java_05

大家可以自行修改字体大小。

这里向大家介绍一个自动补齐的方法,大家打开这个页面:

java坦克大战实例讲解(一)_工作空间_06

在内容辅助中在鼠标的位置java的自动触发器,默认为".",这里我们输入小写abcd-z即可(输入的是a到z的26个字母),就可以让编译器触发默认的代码:

java坦克大战实例讲解(一)_工作空间_07

这样可以方便我们写代码,缩短我们写代码的时间。


二.准备工作之模板方法设计模式

1.我们先写一段计算重复代码输出时间的程序:


package com.itxiaoangzai.test;

public class Test3 {
public static void main(String[] args) {
//打印200次"IT Xiao Ang Zai"

//时间得到的是ms值
long start = System.currentTimeMillis();
for(int i = 0;i < 200;i++)
{
System.out.println("IT Xiao Ang Zai"+i);
}

long end = System.currentTimeMillis();
System.out.println(end - start);
}
}

java坦克大战实例讲解(一)_工作空间_08

2.我们如果想要得到更多重复次数的输出时间,是不是可以用一个通用的办法呢?

当然,我们先新建一个抽象类,然后构建父类的抽象方法:

package com.itxiaoangzai.test;

/**
* 模板方法设计模式构建一个模板类
* 可以在非抽象方法中调用抽象方法
* @author IT Xiao Ang Zai
*
*/

public abstract class GetTime {
public abstract void myThing();
public long getTime(){
//时间得到的是ms值
long start = System.currentTimeMillis();

myThing();

long end = System.currentTimeMillis();
return end - start;
}
}

然后我们再用一个子类继承父类的方法,然后重写父类的抽象方法(这里用到了多态),就可以得到我们想要的结果:


package com.itxiaoangzai.test;

public class MyThing extends GetTime{
public void myThing(){
for(int i = 0;i < 200;i++)
{
System.out.println("IT Xiao Ang Zai"+i);
}
}

}

效果如下:

java坦克大战实例讲解(一)_java_09


三:创建第一个窗体

1.导入lwjgl包(LightWight Java Game Library(轻量级Java游戏工具库),轻量级指的是他不依赖计算机硬件,可以在多平台使用。

大家可能没有听过,不过大家肯定听过我得世界这款游戏吧,它就是用这个jar包创建窗体的。

我们先下载后安装,操作如下:

java坦克大战实例讲解(一)_jar包_10

从GitHub上下载我们需要的lwjgl的jar包:

java坦克大战实例讲解(一)_工作空间_11

java坦克大战实例讲解(一)_工作空间_12

我们可以看到我们已经成功下载到了这个jar包:

java坦克大战实例讲解(一)_jar包_13

这里我想大家分享了一个整理过的文件

我们导入后还要添加依赖:

java坦克大战实例讲解(一)_工作空间_14

java坦克大战实例讲解(一)_工作空间_15

这时,这个jar包就可以供我们使用了。


2.我们先定义一个Windows类,代码如下:


package com.itxiaoangzai.test;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

public abstract class Window {
private final String title;// 标题
private final int width;// 屏幕宽度
private final int height;// 屏幕的高度
private final int fps;// 每秒钟刷新的帧率

private boolean running;
private ScheduledExecutorService pool;
private Map<Integer, ScheduledFuture<?>> tasks = new LinkedHashMap<>();

public Window(String title, int width, int height, int fps) {
this.title = title;
this.width = width;
this.height = height;
this.fps = fps;
}

/**
* 开始游戏
*/
public final void start() {
if (running) {
return;
}
running = true;

pool = Executors.newScheduledThreadPool(16);

// 初始化窗体
initGL();

// 创建时的回调
onCreate();

while (running && !Display.isCloseRequested()) {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

// 处理用户交互输入
processInput();

// 处理UI刷新显示
processDisplay();

Display.update();
Display.sync(fps);
}

pool.shutdownNow();
Display.destroy();
}

/**
* 退出游戏
*/
public final void stop() {
if (!running) {
return;
}
running = false;
}

private void initGL() {
try {
Display.setDisplayMode(new DisplayMode(width, height));
Display.create();
Display.setTitle(title);
Display.setVSyncEnabled(true);
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}

GL11.glEnable(GL11.GL_TEXTURE_2D);

GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

// enable alpha blending
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

GL11.glViewport(0, 0, width, height);
GL11.glMatrixMode(GL11.GL_MODELVIEW);

GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, width, height, 0, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}

private void processInput() {
while (Mouse.next()) {
if (Mouse.getEventButtonState()) {
onMouseEvent(Mouse.getEventButton(), Mouse.getX(), Mouse.getY());
}
}

while (Keyboard.next()) {
if (Keyboard.getEventKeyState()) {
// 按下
int key = Keyboard.getEventKey();
onKeyEvent(key);

addLongPress(key);
} else {
// 释放
int key = Keyboard.getEventKey();
removeLongPress(key);
}
}
}

private void addLongPress(int key) {
ScheduledFuture<?> future = tasks.get(key);
if (future != null) {
future.cancel(true);
future = null;
}

future = pool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
onKeyEvent(key);
}
}, 100, 100, TimeUnit.MILLISECONDS);

tasks.put(key, future);
}

private void removeLongPress(int key) {
ScheduledFuture<?> future = tasks.get(key);
if (future != null) {
future.cancel(true);
future = null;
}
}

private void processDisplay() {
onDisplayUpdate();
}

/**
* 窗体创建时的回调
*/
protected abstract void onCreate();

/**
* 鼠标down事件
*
* @param key
* 0为左键 1为右键
* @param x
* x坐标
* @param y
* y坐标
*/
protected abstract void onMouseEvent(int key, int x, int y);

/**
* 按键事件
*
* @param key
* 按键,{@code Keyboard.key_xx}
*/
protected abstract void onKeyEvent(int key);

/**
* 当屏幕刷新时的回调
*/
protected abstract void onDisplayUpdate();
}

我们写入主程序:

java坦克大战实例讲解(一)_jar包_16

这是我们可以看到一个错误,好像是我们的java.library没有配置环境,那么如何解决这个问题呢?这里大家可以根据我的步骤:

java坦克大战实例讲解(一)_工作空间_17

然后我们就可以得到我们的游戏主窗口界面:

java坦克大战实例讲解(一)_工作空间_18


好了,接下来我们讲解一些素材的创建,欢迎大家给我指导意见。