羊了个羊-JAVA小游戏1

羊了个羊-1

      • 一.游戏入口
      • 二. 游戏中的数据模型
      • 三. 数据模型1 - Brand
      • 四. 数据模型2-Cell类 和 Layer类

一.游戏入口

1. 羊了个羊游戏需求

自定义组件:

  1. Brand(牌): 游戏中的牌: 玉米, 刷子, 毛线…
  2. Layer(图层): 图层是一个有X轴和Y轴的二维矩阵关系 - 重难点之一(涉及很多二维数组和一维数组的转换和遍历)
    3.Map(地图功能): 也是一个重难点(涉及到一个多图层的层级问题: 游戏中牌的遮盖问题, 被遮住的牌是灰色的 不能点的; 当上面的牌被消除掉, 下面的灰色牌变亮,可以的点击)
    4.Cell
  3. ElimiateBox(消除区域): 相同图片要按照顺序排到一起, 当满足3个之后, 三个都要消除掉
  4. Music(音乐)

2. 类的创建和窗口初始化

创建 cn.tedu.
model : 基本类
test: 测试类
util : 工具类
view: Start.class - 入口类, 程序的启动类

3. 创建窗口 - Start.class

// JFrame 是JDK提供的类,继承JFrame之后就可以绘制窗口, 使用窗口的的一些API
public class Start extends JFrame {
    private Brand brand = new Brand("刷子");

    // 无参构造器: fn + Alt + insert
    public Start() throws HeadlessException {
        // 设置窗口标题
        this.setTitle("Java版-羊了个羊");
        // 设置窗口大小
        this.setSize(480,800);
        // 默认关闭窗口不关闭进程 - 关闭窗口同时关闭进程
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置窗口居中
        this.setLocationRelativeTo(null);
        // 设置窗口显示
        this.setVisible(true);
    }
    public static void main(String[] args) {
        new Start();
    }
}

二. 游戏中的数据模型

1.Map类

游戏中最顶层的数据模型是Map, 我们叫做地图类; 包含了所有的元素, 比如:背景, 多个图层, 消除框, 道具等一些内容

2.layer

一个Map当中有多个图层Layer, 层层遮盖, 被盖住的牌就是灰色的不能点击; 这是游戏的关键点; 图层是二维表格, 每个 单元格是一个Cell类的对象

3.cell

Cell类 单元格, 一个图层当中不是所有单元格都有图案, 有的单元格是空的; 所以单元格Cell类有两种状态, 有牌和无牌状态

4.Brand

每个单元格都包含牌, Brand类, 被盖住的牌是灰色的, 不能点击的; 所以牌Brand也有两种状态, 就是灰色 和 不是灰色

总结

  • 自顶向下 Map, Layer, Cell, Brand组成了整个养了个羊游戏的数据结构
  • 理解一下游戏的整体数据模型: 一个地图(Map)有多个图层(Layer),一个图层(Layer)有多个单元格(Cell),一个单元格(Cell)包含0 或者1个牌(Brand), 一个牌(Brand)包含2张图片(1张正常, 一张灰色)
  • 现实中可能会有关卡的类 我们模拟过程中不实现 感兴趣的同学可以在学完之后 在我们上课的基础上进行优化

三. 数据模型1 - Brand

Brand类: Brand 代表游戏中的一张牌

name属性 : String 类型, 存储当前牌的名称

  • name属性有两个作用: 第一, 在消除框有一个基本的消除规则是 三个相同的牌就消除掉, 牌是否相同的判断依据是 name 属性; 第二, 通过name属性找到图片文件, 我们在根目录下创建 imgs 文件夹来存放游戏的素材文件

是否置灰:
正常图片
灰色图片
牌的位置: x轴 和 y轴坐标
牌的大小: width 和 height
最后生成对应的get 和 set 方法 以及构造方法: 快捷键 fn+alt+insert

// 绘制牌是需要继承 Component 
// 在JFrame中 具有了添加组件的方法  -- Start.class
// 添加组件的方法
// 可以添加 自己定义的组件 到当前的窗口当中
// Start.class -- this.getContentPane().add(Component);
public class Brand extends Component{
        private String name; //牌的名称
        private Boolean isGray; //是否置灰
        private Image image;   // 正常的图片
        private Image grayImage; // 灰色的图片
        private Image bg;   //背景图片

        private Integer x;  // x和 y 代表 当前牌 在渲染的时候 左上角的坐标
        private Integer y;

        private Integer width;
        private Integer height;

        // name是非常关键的属性
        // name的值对应imgs下的图片名称前缀
        public Brand(String name) {
            this.name = name;
            // Toolkit是 awt 所有实际实现的抽象超类。 Toolkit类的子类用于将各种组件绑定到特定的本机工具包实现。
            // getDefaultToolkit():获取默认工具包。
            // getImage()返回从指定文件获取像素数据的图像,其格式可以是GIF,JPEG或PNG。
            this.image = Toolkit.getDefaultToolkit().getImage("imgs\\"+name+".png");
            this.grayImage = Toolkit.getDefaultToolkit().getImage("imgs\\"+name+"_灰.png");
            //背景图片
            this.bg = Toolkit.getDefaultToolkit().getImage("imgs\\"+name+".jpg");

            this.isGray = false;
            // 图片的宽高
            this.width=59;
            this.height=66;

            // 坐标动态生成 - 目前先固定
            this.x=0;
            this.y=0;
	}
}
    // 重写绘制自身的函数 - paint()自动生成
    @Override
    public void paint(Graphics g) {
        if(this.isGray==true){
            // 绘制灰色图片
            g.drawImage(this.grayImage, this.x, this.y, null);
        }else{
            // 绘制正常图片
            g.drawImage(this.image, this.x, this.y, null);
        }
    }

Start类中- 添加一张牌到窗口中

public class Start extends JFrame {
// 创建Brand对象
    private Brand brand = new Brand("刷子");
    // 无参构造器
    public Start() throws HeadlessException {
        // 设置窗口居中
        this.setLocationRelativeTo(null);
        // 将牌改变为灰色
        //brand.setGray(true);
        // 绘制游戏中的牌
        this.getContentPane().add(brand);
        // 设置窗口显示
        this.setVisible(true);
    }
   }
}

修改Bug - 图片显示不出来的问题 - Start.class

this.setVisible(true); 位置会影响牌的显示
需要拖动一下才能看到 - 拖动窗口实际上触发了窗口的重新绘制
如果图片无法显示, 其实是我们已经将牌添加到窗口数据结构当中, 但是窗口没有重新绘制, 所以没有显示出来
**解决:**重新定义线程, 定义 autoRefresh方法

 // 定义线程 自动刷新
 // 在构造方法中 调用
    private  void autoRefresh(){
    	// 将this转为局部变量,指当前窗口
        Start start = this;
        //快捷键 new Thread(new Runnable(){ }) .start()
        new Thread(new Runnable(){

            @Override
            // 重写run方法
            public void run() {
            // 写一个死循环, 不停的调用repaint方法 - 重新绘制
                while(true){
                // 当前窗口的repaint(),为了准确,将this赋值给start
                    start.repaint();
                    try {
                    // 每个 40ms 让线程刷新一下
                        Thread.sleep(40);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
 
 // 然后再Start() 中调用  -- this.autoRefresh();

Brand 类实现鼠标点击事件

在实际游戏中, 鼠标点击牌, 牌就从图层当中移动到 下放的消除框当中
先实现点击事件, 让牌消失的过程

public Brand(Brand name){
	 // 定义事件 -- 鼠标点击事件 
            this.addMouseListener(new MouseAdapter() {
                @Override
                // MouseEvent对象, 当前点击的对象,可以获取我们想要的数据
                public void mouseClicked(MouseEvent e) {
                	// 先进行 : 测试
                    System.out.println("Brand.mouseClicked");
                    // 默认返回 Object 需要强转为 Brand
                    Brand brand =(Brand) e.getSource();// 获取当前的组件
                    brand.getParent().remove(brand);  // 通过父容器删除自己 - 一般树形结构使用
                }
            });
}

四. 数据模型2-Cell类 和 Layer类

回顾

  • 一个Map当中有多个图层Layer, 层层遮盖, 被盖住的牌就是灰色的不能点击; 这是游戏的关键点; 图层是二维表格, 每个 单元格是一个Cell类的对象
  • 一个图层当中不是所有单元格都有图案, 有的单元格是空的; 所以单元格Cell类有两种状态, 有牌和无牌状态

1. 单元格类-Cell

/**
 * 单元格类
 * 有两种状态 0 无牌  1 有牌
 */
public class Cell {
    private Integer state = 0;  //单元格的状态 - 有牌或者无牌
    private Brand brand;  // 定义一个牌对象, 有牌的情况下必须设置一个值
	// 提供对应的get 和 set 方法
}

2.图层类-Layer

/**
 * 图层类
 * 二维表格- 使用二维数组进行存储
 */
public class Layer {
    // private Cell[][] cells = new Cell[4][5];
    // 默认状态下, 并不知道图层有多少行, 多少列, 应该是随机的状态
    private Cell[][] cells = null;
    // 提供get和 set 方法
}

3. 图层类的重要属性

rowNum, colNum: 分别代表二维数组的 有多少行 多少列
capcity; 当前图层能最多容纳的牌数量, 最大容量 假设 6 6
size; 图层目前有多少牌 – 当牌添加的时候需要改变值; 当牌减少的时候也需要改变值

  • 区别: 假一辆公交车可以做10个人, 目前只坐了2个人, 那么:size=2; capcity=10;

对应的get 和 set方法

public class Layer {
    // 定义行 和 列的变量
    private Integer rowNum;  // 有多少行
    private Integer colNum;  // 有多少列

    private Integer capcity; // 当前图层能最多容纳的牌数量, 最大容量  6  6
    //当牌添加的时候需要改变值; 当牌减少的时候也需要改变值
    private Integer size; // 图层目前有多少牌  
    //构造方法 -设置初始值,参数: 行号 , 列号
    public Layer(Integer rowNum, Integer colNum) throws Exception {
        this.rowNum = rowNum;
        this.colNum = colNum;

        this.capcity = this.rowNum * this.colNum;
        
        this.cells = new Cell[this.rowNum][this.colNum];
		// size无法确定值, 先设置为 0 
        this.size=0;
    }

4 图层的数据构建 - 测试类 TestBuildLayer

// 在测试类,创建图层
public class TestBuildLayer {
    public static void main(String[] args) throws Exception {
        Layer layer = new Layer(6, 6);
    }
}

Layer类 内部有一个二维数组来存放我们的牌,但是 刚刚我们创建的二维数组是空白的, 没有任何的牌
我们需要把牌方法二维数组中, 步骤如下:

  • 第一步: 创建一个数组, 存放所有牌的名称, 每次随机从中抽取一个牌的名字, 因为每次进入地图, 牌都是随机生成的, 不是整整齐齐摆好的, 那样游戏就没有乐趣了
// 因为经常用到, 所以提前保存一下变量
	public static Random random = new Random();
	// 2. 创建数组, 随机取牌
	public static String[] brandName={
            "刷子","剪刀","叉子","奶瓶",
            "干草","手套","树桩","棉花",
            "毛线","水桶","火","玉米",
            "白菜","草","萝卜","铃铛"
    };
    // 3. 定义方法 getBrandName() 每次调用都随机和获取一个牌的名称
    public static String getBrandName(){
    	// 获取随机数 : 获取随机的一个下标, 最大值是数组的长度
        int randomIndex = random.nextInt(brandName.length);
        return brandName[randomIndex];
    }
    // 在main方法中测试
    // 快捷键: getBrandName().sout
    // System.out.println(getBrandName());
  • 第二步: 创建Brand数组, 容量小于等于图层容量的大小; 注意: 这两有一个游戏逻辑问题: 3张牌消除,如果容量不是 3的倍数, 游戏根本无法全部消除
main(){
	// 创建Brands数组: 容量 与 图层容量相同
	// layer.getCapcity() 当前图层能最多容纳的牌数量
	Brand[] brands = new Brand[layer.getCapcity()];
	for (int i = 0; i < brands.length; i++) {
            System.out.println(brands[i]);  //null
            // 每次循环获取一个随机的牌名称
            String randomBrandName = getBrandName();
            // 需要通过牌的初始化构造器创建牌的对象
            Brand brand = new Brand(randomBrandName);
            // 将获取到的牌放到 brands数组中
            brands[i] = brand;
            System.out.println(brands[i]);
             // 按照现在的代码执行, 不能保证牌出现3张消除 - 优化
             // 基本规则: 三张相同名称的牌 清除
             // 创建牌的时候直接先 生成三种相同的牌
    }
	
	// 测试当前的brands数组
	System.out.println("-----------  测试打印结果-----------");
    for (int i=0;i<brands.length;i++){
            System.out.println(brands[i].getName()+"-");
    }
	
	// 创建牌的时候直接先 生成3张相同的牌
	// i = i+3 i变量3步走
	for (int i = 0; i < brands.length; i=i+3) {
            String randomBrandName = getBrandName(); // 每次循环获取一个随机的牌名称
            Brand brand1 = new Brand(randomBrandName);
            Brand brand2 = new Brand(randomBrandName);
            Brand brand3 = new Brand(randomBrandName);

            brands[i] = brand1;
            brands[i+1] = brand2;
            brands[i+2] = brand3;
    }
	// 带来问题: 如果数组的容量不是3的倍数, 会报错 --- 解决
}

解决: 1.容量必须是3的倍数, 也就是在初始化对象的时候, 就判断一下, 如果不能被3整除, 那么就不能创建图层对象, 抛出自定义的异常对象 - Layer.java构造方法中

	// 控制容量为3的倍数
	public Layer(){
		 if(this.capcity%3!=0){
            throw new Exception("容量不是3的倍数");
        }
        this.cells = new Cell[this.rowNum][this.colNum];
	}
       
  • 第三步: 循环获取牌的名称, 每次产生3个相同的名字的 牌对象, 然后放入 Brand数组中, 注意: 循环的计数器也需要加3, 而不是++
  • 第四步: 把牌的数组 打乱顺序 乱序
for (int i=0;i<brands.length;i++){
            //先获取 当前位置 A 的变量
            // A的索引brandA
            Brand brandA = brands[i];

            // 交换位置的 B 的随机索引位置
            // 先获取一个随机的整数
            int randomIndex = random.nextInt(brands.length);
            // 随机交互索引B的位置 brandB
            Brand brandB = brands[randomIndex];
			// brandA 与 brandB进行位置交换, 先保存一下brandA的位置
			// 防止将B位置赋值给A时,将A的位置丢失掉
            Brand temp = brandA;
	
            brands[i]=brandB;
            brands[randomIndex]=temp;
        }
		System.out.println("--------打乱顺序后打印结果--------------");
        for (int i=0;i<brands.length;i++){
            System.out.println(brands[i].getName()+"-");
        }
  • 第五步: 把 牌 填充到图层当中, 并打印目前的图层
    把一张一张牌, 填充到每一个单元格中, Cell是二维数组
	// 将数组填充到单元格中
        // 通过图层, 获取到每一个单元格  -- 返回二维数组
        Cell[][] cells = layer.getCells();
        // 遍历二维数组
        int flag = 0;
        // 先遍历行号
        for(int row=0;row<cells.length;row++){
            // 在遍历列号
            for (int col=0;col<cells[row].length;col++){
                System.out.println(row +"-"+col);
                // 初始化一个单元格对象 - 两个值 state brand
                Cell cell = new Cell();
                cell.setState(1);
                // 通过setBrand方法把牌放进来, 牌在brands一维数组里
                // 可以在外部定义一个flag变量, 让其++
                cell.setBrand(brands[flag++]);

                // 形成cell对象后, 放大二维数组cell中 -- 非常重要
                cells[row][col] = cell; //把之前空的 图层,设置了值
            }
        }
        System.out.println("--------输出layer图层的值--------------");
        for(int row=0;row<cells.length;row++){
            for (int col=0;col<cells[row].length;col++){

                Brand brands1 = cells[row][col].getBrand();
                System.out.print(brands1.getName()+"-");
            }
            System.out.println();
        }

整体代码

/*
	测试图层数据构建完整代码
*/
public class TestBuildLayer {
	// 因为经常用到, 所以提前保存一下变量
	public static Random random = new Random();
	// 2. 创建数组, 随机取牌
	public static String[] brandName={
            "刷子","剪刀","叉子","奶瓶",
            "干草","手套","树桩","棉花",
            "毛线","水桶","火","玉米",
            "白菜","草","萝卜","铃铛"
    };
    // 3. 定义方法 getBrandName() 每次调用都随机和获取一个牌的名称
    public static String getBrandName(){
    	// 获取随机的一个下标, 最大值是数组的长度
        int randomIndex = random.nextInt(brandName.length);
        return brandName[randomIndex];
    }
	public static void main(String[] args) throws Exception {
		// 1. 先创建容量为 6*6 的图层
		Layer layer  = new Layer(6, 6);
		// 创建Brands数组: 容量 与 图层容量相同
		Brand[] brands = new Brand[layer.getCapcity()];
		// 循环-快捷键: brands.fori
		//for (int i = 0;i
		 	// 每次循环获取一个随机的牌名称
            //String randomBrandName = getBrandName();
            // 需要通过牌的初始化构造器创建牌的对象
            //Brand brand = new Brand(randomBrandName);
			//将获取到的牌放到 brands数组中
            //brands[i] = brand;
			// 按照现在的代码执行, 不能保证牌出现3张消除 - 优化
			// 基本规则: 三张相同名称的牌 清除
        	// 创建牌的时候直接先生成三种相同的牌

        	// i+3 带来新的问题,如果数组容量不是3的倍数, 会报错,数组越界
        	// 为了游戏规则, 让 容量为3的倍数
        	// 判断 layer类下的capcity为3的倍数
					//this.capcity = this.rowNum * this.colNum;
        			// 控制容量为3的倍数
        			//if(this.capcity%3!=0){
            			//throw new Exception("容量不是3的倍数");
        			//}
        	
			for (int i = 0;i<brands.length;i+=3){
            String randomBrandName = getBrandName(); // 每次循环获取一个随机的牌名称
            Brand brand1 = new Brand(randomBrandName);
            Brand brand2 = new Brand(randomBrandName);
            Brand brand3 = new Brand(randomBrandName);

            brands[i] = brand1;
            brands[i+1] = brand2;
            brands[i+2] = brand3;
        }
       
        System.out.println("-----------  测试打印结果-----------");
        for (int i=0;i<brands.length;i++){
            System.out.println(brands[i].getName()+"-");
        }
		//问题: 生成数组的都是顺序整齐的, 要随机打乱
		System.out.println("----------随机打乱的代码------------");
        for (int i=0;i<brands.length;i++){
            //先获取 当前位置 A 的变量
            // A的索引brandA
            Brand brandA = brands[i];

            // 交换位置的 B 的随机索引位置
            // 先获取一个随机的整数
            int randomIndex = random.nextInt(brands.length);
            // 随机交互索引B的位置 brandB
            Brand brandB = brands[randomIndex];
			// brandA 与 brandB进行位置交换, 先保存一下brandA的位置
			// 防止将B位置赋值给A时,将A的位置丢失掉
            Brand temp = brandA;
	
            brands[i]=brandB;
            brands[randomIndex]=temp;
        }
		System.out.println("--------打乱顺序后打印结果--------------");
        for (int i=0;i<brands.length;i++){
            System.out.println(brands[i].getName()+"-");
        }

		// 把牌填充到图层当中, 并打印目前的图层
        // layer.getCells 会返回二维数组
        Cell[][] cells = layer.getCells();
        // cells是二维数组
        // brands是为数组
        //将牌一个一个填充到二维数组中 - 二维数组的遍历
        /**
           * * * * *
           * * * * *
           * * * * *
         */
        int flag = 0;
        // 先遍历行号
        for(int row=0;row<cells.length;row++){
            // 在遍历列号
            for (int col=0;col<cells[row].length;col++){
                System.out.println(row +"-"+col);
                // 初始化一个单元格对象 - 两个值 state brand
                Cell cell = new Cell();
                cell.setState(1);
                // 通过setBrand方法把牌放进来, 牌在brands一维数组里
                // 可以在外部定义一个flag变量, 让其++
                cell.setBrand(brands[flag++]);

                // 形成cell对象后, 放大二维数组cell中 -- 非常重要
                cells[row][col] = cell; //把之前空的 图层,设置了值
            }
        }
        System.out.println("--------输出layer图层的值--------------");

        for(int row=0;row<cells.length;row++){
            for (int col=0;col<cells[row].length;col++){

                Brand brands1 = cells[row][col].getBrand();
                System.out.print(brands1.getName()+"-");
            }
            System.out.println();
        }
        }
	}
}

5.代码重构

在测试类中实现了图层数据的构建,代码都堆在一起, 后期很难阅读和维护
要进行代码的重构, 步骤如下:

  • 第一: 创建BrandUtil工具类,用来封装创建随机牌的功能代码
  • 第二: 创建LayerUtil工具类, 用来封装创建图层数据的功能代码
  • 第三: 对外提供统一的访问入口

BrandUtil.class

/**
 * 工具类
 * 提供 创建牌相关的一些 公共方法
 */
public class BrandUtil {
    public static Random random = new Random();
    public static String[] brandName={
            "刷子","剪刀","叉子","奶瓶",
            "干草","手套","树桩","棉花",
            "毛线","水桶","火","玉米",
            "白菜","草","萝卜","铃铛"
    };
    //getBrandName() 每次调用都随机和获取一个牌的名称
    public static String getBrandName(){
        int randomIndex = random.nextInt(brandName.length);
        return brandName[randomIndex];
    }
    // 定义对外的统一的访问入口
    // 创建随机牌的数组 - 传参
    public static Brand[] buildBrand(Integer capacity){
        Brand[] brands = new Brand[capacity];
        for (int i = 0;i<brands.length;i+=3){
            String randomBrandName = getBrandName(); // 每次循环获取一个随机的牌名称
            Brand brand1 = new Brand(randomBrandName);
            Brand brand2 = new Brand(randomBrandName);
            Brand brand3 = new Brand(randomBrandName);

            brands[i] = brand1;
            brands[i+1] = brand2;
            brands[i+2] = brand3;

        }
        for (int i=0;i<brands.length;i++){

            //当前位置 A的变量拿到
            Brand brandA = brands[i];

            // 交换位置的 B索引
            int randomIndex = random.nextInt(brands.length);
            Brand brandB = brands[randomIndex];

            Brand temp = brandA;

            brands[i]=brandB;
            brands[randomIndex]=temp;
        }
        return brands;
    }
}

LayerUtil.class

/**
 * 创建图层 构建图层的方法
 */
public class LayerUtil {
    public static Layer build(Integer rowNum, Integer colNum){
        Layer layer  = null;  // 容量为36的二维数组图层
        try {
            layer = new Layer(rowNum, colNum);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //System.out.println(getBrandName());
        // 目前的代码 可以生成,但是不保证是至少3个
        Brand[] brands = BrandUtil.buildBrand(layer.getCapcity());

        Cell[][] cells = layer.getCells();
        int flag = 0;
        for(int row=0;row<cells.length;row++){
            for (int col=0;col<cells[row].length;col++){
                System.out.println(row +"-"+col);
                Brand brands1 = brands[flag++];
                Cell cell = new Cell();
                cell.setState(1);
                // 将牌 给到单元格对象
                cell.setBrand(brands1);
                // 让牌 反向找到单元格对象
                brands1.setCell(cell);
                cells[row][col] = cell; //把2之前空的 图层,设置了值
            }
        }
        //System.out.println("-----调用showCells方法查看当前图层的数据------");
//        layer.showCells();
        return layer;
    }
}

Layer.java - 显示图层

//定义 showCells方法, 展示目前图层的数据
public void showCells(){
        for(int row=0;row<cells.length;row++){
            for (int col=0;col<cells[row].length;col++){

                Brand brands1 = cells[row][col].getBrand();
                System.out.print(brands1.getName()+"-");
            }
            System.out.println();
        }
    }

6. 测试渲染图层的功能-TestRenderLayer.java

/**
 * 测试渲染一个图层的数据
 */
public class TestRenderLayer extends JFrame{
    // 1. 通过LayUtil.build 方法, 获取图层对象
    private Layer layer = LayerUtil.build(6, 6);

    // 2. 定义构造器
    public TestRenderLayer(){
        // 1)作用: 初始化窗口的基本信息
        init();
        // 2)渲染图层
        renderLayer();
        // 3)自动刷新
        autoRefresh();
    }
    // 3. 初始化窗口的基本信息的方法
    private void init(){
        this.setTitle("Java版-羊了个羊");
        this.setSize(800,1200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setLocationRelativeTo(null);

        //设置绝对布局
        this.setLayout(null);
        this.setBounds(0,0,480,800);
        // 设置窗口显示
        this.setVisible(true);
    }
    // 4. 定义自动刷新代码
    private  void autoRefresh(){
        JFrame start = this;
        new Thread(new Runnable(){

            @Override
            public void run() {
                while(true){
                    start.repaint();
                    try {
                        Thread.sleep(40);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
    //5. 渲染图层的方法 this.getContentPane().add(Compontent);
    //  有36个单元格,需要一个一个遍历
    // 先获取到 图层的二维数组
    // 将二维数组进行循环遍历 - 复制粘贴代码
    private void renderLayer(){
        Cell[][] cells = layer.getCells();
        for(int row=0;row<cells.length;row++){
            for (int col=0;col<cells[row].length;col++){
                Brand brands1 = cells[row][col].getBrand();
                // 以上步骤走完, 所有 牌显示在一个位置 : 
                // 默认情况下, brand 牌的左上角坐标是0 0 所以 我们要改变 牌的坐标
                // 需要修改坐标
                // 第二 布局方式  默认 swing窗口添加组件  提供了多种布局方式  
                // 如: 网格布局, 流式布局 以及 绝对布局
                // 常用: 绝对布局
                // 在init方法中:
                //          this.setLayout(null)
                //          this.setBounds(0,0,480,800);
                int x = col * 59; // 列号*59 0 59  118  177
                int y = row * 66; // 行号*66
                brands1.setBounds(x,y,59,66);
                this.getContentPane().add(brands1);
            }
            System.out.println();
        }
    }

    // main方法
    public static void main(String[] args) {
        new TestRenderLayer();

    }
}

你可能感兴趣的:(JAVA面向对象,java,开发语言)