JavaGUI-坦克大战04

7.线程的应用03

7.3坦克大战4.0版

7.3.4功能3:敌方坦克自由移动

功能3:让敌人的坦克也可以自由随机地上下左右移动

思路:

  1. 因为要求敌人的坦克自由移动,因此需要将敌人坦克当做线程使用,EnemyTank类实现Runnable接口
  2. 线程的run方法的具体操作为:根据当前的方向继续移动敌坦,然后改变敌坦移动方向,再继续移动,如此不断循环。break的条件是当前的敌人坦克被击中,即enemy.isLive == false。
  3. 在MyPanel类中,每创建一个敌人坦克对象就启动一个线程。

EnemyTank:

package li.TankGame.version04;

import java.util.Vector;

public class EnemyTank extends Tank implements Runnable {

    //在敌人坦克类使用Vector保存多个Shot
Vector<Shot> shots = new Vector<>();
boolean isLive = true; public EnemyTank(int x, int y) {
super(x, y);
} @Override
public void run() {
while (true) {
//根据坦克的方法来继续移动
switch (getDirect()) {
case 0://上
//让坦克保持一个方向走30步
for (int i = 0; i < 100; i++) {
moveUp();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 1://右
//让坦克保持一个方向走30步
for (int i = 0; i < 100; i++) {
moveRight();//走一步
try {
Thread.sleep(50);//每走一步就休眠50毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 2://下
for (int i = 0; i < 100; i++) {
moveDown();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 3://左
for (int i = 0; i < 100; i++) {
moveLeft();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
}
//随机地改变坦克的方向 0-3
setDirect((int) (Math.random() * 4));//[0,4)的取整
//如果被击中了,就退出线程
if (!isLive) {
break;//退出线程
}
}
}
}

MyPanel:line 46-47


7.3.5功能4: 控制坦克移动范围

如图,坦克的绘图以图案的左上方坐标为参考。

在向上时,坦克的纵坐标限制为y>0,向下时,y+60<面板高度;向左时,x>0,向右时,x+60<面板宽度

EnemyTank:控制敌人的坦克不出界

package li.TankGame.version04;

import java.util.Vector;

public class EnemyTank extends Tank implements Runnable {

    //在敌人坦克类使用Vector保存多个Shot
Vector<Shot> shots = new Vector<>();
boolean isLive = true; public EnemyTank(int x, int y) {
super(x, y);
} @Override
public void run() {
while (true) {
//根据坦克的方法来继续移动
switch (getDirect()) {
case 0://上
//让坦克保持一个方向走30步
for (int i = 0; i < 100; i++) {
if (getY() > 0) {
moveUp();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 1://右
//让坦克保持一个方向走30步
for (int i = 0; i < 100; i++) {
if (getX() + 60 < 700) {//700为面板宽度
moveRight();//走一步
}
try {
Thread.sleep(50);//每走一步就休眠50毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 2://下
for (int i = 0; i < 100; i++) {
if (getY() + 60 < 550) {//550为面板宽度
moveDown();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 3://左
for (int i = 0; i < 100; i++) {
if (getX() > 0) {
moveLeft();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
}
//随机地改变坦克的方向 0-3
setDirect((int) (Math.random() * 4));//[0,4)的取整
//如果被击中了,就退出线程
if (!isLive) {
break;//退出线程
}
}
}
}

修改MyPanel类中的keyPressed方法,使我方坦克也不能走出边界:

//控制方向--处理 WSAD 键按下的情况
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {//按下W键-向上
//改变坦克的方向
hero.setDirect(0);
//修改坦克的坐标
if (hero.getY() > 0) {//向上
hero.moveUp();
}
} else if (e.getKeyCode() == KeyEvent.VK_D) {//按下D键-向右
hero.setDirect(1);
if (hero.getX() + 60 < 750) {//向右
hero.moveRight();
}
} else if (e.getKeyCode() == KeyEvent.VK_S) {//按下S键-向下
hero.setDirect(2);
if (hero.getY() + 60 < 550) {//向下
hero.moveDown();
}
} else if (e.getKeyCode() == KeyEvent.VK_A) {//按下A键-向左
hero.setDirect(3);
if (hero.getX() > 0) {//向左
hero.moveLeft();
}
}
//如果用户按下j键,hero就发射子弹
if (e.getKeyCode() == KeyEvent.VK_J) {
hero.shotEnemyTank();
} //让面板重绘
this.repaint();
}

day04-应用线程03的更多相关文章

  1. 26_多线程_第26天(Thread、线程创建、线程池)_讲义

    今日内容介绍 1.多线程 2.线程池 01进程概念 A:进程概念 a:进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行, 即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能 ...

  2. 26_java之进程|线程|线程池

    01进程概念 *A:进程概念 *a:进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行, 即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 02线程的概念 *A:线程的概 ...

  3. [b0026] python 归纳 (十一)_线程_threading.Thread

    总结: 默认父线程跑完,子线程并不会马上退出,不像 thread.start_threadXXXX 父线程跑完了,并没有退出,一直在那里 线程启动速度很快,不占多少开销,不到1毫 秒 代码: # -* ...

  4. 老男孩Python全栈第2期+课件笔记【高清完整92天整套视频教程】

    点击了解更多Python课程>>> 老男孩Python全栈第2期+课件笔记[高清完整92天整套视频教程] 课程目录 ├─day01-python 全栈开发-基础篇 │ 01 pyth ...

  5. 深度解析Java8 – AbstractQueuedSynchronizer的实现分析(上)

    本文首发在infoQ :www.infoq.com/cn/articles/jdk1.8-abstractqueuedsynchronizer 前言: Java中的FutureTask作为可异步执行任 ...

  6. 20160227.CCPP体系详解(0037天)

    程序片段(01):01.一对一模式.c+02.中介者模式.c+03.广播模式.c 内容概要:事件 ///01.一对一模式.c #include <stdio.h> #include < ...

  7. 20160226.CCPP体系详解(0036天)

    程序片段(01):01.多线程.c+02.多线程操作.c 内容概要:多线程 ///01.多线程.c #include <stdio.h> #include <stdlib.h> ...

  8. c#委托中的同步和异步方法即BeginInvoke和EndInvoke

    学习多线程之前我们先了解一下电脑的一些概念,比如进程,线程,这个参考https://www.cnblogs.com/loverwangshan/p/10409755.html 这篇文章.今天我们接着来 ...

  9. Android中多线程编程(三)Handler更新UI的方式

    Handler更新UI的方式和原因以及遇到的问题 1.方式: 仅仅能通过Handler来更新UI. 代码例如以下: package com.chengdong.su.handlerdemo; impo ...

  10. 20160227.CCPP体系具体解释(0037天)

    程序片段(01):01.一对一模式.c+02.中介者模式.c+03.广播模式.c 内容概要:事件 ///01.一对一模式.c #include <stdio.h> #include < ...

随机推荐

  1. 佳翼M2X16 PCIE4.0X16转4盘M.2NVME固态硬盘 - 我的硬件配置

  2. Java并发(七)----线程sleep、yield、线程优先级

    1.sleep 与 yield sleep 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞) 其它线程可以使用 interrupt 方法打断正在睡眠的线 ...

  3. redmine获取cookie和其他系统实现单点登录

    前言 最近有个需求,需要将我们一个平台对接到redmine,让用户可以通过这个平台直接在redmine提工单,需要实现免登录跳转.首先是想到去查redmine有无相应的单点登录功能,查到redmine ...

  4. delphi 里 多用TArray 而不是 array of

    今天写代码发现个bug,是delphi 编译器 核心层面的: unit ddx.att; interface uses System.Generics.Collections, System.Rtti ...

  5. React axios 使用 http-proxy-middleware 解决跨域问题小记

    壹 ❀ 引 在上篇bug分析的记录文中,提到axios可做到取消接口请求,所以想写一篇关于axios.CancelToken使用以及原理分析的文章(主要是自己好奇到底如何做到的取消).在准备工作阶段, ...

  6. Slot 的含义

    Slot 解释 1)slot就是槽的意思,是一个资源单位,只有给task分配了一个slot之后,这个task才可以运行.slot分两种,map slot沪蓉reduce slot.另外,slot是一个 ...

  7. logstash4j-用于日志的输入、转换处理、输出, java 开发者自己的 logstash

    项目简介 logstash4j 用于日志的输入.转换处理.输出, java 开发者自己的 logstash 特性 input output filter metric 开源地址 logstash4j ...

  8. 【Unity3D】UI Toolkit自定义元素

    1 前言 ​ UI Toolkit 支持通过继承 VisualElement 实现自定义元素,便于通过脚本控制元素.另外,UI Toolkit 也支持将一个容器及其所有子元素作为一个模板,便于通过脚本 ...

  9. win10安装和配置weblogic12c

    下载和安装 http://www.oracle.com/technetwork/middleware/ias/downloads/wls-main-097127.html ● 将jar放到jdk的bi ...

  10. Oracle11gr2新增APPEND_VALUES提示

    在11.2中,Oracle新增了APPEND_VALUES提示,使得INSERT INTO VALUES语句也可以使用直接路径插入. 例子很简单: SQL> SELECT * FROM V$VE ...