“单词背多分”项目说明书

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

项目名称:蓝牙单词背多芬
班级:08游戏设计班
制作人:08801112 胡俊豪
08801111 叶纯智
一.可行性分析 (2)
1.1 前景 (2)
1.2开发目的 (2)
二、开发人员 (2)
三.游戏策划 (2)
3.1基本部分 (2)
3.2内容部分 (2)
四.技术剖析(重点) (5)
4.1开发流程及项目开发进程 (5)
4.2主要类 (6)
4.3蓝牙通讯-个人理解 (7)
4.4主要代码 (8)
4.4.1游戏引擎 (9)
4.4.2蓝牙通信 (10)
4.4.3单词数组生成 (13)
五、个人感受及体会 (17)
一.可行性分析
1.1 前景
“英语四六级”虽然是大多数人不愿染指的噩梦,但是在天朝这种“没证没饭吃”这样伟大而和谐的大时代背景下,大多数人还是抱着淹死总比饿死好的觉悟奔向ABC的海洋,梦想终有一天能跨过无尽之海,到达证之彼岸,一睹有饭吃大神的风采。

于是人们开始期盼能有那么一个叫做“单词背多分”的东西诞生,以助他们早日饱腹…
1.2开发目的
解救众生!可以使学习英语单词变得有趣,互动学习更能提高学习效率.
二、开发人员
胡俊豪、叶纯智
三.游戏策划
3.1基本部分
3.1.1游戏名称
单词背多分
3.1.2游戏主题
单词记忆
3.1.3游戏类型
单词记忆类蓝牙对战
3.1.4游戏操作设计
手机按键
3.1.5游戏运行环境
Java平台
3.1.6游戏运作方式
单机模式或蓝牙对战模式
3.2内容部分
描述游戏过程
(单人模式)
游戏一开始运行系统会随机生成一个单词一密码形式显示在“字母提示”栏表示该单词的字母数,该单词的中文释义会出现在“释义提示”栏。

玩家跟据所得到的信息猜测该单词,并将答案输入“输入”栏,“本机上一次输出”栏保存玩家上一次输出的单词。

答案正确时随机生成另一个单词继续猜。

(双人模式)
比双人模式多了一个“对方输出”栏。

a游戏画面
单机模式
服务端客户端
双人模式
四.技术剖析(重点)
4.1开发流程及项目开发进程
4.2主要类
4.27) 框架(4.28)
5.1)
4.30)
5.5) 5.6)
5.12)
?.?)
display, isServer
Engine, isServer
BTConnector
4.3蓝牙通讯-个人理解
服务端:
首先要定义一个UUID类
在蓝牙中,每个服务和服务属性都唯一地由"全球唯一标识符" (UUID)来校验。

正如它的名字所暗示的,每一个这样的标识符都要在时空上保证唯一。

UUID类可表现为短整形(16或32位)和长整形(128位)UUID。

他提供了分别利用String和16位或32位数值来创建类的构造函数,提供了一个可以比较两个UUID(如果两个都是128位)的方法,还有一个可以转换一个UUID为一个字符串的方法。

UUID实例是不可改变的(immutable),只有被UUID标示的服务可以被发现。

然后初始化
localDevice = LocalDevice.getLocalDevice(); // 获得本地设备discoveryAgent = localDevice.getDiscoveryAgent(); // 获得本地设备代理最后设置设备发现模式,/并打开服务连接,等待客户端来唤醒.
if (!localDevice.setDiscoverable(DiscoveryAgent.GIAC)) {
System.out.println("无法设置设备发现模式!...");
return;}
streamConnectionNotifier = (StreamConnectionNotifier) Connector.open(connectionURL); // 打开服务连接
serviceRecord = localDevice.getRecord(streamConnectionNotifier);
// 打开连接,并等待客户端
streamConnection = streamConnectionNotifier.acceptAndOpen();
客户端
如果是客户端使用蓝牙,是通过一个预定义的接口DiscoveryListener实现的,要经过很多步骤才到Connector.open(url)这一步。

这一步连接的实际是选定设备的选定服务。

先说说接口。

这个接口涉及到4个函数需要实现。

第一个deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
在每次发现了一个设备的时候会自动调用
第二个inquiryCompleted(int discType)
在设备搜索已经结束的时候会自动调用
第三个servicesDiscovered(int transID, ServiceRecord[] servRecord)
当选定好设备之后,想要搜索该设备提供的服务时,每寻找到一个服务,该方法就会自动调用
第四个serviceSearchCompleted(int transID, int respCode)
当对该设备的服务搜寻完毕时会自动调用
除了DiscoveryListener接口之外,客户端连接还有几个类比较重要,第一是连接代理DiscoveryAgent,命令设备开始搜索周围设备的startInquiry(),命令开始搜索选定设备服务的searchService()都是通过它。

第二是本地设备也就是这个客户端自己LocalDevice,连接代理就是通过它获得的。

第三是RemoteDevice,就是具有蓝牙功能的周边设备。

第四是SeviceRecord,就是设备所提供的服务,最后要连接的就是它。

当接口的那些方法都实现了之后,就可以通过ServiceRecord的getConnectionURL()获取连接,再通过(StreamConnection)Connector.open(url)打开连接,进行通话。

4.4主要代码
源代码中的BTClient.java 、BTServer.java 、BTConnector.java类取自蓝牙DEMO代码做少许改进,其它类皆为原创。

4.4.1游戏引擎
if (a.equals(Array_EN_Input()))
a表示玩家在输入框内输入的内容,Array_EN_Input()为“字母提示”栏内的单词。

word_i = Math.abs(random.nextInt()%350)+2;
word_i为控制生成随机单词的变量,答对后就随机另一个生成单词数组内相应的单词,350为单词数组的大概长度,+2是因为取到数组的前两个单词的时候会出现莫名其妙的错误(第一个以密码形式输出的时候会多一个字节,第二个会少一个,其它则正常,所以+2),解决不了,老师有时间的话帮忙看下吧。

public void checkWin(String a) {
if (a.equals(Array_EN_Input())) {
Output2.setString("没错!就是" + Input.getString() + ",凤姐的智商都比不上你啊!");
word_i = Math.abs(random.nextInt()%350)+2;
en = Array_EN_Input();
ch = Array_CH_Input();
english.setString(en);
chinese.setText(ch);
System.out.println(word_i);
}
else {
Output2.setString(Input.getString()+"错误");
}
}
4.4.2蓝牙通信
根据玩家身份(服务端和客户端)调用不同的函数
public void start() {
if ( isServer ) {
server = new BTServer( this );
server.start();
System.out.println("服务器btserver类已经启动。

");
} else {
client = new BTClient( this );
client.start();
System.out.println("客户端btclient类已经启动。

");
}
}
//根据当前是服务器还是客户端发送对应的数据
public void sendMessage( String text ) {
if ( isServer==true ) {
System.out.println("服务器打开sendMessage函数");
server.sendMessage( text );
} else {
System.out.println("客户端打开sendMessage函数");
client.sendMessage( text );
}
}
//接收数据message,调用Engine的receiveMessage处理
public void receiveMessage( String message ) {
System.out.println("BTConnector接收到数据" + message );
Engine.receiveMessage(message);
//调用Engine类的receive方法做进一步的处理
}
服务端主要代码:
private void openSerice() {
try {
// 设置设备发现模式,
if (!localDevice.setDiscoverable(DiscoveryAgent.GIAC)) { System.out.println("无法设置设备发现模式!...");
return;
}
streamConnectionNotifier = (StreamConnectionNotifier) Connector
.open(connectionURL); // 打开服务连接
serviceRecord =
localDevice.getRecord(streamConnectionNotifier);
System.out.println( "等待客户端连接..........");
streamConnection =
streamConnectionNotifier.acceptAndOpen(); // 打开连接,并等待客户端dis = streamConnection.openDataInputStream();
dos = streamConnection.openDataOutputStream();
isConn = true;
sendMessage("已经和客户端连接");
} catch (IOException e) {
e.printStackTrace();
}
}
客户端主要代码:
public void inquiryCompleted(int disType) {
System.out.println("搜索设备完毕.......");
chooseBt();//选择连接服务器
try {
//ServiceRecord sr = ( ServiceRecord )records.elementAt(0);
String device_address = btDevice.getBluetoothAddress();
String conURL = "btspp://" + device_address + ":1";
conn = (StreamConnection) Connector.open(conURL); //打开连接
isConn = true; // 设置连接状态为己连接
System.out.println(isConn);
//setTitle("聊天中.........");
dis = conn.openDataInputStream();// 打开输入流
dos = conn.openDataOutputStream();// 打开输出流
new Thread(this).start(); //启动线程
sendMessage("已经和服务器连接");
} catch (Exception e) {
e.printStackTrace();
}
}
4.4.3单词数组生成
// 中文数组
public String Array_CH_Input() {
wordsplit=new getWordInTxt();
chinese_word=wordsplit.getWordInTxt("chinese.txt");
return chinese_word[word_i];
}
//英语数组
public String Array_EN_Input() {
wordsplit=new getWordInTxt();
english_word =wordsplit.getWordInTxt("english.txt");
return english_word[word_i];
//单词分离类
public class getWordInTxt {
private String[] wordsAarry=null;
private InputStream in = null;
private DataInputStream dis = null;
private byte[] data = null;
private int count=0;
public String[] getWordInTxt(String name) {
in = this.getClass().getResourceAsStream("/" + name);//将位于res 目录下的xx.txt中数字读出。

dis = new DataInputStream(in);
try {
dis.mark(dis.available() + 1);
count = dis.available();
dis.reset();
data = new byte[count];
for (int i = 0; i < count; i++) {
data[i] = dis.readByte();
}
String txt = new String(data, "UTF-8");
wordsAarry = split(txt, "%");
// System.out.println("读到的:"+wordsAarry[2]);
} catch (IOException e) {
// TODO自动生成catch 块
e.printStackTrace();
}
return wordsAarry;
}
public static String[] split(String original, String regex) { //分割字符串// 取子串的起始位置
int startIndex = 0;
// 将结果数据先放入Vector中
Vector v = new Vector();
// 返回的结果字符串数组
String[] str = null;
// 存储取子串时起始位置
int index = 0;
// 获得匹配子串的位置
startIndex = original.indexOf(regex);
// System.out.println("0" + startIndex);
// 如果起始字符串的位置小于字符串的长度,则证明没有取到字符串末尾。

// -1代表取到了末尾
while (startIndex < original.length() && startIndex != -1) { String temp = original.substring(index, startIndex);
// 取子串
v.addElement(temp);
// 设置取子串的起始位置
index = startIndex + regex.length();
// 获得匹配子串的位置
startIndex = original.indexOf(regex, startIndex + regex.length());
}
// 取结束的子串
v.addElement(original.substring(index + 1 - regex.length()));
// 将Vector对象转换成数组
str = new String[v.size()];
for (int i = 0; i < v.size(); i++) {
str[i] = (String) v.elementAt(i);
}
// 返回生成的数组
return str;
}
}
五、个人感受及体会
这个项目虽说只是一个期末作业,但是我们真真正正把他当成一个项目来做了,从开始构思找资料到在手机上运行,足足用了半个月,平时学的东西真的要真真正正的做出一个东西出来,才会觉得学的东西是自己的,编程这东西光看书是不行的,一定要实践实践再实践,另外作为一个程序员,自主学习能力很重要,例如我们蓝牙上课没有讲过,但是我们就可以通过网络和一些例子来学习并可以把它应用到我们的项目里面,另外自主解决问题能力也很关键,我们的做法是先看API,然后思考,然后百度,讨论,分析.例如之前这个项目的蓝牙通讯问题,客户端可以无限次的发信息,而服务端只能发两次,研究很久很久,才发现了客户端发信息前都会调用线程把服务端的DATAINPUTSTREAM打开,而服务端没有把客户端的打开,所以老是报了一个STREAM is Close的错误,后来解决办法太麻烦了,干脆重写服务端和客户端,简简单单的就是客户端连接服务端之后,就调用线程把自身的DataInputStream()和DataOutputStream()打开,这样就避免了很多麻烦,再定义一个sendMessage的函数来发信息,这样两端一发一收就很有规矩了.
做完了这个项目,收获良多,很多以前没有办法理解的定义都有了深刻的理解,而且学会了看API自主学习,现在面对上百或上千行的代码不会感到畏惧,不再厌烦,反而感觉想快点看看这个代码是实现什么的.
这半个月的辛勤劳动是值得的,或许成为程序员的第一步已经踏出了,我们一定会很努力的,谢老师,你不要对我们没信心.呵呵.。

相关文档
最新文档