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...
Android小项目合集(经典教程) 看到很强大的实例----高仿【优酷】圆盘旋转菜单 的实现 如何利用手机摄像头拍照 android 播放gif图片 DEMO Android图片浏览之源码 图片浏览器android源码下载 Android瀑布流加载...
余志龙、陈昱勋、郑名杰、陈小风,分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言...
余志龙、陈昱勋、郑名杰、陈小风,分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言...
余志龙、陈昱勋、郑名杰、陈小风,分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言...
《重视大脑的学习指南:Head First Python(中文版)》介绍了Python的动态存储数据的唯一方法、构建基于Python的Web服务器和Web应用程序、在Android平台上编写移动的应用程序、使用PyGame和PyKyra来开发复杂的游戏、 ...
廖雪峰 python3 教程这是小白的Python新手教程,具有如下特点: 中文,免费,零起点,完整示例,基于最新的Python 3版本。 Python是一种计算机程序设计语言。你可能已经听说过很多种流行的编程语言,比如非常难学的...
此时此景,笔者只专注Android、Iphone等移动平台开发,看着这些源码心中有万分感慨,写此文章纪念那时那景! Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这...
有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...
对初学者来说,入门不难,专家们可以利用它的高端功能。查阅方便教程。快速创建交互式动画、 游戏、 应用程序、 演示文稿、 广告、 网站和更多。 容易学 Hippo Animator 使用直观的时间线系统。添加关键帧和声音。...