利用JAVA语言实现坦克大战游戏——画出坦克

一、任务需求

赋予敌人行动和攻击。

二、思路

- 敌人行动

1.需要把EnemyTank做成线程类实现Runnable接口.

run方法中,坦克移动非常快biu biu biu,所以用sleep和for循环进行减速,让他缓慢移动。移动后再让弹可随机选择一个direct,如果坦克islive=false就让该线程结束。另外,增加if语句,当坦克跑出400*300的边界时,坦克不能向外移动。只能向边界内移动。

while (true) {

try {

Thread.sleep(50);

} catch (Exception e) {

e.printStackTrace();

}

switch (Direct) {

case 0:

for(int i=0;i<3;i++){

if(y>0)

y-=speed;

try {

Thread.sleep(500);

} catch (Exception e) {

e.printStackTrace();

}

}

//说明坦克正在向上移动

break;

case 1:

for(int i=0;i<3;i++){

if(y<300)

y+=speed;

try {

Thread.sleep(500);

} catch (Exception e) {

e.printStackTrace();

}

}

break;

case 2:

for(int i=0;i<3;i++){

if(x>0)

x-=speed;

try {

Thread.sleep(500);

} catch (Exception e) {

e.printStackTrace();

}

}

break;

case 3:

for(int i=0;i<3;i++){

if(x<400)

x+=speed;

try {

Thread.sleep(500);

} catch (Exception e) {

e.printStackTrace();

}

}

break;

default:

break;

}

//让坦克随机产生新的方向

Direct = (int)(Math.random()*4);

//判断敌人坦克是否死亡

if(isLive==false){

//让坦克死亡,退出线程

break;

}

2.改进画出敌方坦克代码,并且在MyPanel中定义坦克集合

// 定义敌军

Vector

ets = new Vector();

// 画出敌方坦克

for (int i = 0; i < ets.size(); i++) {

EnemyTank et = ets.get(i);

if (et.isLive) {

drawTank(et.getX(), et.getY(), g, et.getDirect(), ets.get(i)

.getColor());

// 画出敌人坦克子弹

for (int j = 0; j < et.ss.size(); j++) {

Shot enemyShot = et.ss.get(j);// j写错成i

if (enemyShot.isLive) {

g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);

} else {

// 如果敌人的坦克死亡,就从Vector去掉

et.ss.remove(enemyShot);

}

}

}

}

-坦克发射子弹

1.enemyTank改进run,子弹多发。在EnemyTank类run方法中加入time变量,当坦克移动一次,即休眠3*500ms=1.5s后,time++,当每隔三秒进入if(time%2==0)发射一次子弹,并且启动该子弹线程。

2.将之前的MyPanel类run()方法中判断子弹击中坦克部分提取出来,再改写为hitEnemyTank()方法。

3.同上一步骤,改写hitMe()方法。

4. 而之前的hitTank(Shot s,EnemyTank et)改成hitTank(Shot s,Tank et)用以被hitMe()和hitEnemyTank()调用

三、源代码

MyTankGame.java

/**

* 功能:坦克游戏的2.0

* 1.画出坦克

* 2.坦克的移动

* 3.坦克发射子弹,子弹连发,最多五颗

* 4.爆炸效果

* 5.敌人开始行动啦

* 6.我被打爆

*/

package Tank_05;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Image;

import java.awt.Panel;

import java.awt.Toolkit;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.util.Vector;

import javax.swing.JFrame;

import javax.swing.JPanel;

@SuppressWarnings("serial")

public class MyTankGame4 extends JFrame {

MyPanel p1 = null;

public MyTankGame4() {

p1 = new MyPanel();

Thread t = new Thread(p1);

t.start();

add(p1);

setSize(400, 300);

setVisible(true);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

addKeyListener(p1);// 注册监听

}

public static void main(String[] args) {

new MyTankGame4();

}

}

// 画图

@SuppressWarnings("serial")

class MyPanel extends JPanel implements KeyListener, Runnable {

int enSize = 3;

Hero hero = null;

// 定义敌军

Vector ets = new Vector();

// 定义炸弹集合

Vector bombs =

new Vector();

// 定义8张图片,8张图片组成一颗炸弹

Image image1 = null;

Image image2 = null;

Image image3 = null;

Image image4 = null;

Image image5 = null;

Image image6 = null;

Image image7 = null;

Image image8 = null;

public MyPanel() {

hero = new Hero(100, 100);// 设置坦克出现的位置(10,10)

// 初始化敌人的坦克

for (int i = 0; i < enSize; i++) {

// 创建对人的坦克对象

EnemyTank et = new EnemyTank((i + 1) * 80, 0);

et.setColor(1);

et.setDirect(1);

// 启动敌人的坦克

Thread t = new Thread(et);

t.start();

// 给敌人添加子弹

Shot s = new Shot(et.x + 9, et.y + 28, 1);

// 加入给敌人坦克

et.ss.add(s);

Thread t2 = new Thread(s);

t2.start();

ets.add(et);

}

// 初始化图片

image1 = Toolkit.getDefaultToolkit().getImage(

Panel.class.getResource("/blast1.gif"));

image2 = Toolkit.getDefaultToolkit().getImage(

Panel.class.getResource("/blast2.gif"));

image3 = Toolkit.getDefaultToolkit().getImage(

Panel.class.getResource("/blast3.gif"));

image4 = Toolkit.getDefaultToolkit().getImage(

Panel.class.getResource("/blast4.gif"));

image5 = Toolkit.getDefaultToolkit().getImage(

Panel.class.getResource("/blast5.gif"));

image6 = Toolkit.getDefaultToolkit().getImage(

Panel.class.getResource("/blast6.gif"));

image7 = Toolkit.getDefaultToolkit().getImage(

Panel.class.getResource("/blast7.gif"));

image8 = Toolkit.getDefaultToolkit().getImage(

Panel.class.getResource("/blast8.gif"));

}

protected void paintComponent(Graphics g) {

super.paintComponent(g);

g.fillRect(0, 0, 400, 300);// 背景填充

// 画出我方坦克

if(hero.isLive){

drawTank(hero.getX(), hero.getY(), g, hero.Direct, 0);// 一定要传入画笔g

}

// 从ss中取出每一颗子弹,并画出

for (int i = 0; i < hero.ss.size(); i++) {

Shot myShot = hero.ss.get(i);

// 画出子弹

if (myShot != null && myShot.isLive == true) {

// System.out.format("%d %d ", hero.s.x,hero.s.y);

g.setColor(Color.red);

g.draw3DRect(myShot.x, myShot.y, 1, 1, false);

}

if (myShot.isLive == false) {

hero.ss.remove(myShot);// 记住是myShot 不是i

}

}

// 画出炸弹

for (int i = 0; i < bombs.size(); i++) {

// 取出炸弹

Bomb b = bombs.get(i);

// System.out.format("%d",++num);

if (b.life > 8) {

g.drawImage(image1, b.x, b.y, 30, 30, this);

} else if (b.life > 7) {

g.drawImage(image2, b.x, b.y, 30, 30, this);

} else if (b.life > 6) {

g.drawImage(image3, b.x, b.y, 30, 30, this);

} else if (b.life > 5) {

g.drawImage(image4, b.x, b.y, 30, 30, this);

} else if (b.life > 4) {

g.drawImage(image5, b.x, b.y, 30, 30, this);

} else if (b.life > 3) {

g.drawImage(image6, b.x, b.y, 30, 30, this);

} else if (b.life > 2) {

g.drawImage(image7, b.x, b.y, 30, 30, this);

} else if (b.life > 1) {

g.drawImage(image8, b.x, b.y, 30, 30, this);

}

b.lifeDown();

// 如果life为 0 酒吧炸弹从bombs向量去掉

if (b.life == 0) {

bombs.remove(b);

}

}

// 画出敌方坦克

for (int i = 0; i < ets.size(); i++) {

EnemyTank et = ets.get(i);

if (et.isLive) {

drawTank(et.getX(), et.getY(), g, et.getDirect(), ets.get(i)

.getColor());

// 画出敌人坦克子弹

for (int j = 0; j < et.ss.size(); j++) {

Shot enemyShot = et.ss.get(j);// j写错成i

if (enemyShot.isLive) {

g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);

} else {

// 如果敌人的坦克死亡,就从Vector去掉

et.ss.remove(enemyShot);

}

}

}

}

}

public void hitMe() {

// 取出每个敌人的坦克

for (int i = 0; i < ets.size(); i++) {

// 取出坦克

EnemyTank et = ets.get(i);

// 取出每颗子弹

for (int j = 0; j < et.ss.size(); j++) {

Shot enemyShot = et.ss.get(j);

hitTank(enemyShot, hero);

}

}

}

public void hitEnemyTank() {

// 判断是否击中敌人坦克

for (int i = 0; i < hero.ss.size(); i++) {

Shot myShot = hero.ss.get(i);

// 判断子弹是否有效

if (myShot.isLive) {

// 取出每个坦克,与他判断

for

(int j = 0; j < ets.size(); j++) {

EnemyTank et = ets.get(j);

if (et.isLive) {

hitTank(myShot, et);

}

}

}

}

}

