`
ssrc0604hx
  • 浏览: 8912 次
文章分类
社区版块
存档分类
最新评论

汉字先生-----初学android时做的小游戏

 
阅读更多

12年初,开始接触android,看的书是:[Android.游戏开发入门](美)Mario.Zechner.插图版

一边看一边做了这个小游戏,是以选择两个字形组成一个完整的汉字来进行游戏的。

目前只有两种模式:

标准模式:在规定时间内成功组合指定个数的汉字

渡水模式:游戏中,会有一匹白马一直向前行进,如果白马进水游戏便会失败。玩家需要组合汉字使得白马脚下的木桥延长,木桥覆盖过小河游戏便胜利!共5关。


画面比较粗糙,毕竟没有那个美工细胞=.=

整个程序还是有不少问题的,也有很多用户体验不好的地方,大家也理解一下哈。


先看一下截图:




下面是工程结构:


游戏中应用 [Android.游戏开发入门](美)Mario.Zechner一书中介绍的游戏框架,我也对框架进入了适当的修改,以更好地适应自己的游戏。游戏只有一个Activity,继承框架中的DTGame.java 类,游戏中的界面都是Screen的子类,DTGame通过调用 getScreen()获取当前的游戏界面进行绘图。在游戏中可以调用DTGame的setScreen(new Screen())方法来切换界面。整个游戏都只在SurfaceView中更新视图,在框架中GameSurfaceView.java继承 SurfaceView并开启一个线程,调用DTGame中的 getScreen()得到当前Screen对象,调用Screen中的draw()和update()方法。


下面是 自己定义的Activity,继承DTGame:

package cn.dt.mr_cc;

import android.app.ProgressDialog;
import android.app.Service;
import android.os.Handler;
import android.os.Vibrator;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.widget.Toast;
import cn.dt.mr_cc.screen.LoadScreen;
import dt.humen.game.GM;
import dt.humen.game.Screen;
import dt.humen.game.core.impl.DTGame;

public class MrCCActivity extends DTGame {
	
	protected WebView webView=null;//加载html的容器
	protected View aboutView;//关于的视图
	protected boolean gameing=true;//是否在游戏界面中
	protected ProgressDialog progressDialog;
	
	private Handler handler=new Handler(){
		public void handleMessage(android.os.Message msg) {
			switch(msg.what){
			case Constant.GAME_EXIT:
				beforeExit();
				break;
			case Constant.SHOW_INFO:
				Toast.makeText(MrCCActivity.this,msg.getData().getString(Constant.MESSAGE), 4000).show();
				break;
			case Constant.ToAbout:
				toAbout();
				break;
			case Constant.ToMenu:
				toGame();
				break;
			case Constant.LOADING_SHOW:
				progressDialog.show();
				break;
			case Constant.LOADING_HIDE:
				progressDialog.hide();
				break;
			case Constant.VIBRATOR_DEF:
				vibrate(300);
				break;
			case Constant.VIBRATOR_LONG:
				vibrate(1000);
				break;
			}
		}
	};
	
	@Override
	protected void onCreate(android.os.Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		startMyGame();
	}
	
	public void startMyGame(){
		//设置进度条
		progressDialog=new ProgressDialog(this);
		progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		progressDialog.setMessage("加载中...");
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(!gameing){
			handler.sendEmptyMessage(Constant.ToMenu);
			return false;
		}
		return super.onKeyDown(keyCode, event);
	}
	
	@Override
	public void onResume() {
		super.onResume();
		if(Asset.bgMusic!=null)
			Asset.bgMusic.play();
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		if(Asset.bgMusic!=null)
			Asset.bgMusic.pause();
	}
	
	@Override
	public void finish() {
		if(Asset.bgMusic!=null)
			Asset.bgMusic.stop();
		Asset.bgMusic=null;
		super.finish();
	}

	@Override
	public Screen getStartScreen() {
		return new LoadScreen(this);
	}
	
	@Override
	public void afterCreate() {
		//首先加载背景图片
		Asset.background=GM.loadBitmap("imgs/bg.jpg");
		//设置进度条的颜色
		this.getGameBar().barColor=Constant.CELL_COLOR;
	}
	
	@Override
	public Handler getHandler() {
		return handler;
	}
	
	private void toAbout(){
		if(aboutView==null){
			handler.sendEmptyMessage(Constant.LOADING_SHOW);
			LayoutInflater lif=LayoutInflater.from(MrCCActivity.this);
			aboutView=lif.inflate(R.layout.about, null);
			webView=(WebView)aboutView.findViewById(R.id.webview);
			webView.setWebChromeClient(new WebChromeClient(){
				@Override
				public void onProgressChanged(WebView view, int newProgress) {
					if(newProgress==100)
						handler.sendEmptyMessage(Constant.LOADING_HIDE);
					super.onProgressChanged(view, newProgress);
				}
			});
			webView.loadUrl("file:///android_asset/html/about.html");
		}
		gameView.pause();
		gameing=false;
		setContentView(aboutView);
	}
	
	private void toGame(){
		gameView.resume();
		gameing=true;
		setContentView(gameView);
	}
	
	public void vibrate(long ms){
		if(Setting.vibrateAble){
			Vibrator v=(Vibrator)getSystemService(Service.VIBRATOR_SERVICE);
			v.vibrate(ms);
		}
	}
}


框架中的GameSurfaceView类:

package dt.humen.game;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import dt.humen.game.core.impl.DTGame;

/**
 *这个surfaceView 只负责显示
 *
 * @创建者 :集成显卡	1053214511@qq.com
 * @创建日期 :2012-1-26
 * @修改记录 :
 */
public class GameSurfaceView extends SurfaceView implements Runnable{
	public DTGame game;
	public Bitmap gameBuffer;
	public SurfaceHolder holder;
	public Thread thread;
	
	public int sleep=0;//线程间隔
	
	public boolean running=false;//游戏是否在进行
	
	public GameSurfaceView(DTGame game,Bitmap map) {
		super(game);
		this.game=game;
		this.gameBuffer=map;
		this.holder=getHolder();
	}
	
	/**
	 * 游戏恢复时
	 *	
	 *  @date :2012-1-23
	 */
    public void resume() { 
        running = true;
        thread = new Thread(this);
        thread.start();
        System.out.println("线程开启!---->");
    }
    
    /**
     * 游戏暂停时
     *	
     *  @date :2012-1-23
     */
    public void pause() {                        
        running = false;
        System.out.println("线程暂停!---->");
        while(true) {
            try {
                thread.join();
                break;
            } catch (InterruptedException e) {
            }
        }
    }

	@Override
	public void run() {
		Rect rect=new Rect();
		while(running){
			//如果没有可用的外观,就直接跳过
			if(!holder.getSurface().isValid())
				continue;
			//让game的画面更新
			game.getScreen().update();
			game.getScreen().draw();
			
			//将更新后的画布画到屏幕上
			Canvas canvas=holder.lockCanvas();
			canvas.getClipBounds(rect);
			//将gameBuffer 这个 bitmap 画到屏幕上
			canvas.drawBitmap(gameBuffer, null, rect, null);
			holder.unlockCanvasAndPost(canvas);
			try{
				Thread.sleep(sleep);
			}catch(Exception r){}
		}
	}
	
	public void setSleep(int time){
		this.sleep=time;
		if(sleep<0)
			sleep=0;
	}
}

每个Screen都要重写Screen的draw和update方法,前者是绘图,后者是事件处理,这里贴出游戏主菜单 MenuScreen.java 的代码:

package cn.dt.mr_cc.screen;

import java.util.List;

import cn.dt.mr_cc.Asset;
import cn.dt.mr_cc.Constant;
import cn.dt.mr_cc.Setting;
import dt.humen.game.Screen;
import dt.humen.game.core.Game;
import dt.humen.game.unit.Cell;
import dt.humen.game.unit.Point;
import dt.humen.io.Input;
import dt.humen.io.Input.TouchEvent;

public class MenuScreen extends Screen{
	public int count=0;
	private Cell startCell;
	private Cell exitCell;
	private Cell optionCell;
	private Cell aboutCell;
	
	public MenuScreen(Game game) {
		super(game);
		init();
	}
	
	private void init(){
		startCell=new Cell(120, 360,Asset.startBtn,Asset.selectSound);
		exitCell=new Cell(120, 360, Asset.exitBtn,Asset.selectSound);
		optionCell=new Cell(120,360,Asset.optionBtn,Asset.downSound);
		aboutCell=new Cell(120,360,Asset.aboutBtn,Asset.selectSound);
		
		//开始动画!
		exitCell.getAnimate().setEndPoint(new Point(230,360)).start(350);
		optionCell.getAnimate().setEndPoint(new Point(160,400)).start(350);
		aboutCell.getAnimate().setEndPoint(new Point(10,360)).start(350);
		startCell.getAnimate().setEndPoint(new Point(80,400)).start(350);
	}

	@Override
	public void dispose() {
	}

	@Override
	public void pause() {
	}

	@Override
	public void draw() {
		game.getCanvas().drawBitmap(Asset.background, 0, 0, null);
		game.getCanvas().drawBitmap(Asset.logoPNG, 15, 30, null);
		
		startCell.draw(game.getCanvas());
		exitCell.draw(game.getCanvas());
		optionCell.draw(game.getCanvas());
		aboutCell.draw(game.getCanvas());
	}

	@Override
	public void resume() {
		
	}

	@Override
	public void update() {
		List<TouchEvent> list=game.getInput().getTouchEvents();
		if(list.size()==0)
			return ;
		TouchEvent e=list.get(0);
		if(e.type==Input.TOUCH_DOWN){
			//判断是否按下了菜单按钮
			//说明
			if(aboutCell.isClick(e.x, e.y,Setting.soundAble)){
				toAbout();
			}
			//开始
			else if(startCell.isClick(e.x, e.y,Setting.soundAble)){
				game.setScreen(new SelectScreen(game));
			}
			else if(optionCell.isClick(e.x, e.y,Setting.soundAble)){
				game.setScreen(new SettingScreen(game));
			}
			//退出
			else if(exitCell.isClick(e.x, e.y,Setting.soundAble)){
				/*
				 * 因为是线程里面更新UI,需要使用Looper帮助
				 * 还可以使用handler机制,给Activity传递一个Message然后更新UI
				 * 
				 * ps:
				 * 使用Looper会产生一个bug:当点击退出按钮时,可以成功退出,但是两次打开程序时会失去响应!
				 * 用Handler就没有问题
				 */
				//Looper.prepare();
				game.getHandler().sendEmptyMessage(Constant.GAME_EXIT);
				//Looper.loop();
			}
		}
	}
	
	private void toAbout(){
		game.getHandler().sendEmptyMessage(Constant.ToAbout);
	}
}




这里就只介绍这么多了。有兴趣的可以下载看看:下载源代码










分享到:
评论

相关推荐

    Android 初学中阶高阶书籍_集合打包2

    Google.Android开发入门与实战,Android 精通Android游戏开发,3G应用开发之Android,15个Android很有用的代码片 段,Android 图像处理篇,Android_CTS测试研,GoogleMaps基础开发教程,Android_GPS架构分析,android_JNI...

    Android 初学中阶高阶书籍_集合打包3

    Google.Android开发入门与实战,Android 精通Android游戏开发,3G应用开发之Android,15个Android很有用的代码片 段,Android 图像处理篇,Android_CTS测试研,GoogleMaps基础开发教程,Android_GPS架构分析,android_JNI...

    两本书一个小游戏(android)

    1. "Android中文翻译组——Android中文API合集(3).chm":这可能是一份详尽的Android API参考手册,包含了大量的类、方法和接口的中文解释,是开发Android应用时的重要参考资料。 2. "从零开始OPhone游戏编程.pdf...

    android开发资料大全

    Android小项目合集(经典教程) 看到很强大的实例----高仿【优酷】圆盘旋转菜单 的实现 如何利用手机摄像头拍照 android 播放gif图片 DEMO Android图片浏览之源码 图片浏览器android源码下载 Android瀑布流加载...

    Android开发15分钟扫盲.pdf

    ### Android开发基础知识详解 #### 一、Android的背景与历史 - **名称由来**:Android的名字来源于希腊语,意为“机器人”。它的英文名Andy是Andrew的昵称,中文通常译为“安卓”。 - **诞生与发展**:2007年11月5...

    android 3D引擎 JPCT-AE jar包及API

    **Android 3D引擎 JPCT-AE JAR包与API详解** JPCT-AE(Java 3D Engine - Android Edition)是一款专为Android平台设计的3D图形引擎,它允许开发者在Android应用中创建和展示复杂的3D模型和场景。这款引擎基于Java...

    易语言源码易语言射击小游戏1.0源码

    在使用易语言开发射击小游戏时,需要注意以下几个技术要点: - **图形界面操作**:利用易语言内置的图形库绘制游戏界面。 - **事件驱动编程**:响应用户输入和其他游戏事件,如定时器事件,来更新游戏状态。 - **...

    android学习资料集

    本学习资料集汇聚了丰富的Android开发资源,旨在帮助初学者快速掌握Android开发技能,同时也为有经验的开发者提供进阶知识。 一、Apress.Android.Essentials.Jul.2008.7z 这本书籍《Android Essentials》(2008年7...

    HelloAndroid第三版(翻译到第七章)

    - **第四部分:扩展与发布**:包括了如何使用多点触控、开发桌面小部件和动态壁纸,以及如何确保应用兼容不同Android设备和版本,并将其发布到Android市场上。 ### 总结 《Hello, Android》这本书按照从易到难的...

    box2d中文教程.pdf

    ### Box2D中文教程知识点概览 #### 一、Box2D简介 - **Box2D**是一款2D物理引擎,主要用于游戏开发中物体的物理模拟。它通过提供逼真的物体运动效果,使得游戏世界更加生动有趣。Box2D的核心功能在于能够模拟刚体的...

    fang_java_beneathtx5_DEMO_小游戏_塔防源码_

    【标题】"fang_java_beneathtx5_DEMO_小游戏_塔防源码_" 提供的是一款基于Java编程语言的塔防小游戏源代码,它使用了BeneathTX5框架,适合初学者和开发者学习游戏开发。DEMO级别意味着这是一个简化版的示例,可能...

    国内学习B4A(Basic4Android)的中文版教程很少,也没有多少交流论坛,学号这个资料很不错

    B4A,全称Basic4Android,是一款基于Basic语言的Android应用开发工具,它为开发者提供了一种简单易懂的编程语法,使得Android应用开发变得更加容易。在国内,B4A的学习资源相对匮乏,中文教程尤为稀少,因此,能够...

    UnitySetup32-5.6.6f2.exe

    近几年非常流行的一个 3D游戏开发引擎(特别是移动平台),它的特点是跨平台能力强,支持 PC、Mac、Linux、网页、 iOS、Android等几乎所有的平台,移植便捷,3D图形性能出众,为众多游戏开发者所喜爱。功能强大,...

    游戏开发:目前商业上流行的游戏引擎详细比较

    它主要使用TypeScript和JavaScript作为编程语言,并且提供全中文的文档和配套工具,适合初学者和小游戏开发者。然而,Egret支持的平台相对较少,且主要用于开发对性能和效率要求不高的小游戏。 在游戏开发中,使用...

    AndEngine中文文档

    ### AndEngine中文文档知识点概述 #### 一、AndEngine简介 AndEngine是一款专注于Android平台的2D游戏开发引擎,利用...无论是初学者还是经验丰富的开发者,都能从AndEngine中受益,构建出令人满意的Android游戏作品。

    unity3d_book

    ### Unity3D中文手册知识点概览 #### 一、用户指南 **1.1 Unity基础 (Unity Basics)** - **1.1.1 学习界面** - Unity的主界面设计直观,主要包括菜单栏、工具栏、项目视图、层次视图、检视视图、场景视图等几个...

    Texture packer 2.3.5.win32 免费安装包和中文教程

    它支持将多个小图合并成一个大图(纹理 atlas),并生成对应的配置文件(如plist和pvr文件),这些文件在游戏运行时会被引擎读取,用于快速绘制屏幕上的多个精灵。 1. **Texture Atlas原理**:Texture Atlas是一种...

Global site tag (gtag.js) - Google Analytics