LMEH262 2019-01-26 23:50 采纳率: 75%
浏览 644
已采纳

键盘无法控制对象的移动

在做坦克大战的小程序,坦克无法被键盘控制,程序运行后,依然还是贴了第一张,想知道具体原因。
代码如下:
TankJFrame类:

import java.awt.*;
import javax.swing.*;
/**
 * 坦克主体框架,继承JFrame类
 * 
 * **/

public class TankFrame extends JFrame{

    private static final long serialVersionUID = 1L;

    //设置窗口的宽和高
    public static int window_width = 1500;
    public static int window_hight = 1000;

    //新建tankPanel
    TanksPanel t_panel = new TanksPanel();

    //启动框架
    public void lunchFrame() {
        setTitle("坦克大战");
        setSize(window_width, window_hight);
        setLocation(200, 10);

        //add各个组件
        add(t_panel);
        //添加键盘控制
        addKeyListener(t_panel.p_tanks.k_contral);

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setVisible(true);
        //窗口大小不可变
        setResizable(false);

        //启动线程
        new Thread(t_panel).start();

    }


    //主函数
    public static void main(String args[]) {
        new TankFrame().lunchFrame();
    }

}

TankPanel类:

import java.awt.*;
import javax.swing.*;

/**
 * 坦克主面板函数,继承JPanel类
 * **/
public class TanksPanel extends JPanel implements Runnable{

    private static final long serialVersionUID = 1L;

    //新建玩家坦克
    PlayerTanks p_tanks = new PlayerTanks(100, 100, false);

    //重载paintComponent方法
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        //绘制背景
        g.fillRect(0, 0, TankFrame.window_width, TankFrame.window_hight);

        //绘制玩家坦克
        p_tanks.drawTanks();
        g.drawImage(p_tanks.getTankImage(), p_tanks.getLocal_x(), p_tanks.getLocal_y(), p_tanks.getTanks_width(), p_tanks.getTanks_hight(), this);

