写的晚了,在分工个Z市高中的一个成绩查询的系统,原系统居然是用VB写的,我不得不佩服原本写系统的那位哥们真能耐得住。

明天搭建下SVN就等着先发project款然后開始项目了。想想有工资进账,心里也为我那干瘪的钱包小兴奋了一把。

闲话不多说了。今天我们来分析下这个小游戏的工作原理以及核心代码的解析:

工作原理:

“主界面”以及“关卡界面”不多说了。这两个是直接写了xml文件,

然后,我们在“游戏界面”的搭建是:

用java代码动态生成了这个界面。在界面中通过service层还有dao层的方法,得到了所在关卡相应的全部成语对象,然后把这些对象每一个都分解成4个word对象,然后放入到界面中。当点击的时候,推断点击的四个word能不可以组成一个成语(依据他们的级别还有他们点击的顺序推断他们能不能组成一个成语)。

假设可以组成一个成语的话。弹出一个框框。显示这个成语的解释、出处等等信息。

我们先看cn.idiomlianliankan.dao包里边的内容:

GameDaoImpl.java:

package cn.idiomlianliankan.dao.impl;

import java.util.ArrayList;
import java.util.List; import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log; import cn.idiomlianliankan.dao.GameDao;
import cn.idiomlianliankan.domain.CheckPoint;
import cn.idiomlianliankan.domain.Idiom;
import cn.idiomlianliankan.domain.Word; public class GameDaoImpl implements GameDao {
private SQLiteDatabase db;
public GameDaoImpl(){} /**
* 构造一个GameDaoImpl对象,传入数据库输出流
* @param context 传入上下文对象
* @param db 数据库输出流
*/
public GameDaoImpl(Context context,SQLiteDatabase db) {
this.db = db;
}
/**
* 添加一个成语,把要加入的成语对象跟关卡对象绑定在一起
* @param checkpoint 关卡对象
* @param idiom 成语对象
*/
@Override
public void addIdiom(CheckPoint checkpoint,Idiom idiom) {
//插入checkpoint表
//推断checkpoint表里边有没有这个id,假设有就不插入,没有就插入
Cursor cursor = db.rawQuery("select * from checkpoint where checkId=? ", new String[]{String.valueOf(checkpoint.getCheckId())});
if(!cursor.moveToNext()){
db.execSQL("insert into checkpoint(checkId) values(?)",
new Object[]{checkpoint.getCheckId()});
} //插入idiom表
db.execSQL("insert into idiom( idiomContent , idiomExplain , idiomProv , foreignCheckId) values(?,?,? ,?)",
new Object[]{idiom.getIdiomContent(),idiom.getIdiomExplain(),idiom.getIdiomProv(),idiom.getCheckpoint().getCheckId()});
//插入word表
idiom = getIdiom(idiom.getIdiomContent());
addWord(idiom);
Log.i("test", "4");
}
/**
* 把成语分解成四个word对象,然后插入到word表中
* @param idiom 把idiom成语分成4个word对象插入word表中
*/
public void addWord(Idiom idiom){
Log.i("test", "5");
String idiomContent = idiom.getIdiomContent();
for(int i =1;i<=4;i++){
char wordContent = idiomContent.charAt(i-1);
db.execSQL("insert into word(wordContent,wordLevel,foreignIdiomId) values(?,?,?)",new Object[]{wordContent , i ,idiom.getIdiomId()});
}
}
/**
* 依据idiomContent得到数据库中的idiom对象
* @param content 成语的内容
*/
public Idiom getIdiom(String content){ Idiom idiom = new Idiom(); Cursor cursor = db.rawQuery("select * from idiom where idiomContent=?", new String[]{content});
if(cursor!=null && cursor.moveToFirst()){ int idiomId = cursor.getInt(cursor.getColumnIndex("idiomId"));
String idiomContent = content;
String idiomExplain = cursor.getString(cursor.getColumnIndex("idiomExplain"));
String idiomProv = cursor.getString(cursor.getColumnIndex("idiomProv")); idiom.setIdiomId(idiomId);
idiom.setIdiomContent(idiomContent);
idiom.setIdiomExplain(idiomExplain);
idiom.setIdiomProv(idiomProv); }
return idiom;
} /**
* 依据idiomId得到数据库中的idiom对象
* @param idiomId 成语的id
*/
public Idiom getIdiom(int idiomId){
Idiom idiom = new Idiom();
idiom.setIdiomId(idiomId); Cursor cursor = db.rawQuery("select * from idiom where idiomId=? ", new String[]{String.valueOf(idiomId)});
if(cursor!=null && cursor.moveToFirst()){ String idiomContent = cursor.getString(cursor.getColumnIndex("idiomContent"));
String idiomExplain = cursor.getString(cursor.getColumnIndex("idiomExplain"));
String idiomProv = cursor.getString(cursor.getColumnIndex("idiomProv")); idiom.setIdiomContent(idiomContent);
idiom.setIdiomExplain(idiomExplain);
idiom.setIdiomProv(idiomProv); }
return idiom;
} /**
* 返回某一关卡的Idiom的List集合
* @param cp 关卡对象
*/
@Override
public List<Idiom> getIdioms(CheckPoint cp) {
List<Idiom> idioms = new ArrayList<Idiom>();
Log.i("lujing", "dao层");
Cursor cursor = db.rawQuery("select * from idiom where foreignCheckId=?", new String[]{String.valueOf(cp.getCheckId())}); while(cursor.moveToNext()){
int idiomId = cursor.getInt(cursor.getColumnIndex("idiomId"));
String idiomContent = cursor.getString(cursor.getColumnIndex("idiomContent"));
String idiomExplain = cursor.getString(cursor.getColumnIndex("idiomExplain"));
String idiomProv = cursor.getString(cursor.getColumnIndex("idiomProv")); Idiom idiom = new Idiom(idiomExplain, idiomProv, idiomContent, cp);
idiom.setIdiomId(idiomId);
idioms.add(idiom);
}
cursor.close();
return idioms;
} /**
* 通过Idiom对象。从数据库中得到四个Word对象
* @param idiom 通过idiom获得4个word对象
*/
@Override
public List<Word> getWordsByIdiom(Idiom idiom) {
List<Word> words = new ArrayList<Word>();
Cursor cursor = db.rawQuery("select * from word where foreignIdiomId=?", new String[]{String.valueOf(idiom.getIdiomId())}); while(cursor.moveToNext()){
int wordId = cursor.getInt(cursor.getColumnIndex("wordId"));
String wordContent = cursor.getString(cursor.getColumnIndex("wordContent"));
int wordLevel = cursor.getInt(cursor.getColumnIndex("wordLevel")); Word word = new Word(wordLevel, wordContent.charAt(0), idiom);
word.setWordId(wordId); words.add(word);
}
cursor.close();
return words;
} /**
* 通过id找到word对象
* @param id 通过word的id找到word对象
*/
@Override
public Word findWord(int id) {
Word word = new Word();
word.setWordId(id); Cursor cursor = db.rawQuery("select * from word where wordId=? ", new String[]{String.valueOf(id)});
while(cursor.moveToNext()){
String wordContent = cursor.getString(cursor.getColumnIndex("wordContent"));
int wordLevel = cursor.getInt(cursor.getColumnIndex("wordLevel"));
int foreignIdiomId = cursor.getInt(cursor.getColumnIndex("foreignIdiomId")); Idiom idiom = new Idiom();
idiom = getIdiom(foreignIdiomId);
word.setIdiom(idiom); word.setWordContent(wordContent.charAt(0));
word.setWordLevel(wordLevel); } return word;
} }

然后,我们看下service层的代码:

package cn.idiomlianliankan.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List; import android.content.*;
import android.database.sqlite.SQLiteDatabase; import cn.idiomlianliankan.dao.impl.GameDaoImpl;
import cn.idiomlianliankan.domain.CheckPoint;
import cn.idiomlianliankan.domain.Idiom;
import cn.idiomlianliankan.domain.Word;
import cn.idiomlianliankan.initialize.GameConfigue;
import cn.idiomlianliankan.service.GameService; public class GameServiceImpl implements GameService {
private GameDaoImpl gamedaoImpl;
private SQLiteDatabase db; public GameServiceImpl(Context context,SQLiteDatabase db){
gamedaoImpl = new GameDaoImpl(context,db);
this.db = db;
}
/**
* 返回某一关全部成语相应的word对象集合
*/
@Override
public List<Word> getWords(List<Idiom> idioms) {
List<Word> words = new ArrayList<Word>();
Idiom idiom = new Idiom(); Iterator idiomIterator = idioms.iterator();
while (idiomIterator.hasNext()) {
//得到成语对象
idiom = (Idiom) idiomIterator.next(); if(idiom != null){
//定义一个word的list集合,把一个成语获得的4个word对象加入进入
List<Word> wordList = new ArrayList<Word>();
wordList = gamedaoImpl.getWordsByIdiom(idiom); Word word = new Word();
Iterator wordIterator = wordList.iterator();
while(wordIterator.hasNext()){
word = (Word) wordIterator.next();
words.add(word);
}
}
}
Collections.shuffle(words);
return words;
} /**
* 推断方块是否相连
*/
@Override
public boolean link(Word p1, Word p2, Word p3, Word p4) {
if((p1.getIdiom().getIdiomId() == p2.getIdiom().getIdiomId()) && (p3.getIdiom().getIdiomId() == p4.getIdiom().getIdiomId())){
if((p1.getWordLevel() == 1) && (p2.getWordLevel() == 2) && (p3.getWordLevel() == 3) && (p4.getWordLevel() == 4)){
return true;
}
}
return false;
}
}

