zoukankan      html  css  js  c++  java
  • 汉字先生初学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);
    	}
    }




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










  • 相关阅读:
    v4L2编程
    我的c#开发之路
    JS 获取页面input控件 追加样式属性
    FileUpload控件应用
    C# Winform项目下实现左侧菜单右侧界面显示效果
    在DropDownList 控件绑定数据源中新增一条自定义数据
    在datatable数据中自定义增加一列
    java 实现字符串词频统计
    Hibernate3.x 中BLOB、CLOB 注解配置写法
    lucene 排序
  • 原文地址:https://www.cnblogs.com/nerve/p/3185446.html
Copyright © 2011-2022 走看看