1. 程式人生 > >《Android遊戲程式設計之從零開始》筆記

《Android遊戲程式設計之從零開始》筆記

一、遊戲開發基礎
1.快速進入android遊戲開發
自學、demo、問題、百度&Google
2.遊戲簡單概括
    View   Canvas   Paint   重新整理
3.遊戲開發常用三種檢視
     View ——>SurfaceView   2D——>  GLSurfaceView    3D
4.View遊戲框架
    a.繪圖函式onDraw
繪製圖形、圖片等函式都在畫布類中。
    b.設定全屏主要操作:隱去狀態列部分、隱去標題欄部分。
    c。按鍵監聽  onKeyDown、onKeyUp
         觸屏監聽    onTouchEvent
         setFocusable(true)焦點生效
 	 重新繪製畫布  invalidate()  和  postInvalidate()
         觸屏監聽動作:按下、擡起、移動、螢幕壓力、多點觸屏等。
   setFocusableInTouchMode(true)
5.SurfaceView遊戲框架
    a。implements    SurfaceHolder.Callback  控制SurfaceView的大小、格式等
    b。通過SurfaceViewHolder的lockCanvas()函式獲取Canvas物件,加鎖
    c。unlockCanvasAndPost函式用於解鎖畫布和提交
    d。重新整理畫布
   第一種   每次繪圖之前,繪製一個等同於螢幕大小的圖形覆蓋畫布上。
    canvas.drawRect(0,0,this.getWidth(),this.getHeigt(),paint);
    第二種   每次繪圖之前,在畫布上填充一種顏色
    canvas.drawColor(Color.BLACK);
    第三種    每次繪圖之前,指定RGB來填充畫布
    canvas.drawRGB(0,0,0);
     第四種   每次繪圖之前,繪製一張等同於螢幕大小的圖片覆蓋在畫布上。
                 6.SurfaceView檢視新增執行緒
                     固定時間重新整理畫布比如倒計時、動態花草、流水、怪物、錢幣等。
 設計一個執行緒不停去重繪畫布,實時更新遊戲元素狀態。
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable{
	private SurfaceHolder sfh;
	private Paint paint;
	private int textX =10,textY = 10;
	private Thread thread;
	private boolean flag;
	private Canvas canvas;
	private int screenW,screenH;
	public MySurfaceView(Context context) {
		super(context);
		sfh = this.getHolder();
		sfh.addCallback(this);
		paint = new Paint();
		paint.setColor(Color.WHITE);
		setFocusable(true);
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO 檢視建立,響應此函式
		screenW = this.getWidth();
		screenH = this.getHeight();
		flag = true;
		thread = new Thread(this);
		thread.start();
	}
	/**
	 * 遊戲繪圖
	 */
	public void myDraw(){
		try {
			canvas = sfh.lockCanvas();
			if (canvas!= null) {
				//利用繪製矩形的方式刷屏
//				canvas.drawRect(0,0,this.getWidth(),this.getHeight(), paint);
				//利用RGB的方式刷屏
				canvas.drawRGB(0, 0, 0);
				canvas.drawText("Game", textX, textY, paint);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			if (canvas!= null) {
				sfh.unlockCanvasAndPost(canvas);
			}
		}
		
	}
	/**
	 * 遊戲邏輯
	 */
	private void logic(){
	}
	@Override
	public boolean onTouchEvent(android.view.MotionEvent event) {
		textX = (int) event.getX();
		textY = (int) event.getY();
		return true;
	}
	@Override
	public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
		return super.onKeyDown(keyCode, event);
	}
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		flag = false;
	}

	@Override
	public void run() {
		while(flag){
			long start = System.currentTimeMillis();
			myDraw();
			logic();
			long end = System.currentTimeMillis();
			try {
				if (end - start <50) {
					Thread.sleep(50-(end-start));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}
 1).執行緒標識位       便於消亡執行緒,防止重複建立執行緒
 2).獲取檢視的寬和高  this.getWidth和this.getHeight
 3).繪圖函式try一下
        4).提交畫布必須放在finally中
         5).刷幀時間儘可能保持一致
     6.View與SurfaceView的區別
   a。SurfaceView不會出現因主UI執行緒阻塞影響按鍵觸屏等問題。
   b。SurfaceView檢視有雙緩衝機制
   c。棋牌類遊戲適合View,動態類遊戲適合SurfaceView
      7.Bitmap點陣圖的渲染與操作
    BitmapFactory.decodeResource()通過資原始檔生成一張點陣圖
    canvas.save()儲存當前畫布狀態
    canvas.restore()回覆上次儲存的畫布狀態
8.遊戲開發中常用png圖片,支援透明度。
9.剪下區域    由畫布進行設定
  第一種  矩形可視區域canvas.clipRect()
 path.addCircle(30,30.30,Direction.CCW);canvas.clipRect(path);利用path設定可視區域
   設定剪下區域前需要儲存畫布的狀態。
  第二種  利用Regin對畫布設定可視區域
       10. 動畫
      角色的移動,爆炸的效果,過場的特效等。
Animation的每種動畫都是對畫布操作
Animation.AnimationListener
第一種  系統動畫特效
AlphaAnimation、ScaleAnimation、TranslateAnimation、RotateAnimation
第二種   自定義動畫
a 在遊戲邏輯處理中調整x和y軸座標  
b 利用幀動畫
c  剪下圖動畫   最常用
    動態物體的動作幀全部放在一張圖片中,通過設定可視區域完成。
                11.遊戲適屏
                      利用檢視和螢幕寬高獲取x和y座標
  當想要用按下人物一直動的效果時,View的onKeyDown和onKeyUp一起用
  設定private boolean isUP,isDown,isLeft,isRight
  分別在onKeyDown函式中設定isUP,isDown,isLeft,isRight為true
  和在onKeyUp函式中設定isUP,isDown,isLeft,isRight為false
    12。碰撞檢測
         a、矩形碰撞,利用兩個矩形之間的位置進行判斷,如果一個矩形的畫素在另外一個矩形之中,或者之上,就可以認為這兩個矩形發生了碰撞。
         b。圓形碰撞,利用兩圓的圓心距進行判定,當兩圓的圓心距小於兩圓半徑之和時,判定發生了碰撞。
          c。畫素碰撞,以上兩種方式碰撞不精確。但不推薦使用。
首先遍歷算出一張點陣圖所有的畫素點座標,然後與另外一張點陣圖上的所有點座標進行對比,一旦有一個畫素點座標相同,
   d。多矩形碰撞  多個矩形碰撞區域
   e。Region碰撞
        判斷一個點是否在矩形區域內。使用Region類中的contains函式
    13.遊戲音樂與音效
           播放遊戲背景音樂MediaPlayer   遊戲音效類 SoundPool
                        a。MediaPlayer
                            prepare()、start()、pause()、stop()
        setLooping()、seekTo()、getDuration()、getCurrentPosition()
   b。AudioManager音樂管理類,音量大小等
    setStreamVolume()、getStreamVolume()、getStreamMaxVolume()
          c。MediaPlayer.OnCompletionListerner  監聽音樂是否播放完畢
SoundPool類  只能播放小的檔案
   MediaPlayer優缺點
   1)缺點:資源佔用較高,延遲時間較長,不支援多個音訊同時播放等。
快速連續播放聲音,會有明顯的1-3s的延遲。可通過seetTo()解決。
   2)優點:支援大音樂檔案播放,不需要載入準備時間。
         SoundPool優缺點
 1)缺點:短音訊檔案。最大1M空間。不要輕易使用pause和stop方法,容易造成程式莫名終止。音訊格式最好用OGG格式。一般不在構造中呼叫播放函式進行播放,需要載入時間。
2)優點:支援多個音樂檔案同時播放。
  13.遊戲資料儲存
FileInputStream/FileOutputStream  適合遊戲的儲存和使用,
SharedPreference適合儲存配置資訊
SQLite也適合儲存遊戲
ContentProvider不適合儲存遊戲
二、遊戲開發實戰演練
1.準備專案資原始檔
2.劃分遊戲狀態。
三、遊戲開發提高
1.360°平滑遊戲導航搖桿
    首先在螢幕上繪製兩個大小不一的圓形,讓小圓中心點圍繞大圓做圓周運動。
    使用者觸點位置分為兩種情況
    第一種:觸點位置在大圓內或者大圓上,小圓的中心點直接跟隨玩家觸點即可。
    第二種:觸點位置在大圓外,小圓中心在大圓的圓周上,但小圓所在大圓上的角度,應該等同於使用者觸點位置相對於大圓的角度。
   實際使用中,需要通過搖桿控制遊戲主角的移動,首先將整個360°分成4或8等分
2.多觸點實現圖片縮放
3.觸屏手勢識別
    根據玩家接觸螢幕時間的長短、在螢幕上滑動的距離、按下擡起的時間等包裝,就是觸屏事件監聽
    GestureDetector.OnGestureListener監聽手勢
    6個主要抽象函式 
    onDown   onSingleTapUp   onFling  onScroll    onShowPress     onLongPress
    View.onTouchListener 觸屏監聽器介面
    繫結觸屏監聽器如下
     public boolean onTouch(View   view, MotionEvent  event){
      return  GestureDetector.onTouchEvent(event) ; }
 4.加速度感測器 又稱重力感測器
    其他感測器:陀螺儀感測器、光感測器、恆定磁場感測器、方向感測器、壓力感測器
   接近感測器、溫度感測器等。
     SensorManager  感測器管理類
SensorManager sm = (SensorManager)MainActivity;
instance.getSystemService (Service.SENSOR_SERVICE);
Sensor感測器類
Sensor sensor = SensorManager.getDefaultSensor(int type);
SensorEventListener 感測器監聽介面,監聽當前感測器的屬性及狀態。
手機朝向x、y、z
z>0手機螢幕朝上,z<0手機螢幕朝下
當手機是縱向螢幕,
x>0當前手機左翻,x<0當前手機右翻;y>0當前手機下翻y<0上番
當手機是橫向螢幕
x>0當前手機下翻,x<0當前手機上翻;y>0當前手機右翻y<0左番
5.9patch工具
 6.程式碼實現截圖功能
       原理:通過手動建立一張點陣圖,通過此點陣圖得到一個Canvas例項,利用得到的畫布進行繪製, 繪製的圖形都儲存在最初建立的點陣圖上。最後只要利用遊戲主畫布繪製這張點陣圖即可。
  7.效率檢視工具   TraceView
  8.遊戲檢視與系統元件共同顯示
  9.藍芽對戰遊戲
     BluetoothAdapter藍芽介面卡類,  對藍芽是否可見是否可用進行監聽
     BluetoothDevice  藍芽裝置類 ,   
     BluetoothSocket藍芽連線類 ,用於傳送和接收報文資料
10.網路遊戲開發基礎
    角色扮演遊戲(Role-playing game),簡稱為RPG
    ACT(Action Game):動作類遊戲
    FPS是第一人稱射擊類遊戲的簡稱(遊戲專有名詞)。FPS(First-Person Shooter Game)
    格鬥遊戲(Fight Technology Game,簡稱為FTG)
    模擬遊戲(Simulation Game),簡稱為SIM或SLG
    RAC(Race Game):競速類遊戲
    冒險遊戲(Adventure Game),簡稱為AVG
    SIM(模擬經營類):SIM (Simulation)
    SPT(體育類):Sports little game
    即時戰略(RTS,Real-Time Strategy)
    模擬養成遊戲(Education Simulation)
    CAG卡片類遊戲
    PUZ兒童益智類遊戲,需要通關的那種
    a。Socket協議
  Socket協議屬於長連線,下次互動資料不需要再次連線,一直維持互動狀態。適用於通訊類遊戲,如 ARPG、RPG類遊戲。
InputStream  is = Socket.getInputStream();
OutputStream   os  =  Socket.getOutputStream();
    b、http協議
 http協議屬於短連線,客戶端正常連線到伺服器後,資料互動完就斷開。
11.本地化與國際化
     values-en-rUS等

四、Box2D物理引擎
      遊戲引擎是指一些已編寫好的可編輯電腦遊戲系統或者一些互動式實時影象應用程式的核心元件。這些系統為遊戲設計者提供各種編寫遊戲所需的各種工具,其目的在於讓遊戲設計者能容易和快速地做出遊戲程式而不用由零開始。
     Box2D用於2D遊戲的物理引擎。Java平臺的稱為JBox2D。
     Android遊戲中常見遊戲引擎有Rokon、AndEngine、libgdx等。
     1.建立矩形物體
        Box2D中存在兩種2D圖形,圓形和多邊形。建立物體都應該設質量、摩擦力、恢復力三個基本屬性。Box2D屬於工廠模式,建立物體都是由工廠World生成的,不是new出來的。
      分為三步建立:首先建立物體面板,其次建立物體剛體,最後建立物體。
質量density:當物體質量設定為0時,物體視為靜態物體,沒有外力不會發生運動的物體。
摩擦力friction:取值通常設定0~1之間,0沒有摩擦,1最強摩擦。
恢復力restitution:取值通常設定0~1之間,0物體沒有恢復力,1物體有最大恢復力。
弧度-角度:body.getAngle()/180*Math.PI;
角度-弧度:body.getAngle()/Math.PI*180
遍歷body
World.getBodyCount()                     world.getBodyList()
2.設定Body座標與給Body施加力
setXForm(Vec2 position,float angle)
applyForce(Vec2 force,Vec2 point)
3.Body碰撞監聽、篩選與Body感測器
      碰撞監聽器介面 ContactListener
    add  發生碰撞,有新的接觸點時響應的函式;
    persist    ,當已存在的接觸點扔存在響應的函式。
    remove ,當存在的接觸點被刪除時響應的函式。
           result, 每次時間步監聽,如仍有觸點存在則被響應。
       Body碰撞篩選    FilterData類   ContactFilter監聽器
           shouldColide   
        Body感測器
              Body感測器就是Body面板的一個屬性,屬性名為isSensor,預設值false。
               body.getShapeList().m_isSensor = true;
作用:一個Body感測器屬性為true,不會與其他Body產生碰撞效果,但可以監聽到碰撞。
4.關節  Joint
    關節主要作用是限制和約束Body之間的位置、距離、速度、運動軌跡等。
    1.距離關節  DistanceJoint   限制兩個Body的質心距離永遠保持不變
    2,旋轉關節   RevoluteJoint   一個Body圍繞另一個Body旋轉。還需要一個力驅動Body
          RevoluteJointDef例項作為力驅動旋轉
    3.齒輪關節   GearJoint    兩個Body進行齒輪咬合運動。
    4.滑輪關節    PulleyJoint   兩個Body繫結滑輪關節,沿著一個世界錨點進行滑輪運動。
    5。移動關節   PrismaticJoint起兩個作用,一個是讓物體沿著世界錨點進行移動,另一個是讓繫結在移動關節上的兩個Body進行相同的動作。
     6.滑鼠關節   MouseJoint  利用滑鼠提供力的作用,拖拽Body,Body朝向滑鼠點選的位置進行移動,效果如同在Body與滑鼠之間綁定了一個橡皮筋。