项目设计主要知识点:
1. Java面向对象的三大特征:封装、继承、多态;
2. Jpanel类和Graphics类中方法的使用
3. 接口KeyListener方法的实现
4. 列表的选择及使用
文章目录
一、定义并封装坦克父类DrawTank
public class DrawTank {
private int x;//坦克模型基准坐标
private int y;//坦克模型基准坐标
private int direct;//坦克方向
private int speed = 1;//坦克速度
//以下是构造器、getter和setter方法以及上下左右移动方法
public DrawTank(int x, int y) {
this.x = x;
this.y = y;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
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 void moveUp() {
y -= speed;
}
public void moveRight() {
x += speed;
}
public void moveDown() {
y += speed;
}
public void moveLeft() {
x -= speed;
}
}
二、定义子类自己的坦克MyTank继承父类DrawTank
public class MyTank extends DrawTank{
public MyTank(int x, int y) {
super(x, y);
}
}
三、定义子类敌人的坦克EnemyTank继承父类DrawTank
public class EnemyTank extends DrawTank{
public EnemyTank(int x, int y) {
super(x, y);
}
}
四、定义显示界面MyPanel类继承父类JPanel并实现KeyListener接口(重点!!)
此类是绘制坦克的类,里面涉及到Vector的定义及遍历、重写方法、以及switch-case等基础知识,可以用来练手。
public class MyPanel extends JPanel implements KeyListener {
MyTank myTank = null;//声明自己坦克
Vector<EnemyTank> enemyTanks = new Vector<>();//敌方坦克列表
int enemyTankSize = 10;//敌方坦克数量
//构造器
public MyPanel() {
myTank = new MyTank(100, 100);//初始化自己坦克
for (int i = 0; i < enemyTankSize; i++) {//初始化敌人坦克
EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
enemyTank.setDirect(2);//设置敌方坦克方向
enemyTanks.add(enemyTank);//加入到敌方坦克列表
}
}
//重写JPanel 继承的JComponent类中的paint方法
@Override
public void paint(Graphics g) {
super.paint(g);//初始化画笔
g.fillRect(0, 0, 1000, 750);//在面板上绘制填充矩形,默认黑色
painTank(myTank.getX(), myTank.getY(), g, myTank.getDirect(), 0);//调用painTank方法绘制自己坦克,方法在下面定义
for (int i = 0; i < enemyTanks.size(); i++) {//调用painTank方法绘制敌方坦克
EnemyTank enemyTank = enemyTanks.get(i);
painTank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirect(),1);
}
}
//编写方法,画出坦克
/**
* @param x 坦克左上角x坐标
* @param y 坦克左上角y坐标
* @param g 画笔
* @param direct 坦克方向上下左右(0:向上 1: 向右 2:向下 3:向左)
* @param type 坦克类型(0:自己,1:敌方)
*/
public void painTank(int x, int y, Graphics g, int direct, int type) {
//根据不同type设置不同颜色
switch (type) {
case 0:
g.setColor(Color.GREEN);
break;
case 1:
g.setColor(Color.yellow);
break;
}
//根据坦克方向,来绘制坦克(0:向上 1: 向右 2:向下 3:向左)
switch (direct) {
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, x + 20, y + 30);
break;
case 1://向右
g.fill3DRect(x - 10, y + 10, 60, 10, false);//左轮子
g.fill3DRect(x - 10, y + 40, 60, 10, false);//右轮子
g.fill3DRect(x, y + 20, 40, 20, false);//盖子
g.fillOval(x + 10, y + 20, 20, 20);
g.drawLine(x + 50, y + 30, x + 20, y + 30);
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 + 60, x + 20, y + 30);
break;
case 3://向左
g.fill3DRect(x - 10, y + 10, 60, 10, false);//左轮子
g.fill3DRect(x - 10, y + 40, 60, 10, false);//右轮子
g.fill3DRect(x, y + 20, 40, 20, false);//盖子
g.fillOval(x + 10, y + 20, 20, 20);
g.drawLine(x - 10, y + 30, x + 20, y + 30);
break;
default:
System.out.println("暂时没有处理");
}
}
//以下是实现KeyListener接口的三个方法,目前只用到键盘按压监听方法keyPressed
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();//获取英文键盘输入的按键
if (keyCode == KeyEvent.VK_W || keyCode == KeyEvent.VK_UP) {//KeyEvent.VK_W:W对应的code;KeyEvent.VK_UP:向上的键对应的code
myTank.setDirect(0);//设置方向
myTank.moveUp();//调用向上移动方法,下面各个方向同理
} else if (keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT) {
myTank.setDirect(1);
myTank.moveRight();
} else if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN) {
myTank.setDirect(2);
myTank.moveDown();
} else if (keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT) {
myTank.setDirect(3);
myTank.moveLeft();
}
this.repaint();//重绘小球,否则键盘按压坦克无变化
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
五、实现显示坦克界面以及监听事件
在构造器中设置面板大小、事件监听机制等显示设置
public class TankGame1 extends JFrame {
// 定义MyPanel
MyPanel mp = null;
public static void main(String[] args) {
TankGame1 tankGame1 = new TankGame1();//创建坦克游戏对象
}
//构造器
public TankGame1(){
mp = new MyPanel();//面板实例化
this.add(mp);//把面板加入坦克游戏类中(游戏的绘图区域)
this.setSize(1000,750);//设置面板大小
this.addKeyListener(mp);//加入监听事件
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击界面×结束程序
this.setVisible(true);//设置可见
}
}
六、界面展示
运行TankGame1.java后界面显示如下:
按下键盘D或者👉箭头移动自己坦克,界面如下: