java第十六章:坦克大战1.0

java第十六章:坦克大战1.0

java绘图坐标体系

java绘图坐标体系

像素

像素是一个密度单位,厘米是一个长度单位,二者无法比较!

java绘图原理

1.Component类提供了两个和绘图相关最重要的方法:
	(1):paint(Graphics g):绘制组件的外观
	(2):repaint():刷新组件的外观
2.当组件第一次在屏幕显示的时候,程序会自动的调用paint()方法来绘制组件
3.在以下情况paint()将会被调用:
	(1):窗口最小化,再最大化
	(2):窗口的大小发生变化
	(3):repaint方法被调用

Graphics类常用方法

  • 画直线:drawLine(int x1,int y1,int x2,int y2)
  • 画矩形边框:drawRect(int x,int y,int width,int height)
  • 画椭圆边框:drawOval(int x,int y,int width,int height)
  • 填充矩形:fillRect(int x,int y,int width,int height)
  • 填充椭圆:fillOval(int x,int y,int width,int height)
  • 画图片:drawImage(Image img,int x,int y,this(当前对象))
  • 画字符串:drawString(String str,int x,int y)
  • 设置画笔的字体:setFont(Font font)
  • 设置画笔的颜色:setColor(Color c)
package com.lcz.draw;

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

/**
 * @author lcz
 * @version 1.0
 * 需求:
 *      //## Graphics类常用方法
 */
class MyFrame extends JFrame{//2
    private JPanel jPanel;//3

    public MyFrame(){//4
        init();//4.1
        this.setBounds(100,100,500,300);//4.2
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
    public void init(){//5
        jPanel = new MyPanel();//5.1

        this.add(jPanel);//5.2
    }
}
public class MyPanel extends JPanel {
    @Override
    public void paint(Graphics g) {//Graphics相当于画笔,有各种方法
        super.paint(g);//调用父类方法初始化界面
        //- 画直线:drawLine(int x1,int y1,int x2,int y2)
        //g.drawLine(10,10,100,100);
        //- 画矩形边框:drawRect(int x,int y,int width,int height)
        //g.drawRect(10,10,100,100);
        //- 画椭圆边框:drawOval(int x,int y,int width,int height)
        //g.drawOval(10,10,100,100);
        //- 填充矩形:fillRect(int x,int y,int width,int height)
        //g.setColor(Color.blue);
        //g.fillRect(10,10,100,100);
        //- 填充椭圆:fillOval(int x,int y,int width,int height)
        //g.setColor(Color.red);
        //g.fillOval(10,10,100,100);
        //- 画图片:drawImage(Image img,int x,int y,this(当前对象))
        //Image image = Toolkit.getDefaultToolkit().getImage(JPanel.class.getResource("/method1.png"));
        //g.drawImage(image,10,10,172,200,this);
        //- 画字符串:drawString(String str,int x,int y)
        //字符串以第一个字的左下角为x,y
        //g.setColor(Color.red);
        //g.setFont(new Font("黑体",Font.BOLD,50));
        //g.drawString("北京欢迎你",50,50);
        //- 设置画笔的字体:setFont(Font font)
        //- 设置画笔的颜色:setColor(Color c)
    }
}
class Test{
    public static void main(String[] args) {
        new MyFrame();
    }
}

坦克大战1.0

初始化窗口并绘制游戏区域

Hero

package com.lcz.tankgame;

/**
 * @author lcz
 * @version 1.0
 * 需求:
 *      Hero类
 */
public class Hero extends Tank{
    public Hero(int x, int y) {
        super(x, y);
    }
}

MyPanel

package com.lcz.tankgame;

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

/**
 * @author lcz
 * @version 1.0
 * 需求:
 *      坦克大战的绘图区域
 */
public class MyPanel extends JPanel {
    //定义我的坦克
    Hero hero = null;

    public MyPanel() {
        hero = new Hero(100,100);//初始化自己坦克
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.BLUE);
        g.fillRect(0,0,500,750);//填充矩形,默认黑色
    }
}

Tank

package com.lcz.tankgame;

/**
 * @author lcz
 * @version 1.0
 * 需求:
 *      基类Tank
 */
public class Tank {
    private int x;
    private int y;

    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;
    }
}

TankGame01

package com.lcz.tankgame;

import com.lcz.draw.MyPanel;

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

/**
 * @author lcz
 * @version 1.0
 */
public class TankGame01 extends JFrame {//2
    private JPanel jPanel;//3

    public TankGame01(){//4
        init();//4.1
        this.setBounds(0,0,1000,750);//4.2
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
    public void init(){//5
        jPanel = new MyPanel();//5.1

        this.add(jPanel);//5.2
    }
}
class Test{
    public static void main(String[] args) {
        TankGame01 tankGame01 = new TankGame01();
    }
}

绘制坦克

在这里插入图片描述
在MyPanel类中编写drawTank方法,并在MyPanel类的paint方法中调用即可

思路:将绘制坦克封装为方法。

传入参数:int x,int y,Graphics g,int direct,int type

根据switch(direct){

}根据方向不同:画出不同坦克

根据switch(type){

}根据类型不同:决定画笔颜色

public void paint(Graphics g) {
        super.paint(g);;
        //g.setColor(Color.BLUE);
        g.fillRect(0,0,1000,750);//填充矩形,默认黑色
        drawTank(hero.getX(),hero.getY(),g,0,0);
    }
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){
        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;
        default:
            System.out.println("暂时没有处理");
    }
}

