首页 > 代码库 > Android开发系列(十六):【Android小游戏成语连连看】第二篇

Android开发系列(十六):【Android小游戏成语连连看】第二篇

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

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


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

工作原理:

“主界面”以及“关卡界面”不多说了,这两个是直接写了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小游戏成语连连看】第二篇