[Mooc][Python][Week7] 太空船射擊遊戲

image

前言:

自從課程開始忙碌之後,我已經把Android跟Python的順序開始做個調整.不過因為這堂課程的loading一直不算輕鬆,雖然他的主要課程內容圍繞著他所提供的simplegui與codeskulptor之外,他的作業其實都是屬於peer assignment.也就是說你除了寫好作業之外,你還需要改其他同學的作業,不然就像我這個禮拜一樣被扣了20%的分數 orz .

課程筆記:

  • 這次主要是圍繞著如何利用聲音播放與一些OnDraw的相關應用去做出一個太空船射擊的遊戲.這邊其中就會牽扯到一些部分需要瞭解:
    • 關於推動力與摩擦力的運算
    • 關於聲音的播放
    • 對於動態物件的表示,與封裝.比如說隕石跟太空船都是會動的物件,但是隕石會飛出畫面外,太空船則不會.
    • 對於畫面上物件的碰撞計算,前幾天在Android的作業裡面也是一樣的東西.
  • 利用Dictionary 達成variable point 或是 function pointer map.
    • 裡面的programming tip是每個禮拜課程中,都會教導一下關於這個禮拜可能會遇到的一些小技巧與需要注意的地方.
    • 這次提到透過dictionary 裡面去加入其他函示的方式來達成function map的作用.當然舉一反三也可以指向其他的類別
#關於其他function point mapping
def f():
    pass

d = { 0 : f }
d[0]()   # call f function.    



#利用Dictionary 做到類別mapping
class C1:
    def __init__(self):
        self.inVal =  5
        
    def get(self):        
        return self.inVal
    
obj1 = C1()
print str(obj1.get()) #5

d = { 0:C1 }

obj2 = d[0]()
print str(obj2.get()) #5

作業筆記:

作業不簡單,所以寫了一下子才能回來更新部落格.一些筆記如下,大部分與http://www.codeskulptor.org裡面的simplegui處理有關:

  • 關於圖片顯示,原來的圖片都是PNG所以已經能透明,只要需要把圖片換成網路上png自行會處理透明的部分
  • 先試著處理keyboard event 對應著圖片旋轉的部分,這時候會發現圖片預設是0度(degree),所以要處理一下.
  • 要寫這個作業,首先要先來複習一下角度(degree)與弧度(radians).這邊我弄了很久因為我把角度(degree)的起始點弄錯,所自然算出來的弧度(radians)就是錯的.

image


#算出推進力,課堂的影片有提到
forward = (cos(radians) ,  sin(radians) )

參考資料:

[Mooc][Android]Programming Mobile Aplication on Android Platform(week6) - Graphic/Multiple Touch/Multiple Media

image

前言:

到了第六週,也只剩下三週,要好好努力了. 感覺這個禮拜的內容有點多,看來得仔細把筆記做一下,也希望都能熟悉各個元件的用法.

筆記:

  • Graphic 有兩種畫的方式:
    • Draw on canvas: 比較複雜,需要變動的繪圖.
    • Draw on view: 比較簡單,不需要變動的部分.
  • Draw on View:
    • 可以有兩種方式來達成,將所有需要的外觀用xml來敘述,或是寫在程式碼裡面的MainActivity的OnCreate也是可以.
    • xml 可以是引用其他的xml,比如說顏色敘述可以是另外一個xml
// In  main.xml
        android:background="@drawable/sq2"

// In drawable/sq2.xml
< ?xml version="1.0" encoding="utf-8"?>
< shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    < solid android:color="#FFFFFF00" />
    < stroke
        android:width="25dp"
        android:color="#FFFF0000" />
< /shape>
  • Draw on Canvas:
    • 透過View 來達成: (比較少更新)
      • 透過Canvas 提供的View 來使用
      • 透過 OnDraw 來更新畫面
    • 透過SurfaceView 來達成: (需要常更新)
      • 具有比較好的效能來更新UI
      • 不是屬於UI Drawing Thread來更新畫面.
      • 更新方式: (透過Surface callback)
        • surfaceCreated()
        • surfaceChanged()
        • sufaceDestroyed()
      • 使用流程:
        • SufaceHolder.lockCanvas() 先把UI resource 鎖定
        • 透過類似CCanvas.drawBitmap 來更新畫面
        • SufaceHolder.unlockCanvasAndPost() 來歸還UI resource
  • View Animation:
    • TransitionDrawable:
      • 用於兩個Drawable資源的切換,不過僅支援fade in/out的過場特效
    • Animation:
      • 可以做許多不同的Animation,比如說Alpha 變換(也就是fade in/out) 或是 rotate , translate與 scale(大小).
    • ValueAnimator:
      • 可以透過onAnimationUpdate callback 來調整每個animation 要改變的數值
    • ViewPropertyAnimator:
      • 每個view本身都有一個 .animate() 的ViewPropertyAnimator可以取用
      • 可以透過 Runnable去串接下一個Runnable來達成連續Animation的效果
//  TransitionDrawable 
Drawable[] layers = new Drawable[2]; //Two drawable in list
layers[0] = new ColorDrawable(Color.TRANSPARENT);
layers[1] = new BitmapDrawable(bitmap);
TransitionDrawable drawable = new TransitionDrawable(layers);

image.setImageDrawable(drawable);

drawable.startTransition(300);

 
// Animation java code
    // Create animation
    mAnim = AnimationUtils.loadAnimation(this, R.anim.view_animation);
    // Set Animation in ImageView when get focus
    mImageView.startAnimation(mAnim);


// Animation xml
    < alpha   //fade in/out
        android:duration="3000"
        android:fromAlpha="0.0"
        android:interpolator="@android:anim/linear_interpolator"
        android:toAlpha="1.0" />

    < rotate //rotate
        android:duration="4000"
        android:fromDegrees="0"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="3000"
        android:toDegrees="720" />

// View PropertyAnimation
    fadeIn.run();  // Run first runnable

	Runnable fadeIn = new Runnable() {
		public void run() {
			mImageView.animate().setDuration(3000)
					.setInterpolator(new LinearInterpolator()).alpha(1.0f)
					.withEndAction(rotate);
					//Call next runnable rotate.
		}
	};

  • Multiple Touch Event:
    • OnTouch event handle MotionEvent:
      • Pointer ID: 代表著每一個觸碰的點.當有multiple touch發生的時候,Pointer ID 就有複數個.
      • MotionEvent.ACTION_MOVE.ACTION_POINTER_UP: 也是可能有多個pointer ID依序傳入.
      • MotionEvent.ACTION_MOVE: 是一次傳入一個群組的 id,你需要一個個去拿來處理.
    • OnTouch event handle by GestureDetector:
      • GestureDetector可以幫你判別是何種手勢,並且依據支援的手勢來呼叫
      • 如果需要增加新的手勢,需要使用GestureBuilder並且把檔案複製到App
        • 檔案從 /mnt/sdcard/gestures
        • 到 /res/raw 目錄夾
    • 客製化手勢使用流程:
      • 先使用 GesutureLibraries 把客製化的手勢讀進來
      • 輸入新的手勢之後,會得到一個預測的手勢陣列.取出分數最高的來處理
/*
 *  Multiple touch handle by MotionEvent
 */
 
// Init frame layout object 
FrameLayout mFrame = (FrameLayout) findViewById(R.id.frame);

// Create and set on touch listener
mFrame.setOnTouchListener(new OnTouchListener() {

	@Override
	public boolean onTouch(View v, MotionEvent event) {

		switch (event.getActionMasked()) {

		// Show new MarkerView
		
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_POINTER_DOWN: {

			int pointerIndex = event.getActionIndex();
			int pointerID = event.getPointerId(pointerIndex);
            // Each pointerID represent one finger movement. ex: 2 fingers will call twice in this function.
            
            ...  // Do something about handle in each finger point down.
            
			break;
		}


        // Handle move as group.
        case MotionEvent.ACTION_MOVE: {
        
        	for (int idx = 0; idx < event.getPointerCount(); idx++) {
        
        		int ID = event.getPointerId(idx);
        
        		MarkerView marker = mActiveMarkers.get(ID);
        		if (null != marker) {
        			// Do something with marker
        			}
        		}
        	}
        
        	break;
        }


/*
* Multiple touch handle by Gestture Detector and Custom Gestures
*/

// Load custom gestures
    GestureLibrary mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
    if (!mLibrary.load()) {
    	finish();
    }
	public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {

		// Get gesture predictions
		ArrayList predictions = mLibrary.recognize(gesture);

		// Get highest-ranked prediction
		if (predictions.size() > 0) {
			Prediction prediction = predictions.get(0);

			// Ignore weak predictions

			if (prediction.score > 2.0) { //limited prediction score must higher 2.0
			if (prediction.name.equals("CUSTOM_GESTURE_ONE")) {
			        // Do something.

				}
			}

</pre>

- Multiple Media Player
    - 啟動MediaPlayer流程:
        - setDataSource()
        - prepare()
        - start() 
    - 啟動MediaRecorder流程 (以錄音為例):
        - setAudioSource(MediaRecorder.AudioSource.MIC)
        - setOutputFormat(MediaRecorder.OutputFormat.XXX)
        - setOutputFile()
        - setAudioEncoder(MediaRecorder.AudioEncoder.XXX)
        - prepare()
        - start()       

// Start recording with MediaRecorder
private void startRecording() {

	mRecorder = new MediaRecorder();
	mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
	mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
	mRecorder.setOutputFile(mFileName);
	mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

	try {
		mRecorder.prepare();
	} catch (IOException e) {
		Log.e(TAG, "Couldn't prepare and start MediaRecorder");
	}

	mRecorder.start();
}


// Playback audio using MediaPlayer
private void startPlaying() {

	mPlayer = new MediaPlayer();
	try {
		mPlayer.setDataSource(mFileName);
		mPlayer.prepare();
		mPlayer.start();
	} catch (IOException e) {
		Log.e(TAG, "Couldn't prepare and start MediaPlayer");
	}

}
**參考資源:** - Android中圖片璇轉與縮放 - [http://fecbob.pixnet.net/blog/post/36421426-android%E4%B8%AD%E5%AF%A6%E7%8F%BE%E5%9C%96%E7%89%87%E5%8F%8A%E5%8B%95%E7%95%AB%E7%9A%84%E7%B8%AE%E6%94%BE%E5%92%8C%E6%97%8B%E8%BD%89(%E8%BD%89)](http://fecbob.pixnet.net/blog/post/36421426-android%E4%B8%AD%E5%AF%A6%E7%8F%BE%E5%9C%96%E7%89%87%E5%8F%8A%E5%8B%95%E7%95%AB%E7%9A%84%E7%B8%AE%E6%94%BE%E5%92%8C%E6%97%8B%E8%BD%89(%E8%BD%89)) - About TransitionDrawable - [http://jason1peng.blogspot.tw/2013/01/android-ui-1-cross-fading.html](http://jason1peng.blogspot.tw/2013/01/android-ui-1-cross-fading.html) - TransitionDrawable fade in/out - [http://givemepass.blogspot.tw/2012/03/xml.html](http://givemepass.blogspot.tw/2012/03/xml.html)

[MOPCON2014]蒐集一些有趣的MOPCON場次(1)

image

前言:

雖然我沒有去MOPCON2014,但是還是有去看一些有趣的題目,順便找找他的slide出來分享一下. 這裏有全部議題

有趣的題目:

  • 講個秘訣之:離開新手村後也可以順便聽一下的程式「設計」指南
    • Slide:
    • 內容與心得
      • 要提到程式設計中”設計”的思維.既然我們都稱自己是程式設計師,那麼你的作品是不是真的符合所謂”設計”的概念?
      • 裡面提到的設計心理學,如果將它應用到程式設計:
        • 預設用途:
          • 設計任何程式之前,對於他的預設用途必須要先想清楚.
        • 指意:
          • 要能讓別人一看就能了解並且不容易搞混的API設計.
        • 使用侷限:
          • 設計各種功能與API要注意到可能會有許多使用上的侷限.不論是[物理][文化][意義]或是[邏輯]上.
        • 對應性:
          • 設計的時候要有好理解的對應性,才能讓人馬上上手.
        • 回饋:
          • 設計適當的回饋,可以讓使用的人了解到目前的狀況.
        • 概念模型:
          • 高度簡化下,對於事物的如何運作的解釋.
      • 如同講者提到的,其實任何一種設計都是圍繞著人走.所以就算是程式設計也要圍繞者使用的人為出發點去思考,能能算是比較好的設計觀念.
  • in in der 響應式編程
// Impreative Programming
int x,y,z;
x=1; y=2;
z= x+y; //1+1
y= 2;
print("%d", z); //z=2

// Reactive Programming
int x,y,z;
x=1; y=2;
z= x+y; //1+1
y= 2;
print("%d", z); //z=3
 
  • Best software architecture in app development
    • Slide:
    • 內容與心得:
      • 如何容易地展現內容? 建議使用 ListView其中 UICollectionView是功能強大的部分.
        • 優點:
          • UICollectionView 可以自訂顯示方式,並且可以對應到不同的大小顯示方式.
          • Cell 可以重複用,具有彈性的顯示方式
          • 具有自動更新與記憶體管理的部分
      • 修改一次可以同時變更許多地方: (主要提到將一些常用到的顯示部份抽取出來)
        • 顏色:
          • 將顏色變成類別內的變數[參考下面的程式碼(1)]
      • UI Layout 建議使用Xib 而不是Stroyboard
        • 原因: Storyboard 不易閱讀,而且開很大的時候相當耗費時間,並且時常有衝突不好修改.
      • Unit Test: 建議使用XCTest Framework
        • 可以使用內建的Automation 來達成自動測試,就算是GPS相關的問題也可以透過GPX Creator 來測試.
      • 顯示你的內容
//(1)
+ (UIColor *) themeBackGround
{
    return [UIColor colorWithHexString:@"dedede"];
} 

[MOPCON2014]蒐集一些有趣的MOPCON場次(1)

image

前言:

雖然我沒有去MOPCON2014,但是還是有去看一些有趣的題目,順便找找他的slide出來分享一下. 這裏有全部議題

有趣的題目:

  • 講個秘訣之:離開新手村後也可以順便聽一下的程式「設計」指南
    • Slide:
    • 內容與心得
      • 要提到程式設計中”設計”的思維.既然我們都稱自己是程式設計師,那麼你的作品是不是真的符合所謂”設計”的概念?
      • 裡面提到的設計心理學,如果將它應用到程式設計:
        • 預設用途:
          • 設計任何程式之前,對於他的預設用途必須要先想清楚.
        • 指意:
          • 要能讓別人一看就能了解並且不容易搞混的API設計.
        • 使用侷限:
          • 設計各種功能與API要注意到可能會有許多使用上的侷限.不論是[物理][文化][意義]或是[邏輯]上.
        • 對應性:
          • 設計的時候要有好理解的對應性,才能讓人馬上上手.
        • 回饋:
          • 設計適當的回饋,可以讓使用的人了解到目前的狀況.
        • 概念模型:
          • 高度簡化下,對於事物的如何運作的解釋.
      • 如同講者提到的,其實任何一種設計都是圍繞著人走.所以就算是程式設計也要圍繞者使用的人為出發點去思考,能能算是比較好的設計觀念.
  • in in der 響應式編程
// Impreative Programming
int x,y,z;
x=1; y=2;
z= x+y; //1+1
y= 2;
print("%d", z); //z=2

// Reactive Programming
int x,y,z;
x=1; y=2;
z= x+y; //1+1
y= 2;
print("%d", z); //z=3
 
  • Best software architecture in app development
    • Slide:
    • 內容與心得:
      • 如何容易地展現內容? 建議使用 ListView其中 UICollectionView是功能強大的部分.
        • 優點:
          • UICollectionView 可以自訂顯示方式,並且可以對應到不同的大小顯示方式.
          • Cell 可以重複用,具有彈性的顯示方式
          • 具有自動更新與記憶體管理的部分
      • 修改一次可以同時變更許多地方: (主要提到將一些常用到的顯示部份抽取出來)
        • 顏色:
          • 將顏色變成類別內的變數[參考下面的程式碼(1)]
      • UI Layout 建議使用Xib 而不是Stroyboard
        • 原因: Storyboard 不易閱讀,而且開很大的時候相當耗費時間,並且時常有衝突不好修改.
      • Unit Test: 建議使用XCTest Framework
        • 可以使用內建的Automation 來達成自動測試,就算是GPS相關的問題也可以透過GPX Creator 來測試.
      • 顯示你的內容
//(1)
+ (UIColor *) themeBackGround
{
    return [UIColor colorWithHexString:@"dedede"];
} 

未完待續…..

[Mooc][Android]Programming Mobile Aplication on Android Platform(week5) - 2 Assignments

image

前言:

由於這個是我的有繳學費的課程,其實我很認真每天都把進度跑完.誰知道,本週竟然有兩個程式作業,一個是電腦評分,一個是同學們之間的互評.

Program Assignment:

這次的是Notification的作業,其實並不會太困難.要填上的程式碼也不多.只是原先題目拼字有先錯誤,所以找了一下.

Peer Assignment:

這次Peer Assignment 我覺得比較困難,是因為要搞UI的layout,幾個重點分享給大家.

  • 如何在 Andorid 上面做出分割的塊狀?
    • 主要就是利用 Linear Layout 然後記得要設定weight (他會幫你用分割,舉例而言: 兩個button 都設定weight 為1 的話就是平分)
  • Seekbar 的設定顏色部分,可以透過 setBackgroundColor 並且使用 Color.argb() 來調整顏色
  • 最後,如果要繳交Video Snapshot 在Mac上面可以直接透過QuickTime Player來使用

以上就是這次的Peer Assignment 的影片 http://youtu.be/NMd7Tw5aKL4

參考:

[Mooc][Android]Programming Mobile Aplication on Android Platform(week5) - Notification and Threads

image

前言:

來到第五週,其實作業已經越來越花時間.需要好好把握時間趕快做完才行.

筆記:

  • 關於 Broadcast:
    • 可以是有順序的(利用setPriority來設定),其中Priority 越高順序越前面.
    • 一個broadcast 可以同時被多個broadcast receiver 接收.
    • 其中一個Broadcast receiver 可以透過abortBroadcast 來強迫其他receiver來收取broadcast.
    • 關於sticky broadcast 比較需要注意的是:
      • 接收 sticky broadcast可以收到在註冊前發生的變動.
  • 關於 Threads:
    • Java的thread 建立之後不會馬上執行.需要跑start()
    • 背景的thread無法執行UI的相關動作.(這個地方跟 WinApp 跟 iOS App都一樣)
      • 需要執行要跑 runOnUIThread()
      • 或是每一個UI物件都有自己的View的post函式.View.post(Runnable action)

image

  • 關於AsyncTask:
    • 流程:
      • OnPreExecute -> doInBackground() -> publishProgress() -> OnPostExecute()
      • 其中如同上圖,有相對應的UI thread method OnProgressUpdate()最後 ObPostExecute() 也可以執行UI的更新.
  • 關於Alarm:
    • 註冊後,就送機器進入睡眠模式一樣可以收到.(除非關機)
    • 要取用Alarm需要使用 getSystemService(Context.ALARM_SERVICE) 來取得.
    • Kitkat (API 19) 之後,Alarm的使用變成inexact,也就是說他會盡量把幾個差不多時間的Alarm收集起來一起發送,即時他們時間有些許的差異.透過這個方式來節省電源的使用. (詳細可以參考這段)
  • 關於Networking: (Socket, JSON, URLRequest)
    • 要做網路溝通使用 HttpURLConnection 而不要使用 AndroidHttpClient 跟 DefaultHttpClient,由於Android team在 Android 2.3之後就不太積極開發
    • JSON的取用方式:
      • 要先用ResponseHandler 接回 client的 response 之後再逐一分解.
      • data array 可以用 JSONObject.getJSONArray
      • 每個mapping key/value 可以使用JSONObject.get(key)
    • XML的取用方式:
      • 主要有三種存取的方式: (DOM, SAX, PULL)
      • 其中記憶體消耗最高的是DOM,因為讀取的時候會把所有的XML樹狀資料全部載入.
      • SAX與PULL都是屬於event callback的方式,而PULL提供更多的彈性可以逐一的存取,並且可以控制event的結束.

參考資料: