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 < ...
随机推荐
- Go语言实现八大排序|排序算法|超详细保姆级别注释
前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总https://blog.cs ...
- Git企业开发控制理论和实操-从入门到深入(七)|企业级开发模型
前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总 然后就是博主最近最花时间的一 ...
- Java并发(六)----线程start、run、state方法
1.start 与 run 调用 run public static void main(String[] args) { Thread t1 = new Thread("t1&quo ...
- 探索C语言的数据类型:解密编程世界的核心秘密
欢迎大家来到贝蒂大讲堂 养成好习惯,先赞后看哦~ 所属专栏:C语言学习 贝蒂的主页:Betty's blog 1. 常量与变量 1.1 常量 (1) 常量的概念 常量顾名思义就是无法改变的量,比如一周 ...
- shell 两个数组比较,得到元素的并集、交集等
linux shell 实现数组比较,取元素的并集.交集时,可以使用sort排序.uniq统计和awk数据过滤. shell 实现如下 file_list_1=("test1" & ...
- 用set做一轮无重复纯随机
前端时间面腾讯的时候,一位老师问了一个相当有趣的问题:假设存在一个音乐播放器,里面有一个100首歌的歌单.现在需要做一个随机播放功能,要求不重复的随机播放完一百首歌.当时脑子短路了没想出来,几天突然意 ...
- NC24727 [USACO 2010 Feb G]Slowing down
题目链接 题目 题目描述 Every day each of Farmer John's N (1 <= N <= 100,000) cows conveniently numbered ...
- nginx 剔除请求参数 $args 变量中任意指定参数之万金油
剔除任意指定参数配置 只需要修改需要剔除的参数key(如:redirectUrl) #剔除$args中的redirectUrl 参数 server { listen 80; server_name w ...
- 使用ORACLE外部表装载复杂数据
原文:http://www.oracle.com/technetwork/issue-archive/2013/13-jan/o13asktom-1886639.html I am using SQL ...
- Python之密码生成器
介绍 这段程序用来随机批量生成一批安全性相对较高的密码,要了解你当前使用的密码强度到底如何? 可以试一下这个网站: https://howsecureismypassword.net/ 他会告诉你计算 ...