最后是“游戏界面”的代码:

package cn.idiomlianliankan.game;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import cn.idiomlianliankan.dao.GameDao;
import cn.idiomlianliankan.dao.impl.GameDaoImpl;
import cn.idiomlianliankan.domain.CheckPoint;
import cn.idiomlianliankan.domain.Idiom;
import cn.idiomlianliankan.domain.Word;
import cn.idiomlianliankan.initialize.GameConfigue;
import cn.idiomlianliankan.service.GameService;
import cn.idiomlianliankan.service.impl.GameServiceImpl;
import android.app.Activity;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast; public class GameViewActivity extends Activity {
//定义数据库对象
SQLiteDatabase db;
//定义service、dao层对象
private GameService service;
private GameDao dao; private TextView textView;
//定义一个word的list集合
private List<Word> ls = new ArrayList<Word>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//初始化数据库对象。打开数据库
db = SQLiteDatabase.openOrCreateDatabase(this.getFilesDir().toString()+ ("/lianliankan.db"), null);
//初始化service层对象
service = new GameServiceImpl(this,db);
//初始化dao层对象
dao = new GameDaoImpl(this,db); //建立一个线性布局
LinearLayout gameView = new LinearLayout(this);
gameView.setOrientation(LinearLayout.HORIZONTAL);
//由createView()函数创建游戏界面
gameView = createView(gameView);
gameView.setPadding(gameView.getLeft()+130, gameView.getTop()+130, gameView.getRight(), gameView.getBottom()); setContentView(gameView);
} /**
* 创建界面的函数
* @param 传递LinearLayout对象
* @return 返回一个创建好界面的LinearLayout对象
*/
private LinearLayout createView(LinearLayout lay) {
//游戏初始资源配置
int x = GameConfigue.getxSize();
int y = GameConfigue.getySize();
int height = GameConfigue.getPieceHeight();
int width = GameConfigue.getPieceWidth(); //这里仅仅是设置了第一关
CheckPoint cp = new CheckPoint(1);
//获得idioms对象,然后再获得words对象
List<Idiom> idioms = dao.getIdioms(cp);
List<Word> words = service.getWords(idioms); Iterator it = words.iterator();
Word singleword = new Word(); for(int i = 1; i< x+1;i++){
final LinearLayout layView=new LinearLayout(this);
layView.setOrientation(LinearLayout.VERTICAL); for(int j = 1;j<y+1; j++){
if(it.hasNext())
{
singleword = (Word)it.next();
}
TextView mTextView = new TextView(this);
mTextView.setHeight(height);
mTextView.setWidth(width); //这里的text就是这个word对象在数据库中的content
mTextView.setText(singleword.getWordContent()+"");
//这里的id就是这个word对象在数据库的id
mTextView.setId(singleword.getWordId()); mTextView.setTextSize(35);
mTextView.setTextColor(Color.GREEN);
mTextView.setBackgroundDrawable(getResources().getDrawable(R.drawable.back)); //设置点击事件监听
mTextView.setOnClickListener(new TextviewOnclickListener()); mTextView.setPadding(mTextView.getLeft()+18, mTextView.getTop()+7, mTextView.getRight(), mTextView.getBottom());
layView.addView(mTextView);
}
lay.addView(layView);
}
return lay;
}
private final class TextviewOnclickListener implements View.OnClickListener{
Iterator it = ls.iterator();
boolean isLink = false; //首先推断ls集合有几个word对象
//有三个对象的话,推断此次点击的和另外三个是否可以链接
//小于三个对象的话。就加入
@Override
public void onClick(View v) {
if(ls.size() == 3)
{
//要推断这四个是否相连
//假设相连的话。消去。然后调用IdiomDetailsActivity界面
//假设不相连的话,取消全部的背景色
Iterator it = ls.iterator(); Word w1 = new Word();
Word w2 = new Word();
Word w3 = new Word();
Word w4 = new Word(); int id = v.getId();
w4 = dao.findWord(id); while(it.hasNext()){
w1 = (Word) it.next();
w2 = (Word) it.next();
w3 = (Word) it.next();
} isLink = service.link(w1, w2, w3, w4);
if(isLink){ //可以组成一个成语
int idiomId = w1.getIdiom().getIdiomId(); setTextView(w1.getWordId());
textView.setVisibility(View.INVISIBLE);
setTextView(w2.getWordId());
textView.setVisibility(View.INVISIBLE);
setTextView(w3.getWordId());
textView.setVisibility(View.INVISIBLE);
setTextView(w4.getWordId());
textView.setVisibility(View.INVISIBLE); //当得到正确的成语的时候,通过这个成语的id从数据库中获得这个成语的全部信息,然后弹出界面显示
Intent intent = new Intent();
intent.setClass(getApplicationContext(), IdiomDetialsActivity.class);
Bundle bundle = new Bundle();
bundle.putString("id",idiomId+"");
intent.putExtra("bd", bundle);
startActivity(intent); }else{
setTextView(w1.getWordId());
textView.setBackgroundDrawable(getResources().getDrawable(R.drawable.back));
setTextView(w2.getWordId());
textView.setBackgroundDrawable(getResources().getDrawable(R.drawable.back));
setTextView(w3.getWordId());
textView.setBackgroundDrawable(getResources().getDrawable(R.drawable.back)); }
ls.clear();
}else{
v.setBackgroundDrawable(getResources().getDrawable(R.drawable.backfu));
//依据这个方块的id查询得到一个word对象
//把查询得到的word对象加入进ls中
int id = v.getId();
Word word = new Word();
word = dao.findWord(id);
ls.add(word);
}
}
} private void setTextView(int id){
textView = (TextView) this.findViewById(id);
} }

详细的解释写在了代码中,能够看下。

事实上工作原理写完了。这个程序应该就非常好理解了。

写出来仅仅是快慢的问题。

有不懂的能够留言~ ~ ~

Android开发系列(十六):【Android小游戏成语连连看】第二篇的更多相关文章

  1. S3C2416裸机开发系列十六_sd卡驱动实现

    S3C2416裸机开发系列十六 sd卡驱动实现 象棋小子    1048272975 SD卡(Secure Digital Memory Card)具有体积小.容量大.传输数据快.可插拔.安全性好等长 ...

  2. Android开发系列(十五):【Android小游戏成语连连看】第一篇

            学了一个多月安卓.由于暑假的时候要给朋友说写个小游戏.并且也想检測下自己的能力,所以说从7号開始就着手写这个小游戏了,前前后后带上课到今天总算是写完了,可是写的这个小游戏还是有非常多问 ...

  3. Android之旅十六 android中各种资源的使用

    android中各种资源的使用: 在android开发中,各种资源的合理使用应该在各自的xml中进行定义,以便反复使用; 字符串资源:strings.xml,xml中引用:@string/XXX,ja ...

  4. Android开发(十六)——Android listview onItemClick事件失效的原因

    参考: Android listview onItemClick事件失效的原因.http://blog.csdn.net/wangchun8926/article/details/8793178

  5. BizTalk开发系列(十六) XML命名空间

    BizTalk开发过程中如果有对XML进行开发操作,比如在自定义代码里操作XML消息或者在Mapping的时候使用Xpath对XML进行操 作.则有机会遇到XML命名空间的问题.常见的是使用Xpath ...

  6. arcgis api for js入门开发系列十六迁徙流动图

    最近公司有个arcgis api for js的项目,需要用到百度echarts迁徙图效果,而百度那个效果实现是结合百度地图的,怎么才能跟arcgis api结合呢,网上搜索,终于在github找到了 ...

  7. arcgis api 3.x for js 入门开发系列十六迁徙流动图

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  8. 【微信小程序开发•系列文章六】生命周期和路由

    这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地方希望读者指出. [微信小程序开发•系列文章一]入门 [微信小程序开发•系列文章二]视图层 [微信小程序开发•系列文章三]数据层 [微信小程 ...

  9. [转]Android Studio系列教程六--Gradle多渠道打包

    转自:http://www.stormzhang.com/devtools/2015/01/15/android-studio-tutorial6/ Android Studio系列教程六--Grad ...

随机推荐

  1. Hadoop入门进阶步步高(二)-文件夹介绍

    二.Hadoop文件夹结构 这里重点介绍几个文件夹bin.conf及lib文件夹. 1.$HADOOP_HOME/bin文件夹 文件名 说明 hadoop 用于运行hadoop脚本命令,被hadoop ...

  2. 84.Node.js -Mongoose 方法

    转自:https://www.cnblogs.com/chris-oil/p/9136534.html Mongoose 参考手册 标签(空格分隔): MongoDB Mongoose 是什么? 一般 ...

  3. json的认识及对json数据的相互转化

    Json 和 Jsonlib 的使用 什么是 Json JSON(JvaScript Object Notation)(官网网站:http://www.json.org/)是 一种轻量级的数据交换格式 ...

  4. koda java

    https://kodejava.org/category/spring/spring-jdbc/

  5. ubuntu 18.04网卡命名规则改回传统的ethx

    自15版本开始网卡命名规则就不叫eth0了.而是用可预期网络接口设备名称的命名规则,比如网卡名为enp3s0 . 如果想要变回ethx也是可以的,参考以下步骤: 1.编辑/etc/default/gr ...

  6. 图像处理是用的数据类型uint8,double

    将原图像的灰度值转换成double的作用主要是考虑计算过程中的精度的问题,double 的数据是有小数点的,而uint8是0-255的整数,如果直接用uint8计算,会在计算过程中产生舍入误差,这种误 ...

  7. flex属性的取值

    首先明确一点是, flex 是 flex-grow.flex-shrink.flex-basis的缩写.故其取值可以考虑以下情况:flex 的默认值是以上三个属性值的组合.假设以上三个属性同样取默认值 ...

  8. NodeJS学习笔记 (14)URL查询字符串-querystring(ok)

    模块概述 在nodejs中,提供了querystring这个模块,用来做url查询参数的解析,使用非常简单. 模块总共有四个方法,绝大部分时,我们只会用到 .parse(). **.stringify ...

  9. NodeJS学习笔记 (24)本地路径处理-path(ok)

    模块概览 在nodejs中,path是个使用频率很高,但却让人又爱又恨的模块.部分因为文档说的不够清晰,部分因为接口的平台差异性. 将path的接口按照用途归类,仔细琢磨琢磨,也就没那么费解了. 获取 ...

  10. [POI2008]PLA-Postering(单调栈)

    题意 N个矩形,排成一排. 现在希望用尽量少的矩形海报Cover住它们. (n<=250000,wi,di<=109) 题解 这种一堆矩形,又不像数据结构的题,一般都是单调栈. 考虑一个贪 ...