一,程序的关闭
在Java程序中输入了打开窗口的方法,却无法关闭。
所以我们还需要输入一个点击的触发关闭的方法:
代码如下:
//关闭监听
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
在主程序中添加了一个监听器,形参中的方法叫做内部类(一般只用一次)
WindowAdapter类:
1.接收窗口事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象。
2.扩展此类可创建 WindowEvent 侦听器并为所需事件重写该方法。(如果要实现 WindowListener 接口,则必须定义该接口内的所有方法。此抽象类将所有方法都定义为 null,所以只需针对关心的事件定义方法。)
3.使用扩展的类可以创建侦听器对象,然后使用窗口的 addWindowListener 方法向该窗口注册侦听器。当通过打开、关闭、激活或停用、图标化或取消图标化而改变了窗口状态时,将调用该侦听器对象中的相关方法,并将 WindowEvent 传递给该方法。
void windowActivated(WindowEvent e)
激活窗口时调用。
void windowClosed(WindowEvent e)
当窗口已被关闭时调用。
void windowClosing(WindowEvent e)
窗口正处在关闭过程中时调用。
void windowDeactivated(WindowEvent e)
停用窗口时调用。
void windowDeiconified(WindowEvent e)
取消图标化窗口时调用。
void windowGainedFocus(WindowEvent e)
该 Window 被设置为聚焦 Window 时调用,聚焦 Window 意味着该 Window 或其某个子 组件将接收键盘事件。
void windowIconified(WindowEvent e)
图标化窗口时调用。
void windowLostFocus(WindowEvent e)
该 Window 不再为聚焦 Window 时调用,不再为聚焦 Window 意味着键盘事件不再传递 到该 Window 或其任意子组件。
void windowOpened(WindowEvent e)
已打开窗口时调用。
void windowStateChanged(WindowEvent e)
窗口状态改变时调用。
二,人物的移动
人物的移动同样的要使用监听键盘事件来控制
代码如下:
//监听键盘事件
this.addKeyListener(new KeyAdapter() {
//当键盘按下的时候触发
// Var 获取被按下的键的数值 如:a-67,B-68
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch (keyCode){
case KeyEvent.VK_UP:
System.out.println("向上走");
//按向上箭头给人物设置为向上
buffoon.setDir("U");
break;
case KeyEvent.VK_DOWN:
System.out.println("向下走");
buffoon.setDir("D");
break;
case KeyEvent.VK_LEFT:
System.out.println("向左走");
buffoon.setDir("L");
break;
case KeyEvent.VK_RIGHT:
System.out.println("向右走");
buffoon.setDir("R");
break;
default:
}
//人物移动
buffoon.move(buffoon.getDir());
}
使用switch判断按键后更改人物对象内属性 Dir的值,传进人物后进行判断,
对象代码如下:
//人物移动
public void move(String dir){
if ("U".equals(dir)){
this.y=this.y-this.speed;
}
if ("R".equals(dir)){
this.x=this.x+this.speed;
}
if ("D".equals(dir)) {
this.y=this.y+this.speed;
}
if ("L".equals(dir)){
this.x=this.x-this.speed;
}
if ("UR".equals(dir)) {
this.y=this.y-this.speed;
this.x=this.x+this.speed;
}
if ("UL".equals(dir)){
this.y=this.y-this.speed;
this.x=this.x-this.speed;
}
if ("DR".equals(dir)){
this.x=this.x+this.speed;
this.y=this.y+this.speed;
}
if ("DL".equals(dir)) {
this.y=this.y+this.speed;
this.x=this.x-this.speed;
}
}
通过代码判断方向后进行XY轴的加减
写完这些之后,人物依旧无法运动,但是后台里可以清楚的发现了Java在输出指令,说明了switch判断生效。
人物无法移动是因为单线程效率不足,这个时候我们要新建一个线程来让单线程的压力得到充分的分担,就好比一个车间一个人工作的效率比俩个人慢一样。
所以我们要新建线程分担
代码如下:
首先我们先新建一个类在继承一个Runnable接口,然后这个接口需要重新打印那必
然会有自己的游戏窗口,所以我们新建一个窗口属性,并且给他用get,set方法赋值
public class RepaintThiead implements Runnable{
//游戏窗体
private GameClinet gameClinet;
public RepaintThiead(GameClinet gameClinet) {
this.gameClinet = gameClinet;
}
public GameClinet getGameClinet() {
return gameClinet;
}
//通过构造器赋值
public void setGameClinet(GameClinet gameClinet) {
this.gameClinet = gameClinet;
}
重写run方法,采用循环执行线程刷新图像
代码如下:
@Override
public void run(){
while(true){
//每50毫秒 执行一次
try {
Thread.sleep(50);
//重新绘制图像
gameClinet.repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在测试中调用并且创建其对象
代码如下所示:
//开启重新绘制线程
RepaintThiead repaintThiead=new RepaintThiead(this);
Thread thread=new Thread(repaintThiead);
thread.start();
效果图: