Java-坦克移动(面向对象+集合选型)

Java-坦克移动(面向对象+集合选型)

实现过程

  • 普通Tank类;
    • 1.增加了坦克朝向属性direction;
    • 2.增加了坦克移动速度属性speed;
    • 3.为了控制坦克移动,将移动操作(即改变坦克的横纵坐标,重新绘制的过程)封装为方法;
/**
 * 坦克
 * @author: SEA
 * @date: 2023/3/2
 */
public class Tank{
    private int x;//坦克的横坐标
    private int y;//坦克的纵坐标

    private int direction;//坦克的朝向:0 => 向上 ,1 => 向下 ,2 => 向左 , 3 => 向右

    private int speed = 5;

    public Tank(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void moveUp(){
        this.y -= this.speed;
    }

    public void moveDown(){
        this.y += this.speed;
    }

    public void moveRight(){
        this.x += this.speed;
    }

    public void moveLeft(){
        this.x -= this.speed;
    }

    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 getDirection() {
        return direction;
    }

    public void setDirection(int direction) {
        this.direction = direction;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }
}
  • 玩家坦克类;
    • 1.继承了普通坦克类;
/**
 * 游戏玩家坦克
 * @author: SEA
 * @date: 2023/3/2
 */
public class Hero extends Tank {

    public Hero(int x, int y) {
        super(x, y);
    }
}
  • 敌方坦克类;
    • 1.继承了普通坦克类;
/**
 * @author: SEA
 * @date: 2023/3/5
 */
public class EnemyTank extends Tank{
    public EnemyTank(int x, int y) {
        super(x, y);
    }
}
  • 坦克游戏窗口类;
    • 1.为了控制坦克移动,需要在游戏窗口类添加键盘监听KeyListener;
/**
 * 坦克游戏窗口
 * @author: SEA
 * @date: 2023/3/2
 */
class GameFrame extends JFrame {//画框
    GamePanel gamePanel = null;

    public void draw() {
        gamePanel = new GamePanel();

        this.add(gamePanel);
        this.setSize(1000, 800);
        this.setVisible(true);

        this.addKeyListener(gamePanel);//添加键盘监听

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }
}
  • 坦克游戏绘制区域;
    • 1.在paint()方法中实现根据坦克朝向的不同,绘制不同的坦克;
    • 2.实现键盘监听接口KeyListener,并重写该接口中的方法来实现控制坦克向上、向下、向左、向右、加速、减速等操作;
    • 3.增加敌方坦克:
      • 1)集合选型:考虑到后续需要多线程来操控敌方坦克,因此选择Vector来存储;
      • 2)初始化敌方坦克:定义变量enemyTankSize作为默认敌方坦克数量,并使用for循环初始化;
      • 3)绘制敌方坦克:考虑到后续敌方坦克可能被消灭,因此遍历Vector进行绘制时,可以使用普通for循环或者增强for循环,需要注意的是,使用普通for循环时,应遍历当前Vector中坦克的实际数量,例如使用enemyTanks.size();
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

/**
 * 坦克大战绘图区域
 * @author: SEA
 * @date: 2023/3/2
 */


class GamePanel extends JPanel implements KeyListener {//画板

    //定义玩家的坦克
    Hero hero = null;

    //考虑多线程问题,使用Vector来保存敌方坦克
    Vector<EnemyTank> enemyTanks = null;
    int enemyTankSize = 5;


    public GamePanel() {
        //初始化玩家坦克
        hero = new Hero(250, 400);

		//初始化敌方坦克
        enemyTanks = new Vector<EnemyTank>();
        for (int i = 0; i < enemyTankSize; i++) {
            EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 100);
            enemyTank.setDirection(1);
            enemyTanks.add(enemyTank);
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        //游戏窗口背景
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, 1000, 800);

        //标题
        g.setFont(new Font("楷体", Font.BOLD, 32));
        g.setColor(Color.RED);
        g.drawString("TankGame V0.1 by SEA-365", 60, 40);

        //画出坦克-封装成方法
        drawTank(hero.getX(), hero.getY(), g, hero.getDirection(), 0);

        for (EnemyTank enemyTank : enemyTanks) {
            drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirection(), 1);
        }
    }

    /**
     *
     * @param x 坦克左上方x轴坐标
     * @param y 坦克左上方y轴坐标
     * @param g 画笔
     * @param direction 坦克的朝向:0 => 向上 ,1 => 向下 ,2 => 向左 , 3 => 向右
     * @param type 坦克类型:0 => 玩家坦克,1 => 敌方坦克
     */
    public void drawTank(int x, int y, Graphics g, int direction, int type){

        //不同坦克类型,颜色不同
        switch (type){
            case 0://玩家坦克
                g.setColor(Color.YELLOW);
                break;
            case 1://敌方坦克
                g.setColor(Color.CYAN);
                break;
        }

        //不同方向的坦克
        switch (direction){
            case 0://向上坦克
                g.fill3DRect(x, y, 10, 60, false);//坦克左矩形(履带)
                g.fill3DRect(x+34, y, 10, 60, false);//坦克右矩形(履带)
                g.fill3DRect(x+10, y+10, 24, 40, false);//坦克中间矩形(驾驶仓)
                g.fillOval(x+10, y+18, 24, 24   );//坦克中间圆形(炮台)
                g.fill3DRect(x+22, y, 2, 22, false);//坦克中间矩形(炮筒)
                break;
            case 1://向下坦克
                g.fill3DRect(x, y, 10, 60, false);//坦克左矩形(履带)
                g.fill3DRect(x+34, y, 10, 60, false);//坦克右矩形(履带)
                g.fill3DRect(x+10, y+10, 24, 40, false);//坦克中间矩形(驾驶仓)
                g.fillOval(x+10, y+18, 24, 24   );//坦克中间圆形(炮台)
                g.fill3DRect(x+22, y+42, 2, 22, false);//坦克中间矩形(炮筒)
                break;
            case 2://向左坦克
                g.fill3DRect(x, y, 60, 10, false);//坦克上矩形(履带)
                g.fill3DRect(x, y+34, 60, 10, false);//坦克下矩形(履带)
                g.fill3DRect(x+10, y+10, 40, 24, false);//坦克中间矩形(驾驶仓)
                g.fillOval(x+18, y+10, 24, 24   );//坦克中间圆形(炮台)
                g.fill3DRect(x, y+22, 22, 2, false);//坦克中间矩形(炮筒)
                break;
            case 3://向右坦克
                g.fill3DRect(x, y, 60, 10, false);//坦克上矩形(履带)
                g.fill3DRect(x, y+34, 60, 10, false);//坦克下矩形(履带)
                g.fill3DRect(x+10, y+10, 40, 24, false);//坦克中间矩形(驾驶仓)
                g.fillOval(x+18, y+10, 24, 24   );//坦克中间圆形(炮台)
                g.fill3DRect(x+42, y+22, 22, 2, false);//坦克中间矩形(炮筒)
                break;
            default:
                break;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_DOWN || (char)e.getKeyCode() == 'S' || (char)e.getKeyCode() == 's'){
            this.hero.setDirection(1);
            this.hero.moveDown();
        }
        if(e.getKeyCode() == KeyEvent.VK_UP || (char)e.getKeyCode() == 'W' || (char)e.getKeyCode() == 'w'){
            this.hero.setDirection(0);
            this.hero.moveUp();
        }
        if(e.getKeyCode() == KeyEvent.VK_RIGHT || (char)e.getKeyCode() == 'D' || (char)e.getKeyCode() == 'd'){
            this.hero.setDirection(3);
            this.hero.moveRight();
        }
        if(e.getKeyCode() == KeyEvent.VK_LEFT || (char)e.getKeyCode() == 'A' || (char)e.getKeyCode() == 'a'){
            this.hero.setDirection(2);
            this.hero.moveLeft();
        }

        if(e.getKeyCode() == '='){//按 j 键加快移动速度
            this.hero.setSpeed(this.hero.getSpeed() + 2);

        }
        if(e.getKeyCode() == '-'){//按 r 键恢复正常移动速度
            this.hero.setSpeed(this.hero.getSpeed() - 2);
        }

        this.repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }
}

实现效果

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SEA-365

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值