// 写一个函数专门判断: 子弹是否击中敌人坦克

public void hitTank(Shot s, Tank et) {

// 判断该坦克的方向

switch (et.Direct) {

// 方向上或者下,是相同的

case 0:

case 1:

if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) {

// 击中,子弹死亡

s.isLive = false;

// 坦克死亡

et.isLive = false;

// 触发爆炸,放入vector

Bomb b = new Bomb(et.x, et.y);

bombs.add(b);

}

break;

// 方向左右,相同

case 2:

case 3:

if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y <= et.y + 20) {

s.isLive = false;

et.isLive =

false;

Bomb b = new Bomb(et.x, et.y);

bombs.add(b);

}

break;

default:

break;

}

}

/*

* drawTank (坦克坐标x,y,画笔g,方向,坦克类型) 方法介绍: 可以设置-->坦克的颜色(类型:敌方坦克,我方坦克),方向,出现的坐标

*

* 如果type是default 则默认颜色为画出黑色坦克

*

* 封装性:将坦克封装到方法中。

*/

public

void drawTank(int x, int y, Graphics g, int direct, int type) {

switch (type) {

case 0:

g.setColor(Color.cyan);

break;

case 1:

g.setColor(Color.yellow);

default:

break;

}

switch (direct) {

case 0:

// 向上

g.fill3DRect(x, y, 5, 30, false);

g.fill3DRect(x + 15, y, 5, 30, false);

g.fill3DRect(x + 5, y + 5, 10, 20, false);

g.fillOval(x + 4, y + 10, 10, 10);

g.drawLine(x + 9, y + 15, x + 9, y);

break;

case 1:

// 向下w

g.fill3DRect(x, y, 5, 30, false);

g.fill3DRect(x + 15, y, 5, 30, false);

g.fill3DRect(x + 5, y + 5, 10, 20, false);

g.fillOval(x + 4, y + 10, 10, 10);

g.drawLine(x + 9, y + 15, x + 9, y + 30);

break;

case

2:

// 向左

g.fill3DRect(x, y, 30, 5, false);

g.fill3DRect(x, y + 15, 30, 5, false);

g.fill3DRect(x + 5, y + 5, 20, 10, false);

g.fillOval(x + 9, y + 4, 10, 10);

g.drawLine(x + 5, y + 9, x - 4, y + 9);

break;

case 3:

// 向右

g.fill3DRect(x, y, 30, 5, false);

g.fill3DRect(x, y + 15, 30, 5, false);

g.fill3DRect(x + 5, y + 5, 20, 10, false);

g.fillOval(x + 9, y + 4, 10, 10);

g.drawLine(x + 15, y + 9, x + 30, y + 9);

break;

default:

break;

}

// repaint(); 因为监听器里面有repaint() 所以不用在加repaint()了

}

@Override

public void keyTyped(KeyEvent e) {

}

@Override

public void keyPressed(KeyEvent e) {// 实现接口 根据按键上下左右移动 可以控制速度和移动

if (e.getKeyCode() == KeyEvent.VK_W) {

hero.setDirect(0);

hero.moveUp();

} else if (e.getKeyCode() == KeyEvent.VK_S) {

hero.setDirect(1);

hero.moveDown();

} else if (e.getKeyCode() == KeyEvent.VK_A) {

hero.setDirect(2);

hero.moveLeft();

} else if (e.getKeyCode() == KeyEvent.VK_D) {

hero.setDirect(3);

hero.moveRight();

}

if (e.getKeyCode() == KeyEvent.VK_J) {

// 开火

if (hero.ss.size() <= 4) {

hero.shotEnemy();

}

}

// 判断玩家是否按下J攻击键

repaint();

}

@Override

public void keyReleased(KeyEvent e) {

}

@Override

public void run() {

// 每隔100毫秒 重新画图

while (true) {

try {

Thread.sleep(100);

} catch (Exception e) {

e.printStackTrace();

}

hitEnemyTank();

hitMe();

repaint();

}

}

}

members.java

package Tank_05;

import java.util.Vector;

//坦克父类 可以设置坦克出现位置(x,y)

class Tank {

int x = 0;

int y = 0;

int speed = 8;

int Direct = 0;

int color;

boolean isLive = true;

public int getColor() {

return color;

}

public void setColor(int color) {

this.color = color;

}

public int getDirect() {

return Direct;

}

public void setDirect(int direct) {

Direct = direct;

}

public int getSpeed() {

return speed;

}

public void setSpeed(int speed) {

this.speed = speed;

}

public Tank(int x, int y) {

this.x = x;

this.y = y;

}

public int getX() {

return x;

}

public void setX(int x) {

this.x = x;

}

public int getY() {

return y;

}

public void setY(int y) {

this.y = y;

}

// 视频中是把移动放在hero类中

}

// 敌方坦克

// 需要做成线程类

class EnemyTank extends Tank implements Runnable {

int time = 0;

//定义一个向量存放敌人的子弹

Vector ss = new Vector();

//敌人添加子弹,在刚刚创建坦克的时候

public EnemyTank(int x, int y) {

super(x, y);

}

@Override

public void run() {

while (true) {

try {

Thread.sleep(50);

} catch (Exception e) {

e.printStackTrace();

}

switch (Direct) {

case 0:

for(int i=0;i<3;i++){

if(y>0)

y-=speed;

try {

Thread.sleep(500);

} catch (Exception e) {

e.printStackTrace();

}

}

//说明坦克正在向上移动

break;

case 1:

for(int i=0;i<3;i++){

if(y<300)

y+=speed;

try {

Thread.sleep(500);

} catch (Exception e) {

e.printStackTrace();

}

}

break;

case 2:

for(int i=0;i<3;i++){

if(x>0)

x-=speed;

try {

Thread.sleep(500);

} catch (Exception e) {

e.printStackTrace();

}

}

break;

case 3:

for(int i=0;i<3;i++){

if(x<400)

x+=speed;

try {

Thread.sleep(500);

} catch (Exception e) {

e.printStackTrace();

}

}

break;

default:

break;

}

time++;

if(time%2==0){

if(isLive){

if(ss.size()<8){

Shot s = null;

//没有子弹了 就添加

switch(Direct){

case 0:

// 创建一颗子弹

s = new Shot(x + 8, y - 4, 0);

// 把子弹加入向量

ss.add(s);

break;

case 1:

s = new Shot(x + 9, y + 32, 1);

ss.add(s);

break;

case 2:

s = new

Shot(x - 8, y + 8, 2);

ss.add(s);

break;

case 3:

s = new Shot(x + 32, y + 9, 3);

ss.add(s);

break;

default:

break;

}

//启动子单线程

Thread t = new Thread(s);

t.start();

}

}

}

//让坦克随机产生新的方向

Direct = (

int)(Math.random()*4);

//判断敌人坦克是否死亡

if(isLive==false){

//让坦克死亡,退出线程

break;

}

}

}

}

// 我的英雄坦克

class Hero extends Tank {

// 子弹

Vector ss = new Vector();

Shot s = null;

public Hero(int x, int y) {

super(x, y);

}

// 开火

public void shotEnemy() {

switch (Direct) {

case 0:

// 创建一颗子弹

s = new Shot(x + 8, y - 4, 0);

// 把子弹加入向量

ss.add(s);

break;

case 1:

s = new

Shot(x + 9, y + 32, 1);

ss.add(s);

break;

case 2:

s = new Shot(x - 8, y + 8, 2);

ss.add(s);

break;

case 3:

s = new Shot(x + 32, y + 9, 3);

ss.add(s);

break;

default:

break;

}

Thread t = new Thread(s);

t.start();

}

public void moveUp() {

y -= speed;

}

public void moveDown() {

y += speed;

}

public void moveLeft() {

x -= speed;

}

public void moveRight() {

x += speed;

}

}

// 子弹类

class

Shot implements Runnable {

int x;

int y;

int Direct;

int speed = 1;

boolean isLive = true;

public Shot(int x, int y, int Direct) {

this.x = x;

this.y = y;

this.Direct = Direct;

}

@Override

public void run() {

while (true) {

try {

Thread.sleep(50);

} catch (Exception e) {

}

switch (Direct) {

case 0:

y -= speed;

break;

case 1:

y += speed;

break;

case 2:

x -= speed;

break;

case 3:

x += speed;

break;

default:

break;

}

// System.out.println(""+x+" "+y);

// 子弹何时死亡

if (x < 0 || x > 400 || y < 0 || y > 300) {

this.isLive = false;

break;

}

}

}

}

class Bomb {

int x;

int y;

// 炸弹的生命

int life = 9;

boolean isLive = true;

public Bomb(int x, int y) {

this.x = x;

this.y = y;

}

// 减少生命值

public void lifeDown() {

if (life > 0) {

life--;

} else {

isLive = false;

}

}

}

四、效果图

利用JAVA语言实现坦克大战游戏——画出坦克


分享到:


相關文章: