需求:坦克发射子弹思路
我的思路:
1、坦克发射子弹需子弹对象、射击的动作、且按下某个键射出子弹
2、射击出来的子弹需要绘画在画板上,从坦克炮口射出,射出后撞到边界消失
3、这个子弹需启一个线程
老师的思路
代码:
package tankegame3;
//坦克类
public class Tank {
private int x;//坦克的横坐标
private int y;//坦克的纵坐标
private int direct; //增加坦克方向 0 1 2 3 按顺时顺序
private int speed =1 ;
// 上、右、下、左移动方法
public void moveUp() {
y -= speed;
}
public void moveRight() {
x += speed;
}
public void moveDown() {
y += speed;
}
public void moveLeft() {
x -= speed;
}
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;
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
}
package tankegame3;
//我方坦克类
public class Hero extends Tank {
Shot shot = null;
public Hero(int x, int y) {
super(x, y);
}
public void shoutEnemyTank() {//子弹从炮管射出的位置
//创建Shot对象,根据当前Hero方向来创建Shot
switch (getDirect()) { //获取坦克Hero的方向
case 0://向上 根据方向确定子弹射出的位置
shot = new Shot(getX() + 20, getY(), 0);
break;
case 1://向右
shot = new Shot(getX() + 60, getY() + 20, 1);
break;
case 2://向下
shot = new Shot(getX() + 20, getY() + 60, 2);
break;
case 3://向左
shot = new Shot(getX(), getY(), 3);
break;
}
//启动Shot线程
new Thread(shot).start();
}
}
package tankegame3;
//敌方坦克类
public class Enemy_Tank extends Tank {
public Enemy_Tank(int x, int y) {
super(x, y);
}
}
package tankegame3;
//射击方法
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
//坦克的绘图区
//为了监听 键盘事件,实现KeyListener
//为了让Panel 不停重新绘制子弹,需要将Mypanel 当做一个线程使用
public class Mypanel extends JPanel implements KeyListener, Runnable {
//定义我的坦克
Hero hero = null;
//定义敌人坦克数组
Vector<Enemy_Tank> enemyTanks = new Vector<>();
int enemyTankSize = 3;//定义敌人坦克数量为3
public Mypanel() {
hero = new Hero(200, 200);//初始化自己坦克
hero.setSpeed(10);
//初始化敌人坦克3个
for (int i = 0; i < enemyTankSize; i++) {
Enemy_Tank enemyTank = new Enemy_Tank(100 * (i + 1), 0);//创建敌人坦克
enemyTank.setDirect(2);//设置敌人坦克方向向下
enemyTanks.add(enemyTank);//将坦克加入到数组内
}
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填充矩形黑色
//画出坦克 -- 封装方法
drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 0);//自己的坦克
//画出坦克子弹
if (hero.shot != null && hero.shot.isLive == true) {
System.out.println("子弹发射");
g.fill3DRect(hero.shot.x, hero.shot.y, 1, 1, false);
}
for (int i = 0; i < enemyTanks.size(); i++) {//绘制敌人的坦克, 遍历Vector
Enemy_Tank enemyTank = enemyTanks.get(i);
drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
}
// drawTank(hero.getX() + 60,hero.getY(),g,0,0);//坦克1
}
//编写方法画出坦克 考虑坦克的属性
/*
* x 为坦克左上角的x坐标
* y 为坦克左上角y坐标
* g 为画笔
* direct 坦克上下左右方向
* type 坦克类型
*
* */
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);
break;
}
//坦克的方向
switch (direct) { //(0表示向上,1表示向右,2表示向下,3表示向左)
case 0://坦克向上
g.fill3DRect(x, y, 10, 60, false);//画出坦克左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子
g.drawLine(x + 20, y + 30, x + 20, y);//画出炮筒
break;
case 1://坦克向右边
g.fill3DRect(x, y, 60, 10, false);//画出坦克左边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克右边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子
g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子
g.drawLine(x + 30, y + 20, x + 60, y + 20);//画出炮筒
break;
case 2://坦克向下
g.fill3DRect(x, y, 10, 60, false);//画出坦克左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子
g.drawLine(x + 20, y + 30, x + 20, y + 60);//画出炮筒
break;
case 3://坦克向左
g.fill3DRect(x, y, 60, 10, false);//画出坦克左边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克右边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子
g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子
g.drawLine(x + 30, y + 20, x, y + 20);//画出炮筒
break;
default:
System.out.println("暂时不处理");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {//处理 w\d\s\a按下的情况
if (e.getKeyCode() == KeyEvent.VK_W) {//
//改变坦克方式为上
hero.setDirect(0);
hero.moveUp();
} else if (e.getKeyCode() == KeyEvent.VK_D) {
//改变坦克方式为右
hero.setDirect(1);
hero.moveRight();
} else if (e.getKeyCode() == KeyEvent.VK_S) {
//改变坦克方式为下
hero.setDirect(2);
hero.moveDown();
} else if (e.getKeyCode() == KeyEvent.VK_A) {
//改变坦克方式为左
hero.setDirect(3);
hero.moveLeft();
}
//如果用户按下J,就发射子弹,射击敌人子弹
if (e.getKeyCode() == KeyEvent.VK_J) {
hero.shoutEnemyTank();
}
//让面板重绘
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void run() { //每隔一定100ms时间自己重绘区域,子弹就会移动起来了
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
this.repaint();
}
}
}
package tankegame3;
//坦克的画板
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
//坦克的绘图区
//为了监听 键盘事件,实现KeyListener
//为了让Panel 不停重新绘制子弹,需要将Mypanel 当做一个线程使用
public class Mypanel extends JPanel implements KeyListener, Runnable {
//定义我的坦克
Hero hero = null;
//定义敌人坦克数组
Vector<Enemy_Tank> enemyTanks = new Vector<>();
int enemyTankSize = 3;//定义敌人坦克数量为3
public Mypanel() {
hero = new Hero(200, 200);//初始化自己坦克
hero.setSpeed(10);
//初始化敌人坦克3个
for (int i = 0; i < enemyTankSize; i++) {
Enemy_Tank enemyTank = new Enemy_Tank(100 * (i + 1), 0);//创建敌人坦克
enemyTank.setDirect(2);//设置敌人坦克方向向下
enemyTanks.add(enemyTank);//将坦克加入到数组内
}
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填充矩形黑色
//画出坦克 -- 封装方法
drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 0);//自己的坦克
//画出坦克子弹
if (hero.shot != null && hero.shot.isLive == true) {
System.out.println("子弹发射");
g.fill3DRect(hero.shot.x, hero.shot.y, 1, 1, false);
}
for (int i = 0; i < enemyTanks.size(); i++) {//绘制敌人的坦克, 遍历Vector
Enemy_Tank enemyTank = enemyTanks.get(i);
drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
}
// drawTank(hero.getX() + 60,hero.getY(),g,0,0);//坦克1
}
//编写方法画出坦克 考虑坦克的属性
/*
* x 为坦克左上角的x坐标
* y 为坦克左上角y坐标
* g 为画笔
* direct 坦克上下左右方向
* type 坦克类型
*
* */
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);
break;
}
//坦克的方向
switch (direct) { //(0表示向上,1表示向右,2表示向下,3表示向左)
case 0://坦克向上
g.fill3DRect(x, y, 10, 60, false);//画出坦克左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子
g.drawLine(x + 20, y + 30, x + 20, y);//画出炮筒
break;
case 1://坦克向右边
g.fill3DRect(x, y, 60, 10, false);//画出坦克左边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克右边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子
g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子
g.drawLine(x + 30, y + 20, x + 60, y + 20);//画出炮筒
break;
case 2://坦克向下
g.fill3DRect(x, y, 10, 60, false);//画出坦克左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子
g.drawLine(x + 20, y + 30, x + 20, y + 60);//画出炮筒
break;
case 3://坦克向左
g.fill3DRect(x, y, 60, 10, false);//画出坦克左边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克右边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子
g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子
g.drawLine(x + 30, y + 20, x, y + 20);//画出炮筒
break;
default:
System.out.println("暂时不处理");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {//处理 w\d\s\a按下的情况
if (e.getKeyCode() == KeyEvent.VK_W) {//
//改变坦克方式为上
hero.setDirect(0);
hero.moveUp();
} else if (e.getKeyCode() == KeyEvent.VK_D) {
//改变坦克方式为右
hero.setDirect(1);
hero.moveRight();
} else if (e.getKeyCode() == KeyEvent.VK_S) {
//改变坦克方式为下
hero.setDirect(2);
hero.moveDown();
} else if (e.getKeyCode() == KeyEvent.VK_A) {
//改变坦克方式为左
hero.setDirect(3);
hero.moveLeft();
}
//如果用户按下J,就发射子弹,射击敌人子弹
if (e.getKeyCode() == KeyEvent.VK_J) {
hero.shoutEnemyTank();
}
//让面板重绘
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void run() { //每隔一定100ms时间自己重绘区域,子弹就会移动起来了
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
this.repaint();
}
}
}