目录
1.绘制坦克
1.tank类
先建立一个tank类作为父类继承敌我坦克的一些共同属性
public class Tank {
private int direct;//0 上 3下 1 右 2 左
private int speed;
private int x;//坦克的横坐标
private int y;//坦克的纵坐标
//WASD方法
public void move_up(){
y-=speed;
}
public void move_right(){
x+=speed;
}public void move_down(){
y+=speed;
}public void move_left(){
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 int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
}
这里有初始的横纵坐标和移动速度以及方向,以及一些基础的方法。
2.Hero类
public class Hero extends Tank {
public Hero(int x, int y) {
super(x, y);
}
}
继承tank类,封装tank类
3.MyPanel类
写一个MyPanel类去实现JPanel框架和KeyListener监听器
package tankgame2;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
//绘图区
//为了监听键盘事件,实现接口KeyListener
public class MyPanel extends JPanel implements KeyListener {
//定义我的坦克
Hero hero=null;
public MyPanel(){
hero=new Hero(100,100);
hero.setSpeed(1);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0,0,1000,750);//
//画出坦克-封装方法
draw_tank(hero.getX(),hero.getY(),g,hero.getDirect(),0);
}
//编写方法,画出坦克
/**
*
* @param x 坦克左上角x的坐标
* @param y 坦克的左上角y的坐标
* @param g 画笔
* @param direct 坦克方向
* @param type 坦克类型
*/
public void draw_tank(int x,int y,Graphics g,int direct,int type){
switch (type){
case 0:
g.setColor(Color.CYAN);
break;
case 1:
g.setColor(Color.orange);
break;
}
//根据tank的方向绘制
//根据坦克的方向绘制对应形象的坦克
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+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,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;
case 3://表示向上
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;
default:
System.out.println("暂时没有处理");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
//处理wsad按下的键
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_W)
{
//改变坦克的方向
hero.setDirect(0);
hero.move_up();
} else if (e.getKeyCode()==KeyEvent.VK_D) {
hero.setDirect(1);
hero.move_right();
} else if (e.getKeyCode()==KeyEvent.VK_A) {
hero.setDirect(2);
hero.move_left();
} else if (e.getKeyCode()==KeyEvent.VK_S) {
hero.setDirect(3);
hero.move_down();
}
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
}
这里我们通过监听器监听按键事件,实现坦克方向的改变。首先我们绘制出上下左右不同方向坦克的图像如下:
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+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,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;
case 3://表示向上
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;
default:
System.out.println("暂时没有处理");
}
然后再通过监听事件,去实现改变hero里面direct的值,从而改变坦克的方向。然后绘制出改变方向后的坦克,用repaint()方法重绘画板,实现功能。
4.主函数实现功能
public class HspTankGame02 extends JFrame {
//定义MyPanel
MyPanel mp=null;
public static void main(String[] args) {
HspTankGame02 hspTankGame01=new HspTankGame02();
}
public HspTankGame02(){
mp=new MyPanel();
this.add(mp);
this.addKeyListener(mp);//增加监听事件
this.setSize(1000,750);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
设置画布的大小,以及可视化方法setVisble(true),我们这里说一下setVisble和dispose在我们使用dispose()和setVisble(false)的时候,我们会发现结果都是一样的,但是对于dispose来说,他是对资源直接破坏并且释放资源到内存里去,而setVisble只是隐藏。
2.绘制敌人坦克
1.EnemyTank
在原有基础上添加一个EnemyTank类
public class EnemyTank extends Tank{
public EnemyTank(int x, int y) {
super(x, y);
}
}
和 Hero类 类似,都是对Tank做一个继承封装
2.MyPanel类
对MyPanel改动
public class MyPanel extends JPanel implements KeyListener {
//定义我的坦克
Hero hero=null;
//定义敌人的坦克,放入到vector里面
Vector<EnemyTank> enemyTanks=new Vector<>();
int enemyTankSize=3;
public MyPanel(){
hero=new Hero(100,100);
hero.setSpeed(1);
//初始化敌人的tank
for (int e = 0; e < enemyTankSize; e++) {
EnemyTank enemyTank=new EnemyTank(100*(e+1),0);
enemyTank.setDirect(3);
enemyTanks.add(enemyTank);
}
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0,0,1000,750);//
//画出坦克-封装方法
draw_tank(hero.getX(),hero.getY(),g,hero.getDirect(),0);
//画出敌人的坦克
for (EnemyTank enemyTank : enemyTanks) {
draw_tank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
}
}
//编写方法,画出坦克
/**
*
* @param x 坦克左上角x的坐标
* @param y 坦克的左上角y的坐标
* @param g 画笔
* @param direct 坦克方向
* @param type 坦克类型
*/
public void draw_tank(int x,int y,Graphics g,int direct,int type){
switch (type){
case 0:
g.setColor(Color.CYAN);
break;
case 1:
g.setColor(Color.orange);
break;
}
//根据tank的方向绘制
//根据坦克的方向绘制对应形象的坦克
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+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,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;
case 3://表示向上
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;
default:
System.out.println("暂时没有处理");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
//处理wsad按下的键
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_W)
{
//改变坦克的方向
hero.setDirect(0);
hero.move_up();
} else if (e.getKeyCode()==KeyEvent.VK_D) {
hero.setDirect(1);
hero.move_right();
} else if (e.getKeyCode()==KeyEvent.VK_A) {
hero.setDirect(2);
hero.move_left();
} else if (e.getKeyCode()==KeyEvent.VK_S) {
hero.setDirect(3);
hero.move_down();
}
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
}
主要改动在于,我们利用Vetor集合去存敌人的坦克,利用for循环绘制敌方坦克
for (int e = 0; e < enemyTankSize; e++) {
EnemyTank enemyTank=new EnemyTank(100*(e+1),0);
enemyTank.setDirect(3);
enemyTanks.add(enemyTank);
}
结果如下: