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);
}
}
这里就只介绍这么多了。有兴趣的可以下载看看:
下载源代码
分享到:
相关推荐
Google.Android开发入门与实战,Android 精通Android游戏开发,3G应用开发之Android,15个Android很有用的代码片 段,Android 图像处理篇,Android_CTS测试研,GoogleMaps基础开发教程,Android_GPS架构分析,android_JNI...
Google.Android开发入门与实战,Android 精通Android游戏开发,3G应用开发之Android,15个Android很有用的代码片 段,Android 图像处理篇,Android_CTS测试研,GoogleMaps基础开发教程,Android_GPS架构分析,android_JNI...
1. "Android中文翻译组——Android中文API合集(3).chm":这可能是一份详尽的Android API参考手册,包含了大量的类、方法和接口的中文解释,是开发Android应用时的重要参考资料。 2. "从零开始OPhone游戏编程.pdf...
Android小项目合集(经典教程) 看到很强大的实例----高仿【优酷】圆盘旋转菜单 的实现 如何利用手机摄像头拍照 android 播放gif图片 DEMO Android图片浏览之源码 图片浏览器android源码下载 Android瀑布流加载...
### Android开发基础知识详解 #### 一、Android的背景与历史 - **名称由来**:Android的名字来源于希腊语,意为“机器人”。它的英文名Andy是Andrew的昵称,中文通常译为“安卓”。 - **诞生与发展**:2007年11月5...
**Android 3D引擎 JPCT-AE JAR包与API详解** JPCT-AE(Java 3D Engine - Android Edition)是一款专为Android平台设计的3D图形引擎,它允许开发者在Android应用中创建和展示复杂的3D模型和场景。这款引擎基于Java...
在使用易语言开发射击小游戏时,需要注意以下几个技术要点: - **图形界面操作**:利用易语言内置的图形库绘制游戏界面。 - **事件驱动编程**:响应用户输入和其他游戏事件,如定时器事件,来更新游戏状态。 - **...
本学习资料集汇聚了丰富的Android开发资源,旨在帮助初学者快速掌握Android开发技能,同时也为有经验的开发者提供进阶知识。 一、Apress.Android.Essentials.Jul.2008.7z 这本书籍《Android Essentials》(2008年7...
- **第四部分:扩展与发布**:包括了如何使用多点触控、开发桌面小部件和动态壁纸,以及如何确保应用兼容不同Android设备和版本,并将其发布到Android市场上。 ### 总结 《Hello, Android》这本书按照从易到难的...
### Box2D中文教程知识点概览 #### 一、Box2D简介 - **Box2D**是一款2D物理引擎,主要用于游戏开发中物体的物理模拟。它通过提供逼真的物体运动效果,使得游戏世界更加生动有趣。Box2D的核心功能在于能够模拟刚体的...
【标题】"fang_java_beneathtx5_DEMO_小游戏_塔防源码_" 提供的是一款基于Java编程语言的塔防小游戏源代码,它使用了BeneathTX5框架,适合初学者和开发者学习游戏开发。DEMO级别意味着这是一个简化版的示例,可能...
B4A,全称Basic4Android,是一款基于Basic语言的Android应用开发工具,它为开发者提供了一种简单易懂的编程语法,使得Android应用开发变得更加容易。在国内,B4A的学习资源相对匮乏,中文教程尤为稀少,因此,能够...
近几年非常流行的一个 3D游戏开发引擎(特别是移动平台),它的特点是跨平台能力强,支持 PC、Mac、Linux、网页、 iOS、Android等几乎所有的平台,移植便捷,3D图形性能出众,为众多游戏开发者所喜爱。功能强大,...
它主要使用TypeScript和JavaScript作为编程语言,并且提供全中文的文档和配套工具,适合初学者和小游戏开发者。然而,Egret支持的平台相对较少,且主要用于开发对性能和效率要求不高的小游戏。 在游戏开发中,使用...
### AndEngine中文文档知识点概述 #### 一、AndEngine简介 AndEngine是一款专注于Android平台的2D游戏开发引擎,利用...无论是初学者还是经验丰富的开发者,都能从AndEngine中受益,构建出令人满意的Android游戏作品。
### Unity3D中文手册知识点概览 #### 一、用户指南 **1.1 Unity基础 (Unity Basics)** - **1.1.1 学习界面** - Unity的主界面设计直观,主要包括菜单栏、工具栏、项目视图、层次视图、检视视图、场景视图等几个...
它支持将多个小图合并成一个大图(纹理 atlas),并生成对应的配置文件(如plist和pvr文件),这些文件在游戏运行时会被引擎读取,用于快速绘制屏幕上的多个精灵。 1. **Texture Atlas原理**:Texture Atlas是一种...