[JAVA入门] Eclipse+Swing+WindowBuilder+开发小游戏《连连看》

这是本人学习Java时候,以学习为目的做的小游戏。在此整理小结,也希望能为后来者带来一些参考。

Java入门

本人学习Java完全是自我摸索。首先是因为接触Android应用开发,了解了Java的一些基本特性,对Java有了基本的概念和理解。后来阅读经典书籍《Think in Java》和《Effective Java》,有了更加系统的学习。目前也是业余时间零散地了解一些关于JVM的知识以及一些Web开发框架(SSH)。
Java是非常强大的语言,面向对象特性,跨平台特性,开发效率等等各个方面都非常出色。市场上也有大量的Java程序员需求。非常值得我们去学习!

《连连看》

小游戏的最终情况是这样的,如下图:

 

[JAVA入门] Eclipse+Swing+WindowBuilder+开发小游戏《连连看》_第1张图片   [JAVA入门] Eclipse+Swing+WindowBuilder+开发小游戏《连连看》_第2张图片

开发重点

界面

使用的是JDK自带的图形包 java.awt 和 javax.swing。

《连连看中我用到了很多界面组件,总结一下:

a,容器
JFrame(窗口):顶级窗口,包含窗口图标,最小化最大化关闭按钮等,作为一个视图控件的容器,可以添加其他子组件。
JPanel(画布) :常用基本的视图组件,可以设置各种布局,也是一个容器,可以添加其他子组件
JScrollPane(滚动画布):如果子组件的内容超过本身的大小,则会自动产生滚动条。
JSplitPane(分栏画布) :可以将界面分成两栏,可以是上下,或者左右分栏。
JLayeredPane(分层画布):非常好用。跟Photoshop里面图层的概念一样,我们设置背景图片时可以用这个。

b,布局每个容器拥有一个自己的布局,影响其子组件的排版
FlowLayout(浮动布局):最基本的布局。
BorderLayout(边缘布局):分为东西南北中。
CardLayout(卡片布局):非常好用!切换屏幕用这个。
FormLayout(表格布局):非常强大!各行各列的尺寸都可以设置。
GridLayout(格子布局):界面均匀分隔成格子,连连看中的图片用这个。

c, 组件(components)
JLabel(标签):可以显示文字和图片。
JButton(按钮):通常就是设置监听ActionListener。
JTextPane(文章):显示一篇文章,运行时可以被编辑。
JList(列表):可以利用ListModel动态管理列表中的元素。
JProgressBar(进度条):设置max设置value。

事件

我们可以对视图组件设置各种监听器,实现对事件的响应处理。
ComponentListener:监听窗口移动/显示/尺寸变化等事件
ActionListener:监听按钮的点击事件
WindowListener:监听窗口关闭等事件
MouseListener:鼠标点击事件
MouseMotionListener:鼠标移动/进入/离开等事件

插件

Swing包提供了非常多的视图组件,非常多的界面属性和响应函数,直接用代码“写”界面肯定非常不方便。使用WindowBuilder插件吧!
下载地址:http://www.eclipse.org/windowbuilder/download.php
Eclipse菜单Help> Install New Software > Add > 选择下载的zip文件安装。
安装完后重启Eclipse,选择自己设计的界面类(比如继承JFrame的类)java文件,点击右> Open With > Window Builder Editor 可以打开可视化界面设计。
网上还有别的插件工具,我自己没用过就不介绍了。

数据库

任何软件开发几乎都设计到数据库。Java拥有规范的数据库操作接口JDBC(Java DataBase Connectivity)。
在《连连看》中,我用的是轻量级数据库Sqlite。
使用JDBC,我们需要对应的数据库驱动,这里导入一个包sqlite-jdbc-3.7.2.jar
下载地址http://www.xerial.org/maven/repository/artifact/org/xerial/sqlite-jdbc/3.7.2/
怎么导入jar包到自己的project中?
右键点击java project >Properties > Java Build Path > Libraries > Add JARs...
怎么加载数据库驱动?怎么连接数据库?怎么执行SQL语句?

<span style="font-size:14px;">Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection( "jdbc:sqlite:"+GameConfig.DB_NAME ); 
Statement stat = conn.createStatement();
stat.execute(sql);</span>

 

《连连看》算法

怎么判断两个点可以连接消掉?

相信网上已经有了各式各样的算法。不过我自己设计了一个,非常简陋,不过经自己验证还没发现Bug。

两个点 A(3,2),B(6,7)怎么判断能否相连?(如图绿色点)

[JAVA入门] Eclipse+Swing+WindowBuilder+开发小游戏《连连看》_第3张图片

问题分解:

1,两个点之间,有[3,4,5,6]4个横行,必须寻找到至少一条“通道”可以直穿过这4个行(如图,找到2条)

