任务12 绘制地图

任务描述

任务12主要利用二维数组实现坦克游戏的地图设计,并通过绘制方法绘制出地图,地图效果如图12-1所示。


图12-1 坦克游戏地图
图12-1 坦克游戏地图


支撑知识

12.1 二维数组

相对于一维数组只有一个下标维度,二维数组具有两个下标维度,分表表示数组的行和列,图12-2描述了一维数组和二维数组的维度。


图12-2 数组维度
图12-2 数组维度


12.2 维度观点

从维度的观点可以看出,一维数组仅仅通过列下标获取数组元素:array[col],而二维数组多了一个行维度,因此,获取数组元素需要行下标和列下标:array[row][col]。
二维数组的创建与一维数组的创建类似:


//创建二维数组,大小为3行6列
int[][] array = new int[3][6];

其中第一个数字表示行数,第二个数字表示列数。上面的语句表示创建了一个3行6列的二维数组,数组元素的默认值为0,如图12-3所示。


图12-3 二维数组结构
图12-3 二维数组结构


通过行和列的下标,我们可以对指定的二维数组元素进行访问或赋值:


//对指定元素进行赋值与访问
System.out.println(array[1][2]);//赋值前
array[1][2] = 10;       
System.out.println(array[1][2]);//赋值后

赋值后,数组第1行第2列的元素值为10,如图12-4所示。


图12-3 赋值后的数组
图12-4 赋值后的数组


在一维数组中,遍历数组中的元素是一个重复的过程,改变的仅仅是数组的列下标,因此,通过一个for循环以及循环变量i可以达到遍历数组的效果。
二维数组多了一个行维度,因此需要两个for循环,第一个for循环负责行数,第二个for循环负责列数。


int[][] array = new int[3][6];
//循环行数
for (int row = 0; row < 3; row++) {
    //循环列数
    for (int col = 0; col < 6; col++) {
        System.out.print(array[row][col] + " ");
    }
    //打印完一行换行
    System.out.println();
}

12.3 对象观点

从对象的观点来看,二维数组本质是一个一维数组中存放的元素是一维数组:


//定义一维数组,存放元素为整数
int[] array01 = new int[2];
//以对象德观点理解二维数组
//首先创建一个大小为3的一维数组,存放元素是大小为2的一维数组
int[][] array02 = new int[3][2];

一维数组与二维数组的比较以及元素存储如图12-5所示。


图12-5 一维数组与二维数组比较
图12-5 一维数组与二维数组比较


用对象的观点遍历二维数组:


int[] array01 = new int[2];
System.out.println("打印一维数组:" + array01);

int[][] array = new int[3][2];
System.out.println("遍历二维数组");
for (int i = 0; i < array.length; i++) {
    //打印一维数组中存放的元素:一维数组
    System.out.println("第" + i + "个元素:" + array[i]);
}

此时,在控制台将会打印出如下信息:


打印一维数组:[I@21e8bf76
遍历二维数组
第0个元素:[I@3771ed5e1个元素:[I@1896d2c22个元素:[I@55e6cb2a

array[i]打印出来不是一个数值,而是一堆符号,这些符号表示array[i]中存放的是一个对象(一维数组)。要想遍历这些数组中的元素,必须再次使用循环遍历:


int[][] array = new int[3][2];
//遍历一维数组array
for (int i = 0; i < array.length; i++) {
    //遍历一维数组array中的数组元素(一维数组)
    for (int j = 0; j < array[i].length; j++) {
        System.out.print(array[i][j] + " ");
    }
    System.out.println();
}

任务实施

新建Java项目【Project12】,在【Project12/img】文件夹中放入墙壁图片。

任务12.1 新建Tank类

坦克类具有位置、图片、速度属性,四个方向的移动方法,如代码 清单12-1所示。
代码清单12-1:【Project/src/Tank.java】


public class Tank {
    int x;
    int y;
    int speed = 20;
    String url = "img/p1tankU.gif"; 
    //构造方法,初始化坦克位置
    public Tank(int x, int y) {
        this.x = x;
        this.y = y;
    }
    //四个方向移动方法
    public void moveUp() {
        url = "img/p1tankU.gif";
        this.y = this.y - speed;
    }   
    public void moveDown() {
        url = "img/p1tankD.gif";
        this.y = this.y + speed;
    }
    public void moveLeft() {
        url = "img/p1tankL.gif";
        this.x = this.x - speed;
    }
    public void moveRight() {
        url = "img/p1tankR.gif";
        this.x = this.x + speed;
    }
}

任务12.2 新建Map类

地图类仅仅描述地图的结构,在地图类中使用二维数组walls表示地图的结构,数组中德元素值为1表示墙壁,为0表示空地,地图类如代码清单12-2所示。
代码清单12-2:【Project/src/Map.java】


public class Map {
    //创建地图
    int[][] walls = {
            {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 1, 1, 0, 0, 0, 1, 1, 0, 1},
            {1, 0, 1, 1, 0, 0, 1, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 1, 0, 0, 1},
            {1, 0, 0, 1, 1, 1, 1, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
    };
    //判断位置是否墙壁,是墙壁返回true,否则返回false
    public boolean isWall(int row, int col) {
        if(walls[row][col] == 1){
            return true;
        }else{
            return false;
        }
    }
}

任务12.3 新建GamePanel类

面板类主要负责绘制地图,如果二维数组中的元素为1,则绘制,如代码清单12-3所示。
代码清单12-3:【Project/src/GamePanel.java】


mport java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class GamePanel extends JPanel{
    //创建地图
    Map map = new Map();
    //绘制地图大小
    int size = 20;  
    @Override
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
        super.paint(g);
        this.setBackground(Color.BLACK);
        //获取墙壁图片资源
        ImageIcon icon = new ImageIcon("img/wall.gif");
        //将图片资源转换为g能够处理的信息
        Image image = icon.getImage();
        //循环遍历地图对象中的walls数组
        for (int row = 0; row < map.walls.length; row++) {
            for (int col = 0; col < map.walls[row].length; col++) {
                if(map.isWall(row, col)){
                    //绘制墙壁,数组列col对应x轴,行row对应y轴
                    g.drawImage(image, col * size, row * size,  size, size, this);
                }
            }
        }
    }
}

任务12.4 新建Test类

测试类负责创建框架和GamePanel面板,并将面板加入框架中进行显示,如代码清单12-4所示。
代码清单12-4:【Project/src/Test.java】


import javax.swing.JFrame;

public class Test { 
    public static void main(String[] args) {
        JFrame frame = new JFrame("TankGame");      
        GamePanel gamePanel = new GamePanel();
        frame.add(gamePanel);
        frame.setSize(220, 240);        
        frame.setVisible(true);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值