day04-应用线程03
JavaGUI-坦克大战04
7.线程的应用03
7.3坦克大战4.0版
7.3.4功能3:敌方坦克自由移动
功能3:让敌人的坦克也可以自由随机地上下左右移动
思路:
- 因为要求敌人的坦克自由移动,因此需要将敌人坦克当做线程使用,EnemyTank类实现Runnable接口
- 线程的run方法的具体操作为:根据当前的方向继续移动敌坦,然后改变敌坦移动方向,再继续移动,如此不断循环。break的条件是当前的敌人坦克被击中,即enemy.isLive == false。
- 在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的更多相关文章
- 26_多线程_第26天(Thread、线程创建、线程池)_讲义
今日内容介绍 1.多线程 2.线程池 01进程概念 A:进程概念 a:进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行, 即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能 ...
- 26_java之进程|线程|线程池
01进程概念 *A:进程概念 *a:进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行, 即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 02线程的概念 *A:线程的概 ...
- [b0026] python 归纳 (十一)_线程_threading.Thread
总结: 默认父线程跑完,子线程并不会马上退出,不像 thread.start_threadXXXX 父线程跑完了,并没有退出,一直在那里 线程启动速度很快,不占多少开销,不到1毫 秒 代码: # -* ...
- 老男孩Python全栈第2期+课件笔记【高清完整92天整套视频教程】
点击了解更多Python课程>>> 老男孩Python全栈第2期+课件笔记[高清完整92天整套视频教程] 课程目录 ├─day01-python 全栈开发-基础篇 │ 01 pyth ...
- 深度解析Java8 – AbstractQueuedSynchronizer的实现分析(上)
本文首发在infoQ :www.infoq.com/cn/articles/jdk1.8-abstractqueuedsynchronizer 前言: Java中的FutureTask作为可异步执行任 ...
- 20160227.CCPP体系详解(0037天)
程序片段(01):01.一对一模式.c+02.中介者模式.c+03.广播模式.c 内容概要:事件 ///01.一对一模式.c #include <stdio.h> #include < ...
- 20160226.CCPP体系详解(0036天)
程序片段(01):01.多线程.c+02.多线程操作.c 内容概要:多线程 ///01.多线程.c #include <stdio.h> #include <stdlib.h> ...
- c#委托中的同步和异步方法即BeginInvoke和EndInvoke
学习多线程之前我们先了解一下电脑的一些概念,比如进程,线程,这个参考https://www.cnblogs.com/loverwangshan/p/10409755.html 这篇文章.今天我们接着来 ...
- Android中多线程编程(三)Handler更新UI的方式
Handler更新UI的方式和原因以及遇到的问题 1.方式: 仅仅能通过Handler来更新UI. 代码例如以下: package com.chengdong.su.handlerdemo; impo ...
- 20160227.CCPP体系具体解释(0037天)
程序片段(01):01.一对一模式.c+02.中介者模式.c+03.广播模式.c 内容概要:事件 ///01.一对一模式.c #include <stdio.h> #include < ...
随机推荐
- 佳翼M2X16 PCIE4.0X16转4盘M.2NVME固态硬盘 - 我的硬件配置
- Java并发(七)----线程sleep、yield、线程优先级
1.sleep 与 yield sleep 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞) 其它线程可以使用 interrupt 方法打断正在睡眠的线 ...
- redmine获取cookie和其他系统实现单点登录
前言 最近有个需求,需要将我们一个平台对接到redmine,让用户可以通过这个平台直接在redmine提工单,需要实现免登录跳转.首先是想到去查redmine有无相应的单点登录功能,查到redmine ...
- delphi 里 多用TArray 而不是 array of
今天写代码发现个bug,是delphi 编译器 核心层面的: unit ddx.att; interface uses System.Generics.Collections, System.Rtti ...
- React axios 使用 http-proxy-middleware 解决跨域问题小记
壹 ❀ 引 在上篇bug分析的记录文中,提到axios可做到取消接口请求,所以想写一篇关于axios.CancelToken使用以及原理分析的文章(主要是自己好奇到底如何做到的取消).在准备工作阶段, ...
- Slot 的含义
Slot 解释 1)slot就是槽的意思,是一个资源单位,只有给task分配了一个slot之后,这个task才可以运行.slot分两种,map slot沪蓉reduce slot.另外,slot是一个 ...
- logstash4j-用于日志的输入、转换处理、输出, java 开发者自己的 logstash
项目简介 logstash4j 用于日志的输入.转换处理.输出, java 开发者自己的 logstash 特性 input output filter metric 开源地址 logstash4j ...
- 【Unity3D】UI Toolkit自定义元素
1 前言 UI Toolkit 支持通过继承 VisualElement 实现自定义元素,便于通过脚本控制元素.另外,UI Toolkit 也支持将一个容器及其所有子元素作为一个模板,便于通过脚本 ...
- win10安装和配置weblogic12c
下载和安装 http://www.oracle.com/technetwork/middleware/ias/downloads/wls-main-097127.html ● 将jar放到jdk的bi ...
- Oracle11gr2新增APPEND_VALUES提示
在11.2中,Oracle新增了APPEND_VALUES提示,使得INSERT INTO VALUES语句也可以使用直接路径插入. 例子很简单: SQL> SELECT * FROM V$VE ...