Java开发1200例第84例:图片配对游戏(源码及心得)

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.net.URL;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;


public class PictureMatchingFrame extends JFrame implements MouseListener,MouseMotionListener{
 private static int WIDTH = 400;
 private static int HEIGHT = 400;
 private Icon[] icon = new ImageIcon[3];   //存储图标的小组件
 private JLabel img[] = new JLabel[3];   //显示图标的标签
 private JLabel targets[] = new JLabel[3];  //窗体下面显示文字的标签
 private Point pressPoint;               //鼠标按下时的起始坐标
 
 public PictureMatchingFrame(){
  //通过获得的URL地址,对三个小组件分别实例化
  URL imgUrl = PictureMatchingFrame.class.getResource("img/bike.png");
  icon[0] = new ImageIcon(imgUrl);
  imgUrl = PictureMatchingFrame.class.getResource("img/clothing.png");
  icon[1] = new ImageIcon(imgUrl);
  imgUrl = PictureMatchingFrame.class.getResource("img/screen.png");
  icon[2] = new ImageIcon(imgUrl);
  
  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  this.setBounds(200, 200, WIDTH, HEIGHT);  //设置窗体位置及宽高
  this.setTitle("图片配对游戏");   //设置窗体标题
  this.setResizable(false);       //设置窗体大小不可变
  
  JPanel imagePanel = new JPanel(); //得到添加小图标的面板
  imagePanel.setLayout(null);       //设置面板的布局为空
  this.setGlassPane(imagePanel);    //设置玻璃面板为图像标签面板
  this.getGlassPane().setVisible(true);  //设置该玻璃面板为可见状态
  imagePanel.setOpaque(false);      //设置玻璃面板为透明的
  JPanel bottomPanel = new JPanel();//创建添加目标标签的面板
  
  for(int i=0;i<3;i++){
   img[i] = new JLabel(icon[i]); //得到小图标的标签
   img[i].setSize(50, 50);       //设置小图标的尺寸
   img[i].setBorder(new LineBorder(Color.GRAY));   //设置线性边框
   int x = (int)(Math.random()*(WIDTH-60));        //随机生成小图标的横坐标
   int y = (int)(Math.random()*(HEIGHT-160));      //随机生成小图标的纵坐标
   img[i].setLocation(x, y);     //设置小图标的位置
   img[i].addMouseListener(this);                  //为每个图像标签添加鼠标事件监听器  
   img[i].addMouseMotionListener(this);
   imagePanel.add(img[i]);       //将小图标的标签添加到面板中
   
   targets[i] = new JLabel();    //创建匹配位置的空标签
   targets[i].setOpaque(true);   //设置标签为不透明
   targets[i].setBackground(Color.ORANGE);  //设置标签背景颜色
   targets[i].setHorizontalTextPosition(SwingConstants.CENTER);   //设置文本与图像水平居中
   targets[i].setVerticalTextPosition(SwingConstants.BOTTOM);     //设置文本显示在图像下方
   targets[i].setPreferredSize(new Dimension(80,80));             //设置标签首先大小
   targets[i].setHorizontalAlignment(SwingConstants.CENTER);      //文字居中对齐
   bottomPanel.add(targets[i]);   //添加标签到底部面板
  }
  //设置目标标签的文字
  targets[0].setText("自行车");
  targets[1].setText("衣服");
  targets[2].setText("显示器");
  
  //下面这句话不能要,不要再将图像面板添加到框架中,如果添加,那玻璃面板的效果就没有了
  //this.add(imagePanel,BorderLayout.CENTER);         
  this.add(bottomPanel, BorderLayout.SOUTH);        //将目标面板添加到框架中
 }
 
 public static void main(String[] args){
  PictureMatchingFrame frame = new PictureMatchingFrame();   //创建窗体对象
  frame.setVisible(true);       //设置窗体对象为可见状态
 }

 @Override
 public void mouseDragged(MouseEvent e) {
  JLabel source = (JLabel)e.getSource();   //获取事件原图像控件
  Point imgPoint = source.getLocation();   //获取原图像控件坐标
  Point point = e.getPoint();              //获取鼠标坐标
  source.setLocation(imgPoint.x + point.x - pressPoint.x, imgPoint.y + point.y - pressPoint.y);
 }

 public void mouseMoved(MouseEvent e) {
 }
 public void mouseClicked(MouseEvent e) {
 }
 public void mouseEntered(MouseEvent e) {
 }
 public void mouseExited(MouseEvent e) {
 }
 
 @Override 
 public void mousePressed(MouseEvent e) {
  pressPoint = e.getPoint();           //保存拖放图片标签时的起始坐标
 }

 @Override
 public void mouseReleased(MouseEvent e) {
  if(checkPosition()){
   this.getGlassPane().setVisible(false);   //设置框架中的所有面板对象都不可见
   for(int i=0;i<3;i++){
    targets[i].setText("匹配成功");       //设置正确提示
     targets[i].setIcon(icon[i]);          //设置匹配的图标
   }
  }
 }
 //检查是否配对成功
 private boolean checkPosition(){
  boolean result = true;
  for(int i=0;i<3;i++){
   Point location = img[i].getLocationOnScreen();   //获取每个图像标签的位置
   Point seat = targets[i].getLocationOnScreen();   //获得每个对应位置的坐标
   targets[i].setBackground(Color.GREEN);
   //如果配对错误
   if(!(location.x > seat.x && location.x < seat.x + 80 && location.y > seat.y && location.y < seat.y + 80)){
    targets[i].setBackground(Color.ORANGE);
    result = false;
   }
  }
  return result;
 }
}


 

说明:今天自己看着java开发1200例书上的提示写了这个小程序,感觉还是有些收获的,主要有以下几点:

(1)、this.setGlassPane(imagePanel);    //设置玻璃面板为图像标签面板,这句代码让自己清楚的知道了玻璃面板的设置方法;

(2)、targets[i].setOpaque(true);   //设置标签为不透明
             targets[i].setBackground(Color.ORANGE);  //设置标签背景颜色,对于这两句话,标签默认是透明的,如果不设置为不透明的,那么就不能设置标签的背景颜色了;

(3)、最后一点就是,对于开发一个小游戏来说,一定不要奢望一下子把所有的效果都写完,那样如果自己写错了,就很难找到错误点,写一个项目正确的开发步骤应该是:递增式,即先把最简单的效果先(即第一个版本)写出来,这样做的目的一是不容易错,二是自己也会比较有信心写下去了,然后再在原基础上慢慢增加,最后项目就能慢慢的完成了。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值