1、android系统的组件和布局,这些基础知识可以开发一些简单应用程序。
2、游戏界面是由大量美工资源图片构成,在设计游戏界面时,
千万不要使用layout布局。不利于界面刷新,事件消息处理。
3、游戏就是通过状态机让canvas不断在View上画我们想要的东西,这些状态机不仅包含游戏内部执行,还包括外部输入,
4、游戏多采用MVC模式,显示界面视图:View和SurfaceView来实现视图, 控制器:用activity实现,最后实现一个逻辑类,专门用来处理游戏的逻辑计算。
5、游戏中的另外一个重要环节就是处理游戏界面和用户交互所发生的事件,比如用户按键,手触屏,
View类提供了onKeyDown。noKeyUp,onKeyMutiple、onKeyPerImeter、onTrackballEvent、onTouchEvent等方法捕捉并处理。
6、在自定义view时重载onDraw方法和上面方法。当有按键按下或谈起等事件时,按键代码会自动传给这些响应的方法处理。
7、游戏的核心是不断地绘图和刷新界面,我们已经通过onDraw方法绘制。刷新界面可以用invalidate。注:invalidate不能直接在线程中调用,因为
它违背了单线程模型:android UI操作不是线程安全,invalidate只能在UI进程中执行,所有android中常用的方法是利用handler来实现UI线程的更新。
public void handleMessage(Message msg) {
switch(msg.what){
case mainActivity.REFLESH:
mview.invalidate();
break;
}
super.handleMessage(msg);
}
};
8.在android中海提供了一个更新界面的方法postInvalidate(),该方法使用起来更加简单,不需要handler,可以直接在线程中更新。
9、surfaceview 主要用来开发复杂的游戏,对速度要求很高的游戏,因为可以使用双缓冲来显示。surfaceview可以直接访问一个画布,提供需要
直接画像素而不是使用窗体部件。,使用surfaceview绘图时,一般都要是出现在最顶层,使用时需要对其创建,销毁,改变情况进行监视,着就需要实现
surfaceHolder。callback接口,如果要对被绘制的画布进行裁剪,控制其大小时都需要使用surfaceHolder来完成,surfaceholder对象
需要通过getHolder方法来获得,同时还需要addCallback方法来添加“回调函数”。surfacechanged 。surfaceCreate。surfaceDestroyed.参考植物大战僵尸。
10、addcallback()添加回调函数,lockCanvas,锁定画布,绘图之前必须锁定画布才能得到当前画布对象
unlockcanvasandpost,绘制完成后解锁并提交,
removecallback,移除回调函数。
11、surfaceview和view不同在于,surfaceview不需要通过线程来更新视图,但在绘制之前必须使用lockcanvas,绘制完之后解锁,于是才能显示在屏幕上。
12、graphic类开发
要开发游戏,必须在屏幕上绘制2d图形,在android中需要通过graphics类来显示2d图形
graphics包括,Canvas 画布,Paint(画笔,Color(颜料 ,Bitmap(图片( 2d 几何图形,
Graphics具有绘制点,线,颜色,图像处理,2d几何图形的功能,下面分别介绍使用。
Paint()的主要方法。:
setAntiAlias();设置画笔的锯齿效果
setColor():设置画笔的颜色。
SetARGB()设置画笔的A R P G 值。
steAlpha()设置Alpha透明度
setTextSize()设置字体大小
setStyle() 设置画笔的风格,空心或实心。
setStrokeWidth() 设置空心的边框宽。
getColor()获得画笔颜色
getAlpha(0获得画笔Alpha值。
*****color类更简单,就是定义了一些颜色常量。以及颜色的转换。主要12种:color.rgb(255,255,255);alpha(范围(0-255)
color。Black、blue. cyan青绿色 Dkgray灰黑色, Gray灰色,Green ,LTGray 浅灰色。red。Transparent透明,while白色。
13、Canvas() ,setCanvas()
Canvas(Bitmap, bitmap)bitmap不能为空
canvas(GL gl) 在绘制3d效果时使用,与OPEnGl相关。
drawColor()设置canvas背景颜色
setBitmap 设置具体画笔
ClipRect()设置显示区域,即裁剪区域,
isOpaque()检测是否支持透明
rotate() 旋转画布
setViewport()设置画布中显示的窗口
Skew设置偏移量
。在游戏中可能要对某个精灵执行旋转,缩放,和其他操作,这是可以通过旋转画布来实心,但旋转画布会旋转所有对象,这时需要
旋转其中一个需要用的save方法来锁定需要操作的对象,操作完之后通过restore方法来解锁。
14,几何图形的绘制,drawRect()绘制矩形
drawCircle() 绘制圆形
drawOval()绘制椭圆
drawPath() 绘制任意多边形
drawLine() 绘制直线
drawPoint()绘制点
15**。 通过ShapeDrawable()来绘制图形,ShapeDrawable(可以设置画布形状,通过getPaint方法可以得到Paint对象,获得的paint对象
可以一样设置颜色,尺寸等熟悉,在ShapeDrawable(中提供了setBounds方法来设置图形显示的区域,最后通过ShapeDrawable的Draw方法将图形显示到屏幕上
16=、、文本,字符串的绘制,
drawtext 绘制字符串,在绘制之前需要设置画布对象属性,使用FontMetrics来规范字体属性,通过getFontMetrics方法来获得系统字体的相关内容。
setTextSize。
steARGB
getTextWidths,取得字符串宽
setFlags(Paint.ANTI_ALIAS_FLAG)消除锯齿
17、图像绘制,BitmapDrawable getResources().getDrawable(资源索引).getBitmap();
canvas。drawBitmap(bitmap,x, y, paint)。
getWidth。getHeight。
18、矩阵的概念,图像的变化,Matrix 旋转时需要一个3x3的矩阵。
缩放matrix 的postScale方法设置缩放倍数
19.图像像素的操作。image.getPixels(bitmap,0,width,0,0,width,height,false,null)
20.shader专门用来渲染图像以及一些几何图形,shader子类,bitmapShader图片渲染,ComposeShader混合渲染,LinearGradient线性渲染,RadialGradient环形渲染,SweepGradient梯度渲染,
21.双缓冲技术,
时游戏开发中的一个重要技术,主要原理:当一个动画争先显示时,程序又在改变它,前面还没有显示完,程序又请求重新绘制,这样会导致
屏幕不停的闪烁,为了解决这个就用到了双缓冲技术,将要处理的图片都在内存中处理好,再将其显示到屏幕上,这样显示处理的就是完整的图像不闪烁。
surfaceView类其实就是一个双缓冲机制,因此开发游戏时可能会比较到使用surfaceview,这样效率高,功能更完善
View的双缓冲实现,核心技术就是先通过setBitmap方法将要绘制的所有图形绘制到一个Bitmap中,然后再来调用drawbitmap
实现代码
public class gameView extends View implements Runable{
Bitmap mBitQQ =null;
Paint mPaint=null;
Bitmap mScBitmap=null;
Cancas mCanvas=null;
public gameView(context contexe){
super(context);
mBitQQ= ((BitmapDrawable)getResources().getDrawable(R.drawable.qq)).getBitmap();
mScBitmap= Bitmap.createBitmap(320,480,Config.ARGB_8888);
mCanvas= new Canvas();
mCanvas.setBitmap(mScBitmap);
mPaint =new Paint();
mCanvas.drawBitmap(mBitQQ,0,0,mPaint);
new Thread(this).start();
}
public void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawBitmap(mScBitmap,0,0,mPaint);
}
public boolean onTouchEvent(MotionEvent event){
return true;
}
public void run(){
while(!Thread.currentThread().isInterrupted()){
try{
Thread.sleep(100);
}catch (){
Thread.currentThread().interrupt();
}
postInvalidate();
}
}
}
22\| 全屏显示 在代码中
requestWindowsFeature(Window.FEATURE_NO_TITLE);//设置无标题栏
//设置为全屏模式。还可以在清单文件的activity的属性中设置theme属性。
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//设置为横屏
获取窗体属性
DisplayMetrics dm =new DisplayMetrics();//定义displayMetrics对象
//取得窗体属性,
getWindowManager().getDefaultDisplay().getMetrics(dm);
int Width=dm.widthPixels;
int Height=dm.heightPixels;
通过加速感应器让应用程序自动适应屏幕模式,在清单文件中
<activity android:name="mainActivity"
android:screenOrientation="sensor"
23、动画
Tween 动画,四种效果:
Alpha 透明度,
Scale 渐变尺寸,
缩放 Translate:画面位置移动,
Rotate:画面旋转。
tween动画可以通过代码编写,但在xml布局中实现更简单,
2).frame动画。帧动画,放电影
AnimationDrawable
也可以在xml中定义,oneshot
gif动画播放
gif图像进行解码,然后每一帧提取出来保存到容器中然后连续绘制被一帧,
主要介绍android游戏开发框架,介绍图形图像绘制和处理,动画实现原理。这些基本能满足游戏开发需求,
游戏开发需要进行大量的图形图像处理,以及动画的实现,以及更复杂大操作,更高级的处理,精灵,粒子,碰撞。等。
手机游戏被业内人士称之为继短信之后的又一座金矿,从2005年开始,全球手机游戏市场一直以每年40%放入速度增长,
游戏的本质就是在屏幕上不断地显示和更新图片,只不过不是胡乱的更新,而是根据程序的逻辑来控制,比如要实现一个主角在地图上移动,
那么只需要将编辑好的地图先绘制到屏幕上,然后再将主角绘制上去,剩下的便是逻辑判断了,再如当我们按下前进时,只需要将主角绘制的
位置向前移动就可以到达目的,(在碰撞检测之后主角能够移动的情况下)。游戏不那么简单,一款完整的游戏需要多方面的知识,
比如游戏的创意,背景,故事情节,游戏音效果,游戏风格,游戏类型,运行速度,适配机型等
而且游戏开发是需要策划,美工,程序,测试,的协同工作,
1、 一款游戏的策划时最重要的,它将直接决定该游戏饿后期制作和玩家的喜好程度,目前游戏飞速发展,所以在策划之前确定市场的需求,。
在抓住用户心理和客户需求之后,就需要考虑游戏的类型,从大的方面说,游戏时单机,还是联网的。时单人的还是多人的,时动作类型的还是角色扮演类型的,等
在确定了游戏类型之后还需要考虑游戏的可玩性,这就需要考虑游戏的难度设置,关卡控制以及后期的版本控制。
现在我们就可以根据上面的客户和游戏类型来定义游戏的风格了,体现游戏的真实性的同时,游戏本身又是虚幻的东西,玩家把自己放入虚拟世界中
态真实就感到枯燥,需要加上自己的创新,加上美丽的背景和音乐。音效,然后就可以准备写策划方案了,在写方案同时需考虑美工和程序的技术上的
实现和硬件的支持,
2美工拿到策划方案文档之后,根据策划文档发挥自己的想象力,在保持策划一致的情况下进行创新,同时多与程序员交流以确保程序员能很清楚地理解自己的设计,
3,程序员在拿到文档和资源之后不要马上就打开编辑器编辑,而要仔细看文档和资源,根据这些来确定所使用的知识和所实现的功能,然后构建一个整体的框架,
这个整体的框架很重要,一个优秀的程序员会再框架的设计上花很多时间,因为一个号的框架可以使后面的开发,调试更加简单,同时一个好的框架能提高游戏的运行
效率,为了保证质量,每个程序员写的程序都有bug所以我们需要不断地测试,修改,在测试在修改,从而接玩家一个最好的体验,
魔塔游戏流程:
24;游戏开发中的技术,地图,精灵,图层,音效,存档,
游戏中包括地图,主角,整个屏幕,地图和主角的属性,道具,至少需要一个视图显示,并且需要更新界面显示,和一个控制游戏逻辑及事件的类,
1)构建视图类,主要绘制方法noDraw,和事件处理onKeyDown onKeyUp onTouch,同时可以加入自己的一些抽象的方法,比如资源回收,(recycle ,refurbish刷新)
2)有理这些就可以构建一个用显示游戏界面的视图类GameView,当该游戏也不只是这么一个界面,还有菜单页,道具商店,战斗战场,等各个场景
所以这个类应该是一个抽象类,abstract,可以被各个界面使用,GameView类如下:
public abstract class GameView extends View{
public GameView(Context context){
super(context);
}
//绘图
protected abstract void onDraw(Canvas canvas);
//按键按下
public abstract boolean onKeyDown(int KeyCode);
//按键弹起
public abstract boolean onKeyUp(int KeyCode);
public abstract boolean onTouchMotion(motionEvent event);
//回收资源
protected abstract void reCycle();
//刷新屏幕
protected abstract void refurbish();
}
有了视图类来显示界面,还要控制当前屏幕显示哪一个界面,甚至对界面进行一些逻辑上的处理,这时就可以构建一个整个游戏逻辑的MainGame类,在该类中需要根据不同的游戏状态来设置屏幕
需要显示的视图,
gameView mgameview=null;
int mstatus
public void controlView(int status){
//当状态改变时,释放上一个状态的资源
if(mstatus!=status){
if(mgameview!=null){
mgameview.reCycle();
System.gc();
}
}
//释放当前视图对象
freeGameView(mgameview);
//根据不同的游戏状态判断当前屏幕显示的界面,当然这些界面都需要继承自我们上面所创建的GameView
switch(status){
case config.GAME_SPLASH:
mgameview=new SplashScreen(mcontext,this);
break;
case config.GAME_MENU:
mgameview=new MainMenuScreen(mcontext,this);
break;
case config.GAME_HELP:
mgameview=new HelpScreen(mcontext,this);
break;
case config.GAME_ABOUT:
mgameview=new AboutScreen(mcontext,this);
break;
case config.GAME_RUN:
mgameview=new GameScreen(mcontext,magicTower,this,true);
break;
case config.GAME_CONTINUE:
mgameview=new GameScreen(mcontext,magicTower,this,false);
break;
}
setStatus(status);
//得到当前需要显示的对象,以便让其他类使用
public static GameView getMainView(){
return mgameview;
}
}
在创建和控制了视图显示之后,我们就要让游戏能够活起来,需要开启一个线程来实现更新视图显示并刷新视图的方法,下面我们将为游戏开启一个主线程,
可以通过MainGame.getMainView()方法来取得当前显示的视图界面,然后根据不同的界面来进行游戏更新,,本例采用postInvalidate()方法来刷新界面
public Class ThreadCanvas extends View implements Runnable{
private String mTag="ThreadTag";
public ThreadCanvas(Context context){
super(context);
}
//绘制界面
protected void onDraw(Canvas canvas){
if(MainGame.getMainView()!=null){
MainGame.getMainView().onDraw(canvas);
}else{
Log.i(mTag,"null");
}
//开启线程
public void start(){
Thread t=new Thread(this);
t.start();
}
//刷新界面
public void refurbish(){
if(MainGame.getMainView()!=null){
MainGame.getMainView().refurbish();
}
}
public void run(){
while(true){
try{
Thread.sleep(config.Game_loop);
}catch (Exception e){
e.printStackTrace();
}
refurbish();//更新显示
postInvalidate();//刷新屏幕
}
}
//按键按下处理
boolean onKeyDown(int keyCode){
if(MainGame.getMainView()!=null){
MainGame.getMainView().onKeyDown(keyCode);
}else{
log.i(mTag,"null");
}
return true;
}
}
//按键弹起处理
boolean onKeyDown(int keyCode){
if(MainGame.getMainView()!=null){
MainGame.getMainView().onKeyUp(keyCode);
}else{
log.i(mTag,"null");
}
return true;
}
}
}
3)、在完成这些模块之后就需要通知一个Activity来显示界面,这里我们是在ThreadCanvas中控制界面的显示
所以使用setContentView方法来显示一个ThreadCanvas类对象即可,当然按键事件的处理也就可以调用ThreadCanvas类来处理,
ThreadCanvas类会和MainGame 一起配合来找到我们所指定的界面,
public class MagicTower extends Activity{
private ThreadCanvas mthreadCanvas=null;
public void onCreate(Bundle savaInstanceState){
super.onCreate();
new MainGame(this);
setContentView(mthreadCanvas);
}
}
到这里为止我们基本上完成了一个游戏的整体的框架,后面的所有视图类界面显示都需要继承自我们自定义的抽象类GameView,
然后再MainGame中判断和更改当前游戏的状态,程序便自动找到我们需要更新和释放的视图类然后进行操作,