        p_tanks.move();
    }



    @Override
    //实现Runnable接口抽象方法run
    public void run() {
        while(true) {
            this.repaint();
            //实现线程,使坦克每隔100毫秒重新绘制一次
            try {
                Thread.sleep(100);
            }catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

Tanks类:

import java.awt.*;

/**
 * 坦克抽象父类,定义敌方与玩家坦克的共有属性和抽象方法
 * 
 * **/
public abstract class Tanks {
    //坦克初始位置坐标,x值和y值
    int local_x;
    int local_y;

    //坦克的大小,即贴图的宽高
    int tanks_width = 300;
    int tanks_hight = 300;

    //坦克的速度
    int speed = 100;

    //坦克的移动方向
    Orientation oriTanks;

    //坦克炮塔的移动方向
    Orientation oriTurret;

    //声明坦克贴图
    Image tankImage;

    //判断坦克是否存活
    boolean isAlive = true;

    //判断坦克是否为玩家坦克
    boolean isEnemy = false;

    //将变量进行封装
    public int getLocal_x() {
        return local_x;
    }

    public void setLocal_x(int local_x) {
        this.local_x = local_x;
    }

    public int getLocal_y() {
        return local_y;
    }

    public void setLocal_y(int local_y) {
        this.local_y = local_y;
    }

    public int getTanks_width() {
        return tanks_width;
    }

    public void setTanks_width(int tanks_width) {
        this.tanks_width = tanks_width;
    }

    public int getTanks_hight() {
        return tanks_hight;
    }

    public void setTanks_hight(int tanks_hight) {
        this.tanks_hight = tanks_hight;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public Orientation getOriTanks() {
        return oriTanks;
    }

    public void setOriTanks(Orientation oriTanks) {
        this.oriTanks = oriTanks;
    }

    public Orientation getOriTurret() {
        return oriTurret;
    }

    public void setOriTurret(Orientation oriTurret) {
        this.oriTurret = oriTurret;
    }

    public Image getTankImage() {
        return tankImage;
    }

    public void setTankImage(Image tankImage) {
        this.tankImage = tankImage;
    }

    public boolean isAlive() {
        return isAlive;
    }

    public void setAlive(boolean isAlive) {
        this.isAlive = isAlive;
    }

    public boolean isEnemy() {
        return isEnemy;
    }

    public void setEnemy(boolean isEnemy) {
        this.isEnemy = isEnemy;
    }

    //构造方法
    public Tanks(int local_x, int local_y, boolean isEnemy) {
        super();
        this.local_x = local_x;
        this.local_y = local_y;
        this.isEnemy = isEnemy;
    }

    //获取图片绘制坦克抽象函数
    public abstract void drawTanks();

    //移动函数
    public abstract void move();

    //获取当前位置,返回整张矩形(坦克)
    public abstract Rectangle getRect();

    //获取下一个矩形的位置,返回整个下一个矩形
    public abstract Rectangle getNextRect();
}

PlayerTanks类:

import java.awt.*;
import java.awt.event.*;

/**
 * 玩家坦克类,继承坦克父类Tanks
 * **/

public class PlayerTanks extends Tanks{
    //坦克移动方向
    Orientation oriTanks = Orientation.Stop;
    //坦克炮塔方向
    Orientation oriTurret = Orientation.U;

    public KeyContral k_contral = new KeyContral();

    //构造函数
    public PlayerTanks(int local_x, int local_y, boolean isEnemy) {
        super(local_x, local_y, isEnemy);
    }

    @Override
    //绘制坦克函数
    public void drawTanks() {
        switch(oriTurret) {
            //炮塔向上图片
            case U:
                oriTurret = Orientation.U;
                setTankImage(Toolkit.getDefaultToolkit().getImage("image/t1_shang.png"));
                break;
            //炮塔向左图片
            case L:
                oriTurret = Orientation.L;
                setTankImage(Toolkit.getDefaultToolkit().getImage("image/t1_zuo.png"));
                break;
            //炮塔向下图片
            case D:
                oriTurret = Orientation.D;
                setTankImage(Toolkit.getDefaultToolkit().getImage("image/t1_xia.png"));
                break;
                //炮塔向上图片
            case R:
                oriTurret = Orientation.R;
                setTankImage(Toolkit.getDefaultToolkit().getImage("image/t1_you.png"));
                break;
        default:
            setTankImage(Toolkit.getDefaultToolkit().getImage("image/t1_shang.png"));
            break;
        }
    }

    @Override
    //判断坦克是否越界
    public void move() {
        //用户按“W”,坦克向上走时
        if(oriTanks == Orientation.U) {
            //坐标减每一次移动,每一次都大于0(不越界)
            if(local_y - speed >= 0) 
                //向上移动,使用方法,更加安全
                setLocal_y(local_y -= speed);
        }else if(oriTanks == Orientation.L) {//用户按“A”, 坦克向左走
            if(local_x - speed >= 0) 
                setLocal_x(local_y -= speed);
        }else if(oriTanks == Orientation.D) {//用户按“S”, 坦克向下走
            if(local_y + speed <= TankFrame.window_hight) 
                setLocal_y(local_y += speed);
        }else if(oriTanks == Orientation.R) {//用户按“D”, 坦克向右走
            if(local_x + speed <= TankFrame.window_width) 
                setLocal_x(local_x += speed);
        }else {}

    }

    @Override
    public Rectangle getRect() {
        // TODO 自动生成的方法存根
        return null;
    }

    @Override
    public Rectangle getNextRect() {
        // TODO 自动生成的方法存根
        return null;
    }

    //内部类,继承KeyAdapter
    public class KeyContral extends KeyAdapter{

        //重写KeyPressed函数来实现对键盘按压事件的收集,做出坦克的移动
        public void KeyPressed(KeyEvent e) {
            super.keyPressed(e);

            //判断用户按下的按键
            if(e.getKeyCode() == KeyEvent.VK_W) {//用户按“W”,坦克向上走
                oriTanks = oriTurret = Orientation.U;
            }else if(e.getKeyCode() == KeyEvent.VK_A) {//用户按“A”, 坦克向左走
                oriTanks = oriTurret = Orientation.D;
            }else if(e.getKeyCode() == KeyEvent.VK_S) {//用户按“S”,坦克向下走
                oriTanks = oriTurret = Orientation.L;
            }else if(e.getKeyCode() == KeyEvent.VK_D) {//用户按“D”,坦克向右走
                oriTanks = oriTurret = Orientation.R;
            }else {//用户按其他按键,坦克不移动
                oriTanks = oriTurret = Orientation.Stop;
            }

        }

        //重写KeyReleased,判断用户松开KeyPressed定义的按键后,坦克停止移动
        public void KeyReleased(KeyEvent e) {
            super.keyReleased(e);

            //判断用户释放的是否是所定义好的按键
            if(e.getKeyCode() == KeyEvent.VK_W ||e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_D) {
                oriTanks = Orientation.Stop;
            }
        }
    } 
}

枚举:

public enum Orientation {
    U, D, L, R, Stop;
}

运行结果:
图片说明

  • 写回答

2条回答 默认 最新

  •  LLLL 2019-01-28 10:06
    关注

    我也碰到了这种情况,你肯定是同时打开了ps和ai,当关闭ps后,ai鼠标移动又可以使用啦 同时按住Ctrl+Alt+B就可以了,应该是忙乱中按错快捷键了。!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 vue3加ant-design-vue无法渲染出页面
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 路易威登官网 里边的参数逆向
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程
  • ¥20 模型在y分布之外的数据上预测能力不好如何解决
  • ¥15 processing提取音乐节奏
  • ¥15 gg加速器加速游戏时,提示不是x86架构
  • ¥15 python按要求编写程序