小球移动案例:

事件处理机制:
事件源和事件:

事件和事件源

事件监听器:

事件监听器接口

示意图:

在这里插入图片描述

MyPanel2

package com.lcz.schoolwork.GUI.ballmove;

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

/**
 * @author lcz
 * @version 1.0
 */
public class MyPanel2 extends JPanel implements KeyListener {//键盘监听器
    //小球坐标初始化
    int x = 10;
    int y = 10;
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillOval(x,y,50,50);
    }

    @Override
    public void keyTyped(KeyEvent e) {//响应:键盘输出字符

    }

    @Override
    public void keyPressed(KeyEvent e) {//响应:键盘按下
        //KeyEvent.VK_DOWN (int):为一个键的十六进制的编码值
        if(e.getKeyCode() == KeyEvent.VK_DOWN)
            y++;
        else if(e.getKeyCode() == KeyEvent.VK_UP)
            y--;
        else if(e.getKeyCode() == KeyEvent.VK_LEFT)
            x--;
        else if(e.getKeyCode() == KeyEvent.VK_RIGHT)
            x++;
        //重绘
        repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {//响应:键盘释放

    }
}

Test

package com.lcz.schoolwork.GUI.ballmove;

/**
 * @author lcz
 * @version 1.0
 */
public class Test {
    public static void main(String[] args) {
        new BallMove();
    }
}

BallMove

package com.lcz.schoolwork.GUI.ballmove;

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

/**
 * @author lcz
 * @version 1.0
 */
public class BallMove extends JFrame {
    JPanel jPanel;

    public BallMove() throws HeadlessException {
        init();

        this.setBounds(100,100,500,300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
    public void init(){
        jPanel = new MyPanel2();

        this.add(jPanel);
        this.addKeyListener((KeyListener) jPanel);
    }
}

绘制不同方向的坦克

思路:想要绘制不同方向的坦克,把坦克方向作为变量:做为Tank类的私有属性并提供getter和setter方法

向上和向右坦克分析

向下和向左坦克分析

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,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("暂时没有处理");
        }

让坦克动起来

思路:

​ 1.MyPanel类实现KeyListenner接口,重写相关方法响应键盘事件

​ 2.w a s d对应不同逻辑:分为改变坦克方向、坦克进行移动(封装到Tank类的相关方法)

​ 3.改变坦克方向:用坦克方向的setter方法即可

​ 4.坦克移动的速度可以作为Tank类的私有属性并提供getter、setter方法,以后创建坦克时可以设置速度

核心代码

MyPanel类

@Override
public void keyTyped(KeyEvent e) {

    }

@Override
public void keyPressed(KeyEvent e) {
    if(e.getKeyCode() == KeyEvent.VK_W){
        //1.更改坦克方向
        hero.setDirect(0);
        //2.坦克移动:封装为方法
        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();
    }
    this.repaint();
}

@Override
public void keyReleased(KeyEvent e) {

}

Tank类

private int speed = 1;//速度默认为 1

    public int getSpeed() {
        return speed;
    }

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

    private int direct;//坦克方向:0 上 1 右 2 下 3 左
    //坦克移动方法 上 右 下 左
    public void moveUp(){//上
        y -= speed;
    }
    public void moveRight(){//右
        x += speed;
    }
    public void moveDown(){//下
        y += speed;
    }
    public void moveLeft(){//左
        x -= speed;
    }


    public int getDirect() {
        return direct;
    }

    public void setDirect(int direct) {
        this.direct = direct;
    }

本章作业:

在这里插入图片描述

分析:

  1. 因为敌人的坦克,是在MyPanel,所以我们的代码在MyPanel
  2. 因为敌人的坦克,后面有自己特殊的属性和方法,可以单开一个EnemyTank
  3. 敌人坦克数量多,可以放入到集合Vector,因为考虑多线程问题

EnemyTank

package com.lcz.tankgame.tankgame02;

/**
 * @author lcz
 * @version 1.0
 *      EnemyTank类
 */
public class EnemyTank extends Tank{
    public EnemyTank(int x, int y) {
        super(x, y);
    }
}

MyPanel

Vector<EnemyTank> enemyTanks = new Vector<>();
    int enemyTankSize = 3;
    public MyPanel() {//初始化坦克相关属性
        hero = new Hero(100,100);//初始化坐标位置
        //hero.setSpeed(3);
        //添加敌人坦克
        for (int i = 0; i < enemyTankSize; i++) {
            EnemyTank enemyTank = new EnemyTank(100 * (i + 1),0);
            enemyTank.setDirect(2);
            enemyTanks.add(enemyTank);
        }
    }
    //绘画默认调用方法
    @Override
    public void paint(Graphics g) {
        super.paint(g);;
        //g.setColor(Color.BLUE);
        g.fillRect(0,0,1000,750);//填充矩形,默认黑色
        drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),1);
        for (int i = 0; i < enemyTankSize; i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            drawTank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirect(),0);
        }
    }

k = new EnemyTank(100 * (i + 1),0);
enemyTank.setDirect(2);
enemyTanks.add(enemyTank);
}
}
//绘画默认调用方法
@Override
public void paint(Graphics g) {
super.paint(g);;
//g.setColor(Color.BLUE);
g.fillRect(0,0,1000,750);//填充矩形,默认黑色
drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),1);
for (int i = 0; i < enemyTankSize; i++) {
EnemyTank enemyTank = enemyTanks.get(i);
drawTank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirect(),0);
}
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值