[JAVA入门] Eclipse+Swing+WindowBuilder+开发小游戏《连连看》_第4张图片

2,A,B两点必须能“直达”一条通道(如图,一条满足条件)

[JAVA入门] Eclipse+Swing+WindowBuilder+开发小游戏《连连看》_第5张图片

连连看的规则其实很简单。接下来关键就是怎么写代码了。

我用了最简陋的运算:位运算!因为我认为这是最快的而且是最简便的方法。

把整个界面用char数组来表示,有图片的格子用1表示,没有图片用0表示。

下面是10*10时的矩阵初始情况:

<span style="font-size:14px;">0000000000001111 //matrix[0]
0111111111101111 //matrix[1]
0111111111101111 //matrix[2]
0111111111101111 //matrix[3]
0111111111101111 //matrix[4]
0111111111101111 //matrix[5]
0111111111101111 //matrix[6]
0111111111101111 //matrix[7]
0111111111101111 //matrix[8]
0111111111101111 //matrix[9]
0000000000001111 //matrix[10]<span style="font-size:18px;"></span></span>

 寻找“通道”的代码:

<span style="font-size:14px;">char[] matrix = new char[10];
char temp = 0x0000;
for( int i=3; i<=7; ++i ){
    temp |= matrix[i];//按位或运算
}
if( temp == 0xFFFF ){
    ;//无通道
}else{
    ;//有通道
}
</span>

以上只是算法的一部分,不过其实问题已经可以引刃而解了。

图片伸缩

怎么让图片根据JLabel的尺寸缩放?
自己继承JLabel,在Eclipse的workspace中找到项目文件夹,放入图片beauty.jpg

<span style="font-size:14px;">public class ImageJLabel extends JLabel {
    Image img = ImageIO.read( new File( "res/beauty.jpg" ));//需要catch Exception
    @Override
    public void paintComponent( Graphics g ){
        g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
    }
</span>

数据库异常

ResultSetis TYPE_FORWARD_ONLY
Statement对象是用来执行SQL语句的,通过createStatement()方法可以获得其实例。
Statement stateMent = connection.createStatement();
执行select语句可以得到一个结果集ResultSet
经常查询完需要判断结果集是否为空。比如:
ResultSet rs = stateMent.executeQuery("Select * From table");
if( rs.first() ){ ... }
那么,这时就会报异常了,因为用createStatement()方法得到并查询的结果集游标只能moveforward
The constant indicating the type for a ResultSet object whose cursor may moveonly forward.
解决方法有两种,我采用下面的第二种方法:
1StatementstateMent =connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
2if(rs.next() ){ ... }//next()代替first()

 产生两两对应的图片

我的图片命名很简单:001.jpg,002.jpg,003.jpg 以此类推。

于是我们的问题转换为如何获得两两对应的数字?下面是我自己写的类:

<span style="font-size:14px;">package com.yarkey.tools;

public class IntClass {
	private int value;
	private int num;
	
	public IntClass( int value ){
		this.value = value;
		num = 0;
	}
	
	public int add( int i ){
		num += i;
		return num;
	}
	public int minus( int i ){
		num -= i;
		return num;
	}
	
	public int getValue(){
		return value;
	}
	public int getNum(){
		return num;
	}
}</span>

 

<span style="font-size:14px;">package com.yarkey.tools;

import java.util.ArrayList;
import java.util.Random;

public class RandomType {
	
	private static final String TAG = "RandomType";
	
	Random random = new Random();
	ArrayList<IntClass> typeList = new ArrayList<IntClass>();
	private final int type;
	private final int numOfPerType;
	
	public RandomType( int type, int numOfPerType ){
		this.type = type;
		this.numOfPerType = numOfPerType;
		for( int i=0; i<type; ++i ){
			typeList.add( new IntClass(i) );
		}
	}
	
	public int get(){
		int rd = random.nextInt( typeList.size() );
		int rdType = typeList.get(rd).getValue();
		if( typeList.get(rd).add(1) >= numOfPerType ){
			typeList.remove(rd);
			Log.d(TAG, "typeList.remove("+rd+") >>> type="+rdType, 15);
		}
		return rdType;
	}
	
	public void reset(){
		typeList.clear();
		for( int i=0; i<type; ++i ){
			typeList.add( new IntClass(i) );
		}
	}
}</span>

type:图片的种数

numOfPerType:每张图片出现的次数。

好了,如果我们的连连看是10*10的情况,我们有25张图片,那么每张图片出现4次

我们依次生成随机数,依次分给0-99的界面位置:

<span style="font-size:14px;">RandomType randomType = new RandomType( type, blocks/type );
for( int i=0; i<100; ++i ){
    int randomInt = randomType.get();
    ;//选择图片或者其他操作
}</span>

欢迎交流,也欢迎批评指正。

Good night world !

你可能感兴趣的:(java,eclipse,连连看,游戏编程)