JAVA游戏项目之消除区域和背景音乐
消除区域和背景音乐
一、本章目标
绘制消除区域
添加背景图片
添加背景音乐
二、涉及知识点
集合的排序: 名称相同的牌在一起,准备消除
集合的Stream操作: 三个一组可以执行删除,Stream流,水流
集合的删除:并发删除异常, 如果是三个执行删除操作
集合的遍历: map集合的遍历方式,list和set都比较简单
jdk8的新特性: lamda表达式、方法引用
三、知识点讲解
集合的排序
实现牌的排序功能
package cn.yunhe.demo;
import cn.yunhe.model.Brand;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestArrayList {
public static void main(String[] args) {
Brand brand1 = new Brand("刷子");
Brand brand2 = new Brand("剪刀");
Brand brand3 = new Brand("水桶");
Brand brand4 = new Brand("剪刀");
Brand brand5 = new Brand("剪刀");
Brand brand6 = new Brand("水桶");
List<Brand> list = new ArrayList<Brand>();
list.add(brand1);
list.add(brand2);
list.add(brand3);
list.add(brand4);
list.add(brand5);
list.add(brand6);
//要想排序:第一元素自身是可以比较的,每个人的身高,可以比较的;
//第二种容器是有序的:高铁车厢座位都是有序的,电影院的座位也是有序的
//第一种比较方法使用Collections工具类,Brand类需要实现Comparable接口,并实现其方法
//Collections.sort(list);
//第二种比较方法,直接调用list接口的sort方法,给他传入一个比较器,定义比较的规则
/*
list.sort(new Comparator<Brand>() {
@Override
public int compare(Brand o1, Brand o2) {
return o1.getName().compareTo(o2.getName());
}
});
*/
//第三种方式使用lamda表达式
//list.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
//第四种方式直接调用接口的静态方法,比较的是牌的名称
list.sort(Comparator.comparing(Brand::getName));
for (Brand brand : list) {
System.out.print(brand.getName()+"--");
}
}
}
在面向对象里,如何具备某个能力?直接调用Collections.sort方法出错。原因元素自身不可以比较。
java: 对于sort(java.util.List<cn.yunhe.model.Brand>), 找不到合适的方法
方法 java.util.Collections.<T>sort(java.util.List<T>)不适用
(推论变量 T 具有不兼容的限制范围
等式约束条件: cn.yunhe.model.Brand
上限: java.lang.Comparable<? super T>)
方法 java.util.Collections.<T>sort(java.util.List<T>,java.util.Comparator<? super T>)不适用
(无法推断类型变量 T
(实际参数列表和形式参数列表长度不同))
==第一种比较方法使用Collections工具类,Brand类需要实现Comparable接口,让元素具备比较性==
你的电脑功能强大吗?功能丰富吗?你的手机功能强大吗?功能丰富吗?你的电视等等。
package cn.yunhe.model;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
//继承组件类
public class Brand extends JComponent implements Comparable<Brand>{
private String name;//牌的名称
private boolean isGray;//是否灰色
private Image image;//正常图片
private Image grayImage;//灰色图片
//省略代码......
@Override
public int compareTo(Brand obj) {
// obj是要比较的对象, 和谁比较,和当前对象,this
int i = this.getName().compareTo(obj.getName());
return i;
}
}
第一种完整代码:
package cn.yunhe.demo;
import cn.yunhe.model.Brand;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Demo1 {
public static void main(String[] args) {
Brand brand1 = new Brand("刷子");
Brand brand2 = new Brand("剪刀");
Brand brand3 = new Brand("水桶");
Brand brand4 = new Brand("剪刀");
Brand brand5 = new Brand("剪刀");
Brand brand6 = new Brand("水桶");
List<Brand> list = new ArrayList<>();//普通的集合类,有序不允许重复
list.add(brand1);
list.add(brand2);
list.add(brand3);
list.add(brand4);
list.add(brand5);
list.add(brand6);
System.out.println("排序之前: ");
for (Brand brand : list){
System.out.print(brand.getName() + "\t");
}
//1. 第一种排序方式:默认出错,Collections不知道排序的依据
Collections.sort(list);
System.out.println("\n排序之后:");
for (Brand brand : list){
System.out.print(brand.getName() + "\t");
}
}
}
==第二种比较方法,直接调用list接口的sort方法,给他传入一个比较器,定义比较的规则,让容器具备排序功能==
首先把Brand类实现的接口注释掉,Demo1出错,注释:Collections.sort(list);
package cn.yunhe.demo;
import cn.yunhe.model.Brand;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Demo2 {
public static void main(String[] args) {
Brand brand1 = new Brand("刷子");
Brand brand2 = new Brand("剪刀");
Brand brand3 = new Brand("水桶");
Brand brand4 = new Brand("剪刀");
Brand brand5 = new Brand("剪刀");
Brand brand6 = new Brand("水桶");
List<Brand> list = new ArrayList<>();//普通的集合类,有序不允许重复
list.add(brand1);
list.add(brand2);
list.add(brand3);
list.add(brand4);
list.add(brand5);
list.add(brand6);
System.out.println("排序之前: ");
for (Brand brand : list){
System.out.print(brand.getName() + "\t");
}
//第2种排序方法,调用list的sort方法,需要一个比较器
//告诉容器按照什么方式进行比较,高铁车厢有编号,电影院也是一个容器,具备排序功能,几排几号。
list.sort(new Comparator<Brand>() {
@Override
public int compare(Brand o1, Brand o2) {
return o1.getName().compareTo(o2.getName());
}
});
System.out.println("\n排序之后:");
for (Brand brand : list){
System.out.print(brand.getName() + "\t");
}
}
}
==第三种比较方法,直接调用list接口的sort方法,使用Lamda表达式简化代码而已==
//第2种排序方法,调用list的sort方法,需要一个比较器
//告诉容器按照什么方式进行比较,
/*
list.sort(new Comparator<Brand>() {
@Override
public int compare(Brand o1, Brand o2) {
return o1.getName().compareTo(o2.getName());
}
});
*/
//第3种比较方式实用lambda表达式
list.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
==第四种比较方法,使用jdk8的新特性,比使用Lamda表达式还要简单==
package cn.yunhe.demo;
import cn.yunhe.model.Brand;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Demo4 {
public static void main(String[] args) {
Brand brand1 = new Brand("刷子");
Brand brand2 = new Brand("剪刀");
Brand brand3 = new Brand("水桶");
Brand brand4 = new Brand("剪刀");
Brand brand5 = new Brand("剪刀");
Brand brand6 = new Brand("水桶");
List<Brand> list = new ArrayList<>();//普通的集合类,有序不允许重复
list.add(brand1);
list.add(brand2);
list.add(brand3);
list.add(brand4);
list.add(brand5);
list.add(brand6);
System.out.println("排序之前: ");
for (Brand brand : list){
System.out.print(brand.getName() + "\t");
}
//第4种排序方法,
//①jdk8的第一个新特性:接口的默认方法,静态方法
//②jdk8的第二个新特性:方法引用,本质是调用方法
list.sort(Comparator.comparing(Brand::getName));
System.out.println("\n排序之后:");
for (Brand brand : list){
System.out.print(brand.getName() + "\t");
}
}
}
字符串怎么进行比较的?普通的英语单词比较的字母的ASCII,汉字比较的编码对应的数字,GBK编码和UTF-8编码是不一样的。
ASCII码 | 字符 | ASCII码 | 字符 | ASCII码 | 字符 | ASCII码 | 字符 |
---|---|---|---|---|---|---|---|
0 | NUT | 32 | (space) | 64 | @ | 96 | 、 |
1 | SOH | 33 | ! | 65 | A | 97 | a |
2 | STX | 34 | ” | 66 | B | 98 | b |
3 | ETX | 35 | # | 67 | C | 99 | c |
4 | EOT | 36 | $ | 68 | D | 100 | d |
5 | ENQ | 37 | % | 69 | E | 101 | e |
6 | ACK | 38 | & | 70 | F | 102 | f |
7 | BEL | 39 | , | 71 | G | 103 | g |
8 | BS | 40 | ( | 72 | H | 104 | h |
9 | HT | 41 | ) | 73 | I | 105 | i |
10 | LF | 42 | * | 74 | J | 106 | j |
11 | VT | 43 | + | 75 | K | 107 | k |
12 | FF | 44 | , | 76 | L | 108 | l |
13 | CR | 45 | - | 77 | M | 109 | m |
14 | SO | 46 | . | 78 | N | 110 | n |
15 | SI | 47 | / | 79 | O | 111 | o |
16 | DLE | 48 | 0 | 80 | P | 112 | p |
17 | DCI | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 | 50 | 2 | 82 | R | 114 | r |
19 | DC3 | 51 | 3 | 83 | X | 115 | s |
20 | DC4 | 52 | 4 | 84 | T | 116 | t |
21 | NAK | 53 | 5 | 85 | U | 117 | u |
22 | SYN | 54 | 6 | 86 | V | 118 | v |
23 | TB | 55 | 7 | 87 | W | 119 | w |
24 | CAN | 56 | 8 | 88 | X | 120 | x |
25 | EM | 57 | 9 | 89 | Y | 121 | y |
26 | SUB | 58 | : | 90 | Z | 122 | z |
27 | ESC | 59 | ; | 91 | [ | 123 | { |
28 | FS | 60 | < | 92 | \ | 124 | | |
29 | GS | 61 | = | 93 | ] | 125 | } |
30 | RS | 62 | > | 94 | ^ | 126 | ~ |
31 | US | 63 | ? | 95 | — | 127 | DEL |
集合的Stream操作
实现牌的三个一组,如果一组有三个可以消除了。
package cn.yunhe.demo;
import cn.yunhe.model.Brand;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TestStream {
public static void main(String[] args) {
Brand brand1 = new Brand("刷子");
Brand brand2 = new Brand("剪刀");
Brand brand3 = new Brand("水桶");
Brand brand4 = new Brand("剪刀");
Brand brand5 = new Brand("剪刀");
Brand brand6 = new Brand("水桶");
List<Brand> list = new ArrayList<Brand>();
list.add(brand1);
list.add(brand2);
list.add(brand3);
list.add(brand4);
list.add(brand5);
list.add(brand6);
//需要存储:牌的名称----牌的数量 键值对
Map<String,Integer> map = new HashMap<String, Integer>();
for (Brand b : list) {
//如果包括牌的名称
if (map.containsKey(b.getName())) {
Integer num = map.get(b.getName());
map.put(b.getName(), ++num);
} else {
map.put(b.getName(), 1);
}
}
System.out.println(map);
}
}
stream的操作,流的概念,水流就要有水库(水源),蓄水池,电流要有输变电站(电源)。也可以理解为流水线,富士康的生产线。FileInputStream
实体类:
package cn.yunhe.demo;
public class Employee {
private int id;
private String name;
private int age;
private double salary;
private Status status;
public Employee(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
public Employee(int id,String name, int age, double salary, Status status) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
this.status = status;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
", status=" + status +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public enum Status {
FREE, BUSY, VOCATION;
}
}
stream的操作:
package cn.yunhe.demo;
import cn.yunhe.model.Brand;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TestStream {
private static List<Employee> list = new ArrayList<>();
static {
list.add( new Employee("张三",38,5500.00) );
list.add( new Employee("李四",30,4500.00) );
list.add( new Employee("王五",48,6500.00) );
list.add( new Employee("赵六",28,8500.00) );
list.add( new Employee("赵六",28,8500.00) );
list.add( new Employee("赵六",28,8500.00) );
list.add( new Employee("赵六",28,8500.00) );
}
public static void main(String[] args) {
demo3();
}
public static void demo3() {
//获取集合的所有对象的姓名,再组成一个List集合
List<String> listName = list.stream().
map(Employee::getName).collect(Collectors.toList());
listName.forEach(System.out::println);
//过滤薪水大于5000,只取前3名,limit
list.stream().filter(e -> e.getSalary()>5000).limit(3)
.forEach(System.out::println);
}
//净水器是干什么的?
public static void demo2() {
Stream<Employee> employeeStream = list.stream().filter(e -> e.getAge() > 35);
employeeStream.forEach(System.out::println);
}
}
Stream的收集collect操作:
package cn.yunhe.demo;
import cn.yunhe.model.Brand;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class TestBrandGroup {
public static void main(String[] args) {
Brand brand1 = new Brand("刷子");
Brand brand2 = new Brand("剪刀");
Brand brand3 = new Brand("水桶");
Brand brand4 = new Brand("剪刀");
Brand brand5 = new Brand("剪刀");
Brand brand6 = new Brand("水桶");
List<Brand> list = new ArrayList<Brand>();
list.add(brand1);
list.add(brand2);
list.add(brand3);
list.add(brand4);
list.add(brand5);
list.add(brand6);
//牌的分组,满足3张调用删除方法
Map<String,List<Brand>> map= list.stream()
.collect(Collectors.groupingBy(Brand::getName));
Set<String> brandName = map.keySet();
for (String name : brandName) {
System.out.println(name + map.get(name).size());
}
}
public void test(){
List<String> list = emps.stream().map(Employee::getName)
.collect(Collectors.toList());
list.forEach(System.out::println);
System.out.println("====================");
Set<String> set = emps.stream().map(Employee::getName)
.collect(Collectors.toSet());
set.forEach(System.out::println);
System.out.println("====================");
HashSet<String> hashSet = emps.stream().map(Employee::getName)
.collect(Collectors.toCollection(HashSet::new));
hashSet.forEach(System.out::println);
}
}
集合的删除
实现牌的删除
不能在遍历的时候删除集合中的元素,会出现并发修改异常:
package cn.yunhe.demo;
import cn.yunhe.model.Brand;
import java.util.ArrayList;
import java.util.List;
public class TestBrandDelete {
public static void main(String[] args) {
Brand brand1 = new Brand("刷子");
Brand brand2 = new Brand("剪刀");
Brand brand3 = new Brand("水桶");
Brand brand4 = new Brand("剪刀");
Brand brand5 = new Brand("剪刀");
Brand brand6 = new Brand("水桶");
List<Brand> list = new ArrayList<Brand>();
list.add(brand1);
list.add(brand2);
list.add(brand3);
list.add(brand4);
list.add(brand5);
list.add(brand6);
//剪刀超过3张,怎么删除
for (Brand brand : list) {
if (brand.getName().equals("剪刀")){
list.remove(brand);
}
}
System.out.println("===========删除之后==============");
System.out.println(list);
}
}
执行之后的异常:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at cn.yunhe.demo.TestBrandDelete.main(TestBrandDelete.java:24)
进程已结束,退出代码1
怎么删除?使用迭代器的方式遍历和删除。
package cn.yunhe.demo;
import cn.yunhe.model.Brand;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class TestBrandDelete {
public static void main(String[] args) {
Brand brand1 = new Brand("刷子");
Brand brand2 = new Brand("剪刀");
Brand brand3 = new Brand("水桶");
Brand brand4 = new Brand("剪刀");
Brand brand5 = new Brand("剪刀");
Brand brand6 = new Brand("水桶");
List<Brand> list = new ArrayList<Brand>();
list.add(brand1);
list.add(brand2);
list.add(brand3);
list.add(brand4);
list.add(brand5);
list.add(brand6);
//剪刀超过3张,怎么删除
//相当于小朋友上学在校门口排队,老师一个一个扒拉学生,看看有没有恐怖分子,冒牌货,不是学校的学生
Iterator<Brand> it = list.iterator();//iterator 迭代器可以理解为这个老师
while (it.hasNext()) {
Brand brand = it.next();//看下一个学生
if (brand.getName().equals("剪刀")){
it.remove();
}
}
/*for (Brand brand : list) {
if (brand.getName().equals("剪刀")){
list.remove(brand);
}
}*/
System.out.println("===========删除之后==============");
list.forEach(e -> System.out.println(e.getName()));
}
}
map集合的遍历
实现牌的名称和数量的遍历
Map<String,List<Brand>> map = list.stream().collect(Collectors.groupingBy(Brand::getName));
Set<String> brandName = map.keySet();
for (String name : brandName) { //遍历所有的key
System.out.println(name + map.get(name).size());
}
jdk8的新特性
实现代码的简化
四、代码实现
1、绘制消除区域
把点击的牌放到一起list容器里,所谓绘制消除区域就是把list容器中的牌依次绘制到窗体上。
package cn.yunhe.model;
import java.util.ArrayList;
import java.util.List;
/**
* 消除区域
*/
public class EliminateBox {
//注意加static关键字
private static List<Brand> slot = new ArrayList<>();
public void addSlot(Brand brand){
slot.add(brand);
//调用绘制方法
paint();
}
//绘制消除框
public void paint(){
for (int i = 0; i <slot.size(); i++){
Brand brand = slot.get(i);
int x = i * brand.getWidth() + 10; //宽度50,第1张牌x=10,第2张:60,110
brand.setBounds(x,600,50,50);
}
}
}
-
在Brand类中增加EliminateBox属性,调用消除牌的方法
public class Brand extends JComponent{
//省略代码
private int width = 50;
private int height = 50;
private Cell cell;
//增加消除框属性
private EliminateBox eliminateBox = new EliminateBox();
public Brand(String name) {
//省略部分代码
//添加事件处理机制
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Brand brand = (Brand) e.getSource();
if (brand.isGray()) {
return;// 表示的结束方法的执行,直接返回
}
System.out.println("你点击了" + brand.getName());
//brand.getParent().remove(brand);
eliminateBox.addSlot(brand);//调用消除框方法
//删除数据结构中的数据
cell.setStatus(0);//无牌状态,你必须设置是当前牌所在的单元格
cell.setBrand(null);
TestRenderMap.map.compareAll();//每次点击之后都要重新计算一下图层的遮盖
}
});
}
//下面代码省略
执行效果:
-
增加牌的排序功能,名称相同的牌放在一起
public void addSlot(Brand brand){
slot.add(brand);
//牌的排序,根据牌的名称
slot.sort(Comparator.comparing(Brand::getName));
//调用绘制方法
paint();
}
-
问题:牌的消除条件是什么?如果达到这个条件就要消除牌,下面实现牌的删除方法。
package cn.yunhe.model;
import java.util.*;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 消除区域
*/
public class EliminateBox {
private static List<Brand> slot = new ArrayList<>();
public void addSlot(Brand brand){
slot.add(brand);
//牌的排序,根据牌的名称
slot.sort(Comparator.comparing(Brand::getName));
Map<String, List<Brand>> map = slot.stream().collect(Collectors.groupingBy(Brand::getName));
Set<String> keySet = map.keySet();
for (String key : keySet) {
List<Brand> brands = map.get(key);
if (brands.size() == 3){
deleteBrand(key);
}
}
//调用绘制方法
paint();
}
/**
* 迭代器清空集合方法
*/
public void deleteBrand(String name){
Iterator<Brand> iterator = slot.iterator();
while (iterator.hasNext()) {
Brand brand = iterator.next();
if (brand.getName().equals(name)) {
brand.getParent().remove(brand);//ui界面删除
iterator.remove();//数据结构删除
}
}
}
//绘制消除框
public void paint(){
for (int i = 0; i <slot.size(); i++){
Brand brand = slot.get(i);
int x = i * brand.getWidth() + 10;
brand.setBounds(x,600,50,50);
}
}
}
-
游戏退出的条件是什么?
在EliminateBox类中添加游戏退出的方法,在添加牌的同时调用该方法。
package cn.yunhe.model;
import javax.swing.*;
import java.util.*;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 消除区域
*/
public class EliminateBox {
private static List<Brand> slot = new ArrayList<>(); //注意静态的属性
public void addSlot(Brand brand){
slot.add(brand);
//省略部分代码
//调用绘制方法
paint();
//调用游戏结束的方法
gameOver();
}
//游戏退出的方法
public void gameOver(){
if (slot.size() == 7){
JOptionPane.showMessageDialog(null,"Game Over!!");
System.exit(0);
}
}
}
-
添加音乐和背景
在项目目录下创建music和lib文件夹,并把音乐文件和jar包复制到对应的文件夹;注意把jar把添加到构建路径。点击File — Project Structre菜单,弹出项目结构对话框:
最终效果截图:
-
添加播放音乐的工具类
package cn.yunhe.model;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class Music {
public void play() {
try {
String str = System.getProperty("user.dir") +"/music/music.mp3";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(str));
Player player = new Player(bis);
player.play();//播放音乐
}catch (FileNotFoundException|JavaLayerException e) {
e.printStackTrace();
}
}
}
-
在TestRenderMap类中调用播放方法
public class TestRenderMap extends JFrame {
public static final Map map = MapUtil.buildMap(3);
public TestRenderMap() {
//1. 初始化窗体
init();
//2.渲染图层:问题图层在哪里???
List<Layer> layerList = map.getList();
for (int i = 0; i <layerList.size(); i++) {
renderLayer(layerList.get(i));
}
//3.调用compareAll方法,判定是否为正常图片
map.compareAll();
//4.自动刷新线程
autoRefresh();
//5.调用播放音乐的方法
new Music().music();
}
//下面代码略
}
测试一下是否可以播放音乐。
-
添加背景和消除框图片,==注意删除Brand类的width和height的getter、setter方法==
修改TestRenderMap类增加两个属性:
public class TestRenderMap extends JFrame {
public static final Map map = MapUtil.buildMap(3);
private Brand bj = new Brand("背景草地");//背景图片
private Brand xc = new Brand("消除区域");//消除背景图片
public TestRenderMap() {
//1. 初始化窗体
init();
//绘制背景和消除区域
xc.setBounds(0,575,450,800);
this.getContentPane().add(xc);
bj.setBounds(0,0,450,800);
this.getContentPane().add(bj);
//2.渲染图层:问题图层在哪里???
List<Layer> layerList = map.getList();
for (int i = 0; i <layerList.size(); i++) {
renderLayer(layerList.get(i));
}
//3.调用compareAll方法,判定是否为正常图片
map.compareAll();
//4.自动刷新线程
autoRefresh();
//5.调用播放音乐的方法
new Music().music();
}
/**
* 渲染的图层的数据
*/
public void renderLayer(Layer layer ){
//获取单元格
Cell[][] cells = layer.getCells();
for (int row = 0; row < cells.length; row++) {
for (int col = 0; col < cells[row].length; col++) {
Brand brand = cells[row][col].getBrand();
int x = col * 50 + layer.getOffsetx();
int y = row * 50 + layer.getOffsety();
brand.setBounds(x,y,50,50);
this.getLayeredPane().add(brand);//注意改为LayeredPane否则出现遮盖
}
}
}
//后面代码.....
}
-
再次调试运行,如下图所示, 点背景草地和消除区域出现bug,两个牌也隐藏了,如何解决:
在Brand类的事件处理机制加如下代码:
public Brand(String name) {
//给name属性赋值
this.name = name;
//给定图片的路径,通过该工具类加载图片
this.image = Toolkit.getDefaultToolkit().getImage("imgs//" + name + ".png");
this.grayImage = Toolkit.getDefaultToolkit().getImage("imgs//" + name + "_gray.png");
//添加事件处理机制
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Brand brand = (Brand) e.getSource();
if (brand.isGray() || brand.getName().equals("背景草地") || brand.getName().equals("消除区域")) {
return;// 表示的结束方法的执行,直接返回
}
System.out.println("你点击了" + brand.getName());
//brand.getParent().remove(brand);//自杀方式
eliminateBox.addSlot(brand);
brand.removeMouseListener(this);//消除框的牌移除事件
//删除数据结构中的数据
cell.setStatus(0);//无牌状态,你必须设置是当前牌所在的单元格
cell.setBrand(null);
TestRenderMap.map.compareAll();//每次点击之后都要重新计算一下图层的遮盖
}
});
}
再次测试运行即可。
五、本章总结
集合的排序
集合的Stream操作
集合的删除:并发删除异常
map集合的遍历
jdk8的新特性
六、本章作业
集合的排序
集合的Stream操作
集合的删除:并发删除异常
map集合的遍历
jdk8的新特性
- 点赞
- 收藏
- 关注作者
评论(0)