Godaddy郵箱與Outlook設定

Godaddy郵箱與Outlook設定
Godaddy郵箱與Outlook設定
Godaddy郵箱與Outlook設定

購買Godaddy虛擬主機,均免費贈送你私有域名電子郵箱.你可在名片印以你公司域名獨有電郵.但你要設定電郵帳戶與Outlook賬戶才能啟用.
1. 登入Godaddy帳戶->我的產品
2. 個人電郵->Workspace 電子信箱->管理所有
3. 在Workspace Control Center創建電郵帳戶Create a new account
4. Email Address:填電郵地址如:XXX@bookcard.net
5. Password 與Confirm Password:填電郵密碼,不小於5個字符.
6. 設定郵箱空間配額Quota:我這裡填1000MB
設定Outlook電郵賬戶
1. 賬戶資訊->新增賬戶
2. 填電郵帳戶如:XXX@bookcard.net
3. 『進階選項』->勾選『我要手動設定我的帳戶』
4. 選擇『POP』類型郵箱
5. 內送郵件『伺服器』pop.secureserver.net
6. 內送郵件『連接埠』995
7. 勾選『此伺服器需要加密連線(SSL/TLS)』
8. 外寄郵件『伺服器』smtpout.secureserver.net
9. 外寄郵件『連接埠』465
10. 『加密方法』選『SSL/TLS』
11. 填電郵『密碼』然後『連線』
後期設定Outlook電郵帳戶
1. 『賬戶資訊』選擇pop/smtp電郵帳戶
2. 賬戶設定->管理設定檔
3. 帳戶設定->電子郵件
4. 雙擊編輯電郵帳戶.內容與上面設定一至不再重複.

DeepUV安裝與設置

DeepUV安裝與設置

DeepUV是由Right Hemisphere公司開發用於UV展開貼圖專業軟件.即把重設UV座標然後在3D模型文檔中更新.但其網站http://www.righthemisphere.com以無法訪問.因為手動移動UV座好難正與紋理對齊.而DeepUV可以不管模型形狀而占開紋理座標.而唔會影響3D模型形狀

  1. 安裝DeepUV時一定要安裝3D Studio Max插件
  2. 若DeepUV出現渲染問題可嘗試設定渲染方式.File->Preferences->Rendering將Preferred 2D/3D Renderer『首選二維三維渲染』設為Software軟件渲染.這可使DeepUV直接使用顯卡驅動.我這裡需使用OpenGL三維維染.否則選擇紅線不清.
  3. 若3ds式等模型文檔若無法展開UV座標.可嘗試用Deep Exploration/3D Exploration重新『另存為』Save as為3ds格式.
  4. DeepUV只支持以下格式
3D格式 簡介
Autodesk 3D Studio(*.3ds) 3D Studio MAX所用格式
Lightwave 3D and Binary Object(*.lwo,*lw) LightWave3D所用格式
Wavefront Object(*.obj) Maya所用格式
RH3 Scene File(*.rh3)
Right Hemisphere Binary(*.rh)
SOFTIMAGE XSL(*.xsi) SOFTIMAGE 3D已停止開發

 

trueSpace建模之鍵盤快捷鍵

trueSpace建模之鍵盤快捷鍵

trueSpace建模與鍵盤配合『快捷鍵』.特別投影切換小鍵盤非常好記出中心5是透視,其它數字按方向排列.不過trueSpace『快捷鍵』有Bug它並非是全域鍵.若焦點位於某面板輸入框中『快捷鍵』便失效,此時最好用滑鼠點擊『對象工具』Object tool

工具 快捷鍵
旋轉對象『Object Rotae』 R
移動工具 G
縮放對象 X
啟用/禁用X軸導航 A
啟用/禁用Y軸導航 Y
啟用/禁用Z軸導航 Z
『對象工具』Object tool Space空格
『將視點對齊對象模型』Look at Current Object V
關閉所有面板 Backspace退格
彈所有出面板 Tab
拷貝所選模型 Ctrl+C
撤消操作 Ctrl+Z
刪除所選模型 Del
選擇/切換前後對象 Left/Right
使用箭頭鍵在層次結構內移動 Up/Down
頂正交投影視圖 小鍵盤0
前正交投影視圖 小鍵盤1
前正交投影視圖 小鍵盤2
後背正交投影視圖 小鍵盤3
左正交投影視圖 小鍵盤4
透視投影視圖 小鍵盤5
右正交投影視圖 小鍵盤6
頂正交投影視圖 小鍵盤7

 

歌謠之月光光

歌謠之月光光

『月光光 照地塘 年卅晚 摘檳榔 檳榔香 買紫薑 紫薑辣 買芙薘 芙薘苦 買豬肚 豬肚肥 買牛皮 牛皮薄 買菱角 菱角尖 買馬鞭 馬鞭長 起屋樑 屋樑高 買張刀 刀切菜 切死兩個紅毛番鬼仔』

整首歌謠大部分以接龍形式,所出現之物大都並無關聯.但最後卻現殺機.它與廣州城一段歷史有關.1840年第一次鴉片戰爭.後再在1842年簽訂南京條約,清答應英國五口通商.之一就是進入廣州城.而到1858年廣州城依然唔肯讓英人進入廣州城內.英人只能在十三行居住.原因是兩廣總督葉名琛以廣州城內有刁民見紅毛番鬼就摞刀劈.為保障英人安全不讓進廣州城內.其實英人早已得知是葉名琛給錢地痞.讓其只止要見鬼頭就摞刀劈.最後葉名琛於1857年被英軍俘虜.

trueSpace建模之怪獸

trueSpace建模之怪獸

使用trueSpace怪獸建模.因為最後應用手遊.應儘量減小多邊形.最好在超過2千個多邊形左右.因為模型左右對稱.只需要創建一半模型之後再鏡像.可以減小紋理尺寸.怪獸分3部分建造.

  1. 怪獸身軀
  2. 獸腿
  3. 獸臂
  4. 將模型導出COB文檔File->Save As->Object命令
  5. 首先新建場景New->New Scene
  6. 將剛創建三怪獸組件逐個加在到同一個場景.Load->Load Object命令.『檔案類型』 選擇Caligari Object *.cob
  7. 若模型使用NURBS建模可先為多面體『NURBS面片轉多邊體』NURBS Path to Polyhedron工具.將靜態分辨率改為3至0.2之間
  8. 通過均勻『縮放』腿與臂,比例要要恰如其分.從而使它放到身軀旁.『然旋』轉大退呈大字型.
  9. 切換到透視投影.並將渲染環境設置為實體模式.要確保腿與臂完全伸入到身軀內.否則最終模型合併後會產生空洞.最後『合併』模型.
  10. 切割怪獸使它只有身體一半,切割有兩個方法.使用大立方體將左側『切除』.或者選擇左則『點』然後『刪除
  11. 導出3ds文檔SaveAS->Save Object『存檔類型』選3DStudio binary *.3ds 『檔案名稱』最後為英文字母.最後按『存檔』

trueSpace建模之NURBS面片轉多邊體

trueSpace建模之NURBS面片轉多邊體

trueSpace使用NURBS完成建模後,要將其組合或導出時.需將NURBS面片轉化為多面體.其實就是將由『曲線』組成面片轉為『直線』組成多邊形

  1. 因為NURBS轉換多邊形過程不可逆轉.首先要備份模型
  2. 滑鼠右擊『將NURBS面片轉化為多面體』Convert NURBS Patch to Polyhedron.打開Patch Options『面片選項』.設定參數後將其轉為多邊形模型.修改『靜態分辨率』為2
  3. 滑鼠點擊『將NURBS面片轉化為多面體』Convert NURBS Patch to Polyhedron工具. 不可逆轉為多邊形網格.
Patch Options『面片選項』 簡介
Static res『靜態分辨率』 生成NURBS分辨率,默認值為0.67.修改為0.2~0.3
Manipulation res『操縱分辨率』 改變模型形式多邊形顯示分辨率. 默認值為0.3若建模過程遲緩不連貫.請降低此值.

 

trueSpace建模之點自動對齊

trueSpace建模之點自動對齊

trueSpace建模過程中你可能發現同一面上『點』並不對齊,若通過逐點『移動』對齊不但費時失事,而且效果亦未能理想.其實有更很容易方法對齊所有『點』.

  1. 滑鼠右鍵選擇模型.彈出Point Edit
  2. 選擇你要對齊『點』
  3. 激活『縮放』工具.鎖定X軸.橫向移動滑鼠.直到頂點垂直對齊.
  4. 水平對齊同理

trueSpace建模之怪獸手臂

trueSpace建模之怪獸手臂
trueSpace建模之怪獸手臂

怪獸『手臂』要比『大腿』複雜.而且戴上腕箍暗示其『無性』.手指長長指甲暗示其具有『攻擊性』.

  1. 在場景中添加10面『圓柱體』製作『腕箍』
  2. 使用『尖端』工具對其相隔5個面拉出針尖狀.按CTRL鍵選擇所有尖端『縮小』針尖長度
  3. 在『腕箍』一側使用『拉伸』工具創建手臂,每拖動一次就縮放一次.直至得到手臂形狀.手臂全是肌肉
  4. 選擇『腕箍』另一側『面』使用『拉伸』後『縮放』形成手掌.
  5. 填加手指.首先將端面拆分成4個小『面』使用『細分表面』Add Edges工具.
  6. 再使用『倒角』Bevel工具拉出4只手指.
  7. 因為現在手指呈四方形. 使用『細分』工具分割為八面.然後移動各『點』形成圓形.繼續使用『拉伸』工具創建手指.最後『倒角』形成指尖
  8. 生成野獸指甲.分別選擇手指尖端兩個『面』使用『尖端』Tip工具拉出4只指甲.然後按住CTRL鍵選擇4個指甲尖『移動』形成長指甲
  9. 重複第6、7、8步驟生成大拇指

trueSpace建模之獸腿

trueSpace建模之獸腿
trueSpace建模之獸腿

獸腳特點有極粗大腿,但只有三隻腳趾.

1.      首先使用『繪畫面板Draw Panel工具繪畫腳掌曲線然後拉伸.制後繼續『擠壓』建

2.      使用『細化片面』工具添加曲線.切換到『頂正交投影』通過移動與縮放形成腳掌

3.      移動最頂『點』形成圓形腳踝形

4.      重複第二部繼續通過細化片面在頂部添加曲線.並通過『移動』與『拉伸』槊造小腿與大腿.

trueSpace建模之NURBS 繪畫面板

trueSpace建模之NURBS 繪畫面板

之前介紹trueSpace使用NURBS擠壓模型.但還有一種繪畫『樣條曲線』然後拉伸位NURBS模型方式

  1. 啟用『3D控制器
  2. 單擊『繪畫面板』Drawpanel tool它通常位於屏幕底工具欄
  3. 在透視投影中單擊滑鼠生成『繪畫面板』拖動其邊緣改變其大小.按右鍵退出重新選擇可在object info中選擇
  4. object info中讓其置於場景中心
  5. 切換到『頂部正交視圖』
  6. 選擇『添加曲線』Add Curve工具.然後繪畫圖形.要儘量閉合.形狀不必太完美.因為可以移動『點』調整圖形.
  7. 使用『閉合曲線』Close Curve工具閉合圖形
  8. 創建常規圖形之後,點擊曲線『點』.顯示其『控制手柄』.拖動『手柄』中心點到新位置.拖動『手柄』兩端調整圖形曲線
  9. 過多『點』否則只會增加多邊形量. 『刪除曲線點』Delete curve point工具
  10. 當對曲線滿意時.按滑鼠右鍵退出曲線編輯面板.並切換為『透視投影』
  11. 使用『拉伸曲線』Extrude tool工具.彈出垂直於所繪畫圖形雙向控制句柄,然後單擊並拖動手柄端點形成基底.
  12. 按滑鼠右鍵退出拉伸模式.此時模型上下兩端開放沒有『面』
  13. 使用『擠壓』繼續完成建模.最後『補洞』ADD Face工具封閉模型

 

trueSpace建模之怪獸身軀

trueSpace建模之怪獸身軀
trueSpace建模之怪獸身軀

以trueSpace構建『怪獸』Kaiju身軀,並以NURBS方式建模.你可以在五分鐘內完成模型.

  1. 在場景中生成NURBS球體.它與多邊形球體模型一起放置.長按『多邊形』基本模型彈出NURBS球體.生成NURBS分辨率修改為3.
  2. 隱藏『3D控制器』已免妨礙其後續操作
  3. 切換到正交視圖
  4. 選擇球體曲線向下拖動形成『尾龍骨』
  5. 選擇拉動球體底部點形成『尾部』
  6. 按住Ctrl鍵球體上方左右兩則點.向內側縮放形成『背』與『肩』
  7. 讓怪獸頸椎高高隆起.向上拖動該點形成頸椎,彈出『控制句柄』調整頸椎銳度
  8. 拉伸頭部並『細化片面』然後繼續調整頭部形狀.
  9. 刪除不必要曲線
  10. File->Save As->Object導出COB模型

trueSpace建模之NURBS模型

trueSpace建模之NURBS模型

NURBS全稱Non-Uniform Rational B-Splines.漢譯為『非均勻有理B樣條』.『B樣條』其實就是『貝賽爾(Bezier)曲線』, NURBS為高密度網格但呈現出平滑外型.trueSpace作為與『3D Studio MAX』與『Maya』同級別三維軟件當然也支持NURBS.建模過程與使用『橡皮泥』手工製作模型非常類似.剛開此使用時你可能不習慣.但好快會喜歡它. NURBS建模缺點是顯著增加多邊形量.但NURBS建模速度快.將會是未來遊戲建模方式.但現役手機GPU圖形處理能力還差一大截.控制多邊形數量還很必要.

  1. 『NURBS』基本模型與『多邊形』基本模型一起放置,長按『多邊形』基本模型彈出可選模型.以『球體』為例長按Sphere彈出並選擇NURBS Sphere
  2. 滑鼠右擊NURBS sphere彈出屬性選項面板.設置經度與緯度
  3. 滑鼠點選NURBS Sphere即可在場景中心生成NURBS球體
  4. 3D控制器』包裹著模型.但現在它卻妨礙NURBS模型操作.打開『設置』preferences隱藏3D Controls
  5. 擠壓模型』滑鼠右擊NURBS模型彈出Patch Edit工具組.移動滑鼠時『曲線』或『點』高亮顯示.曲線相交形成『片面』操縱曲線或點片面就會發生變形,從而改變對象形狀.
  6. 細化片面』通過增加曲線量來增加模型分辨率.先選擇一條『曲線』使其高亮顯示.然後單擊『細化片面』Refine Patch工具.單擊並拖動橙色曲線.當到達想要放置位置釋放滑鼠。
  7. 銳化點』滑鼠右擊『點』彈出『控制句柄』拖動其十字句柄改變『點』銳度
  8. 刪除模型多餘曲線使用『刪除曲線』工具
  9. 滑鼠右擊『Convert NURBS Patch to Polyhedron』.打開Patch Options『面片選項』.設定參數後將其轉為多邊形模型
Patch Options『面片選項』 簡介
Static res『靜態分辨率』 生成NURBS分辨率,默認值為0.67.修改為0.3
Manipulation res『操縱分辨率』 改變模型形式多邊形顯示分辨率. 默認值為0.3若建模過程遲緩不連貫.請降低此值.

 

trueSpace建模之NURBS銳化點

trueSpace建模之NURBS銳化點

擠壓NURBS模型也未必達到你想要型狀時,可嘗試改變調整『點』銳度

  1. 隱藏『3D控制器』已免妨礙其後續操作
  2. 切換到『投視投影』
  3. 滑鼠右擊NURBS模型彈出Patch Edit工具組.
  4. 激活選擇『選擇點』工具只對『點』高亮顯示.多選『點』無法彈出『控制句柄』.
  5. 滑鼠右擊『點』彈出『控制手柄』形狀如十字每邊一箭頭,點中心為一圓點
  6. 拖動箭頭改變『點』銳度
  7. 拖動圓點移動『點』位置
  8. 按滑鼠右鍵鍵退出

trueSpace建模之NURBS刪除曲線

trueSpace建模之NURBS刪除曲線

NURBS模型在建模過程中可能會產生多餘『曲線』.模型曲線越多最終多邊形轉換越多.刪除曲線是trueSpace優化模型最重要手段.

  1. 隱藏『3D控制器』已免妨礙其後續操作
  2. 滑鼠右擊NURBS模型彈出Patch Edit工具組.
  3. 激活『選擇行』Select rows of points工具使『曲線』高亮顯示.
  4. 點選『刪除點行』Delete Row of Points工具.然後滑鼠點選刪除多餘曲線.此工具與『細化片面』Refine Path相對應
  5. 點擊滑鼠左鍵繼續刪除曲線.按右鍵退出

trueSpace建模之NURBS細化片面

trueSpace建模之NURBS細化片面

NURBS建模可通過增加曲線數量來增加模型分辨率.從而獲的更多控制點擠壓模型.

  1. 隱藏『3D控制器』已免妨礙其後續操作
  2. 滑鼠右擊NURBS模型彈出Patch Edit工具組
  3. 通過『選擇行』工具選擇『曲線』使其高亮顯示.若難以選擇『曲線』.按空格鍵退出模型選擇.然後重複第2步
  4. 然後單擊『細化片面』Refine Patch工具.單擊並拖動橙色曲線.當到達想要放置位置釋放滑鼠
  5. 點擊滑鼠左鍵繼續添加曲線.按右鍵退出

trueSpace建模之NURBS擠壓模型

trueSpace建模之NURBS擠壓模型

NURBS全稱Non-Uniform Rational B-Splines.漢譯為『非均勻有理B樣條』.『B樣條』其實就是『貝賽爾(Bezier)曲線』, NURBS為高密度網格但呈現出平滑外型.trueSpace作為與『3D Studio MAX』與『Maya』同級別三維軟件當然也支持NURBS.剛開此使用NURBS建模可能不習慣.但你好快會喜歡它. NURBS建模缺點是顯著增加多邊形量.NURBS建模將會是未來遊戲建模方式.但現役手機GPU圖形處理能力還差一大截.控制多邊形數量還很必要.

  1. 『NURBS』基本模型與『多邊形』基本模型一起放置,長按『多邊形』基本模型彈出可選模型.以『球體』為例長按Sphere彈出並選擇NURBS Sphere
  2. 滑鼠點選NURBS Sphere即可在場景中心生成NURBS球體
  3. 3D控制器』包裹著模型.但現在它卻妨礙NURBS模型操作.打開『設置』preferences隱藏3D Controls
  4. NURBS建模過程與使用『橡皮泥』手工製作模型非常類似.
  5. 『擠壓模型』滑鼠右擊NURBS模型彈出Patch Edit工具組.移動滑鼠時『曲線』或『點』高亮顯示.曲線相交形成『片面』操縱曲線或點片面就會發生變形,從而改變對象形狀.
  6. 『細化片面』通過增加曲線量來增加球體分辨率.先選擇一條『曲線』使其高亮顯示.然後單擊『細化片面』Refine Patch工具.單擊並拖動橙色曲線.當到達想要放置位置釋放滑鼠。
  7. 『點銳度』滑鼠右擊『點』彈出『控制句柄』拖動其十字句柄改變『點』銳度
  8. 滑鼠右擊『Convert NURBS Patch to Polyhedron』.打開Patch Options『面片選項』.設定參數後將其轉為多邊形模型
Patch Options『面片選項』 簡介
Static res『靜態分辨率』 生成NURBS分辨率,默認值為0.67
Manipulation res『操縱分辨率』 改變模型形式多邊形顯示分辨率. 默認值為0.3若建模過程遲緩不連貫.請降低此值.

trueSpace建模之3D控制器

trueSpace建模之3D控制器

trueSpace『3D控制器』它可以幫助你.對『模型』『點』『邊』『面』進行操作. 『3D控制器』包裹著模型,每條邊分為三段『中間』移動與『兩則』縮放『圓球』旋轉.操作時切換到『正交投影』已保正沿某軸完成操作.要顯示『視點控制器』必須打開『3D控制器』.打開『設置』preferences勾選3D Controls.要隱藏即取消勾選.

3D控制器 簡介
中間 沿某軸『移動』MOVE模型
兩則 沿某軸『縮放』SCALE模型
軸旋轉球 左鍵點擊『圓球』彈出. 繞某軸『旋轉』ROTATE模型

 

trueSpace建模之等離子槍

trueSpace建模之等離子槍
trueSpace建模之等離子槍
trueSpace建模之等離子槍
trueSpace建模之等離子槍
trueSpace建模之等離子槍

3D建模之前需先確定模形尺寸,等離子槍給4米高史前食人怪使用武器.而等離子槍長約身高一半大約2米.槍托到彈夾則大約1米.多邊形數量應儘量低,其外觀主要依靠紋理.你需要一張建模用參考圖.長寬比為2比1.
1. 設置等離子槍參考圖平面
2. 構建槍口,其實是兩個相連蛋形球體.在場景中添加球體,緯度與經度均為12.然後旋轉90度,通過縮放移動拉伸與參考圖相近.選擇並刪除前四個分段.
3. Ctrl+C複製球體,並刪除前兩個分段.通過縮放移動拉伸與參考圖相近.切換到正交視圖並鎖定X軸.選擇最前端頂點,通過移動移下方球體拼排.
4. 將兩個球體補洞,使用『合拼對象』工具,將兩個球體結合為槍口.如果兩面完全對齊.則會只有一個前側面.選擇槍口『面』通過 『拉伸』與 拉伸縮放 形成喇叭口.
5. 在喇叭口中添加10邊『全柱體』或『圓錐體』, 通過『銑削』挖空槍口.
6. 等離子槍管其實就八面『全柱體』並旋轉90度.選擇槍管背『面』通過 『拉伸』形成槍托.對槍托頂部與背面使用『倒角』工具.通過『銑削』偷空槍管,
7. 添加十面『全柱體』置於槍管中心,然後『合拼對象』.
8. 創建12分段『圓環』作為彈夾置於槍托之上『合拼對象』.
9. 添加十面『全柱體』然後橫向擠壓形成槍把.通果『球體』作為『銑削』工具形成握手
10. 在槍把下方通過『拉伸』形成兩把刀片,刀尖通過『尖端』工具生成
11. 在握手前方安裝板機,生成六面『全柱體』.選擇最前端『邊』通過移動形成內凹體.選擇最底『面』通過『拉伸』與旋則形成板機.與槍管『合拼』
12. 在槍口上則製作環形吊帶.生成12分段『圓環』與『圓形圓柱體』槍口上方,並與槍口『合拼』
13. 在槍口下方製作能量傳送管. 生成兩個六面『全柱體』作為管箍.分別置於槍口與槍管下方並『合拼』.對管箍進行『倒角』後使用『拉伸』拉出軟管.最後使用『連接邊』工具連接軟管.
14. 優化模型.縮減多邊形量
15. 對模型進行三角剖分.
16. 導出STL模型

trueSpace建模之連接邊

trueSpace建模之連接邊

添加面』Add Face工具可以對環形邊進行『補洞』.但若像上圖鏈接環形管.則trueSpace需要使用『添加邊』Add Edges工具.

  1. 首先選擇模型, 切換到『透視投影』
  2. 滑鼠右擊模型彈出Point Editing
  3. 使用『添加邊』Add Edges工具. 分別選擇兩個『點』生成邊
  4. 第一個『面』需要鏈接兩條『邊』生成. 之後逐條『邊』連接生成『面』
  5. 按右鍵退出

trueSpace建模之導出STL模型

trueSpace建模之導出STL模型

當模型完成『三角剖分』後.需要把模型導出為Maya與3D Studio Max等程序可以理解STL文檔格式.STL格式全稱為stereo lithography『立體』.最早用於模具製作.3D打印切片軟件正是使用這種格式.當你導出STL格式後.就可為生成『紋理』圖作準備,即展開UV紋理座標,將它地平鋪.從而在PhotoShop中處理『紋理』圖.將模型導出為STL格式:

  1. File->SaveAs->Save Object
  2. 在保存對話框選Save As Type(保存類型)中選擇『stereo lithography .STL』

trueSpace建模之三角剖分

trueSpace建模之三角剖分

trueSpace在建模過程中為使模型更易操縱,並一定以三角形形式出現.當trueSpace導出模型給其它三維建模工具,如Maya 或3D Studio Max使用時,所有面都要進行『三角剖分』.所有頂點都會在最基本層級上進行連接,從而使模型由三角形組成.

  1. 首先保存場景
  2. 使用『三角剖分』Triangulate Object工具.它位於『拆分四邊形』Quad Divide中.

trueSpace建模之優化模型

trueSpace建模之優化模型
trueSpace建模之優化模型

大部分3D建模書籍都會在建模完成對模性進行優化.其實在最後才發現模型有致命缺陷,最好是在建模過程中進行優化.因為要儘量降低多變形量.無需百分百按照原圖建模.降低模型多邊形量其實就清除多餘『面』,『邊』,『點』

  1. 首先睇模型多邊形量.右擊Object Tool睇faces與武器多邊形量維持在300左右,而角色多邊形量維持在2000左右.
  2. 將多邊形量保持在最低水平,通過紋理細節提高模型清晰度
  3. 通過『顏色著色器』Color Shaders將模型設為純色
  4. 通過『顯示選項』Display options將線框顏色該為較亮色
  5. 將『渲染模式』設為『實體線框模型對象』Draw Object as Solid Outline
  6. 通過『焊接頂點』Wled Vertices刪除多除面
  7. 刪除多餘『邊』其實也是刪除『面』,通過『刪除點』Erase Vertices實現
  8. 細碎小『面』除左增加模型多邊量外別無益處.一律刪除
  9. 將『渲染模式』設為『透明輪廓模型對象』Draw Objects as transparent Outline並切換為『正交投影』
  10. 通過滾輪放大網格密集區域.刪除距離過近『點』和『面』
  11. 在優化過程中可能會產生怪『邊』.果斷刪除即可
  12. 最後睇下有無空洞進行『補洞』Add Face操作.

trueSpace建模之焊接點

trueSpace建模之焊接點

trueSpace『焊接點』Wled Vertices工具即是將兩個或多個『點』合拼為一個.合併『點』其實也是刪除『邊』與『面』.選擇要合拼兩個相鄰『點』之間『邊』.然後使用『焊接點』工具合併『點』但此方法經常出現奇怪問題.正確方法如下

  1. 點擊選擇模型
  2. 右擊模型彈出『點編輯』Point Edit
  3. 切換到『正交投影』
  4. 選擇Point Edit: Vertices工具,將要合併『點』通過『移動』儘量重合.
  5. 然後按住Ctrl鍵選擇『點』使用『焊接點』Wled Vertices工具合併『點』
Point edit點編 簡介
Highlight 對以選『面』『點』『邊』高亮顯示
Coincident Weld 重合焊縫距離,默認為0.05,可適當調整此值

 

trueSpace建模之圓形圓柱體

trueSpace建模之圓形圓柱體

在trueSpae5之前並無『圓形圓柱體』Rounded Cylinder工具.你只能通過兩個『球體』與『圓柱體』在兩端相『結合』生成.而新版trueSpace已提供這工具.

  1. 首先右鍵點擊『圓形圓柱體』Rounded Cylinder工具,設定參數值.緯度與經度設分別設為4和6可生成圓滑『圓形圓柱體』
  2. 點選『圓形圓柱體』工具在場景生成
  3. 按右鍵退出
  4. 通過『縮放』使其與圖形相批配
Rounded Cylinder參數 簡介
Latitude 緯度最小1, 設為4可讓模型較圓滑
Longitude 經度最小3. 設為6可讓模型較圓滑

 

trueSpace建模之圓環

trueSpace建模之圓環

『圓環』形物體在歷史中不斷製造出來,如『介指』『花環』. 『圓環』Torus是trueSpace基礎模型之一.

  1. 首先右鍵點擊『圓環』工具,設定Torus參數值.緯度與經度設12可生成圓滑『圓環』
  2. 點選『圓柱體』工具在場景生成『圓柱體』
  3. 按右鍵退出
Torus參數 簡介
Latitude 緯度默認值填12,最小3
Longitude 經度默認值填12,最小3.
Inner Rad 內孔徑值範圍0~0.99默認0.5

值越大『圓環』越細內孔越大

值越小『圓環』越粗內孔越小

若為0則是閉孔

 

trueSpace建模之尖端

trueSpace建模之尖端

若把模型削尖,可先『伸展』後將頂『點』合併. 而trueSpace提供『尖端』Tip工具.若想生成多個分段可右擊『尖端』Tip工具,編輯Segments屬性.

  1. 首先選擇模型
  2. 滑鼠右擊模型彈出Point Editing
  3. 選擇『面』
  4. 使用『尖端』Tip工具生成『點』.
  5. 切換到『正交投影』拖動『點』以修正『尖端』
  6. 按右鍵退出
Tip屬性 簡介
Segments 尖端分段,最小默認1
X X軸偏移量,默認值0
Y Y軸偏移量,默認值0
Z 尖端長度默認值0.5
Bend 彎曲未知用途

 

trueSpace建模之補洞

trueSpace建模之補洞

在添加『邊』Edge後, trueSpace有可能生成非封閉面.若無產生新著色區域,需使用『添加面』Add Face工具.此工藝稱為『補洞』.滑鼠右擊『添加面』Add Face工具打開Point edit屬性,一定要啟用高亮顯示.否則無法睇到是否正確選中.

  1. 首先選擇模型
  2. 滑鼠右擊模型彈出Point Editing
  3. 使用『添加面』Add Face工具.選擇要用補空洞
  4. 按右鍵退出
Point edit屬性 簡介
Quadrangles 動態細分四邊形,默認禁用
Triangles 動態細分三角形,默認禁用
No DynDiv 點編輯時無動態細分,默認啟用
Highlight 高亮顯示,默認啟用
Coincident Weld 重合焊接,用於移除焊接點.默認為0.05.相當於點焊接容差值.默認啟用

 

trueSpace建模之細分表面

trueSpace建模之細分表面

建模過程中常手動將『面』細分, trueSpace利用『添加邊』Add Edges工具在兩個頂點之間連上一條『邊』. 此工藝稱為『細分表面』Subdivision.

  1. 首先選擇模型
  2. 滑鼠右擊模型彈出Point Editing
  3. 使用『添加邊』Add Edges工具.選擇要劃分面兩個『點』Vertex生成新『邊』
  4. 若新鍵『邊』跨越另一『邊』.需先劃分該『邊』否則無法生成『邊』.
  5. 按右鍵退出
  6. 若選錯『點』應將新『邊』刪除後重複第三步.

trueSpace建模之倒角

trueSpace建模之倒角

在trueSpace中『倒角』Bevel工具,它並不是直接修改模型.而是伸展『面』Face後『縮小』後形成『倒角』.

  1. 首先選擇模型
  2. 滑鼠右擊模型彈出Point Edit
  3. 選擇『面』Face
  4. 點選Bevel工具生成『倒角』
  5. 右擊Bevel工具彈出屬性編輯
倒角屬性 簡介
Bevel 斜角拉伸高度
Angle 斜角角度

 

trueSpace建模之圓柱體

trueSpace建模之圓柱體

trueSpace基本模型『圓柱體』Cylinder

  1. 首先右键点击『圓柱體』Cylinder工具,设定参数值
  2. 点选『圓柱體』工具在场景生成『圓柱體』
  3. 按右键退出
圓柱體參數 簡介
Latitude 緯度默認值填1
Longitude 經度最小可輸入3生成三角柱

若填4則生成方柱

值越大圓柱越光滑.8是圓柱體較佳值.

Top Radius 若填0則生成圓錐體

若填1則生成圓柱體(默認值)

若大於等與2則生成上寬下窄圓柱

 

 

trueSpace建模之刪除工具

trueSpace建模之刪除工具

所有3D模型均有多個『面』所組成,trueSpace刪除工具有兩款.

  1. 首先選擇模型
  2. 滑鼠右鍵點選模型彈出『Point Edit』
  3. 選擇選區然後刪除
刪除工具 簡介
Delete Face 選擇『刪除面』工具,然後直接點選『面』Face
Erase Vertices 與『選擇工具』相配合先選擇『面』『點』『邊』然後再點擊『刪除點』工具

 

trueSpace建模之選擇工具

trueSpace建模之選擇工具

trueSpace有四個選擇工具,支持『面』Face『點』Vertex『邊』Edge.與『點編輯』工具相配合使用.滑鼠右鍵點擊彈出Selection勾選『背面』和『高亮』.選擇時按CTRL鍵隱藏『3D控制器』,而且最好在『正交投影』下操作

選擇工具 簡介
Select using Rectangle 滑鼠拖放多選
Select using Free-Hand 滑鼠移動多選
Select using Lasso 滑鼠繪畫套索多選
Named selection 對『面』『點』『邊』進行命名,按『名』Named選擇

 

點編輯工具需與選擇工具相配合使用. 簡介
Point Edit:Vertices 選擇『點』Vertex
Point Edit:Edges 選擇『邊』Edge
Point Edit:Faces 選擇『面』Face
Point Edit:Context 自動選擇

 

按鍵 簡介
CTRL 多選並隱藏『3D控制器』3D Controls
SHIFT 取消選擇

 

Selection設定 簡介
Backside 選擇時連背『面』FACE也自動選擇
highlight. 對以選『面』『點』『邊』高亮顯示

 

選擇 簡介
Face
Vertex
Edge.

 

Windows10刪除暫存檔案

Windows10刪除暫存檔案

你明明沒有在C盤安裝很多『軟件』或『遊戲』.卻Windows10經常報『磁盤空間不足』首先刪除所有『臨時文檔』和『禁用休眠

  1. 刪除『C:\Windows\Temp』下所有文檔
  2. 刪除『C:\Users\XXX\AppData\Local\Temp』下所有文檔

若依然如事.可以嘗試查找大於128M

  1. win+e打開『檔案總管』
  2. 打開『C:』磁盤
  3. 在查找中輸入『大小:>128m』
  4. 刪除廢棄安裝文檔與緩存

trueSpace建模之球體

trueSpace建模之球體

trueSpace 基本模型『球體』Sphere由多個『面』FACE組成.可設置『經度』與『緯度』兩值

  1. 滑鼠右擊『球體』Sphere工具,設置『緯度』與『經度』
  2. 設置『緯度』Latitude最小可填
  3. 設置『經度』Longitude最小可填
  4. 若要生成光滑球體『緯度』與『經度』最小要填12
  5. 若要生成上下尖三角淩形『緯度』填2『經度』填3
  6. 點擊『球體』Sphere在場景中添加一個球體.然後右鍵退出.

trueSpace建模之伸展

trueSpace建模之伸展

在Maya建模使用『擠壓』Extrude工具進行『盒式』建模.而trueSpace這工具稱為『伸展』Sweep.

  1. 首先點擊模型對象
  2. 右鍵點擊模型對象,彈出編輯工具
  3. 選擇你需要『伸展』面Face,若要多選按住CTRL鍵選擇面Face,而取消選擇則按SHIFT鍵在點擊面
  4. 點擊『伸展』Sweep工具.然後對伸展出『面』Face進行『移動/縮放/旋轉』編輯

trueSpace建模之銑削

trueSpace建模之銑削

3D建模中若要在模型中雕刻.有一種稱為『銑削』Drilling工藝.即使用『刪減對象』Object Subtraction工具.

  1. 先製作『銑刀』通常為『立方』『圓柱』『球體』
  2. 將『銑刀』對準模型
  3. 選擇模型
  4. 滑鼠點擊『刪減對象』Object Subtraction工具.
  5. 然後點擊『銑刀』
  6. 若『銑刀』要重複使用.滑鼠右鍵『刪減對象』Object Subtraction彈出Booleans勾選『保留銑刀』Keep Drill

trueSpace建模之合拼對象

trueSpace建模之合拼對象

trueSpace中將兩模型對象結合在一起,使用『合拼對象』Object Union如果合併對象『面』Face完全對齊,得到立體對象只有一個前側面,

  1. 點選模型對象
  2. 點擊『合拼對象』Object Union工具
  3. 然後再點選要合拼對象
  4. 若無發對齊可滑鼠右鍵點擊『合拼對象』Object Union打開調整Identity distance值範圍1~100,值越大容差越大,默認值為50.
  5. 若要保留合拼對象,勾選『Keep Drill』

 

trueSpace建模之移動縮放旋轉

trueSpace建模之移動縮放旋轉

trueSpace在新建模型時會彈出『魔力環』,單按右鍵『魔力環』則會消失再無法調出.但可通過左鍵點擊物體彈出『3D控制器』.務必要熟識此工具.否則建模會很困難. 『3D控制器』包裹著模型,每條邊分為三段『中間』與『兩則』.操作時切換到『正交投影』已保正沿某軸完成操作. 若沒有彈出『3D控制器』可打開 preferences 勾選『3D Controls』

若單純通過『移動』『縮放』『旋轉』工具操作.可先隱藏『3D控制器』打開『設置』preferences.取消勾選3D Controls.然後選擇『模型』『點』『邊』『面』進行操作.若鎖定某軸『移動』『縮放』『旋轉』只對某軸進行,可禁用其它兩軸,在『透視投影』X軸橫向Y軸縱向Z垂直於網格.而『正交投影』則有點不同X軸橫行Y軸垂直.

3D控制器 簡介
中間 沿某軸『移動』MOVE模型
兩則 沿某軸『縮放』SCALE模型
軸旋轉球 左鍵點擊『圓球』彈出. 繞某軸『旋轉』ROTATE模型

你也可以通過『object info』精確控制模型,滑鼠右擊白色箭頭彈出

對像信息 簡介
Location 位置
Rotation 旋轉
Size 尺寸
Name 模型名

 

trueSpace建模之座標軸與視點控制器

trueSpace建模之座標軸與視點控制器

學習trueSpace建模需要理解其座標系統.而trueSpace座標軸與OpenGL座標軸有所不同.

座標軸 簡介
X軸 網格橫向為X軸,左則為負右則為正
Y軸 網格縱向為Y軸,指向屏幕為負反向則為正
Z軸 Z軸則垂直於網格下負上正.

要在3D場景中移動『位置』與『視點』可通過『view control』巡覽指示器.它通常在屏幕右下角.但有個更好用工具,按V鍵將視點對齊對象模型『Look at Current Object』

工具 簡介
半圓 繞『對象/視點』旋轉
圓套 拖動則移動控制器,而點擊則修改屬性
橫軸 左鍵繞Y軸旋轉,右鍵繞XZ軸旋轉
橫軸箭頭 視點沿X軸移動
縱軸 左鍵繞X軸旋轉,右鍵繞ZY軸旋轉
縱軸箭頭 視點沿Z軸移動
垂直軸 左鍵繞Z軸旋轉,右鍵繞XY軸旋轉
垂直箭頭 視點沿Y軸移動
步行 按滑鼠移動方向移動
XY平面 左鍵XY平面移動,沿Z軸移動
YZ平面 左鍵YZ平面移動,沿X軸移動
XZ平面 左鍵XZ平面移動,沿Y軸移動
雙下箭頭 飛行模式
單下箭頭 步行模式
十字箭頭 拖放實現控制器縮放
關閉『view control』巡覽指示器
關閉 關閉屬性

 

trueSpace建模之設置參考圖

trueSpace建模之設置參考圖

3D建模你需要『素描圖』或『照片』作為參考圖,最常用方法是創建『plane』平面.然後貼上參考圖

  1. 新建『Scene』場景『File->New->Scene』
  2. 在常境中添加『Plane』平面.
  3. 3D模型尺寸.這裡設長2米高1米
  4. 按『space』空格『Object Tool』選擇平面
  5. 滑鼠右擊『Object Tool』打開『object info』
  6. 『Size』X輸入2(長2米).Y輸入1(高1米).Z輸入0
  7. 『Rotation』x輸入90(垂直圖層).z輸入-180(倒轉圖層)
  8. 『Loaction』x輸入0(中心).y輸入0(中心).z輸入5
  9. 滑鼠點擊『Image Browser』圖片瀏覽器輸入路徑打開圖像
  10. 滑鼠點擊『Material Library』材質庫.把『Image Browser』圖片拖過來『Material Library』.作為『材質』以備使用
  11. 然後將『材質』拖放到『Plane』平面.貼上參考圖
  12. 『Local Light』添加全域燈光.並調至最光.

trueSpace之設置場景單位與對象單位

trueSpace之設置場景單位與對象單位

在3D建模過程中你可能會忽略模型尺寸.雖然你可以通過『縮放』與遊戲相適配.良好建模習慣是預先計算模型尺寸.『3D建模環境』中1米等於『3D遊戲世界』中1米.准好使用公制標準,因為大部分遊戲引擎都以此為標準.

  1. 滑鼠右擊『Object tool』對象工具(白色箭頭)按鈕.打開『object info』面板
  2. 滑鼠點擊『object info』面板右上角『紅三角』展開面板
  3. 將『Convert』對象轉換設置為Meters(米)
  4. 將『Units』對象單位設置為Meters(米)
  5. 將『Units』場景單位設置為Meters(米)

經設定後trueSpace網格單位為1m2.其網格長寬均24格.亦即長寬均24米『Meters』.而『object info』面板也應將其保留.可以隨時睇到『#vertices』頂點量與『#faces』三角量.

設定對象尺寸與角度,位置.

Location 『位置』
Rotation 『旋轉』角(0~360)
Size 『尺寸』以『Obj.Units』為單位

 

Android遊戲之跟隨相機

Android遊戲之跟隨相機

『跟隨相機』與『歐拉相機』喂一區別在於屬性設置不同.跟隨相機常將它固定在移動物體上.它需要以下屬性:

3D空間位置position

向上向量.相當於在相機上貼上一個向上箭頭up

視點向量即相機視口朝向目標lookAt

遠裁剪面far

近裁剪面near

『視場』即視口角度fieldOfView

視口縱橫比aspectRatio

再移動相機時你需要分被相機『位置』與『視點』.『跟隨相機』生成代碼:

設定相機視口,寬與高為屏幕分辨率

gl.glViewport(0,0,width,height);

設置相機矩陣,將當前堆棧設為投影矩陣

gl.glMatrixMode(GL10.GL_PROJECTION);

棧頂載入單位矩陣

gl.glLoadIdentity();

設置透視投影矩陣.定義視錐體參數.『視口角度』『視口縱橫比』『遠近裁剪面』

GLU.gluPerspective(gl, fieldOfView, aspectRation, near, far);

將當前堆棧設為模型視圖矩陣

gl.glMatrixMode(GL10.GL_MODELVIEW);

棧頂載入單位矩陣

gl.glLoadIdentity();

生成方位矩陣,好處在於能防止出現弄反位置或角度

GLU.gluLookAt(gl, position.x,position.y,position.z,

lookAt.x, lookAt.y, lookAt.z,

up.x, up.y, up.z);

Android遊戲之第一人稱相機(歐拉相機)

Android遊戲之第一人稱相機(歐拉相機)

歐拉相機即第一稱射擊遊戲中時用相機.你需要定義以下屬性

『視場』即視口角度fieldOfView

視口縱橫比aspectRatio

遠裁剪面far

近裁剪面near

3D空間位置position

繞y軸旋轉角yaw

繞x軸旋轉角pitch.角度值-90~+90度之間.這類似於頭部傾斜角.若超過這角度則造成骨折.

 

設定歐拉相機視口,寬與高為屏幕分辨率

gl.glViewport(0,0,width,height);

設置歐拉相機矩陣.首先將當前堆棧設為投影矩陣

gl.glMatrixMode(GL10.GL_PROJECTION);

棧頂載入單位矩陣

gl.glLoadIdentity();

設置投影矩陣.你需定義要視錐體

GLU.gluPerspective(gl, fieldOfView, aspectRatio, near, far);

設為模型視圖矩陣

gl.glMatrixMode(GL10.GL_MODELVIEW);

棧頂載入單位矩陣

gl.glLoadIdentity();

繞x軸旋轉角度

gl.glRotatef(-pitch,1,0,0);

繞Y軸旋轉角度

gl.glRotatef(-yaw,0,1,0);

移動相機,相機位於原點且鏡頭指向z軸負方向

gl.glTranslatef(-position.x,-position.y,-position.z);

 

獲取相機方向

相機未旋轉時指向z軸負向

float[] inVec = {0,0,-1,1};

float[] outVec = {0,0,0,0};

設置單位矩陣

float[] matrix = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};

Matrix.setIdentityM(matrix,0);

繞x軸俯仰

Matrix.rotateM(matrix, 0, yaw,0,1,0);

繞Y軸旋轉

Matrix.rotateM(matrix, 0, pitch,1,0,0);

將矩陣和向量相乘的單位方向向量

Matrix.multiplyMV(outVec, 0, matrix, 0, inVec, 0);

direcion.set(outVec[0],outVec[1],outVec[2]);

 

 

Android遊戲之紋理鏈Mipmap

Android遊戲之紋理鏈Mipmap

當相機遠離模型時,模型也會變小.其紋理渲染採樣時會顆粒狀失真.解決失真問題關鍵在於讓屏幕中體積較小物體或遠離視點時.使用低分辯率『紋理Texture』圖像.稱值為紋理鏈.首先獲取紋理尺寸.然後創建比小分辨率紋理圖,把分辨率縮小一半.重複這一過程直到分辨率為1.為了在OpenGL ES使用紋理鏈,需要執行以下兩步

  1. 將縮小係數過濾器設置為GL_XXX_MIPMAP_XXX這裡設置為如果不使用MIPMAP.只會使用首個紋理
  2. 通過縮小紋理創建圖鏈.並將圖片上傳提交給OpenGL ES.作為當前圖層.圖層從0開此,0圖層為原始圖層,然後上傳圖層.然後將其寬度與高除以2不斷創建縮小圖層並上傳.回收位圖.直到寬與高等於零.最後一張紋理1*1像素.則退出循環.並且紋理鏈只能綁定單一紋理
  3. 對於3D模形使用紋理鏈mipmap,而在2D材質無需應用
  4. 若啟用mipmap所繪製物較小.性能提升較明顯.因為GPU只需從小圖片中提取紋理元素
  5. 若啟用mipmap紋理鏈會比沒有使用多佔用33%記憶體.但可換來視角效果提升.特別對遠景物體可修正粒狀失真.
  6. mipmap紋理鏈僅對正方形紋理有效.並且僅在OpenGL ES 1.x獲得支持.

 

紋理位圖載入與綁定.在其基礎加入紋理鏈代碼

GL10 gl = GRAPHICS.gl;

生成空的紋理對象,並獲取id

gl.glGenTextures(1, ids,0);

int id = ids[0];

讀取紋理圖

Bitmap  bitmap = BITMAP.Read(file_name);

綁定紋理ID

gl.glBindTexture(GL10.GL_TEXTURE_2D, id);

設置紋理屬性,紋理過濾器,指定縮小倍數過濾器

gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR_MIPMAP_NEAREST);

指定放大倍數過濾器

gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

獲取紋理寬度與高度

int    width = bitmap.getWidth();

int    height = bitmap.getHeight();

原始圖層索引為0

int level = 0;

while(true) {

上傳紋理

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bitmap, 0);

圖層索引號加一

++level;

計算縮小一半紋理位圖寬與高

int newWidth = bitmap.getWidth()/2;

int newHeight = bitmap.getHeight()/2;

寬與高等於零時跳出循環

if(newWidth == 0)

break;

創建縮小一半紋理位圖

Bitmap  newBitmap = Bitmap.createBitmap(newWidth,newHeight,bitmap.getConfig());

Canvas canvas = new Canvas(newBitmap);

canvas.drawBitmap(bitmap,

new Rect(0,0,bitmap.getWidth(),bitmap.getHeight()),

new Rect(0,0,newWidth,newHeight),

null);

回收位圖資源

bitmap.recycle();

bitmap = newBitmap;

}

取消邦定紋理ID

gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);

回收位圖資源

bitmap.recycle();

 

Android遊戲之射燈

Android遊戲之射燈

射燈是OpenGL ES中燈光中最耗GPU資源燈光.但其3D效果十分逼真.睇上圖.射燈有多個參數需指定.『位置』『照射方向』『照射角度』小於180度、『衰減指數』小於零,若設為0則亮度不衰減,實制『衰減值』與遊戲3D空間尺寸有關.這裡設為0.01.以及三個光照顏色『環境色』『漫反射色』『鏡面反射色』

public class LightSpot {

private float[] ambient  = {1.0f, 1.0f, 1.0f, 1.0f};// 射燈-環境色

private float[] diffuse  = {1.0f, 1.0f, 1.0f, 1.0f};// 射燈-漫反射色

private float[] specular = {0.0f, 0.0f, 0.0f, 1.0f};// 射燈-高光顏色

private float[] position = {0.0f, 3.0f, 0.0f, 1.0f};// 射燈-位置

private float[] direction = {0.0f, -1.0f, 0.0f, 0.0f};// 射燈-方向

private float  cutoff    = 45;// 射燈-角度範圍,缺省為180.0

private float  exponent  = 0.01f;// 衰減指數,缺省為0.0f

int     id = 0;// 光照ID

// 射燈ID 輸入:GL10.GL_LIGHT0至GL10.GL_LIGHT7

LightSpot(int ID){

this.id = ID;

}

//設置射燈方向,轉換為方向向量.最後w分量設0,代表方向

public void setDirection(float x,float y,float z){

direction[0] = x – position[0];

direction[1] = y – position[1];

direction[2] = z – position[2];

direction[3] = 0;

}

// 設定射燈位置.w分量設為1代表位置向量

public void setPosition(float x,float y,float z){

position[0] = x;

position[1] = y;

position[2] = z;

position[3] = 1;

}

// 設定射燈顏色

public void setColor(float r,float g,float b){

ambient[0] = r;

ambient[1] = g;

ambient[2] = b;

ambient[3] = 1;

}

//使能射燈

public void enable(){

GL10 gl = GRAPHICS.gl;

gl.glEnable(id);//使能

gl.glLightfv(id,GL10.GL_AMBIENT, ambient, 0);// 射燈-環境色

gl.glLightfv(id,GL10.GL_DIFFUSE, diffuse, 0);// 射燈-漫反射色

gl.glLightfv(id,GL10.GL_SPECULAR, specular, 0);// 射燈-高光顏色

gl.glLightfv(id,GL10.GL_POSITION, position, 0);// 位置

gl.glLightfv(id,GL10.GL_SPOT_DIRECTION, direction, 0);// 方向

gl.glLightf(id,GL10.GL_SPOT_CUTOFF,cutoff); //  角度範圍

gl.glLightf(id,GL10.GL_SPOT_EXPONENT,exponent);// 衰減指數

}

// 屏蔽射燈

public void disable(){

GL10 gl = GRAPHICS.gl;

gl.glDisable(id);

}

}

Android遊戲之材質

Android遊戲之材質

物體都由特定材質構成.材質決定照射在物體上光返射方式並會改變反射光顏色.材質為多邊形設置材質屬性用於光照計算,它是全域性影響所有繪製多邊形,直到它在次調用.OpenGL ES中需要為每種材質指定『環境色』『漫反射色』『鏡面反射色』RGBA顏色值.此材質吸收光.只有『光源顏色』與『材質顏色』最小值運算(RGB值)得到『反射光顏色』

材質顏色 光源顏色 反射光顏色『最小值運算』
(0,1,0) (1,1,1) (0,1,0)
(0,1,0) (1,0,0) (0,0,0)
(0,0,1) (1,1,1) (0,0,1)

材質類代碼

public class Material {

private float[] ambient  = {1.0f, 1.0f, 1.0f, 1.0f};// 材質-環境色

private float[] diffuse  = {1.0f, 1.0f, 1.0f,  1.0f};// 材質-漫反射色

private float[] specular = {1.0f, 1.0f, 1.0f, 1.0f};// 材質-鏡面顏色

//設置材質環境色

public void setAmbient(float r,float g,float b){

ambient[0]=r;

ambient[1]=g;

ambient[2]=b;

ambient[3]=1;

}

// 設置材質漫反射色

public void setDiffuse(float r,float g,float b){

diffuse[0]=r;

diffuse[1]=g;

diffuse[2]=b;

diffuse[3]=1;

}

// 設置材質鏡面反射色

public void setSpecular(float r,float g,float b){

specular[0]=r;

specular[1]=g;

specular[2]=b;

specular[3]=1;

}

//使能材質

public void enable(){

GL10 gl = GRAPHICS.gl;

gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_AMBIENT,  ambient, 0);// 環境色

gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_DIFFUSE,  diffuse, 0);//  漫反射色

gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_SPECULAR, specular,0);//  鏡面反射色

}

}

Android遊戲之定向光

Android遊戲之定向光

定向光具有方向但沒有位置.首先在3D空間定義一個點,而『方向』表示為該點指向『原點』向量之方向.若在3D空間右則射過來定向光

public class LightDirectional {

private float[] ambient  = {1.0f, 1.0f, 1.0f, 1.0f};// 點光-環境色

private float[] diffuse  = {1.0f, 1.0f, 1.0f, 1.0f};// 點光-漫反射色

private float[] specular = {0.0f, 0.0f, 0.0f, 1.0f};// 點光-高光顏色
private float[] direction = {0, 0, -1, 0};// 定向光-方向

int id = 0;//  燈光ID

構造定向光.燈光id:GL10.GL_LIGHT0至GL10.GL_LIGHT7

public LightDirectional(int ID){

this.id = ID;//  燈光ID

}

設置方向,將位置轉換為方向.將w分量設0,代表方向

public void setDirection(float x,float y,float z){

direction[0] = -x;

direction[1] = -y;

direction[2] = -z;

direction[3] = 0;

}

設置定向光顏色

public void setColor(float r,float g,float b){

ambient[0] = r;

ambient[1] = g;

ambient[2] = b;

ambient[3] = 1;

}

使能設置頂向光顏色環境色、漫反射色、高光顏色、位置.最後一個參數是數組索引

public void enable(){

GL10 gl = GRAPHICS.gl;

gl.glEnable(id);//使能

gl.glLightfv(id,GL10.GL_AMBIENT, ambient, 0);

gl.glLightfv(id,GL10.GL_DIFFUSE, diffuse, 0);

gl.glLightfv(id,GL10.GL_SPECULAR, specular, 0);

gl.glLightfv(id,GL10.GL_POSITION, direction, 0);

}

定向光屏蔽

public void disable(GL10 gl){

gl.glDisable(id);

}

}

Android遊戲之點光

Android遊戲之點光

點光(燈光)特點是有固定3D位置.首先你需要啟用0號燈光

gl.glEnable(GL10.GL_LIGHT0);

設定燈光顏色,燈光索引為0,最後一個參數是顏色數組偏移量.

float[] ambient = {1.0f, 1.0f, 1.0f, 1.0f};// 點光-環境色

float[] diffuse  = {1.0f, 1.0f, 1.0f, 1.0f};// 點光-漫反射色

float[] specular = {0.0f, 0.0f, 0.0f, 1.0f};// 點光-高亮顏色

gl.glLightfv(GL10.GL_LIGHT0,GL10.GL_AMBIENT, ambient, 0);

gl.glLightfv(GL10.GL_LIGHT0,GL10.GL_DIFFUSE, diffuse, 0);

gl.glLightfv(GL10.GL_LIGHT0,GL10.GL_SPECULAR, specular, 0);

設定燈光位置,設定3D空間xyz座標,第四個元素必須設置為1,即光源有位置.

float[] position = {0, 0, 0, 1};// 點光-位置

gl.glLightfv(GL10.GL_LIGHT0,GL10.GL_POSITION, position, 0);

完成渲染後關閉燈光

gl.glDisable(GL10.GL_LIGHT0);

燈光類代碼

public class LightPoint {

private float[] ambient  = {1.0f, 1.0f, 1.0f, 1.0f};// 點光-環境色

private float[] diffuse  = {1.0f, 1.0f, 1.0f, 1.0f};// 點光-漫反射色

private float[] specular = {0.0f, 0.0f, 0.0f, 1.0f};// 點光-高亮顏色

private float[] position = {0, 0, 0, 1};// 燈光位置

int id = 0;//  燈光ID

構造點光(燈泡) 燈光ID輸入:GL10.GL_LIGHT0至GL10.GL_LIGHT7

public LightPoint(int ID ){

this.id = ID;//  燈光ID

}

設定點光(燈泡)位置

public void setPosition(float x,float y,float z){

position[0] = x;

position[1] = y;

position[2] = z;

position[3] = 1;

}

設定點光(燈泡)顏色

public void setColor(float r,float g,float b){

ambient[0] = r;

ambient[1] = g;

ambient[2] = b;

ambient[3] = 1;

}

使能點光(燈泡)

public void enable(){

GL10 gl = GRAPHICS.gl;

gl.glEnable(id);//使能

gl.glLightfv(id,GL10.GL_AMBIENT, ambient, 0);

gl.glLightfv(id,GL10.GL_DIFFUSE, diffuse, 0);

gl.glLightfv(id,GL10.GL_SPECULAR, specular, 0);

gl.glLightfv(id,GL10.GL_POSITION, position, 0);

}

屏蔽點光(燈泡)

public void disable(){

GL10 gl = GRAPHICS.gl;

gl.glDisable(id);

}

}

Android遊戲之環境光

Android遊戲之環境光

環境光是一種特殊光.它沒有位置和方向.它只會均勻照射3D空間中所有物體.在OpenGL ES中啟用全域環境光.

啟用光照

gl.glEnable(GL10.GL_LIGHTING);

環境光純白色,色域範圍為0~1浮點數.影射對應0~255整數

float[] color = {1.0f,1.0f,1.0f,1f};// 環境光浮點數組

設定環境光最後參數color偏移量通常設為0

gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, color, 0);

全域環境光代碼

public class LightAmbient {

static private float[] color = {1.0f,1.0f,1.0f,1f};// 環境光

//設定環境光

static public void setColor(float r,float g,float b ){

color[0] = r;

color[1] = g;

color[2] = b;

color[3] = 1;

}

//使能環境光

static public void enable(){

GL10 gl = GRAPHICS.gl;

gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, color, 0);

}

}

Android遊戲之光照

Android遊戲之光照

光照系統它可以令3D遊戲更加逼真.要模擬光照需要光源發射光線.和被光照照射物.最後需要一台相機捕足光源發射光以及被物體反射光.光照會改變觀察者對被觀察者物體顏色感受.取卻於以下幾個因素

  1. 光源類型
  2. 光源顏色和強度
  3. 光源相對於被照射物體位置和方向
  4. 被照射物材質和紋理

被照射物體反射光強度取決於光照射到至物體平面時光與物體平面夾角.光與其所照射平面越接近垂直,物體表面反射光強度越大

一旦光照射到平面它會以兩種方式反射.鏡面反射會物體上表現出強光效果.物體鏡面反射效果取決於材質.

漫反射:大部分反射光線會因為物體不規則表面而隨機地發散開來,具有光滑表面

鏡面反射:光照射到光滑鏡面後返射回來,具有粗糙不平整表面是不可能形成

而光照射到表面時反射光顏色還取決於光源和材質顏色.

OpenGL ES可以創建出四種不同光源

環境光源:環境光本身非光源,而是由所在環境中其它光源發出光反射在周圍得到.這些環境光混合形成照明效果.環境光無方向並且被環境光照射所有物體都有共同亮度.

點光源:點光源在空間中有固定位置,並且向個方向照射.如燈泡

定向光源:定向光需要一個方向並延伸至無限遠.如太陽是標準定向光源

投射光源:在3D空間中有固定位置.並且有個照射方向.並且具有錐形照射區域.如街燈就是標準投射光.但很耗GPU資源.

OpenGL ES允許指定光顏色與強度,使用RGBA指定顏色

環境光色:被照射無體整體受到光色.物體將會接受這種顏色照射.並且與光源位置和方向無關.

漫反射色:物體反射時受到光色.背著光源另一面不會被照射到

鏡面反射色:鏡面反射色僅僅影響面向觀察者和光源面

投射色:僅影響錐型照射物

啟用光照,一旦開啟光照系統將被應用於所有渲染.你還需要指定光源與材質以及頂點法線確定最後光照效果

GL10.glEnable(GL10.GL_LIGHTING);

渲染完成必需關閉光照.否則影響之後GUI渲染.

GL10.glDisable(GL10.GL_LIGHTING);

OpenGL ES允許每個場景中最多使用8個光源,外加一個全域光源.光源ID從GL10.GL_LIGHT0至GL10.GL_LIGHT7

光源0使能並將其應用所有渲染物

GL10.glEnable(GL10.GL_LIGHT0);

若想單獨禁用某光源

GL10.glDisable(GL10.GL_LIGHT0);

光源實現代碼
環境光
定向光
燈光
射燈
材質

 

 

Android遊戲之矩陣和變換

Android遊戲之矩陣和變換

OpenGL ES矩陣提供以下運算能力

  1. 『矩陣』可將『頂點』移動glTranslatef()
  2. 『矩陣』縮放『頂點』,即將『頂點』個座標分量剩以縮放值glScalef()
  3. 『矩陣』可令『頂點』繞某軸旋轉glRotatef()
  4. 『頂點』剩以『單位矩陣』相當於剩 glLoadIdentity()
  5. 兩個『矩陣』相剩得到新『矩陣』剩以某個頂點.相當於兩『矩陣』剩以頂點後再相剩glMultMatrixf()

OpenGL ES提供有三種『矩陣』

投影矩陣:建立視錐體形狀和尺寸.它決定投影類型和睇到範圍

模型視圖矩陣:在模型空間中用該矩陣變換3D模型.並將其在3D空間中移動

紋理矩陣:用於動態操縱紋理矩陣

設置當前矩陣為『投影矩陣』

GL10.glMatrixMode(GL10.GL_PROJECTION);

在棧頂載入單位據陣

GL10.glLoadIdentity();

然後剩以正交投影矩陣

GL10.glOrthof(-1,1,-1,1, 1, -1);

設置當前矩陣『模型視圖矩陣』

GL10.glMatrixMode(GL10.GL_PROJECTION);

在棧頂載入單位據陣

GL10.glLoadIdentity();

3D空間中平移

GL10.glTranslatef(x,y,z);

繞Y軸旋轉

GL10.glRoate(angle,0,1,0);

將當前棧頂拷貝並壓入棧頂

GL10.glPushMatrix();

矩陣棧頂出棧

GL10.glPopMatrix();

Android遊戲之透明混合

Android遊戲之透明混合

OpenGL要啟用混合,要將每個頂點顏色ALPHA分量置設為0.5f.這樣模型後方對象都能透過模型睇到

1.       OpenGL ES 將在『深度緩存Z-Buffer』和『幀緩存』中渲染模型

2.       OpenGL ES結合z-buffer啟用混合時.必需確保所有透面對象跟據其距離照相機遠近按升序排序.並且從後往線渲染對象.所有非透明必須在透明對象之前被渲染,而非透明對象不需要經過排序

啟用混合:

1.       啟用深度檢測(Z軸緩存)一定要調用glEnable(GL_DEPTH_TEST);.保證光照正確繪製和模形前後正確繪製

2.       啟用混合gl.glEnable(GL10.GL_BLEND);

3.       設定混合方程式gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);

4.       設定模型透明度gl.glColor4f(1.0f, 1.0f, 1.0f,0.5f);

5.       完成渲染後禁用混合glDisable(GL_BLEND);

當需要在OpenGL ES中啟用混合.需要按以下方式渲染

1.       首先渲染所有不透明對象

2.       將所有透明對象按照其與相機距離運近排序(由遠及近)

3.       渲染排好序透明對象(由遠及近)

混合係數

簡介

GL_ZERO

將顏色設為{0,0,0,0}

GL_ONE

不改變當前顏色(r,g,b,a)*(1,1,1,1)

GL_SRC_COLOR

目標與來源相乘dest (r,g,b,a)* sour (r,g,b,a)

GL_DST_COLOR

來源與目標相乘sour (r,g,b,a)* dest (r,g,b,a)

GL_ONE_MINUS_SRC_COLOR

(r,g,b,a)*((1,1,1,1)- sour(r,g,b,a))

GL_ONE_MINUS_DST_COLOR

(r,g,b,a)*((1,1,1,1)- dest(r,g,b,a))

GL_SRC_ALPHA

(r,g,b,a) * sour(alpha)

GL_DST_ALPHA

(r,g,b,a) * dest(alpha)

GL_ONE_MINUS_SRC_ALPHA

(r,g,b,a) * (1- sour(alpha))

GL_ONE_MINUS_DST_ALPHA

(r,g,b,a) * (1- dest(alpha))

GL_SRC_ALPHA_SATURATE

(r,g,b,a) *MIN (sour(alpha),1-dest(alpha))

 

Android遊戲之z-buffer

Android遊戲之z-buffer

OpenGL中『幀緩存』用於儲存屏幕每個像素.而z-buffer『深度緩存』則儲存像素『深度值』.『深度值』為3D空間中對應點與相機『近裁剪面』距離.

OpenGL ES將z-buffer『深度緩存』為每個像素寫入深度值.OpenGL ES會初此『深度緩存』每個深度值為無窮大(大數).

gl.glEnable(GL10.GL_DEPTH_TEST);

每當渲染像素時將像素深度值和『深度緩存』深度值進行比較.如果深度值更小則表示它接近於『近裁剪面』則更新『幀緩存』像素與『深度緩存』深度值.這一過程稱為『深度測試』.如果未能通過『深度測試』則像素與深度值均不寫入『幀緩存』與『深度測試』

每幀渲染時『幀緩存』與『深度緩存』均需清零.否則上一幀數據會被保留下來

gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

在渲染所有3D場景後需關閉『深度測試』.因為渲染2D圖形UI元素無Z軸座標.更無需深度測試.渲染順序由代碼繪製順序決定.

gl.glDisable(GL10.GL_DEPTH_TEST);

Android遊戲之透視投影

Android遊戲之透視投影

2D遊戲使用『正交投影』這意味著模型與視點距離無論多遠,其屏幕尺寸大小總為一至.而3D遊戲則使用『透視投影』模型離視點越近其屏幕尺寸越大.而模型離視點越遠其屏幕尺寸越細.

在『正交投影』就像置身於『矩形盒』.而『透視投影』就像切掉『金字塔』頂部,頂部為『近裁剪面』底部為『遠裁剪面』.而另外四面則分別為『左裁剪面』『右裁剪面』『頂裁剪面』『底裁剪面』

透視錐體由四個參數組成

1.『近裁剪面』與相機矩離

2.『遠裁剪面』與相機矩離

3.視口縱橫比,即視口『近裁剪面』寬高比

4.『視場』指定視錐體寬,也就是它所容納場景

桌面OpenGL帶有GLU輔助函式庫.而Android系統也含有GLU庫.設置投影矩陣

GLU.gluPerspective(GL10 gl,float fieldOfView,float aspectRatio,float near,flat far);

該函式將『透視投影矩陣』與當前矩陣相乘.

gl:為GL10實例

fieldOfView:視場角度,人眼視場角大約67度.加減此值可調整橫向視察範圍

aspectRatio:視口縱橫比,此值為一浮點數

near:遠裁剪面與相機距離

far:近裁剪面與相機距離

『透視投影』代碼

GL10 gl = GRAPHICS.GetGL();

清屏

gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

設定視口

gl.glViewport(0,0, GRAPHICS.GetWidth(),GRAPHICS.GetHeight());

設定當前矩陣為投影矩陣

gl.glMatrixMode(GL10.GL_PROJECTION);

載入單位矩陣

gl.glLoadIdentity();

設置投視投影

GLU.gluPerspective(gl, fieldOfView, aspectRatio, near, far);

設定當前矩陣為模型視圖矩陣

gl.glMatrixMode(GL10.GL_MODELVIEW);

載入單位矩陣

gl.glLoadIdentity();

 

 

 

 

Android遊戲之3D頂點索引

Android遊戲之3D頂點索引

在進入豐富多彩3D世界中需要定以『視錐體』和『精靈頂點』.3D空間中頂點需有xyz座標.並且使用『透視投影』.距離相機越遠,物體越小.離相機較近對象覆蓋較進隊象.3D頂點包含『位置(xyz)』『顏色(rgba)』『法線(x,y,z)』並且完成3D頂點『模型』渲染

public class VERTICES3D {

擁有頂點顏色

boolean hasColor = false;

擁有紋理坐標

boolean hasTexCoord =false;

擁有法線

boolean hasNormal = false;

每個頂點所占空間

int vertex_size = 0;

最大頂點量

int vertex_max = 0;

最大索引量

int index_max = 0;

頂點數組

IntBuffer vertex_array = null;

索引數組

ShortBuffer index_array = null;

頂點緩存

int[] vertex_Buffer;

構造函式分配頂點記憶體,vertex_max為最大頂點量,index_max為最大索引量

VERTICES3D(int vertex_max,int index_max,boolean hasColor,boolean hasTexCoord,boolean hasNormal){

ByteBuffer buffer = null;

this.vertex_max    = vertex_max;

this.index_max     = index_max;

this.hasColor  = hasColor;//  是否擁有頂點顏色

this.hasTexCoord = hasTexCoord;// 是否擁有紋理坐標

this.hasNormal = hasNormal;// 是否擁有法線

計算每頂點所占大小.顏色(rgbs)占4單元.紋理座標(uv)占2單元.3D座標(xyz)占3單元.每個整數占4字節

this.vertex_size = (3 + (hasColor ? 4 : 0) + (hasTexCoord ? 2 : 0) + (hasNormal ? 3: 0)) * 4;

vertex_Buffer = new int[vertex_max * vertex_size / 4];

因為OpenGL ES是以C API結口提供.無法直接使用JAVA數組.因此你需要C數組系統堆棧記憶體.而非JAVA虛擬機記憶體.需要 FloatBuffer分配頂點記憶體.vertex_max為最大頂點量.

buffer = ByteBuffer.allocateDirect(vertex_size * vertex_max);

將『網絡字節』改為『主機字節』或稱為『CPU字節』

buffer.order(ByteOrder.nativeOrder());

獲取頂點整數數組

vertex_array = buffer.asIntBuffer();

每索引占兩BYTE.即OpenGL ES每次最多渲染65536個頂點.

if(index_max > 0){

每個短整形占兩個字節.index_max為最大索引量

buffer = ByteBuffer.allocateDirect(index_max * Short.SIZE/8);

將『網絡字節』改為『主機字節』

buffer.order(ByteOrder.nativeOrder());

獲取頂點短整數數組

index_array = buffer.asShortBuffer();

}

}

將頂點提交給OpenGL數組並觸發

public void setVertices(float[] vertices,int offset,int count){

清空緩存.設定當前位置

vertex_array.clear();

int len = offset + count;

for(int i=offset, j=0; i < len; i++, j++)

vertex_Buffer[j] = Float.floatToRawIntBits(vertices[i]);

寫入數據.移動當前位置

vertex_array.put(vertex_Buffer, 0, count);

觸發

vertex_array.flip();

}

將頂點索引提交給OpenGL數組

public void setIndices(short[] indices,int offset,int count) {

清空緩存.設定當前位置

index_array.clear();

寫入數據.移動當前位置

index_array.put(indices, offset, count);

觸發

index_array.flip();

}

 

獲取索引量

public int getNumIndices(){

return index_array.limit();

}

獲取頂點量

public int getNumVertices(){

return    vertex_array.limit() / (vertex_size/4);

}

綁定頂點數據

public void Bind(){

GL10 gl = GRAPHICS.gl;

啟用頂點數組

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

設置當前寫入位置0

vertex_array.position(0);

設置頂點指針,每個頂點包含xyz分量

gl.glVertexPointer(3, GL10.GL_FLOAT, vertex_size, vertex_array);

擁有頂點顏色

if(hasColor == true) {

啟用頂點顏色數組

gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

設置當前寫入位置3

vertex_array.position(3);

設置顏色指針,RGBA四分量

gl.glColorPointer(4, GL10.GL_FLOAT, vertex_size, vertex_array);

}

擁有紋理坐標

if(hasTexCoord == true){

啟用紋理坐標

gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

設置當前寫入位置

vertex_array.position(hasColor?7:3);

設置紋理坐標指針UV分量

gl.glTexCoordPointer(2, GL10.GL_FLOAT, vertex_size, vertex_array);

}

擁有法線

if (hasNormal = true) {

啟用法線

gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

int offset = 3;

if (hasColor)

offset += 4;

if (hasTexCoord)

offset += 2;

設置當前寫入位置

vertex_array.position(offset);

設置法線指針,xyz分量

gl.glNormalPointer(GL10.GL_FLOAT, vertex_size, vertex_array);

}

}

取消綁定數據

public void Unbind(){

GL10 gl = GRAPHICS.gl;

關閉頂點紋理數組

if(hasColor)

gl.glDisableClientState(GL10.GL_COLOR_ARRAY );

關閉頂點顏色數組

if(hasTexCoord)

gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

關閉法線數組

if (hasNormal)

gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

}

繪畫3D模型.需要先綁3D頂點

public void Draw(int mode,int offset,int count){

GL10 gl = GRAPHICS.gl;

繪畫頂點

if(index_array != null) {// 繪畫

index_array.position(offset);

gl.glDrawElements(mode, count, GL10.GL_UNSIGNED_SHORT, index_array);

}

else {

gl.glDrawArrays(mode, offset, count);

}

}

}

Android遊戲之3D矢量

Android遊戲之3D矢量

與『2D矢量』相比『3D矢量』僅是在x,y軸座標加上z軸座標.還有『點積』和『叉積』運算.與繞軸旋轉算法. 無左計算向量角度函式.

public class VECTOR3D {

3D浮點數座標

public float x,y,z;

角度轉弧度

public static float DEGREES_TO_RADIANS = ((1.0f/180.0f)* (float)Math.PI);

弧度轉角度

public static float RADIANS_TO_DEGREES = ((1.0f/(float)Math.PI)*180.0f);

用於繞軸旋轉

private static final float[] matrix = new float[16];

private static final float[] inVec = new float[16];

private static final float[] outVec = new float[16];

購造函式並設定x,y,z

public VECTOR3D(float x, float y,float z){

this.x = x;

this.y = y;

this.z = z;

}

拷貝3D矢量

public VECTOR3D Copy(){

VECTOR3D v;

v=new VECTOR3D(x,y,z);

return v;

}

重設3D矢量數值

public VECTOR3D set(VECTOR3D v){

this.x = v.x;

this.y = v.y;

this.z = v.z;

return this;

}

3D矢量加法運算

public VECTOR3D add(VECTOR3D v){

this.x = this.x + v.x;

this.y = this.y + v.y;

this.z = this.z + v.z;

return this;

}

3D矢量減法運算

public VECTOR3D sub(VECTOR3D v){

this.x = this.x – v.x;

this.y = this.y – v.y;

this.z = this.z – v.z;

return this;

}

3D矢量乘法(即縮放)

public VECTOR3D mul(float scalar){

this.x = this.x * scalar;

this.y = this.y * scalar;

this.z = this.z * scalar;

return this;

}

計算3D矢量長度

public float Len(){

float len;

len = (float) Math.sqrt(x*x+y*y+z*z);

return len;

}

3D矢量單位化,長度為1

public VECTOR3D normer(){

float len;

len = Len();

if(len != 0){

x = x / len;

y = y / len;

z = z / len;

}

return this;

}

繞某軸旋轉,先定義3D矢量,然後設置矩陣為零,然後用rotateM()旋轉,在乘以3D向量

public VECTOR3D rotate(float angle,float axisX,float axisY,float axisZ){

inVec[0] = x;

inVec[1] = y;

inVec[2] = z;

inVec[4] = 1;

Matrix.setIdentityM(matrix, 0);

Matrix.rotateM(outVec,0, angle, axisX, axisY, axisZ);// 選轉

Matrix.multiplyMV(outVec, 0, matrix, 0, inVec, 0);

x = outVec[0];

y = outVec[1];

z = outVec[2];

return this;

}

計算兩3D矢量之間距離

public float Dist(VECTOR3D v){

float distX = this.x – v.x;

float distY = this.y – v.y;

float distZ = this.z – v.z;

float dist = (float)Math.sqrt(distX*distX + distY*distY + distZ*distZ);

return dist;

}

計算兩個3D矢量之間距離平方

public float DistSquared(VECTOR3D v){

float distX = this.x – v.x;

float distY = this.y – v.y;

float distZ = this.z – v.z;

float dist = distX*distX + distY*distY + distZ*distZ;

return dist;

}

計算兩個3D向量叉積,叉積是一個向量,它與va和vb垂直.

void cross(VECTOR3D va, VECTOR3D vb){

x =  ( (va.y * vb.z) – (va.z * vb.y) );

y = -( (va.x * vb.z) – (va.z * vb.x) );

z =  ( (va.x * vb.y) – (va.y * vb.x) );

}

計算3D向量點積.返回值為浮點數

float dot(VECTOR3D v){

return( (x * v.x) + (y * v.y) + (z * v.z) );

}

3D向量取反數

VECTOR3D inverse(){

this.x = -this.x ;

this.y = -this.y ;

this.z = -this.z ;

return this;

}

}

 

Photoshop之刪除背景色

Photoshop之刪除背景色

照片素材大都有純色背景.可以通過Photoshop魔法捧選擇背景範圍並刪除.但對於大量細小單獨背景魔法捧則略有不足.Photoshop有另一高效工具『顏色範圍』幫你完成所有工作.

  1. Photoshop打開圖片素材
  2. 選取->顏色範圍
  3. 勾選『選取範圍』
  4. 勾選『負片效果』
  5. 縮略圖中白色區域即你想要區域.按確定選定範圍.
  6. 複製選定範圍並新建圖層.按『Ctrl+C』複製、『Ctrl+V』貼上

點陣字體生成器CBFG

點陣字體生成器CBFG

之前講解在Android遊戲種使用『點陣字體』使用Photoshop繪畫.但要對齊所有字符效果並不理想.但『Codehead’s Bitmap Font Generator』可以幫助你生成『點陣字體』.而且把非等距字體自動對齊.通過記錄每個自體寬度生成非等距文本.可以從www.codehead.co.uk/cbfg/免費獲取.以創建羅馬體為例:

  1. 下載並啟動exe
  2. 字體選擇『Times New Roman』
  3. 圖像尺寸『Image Size』輸入512*512(像素)
  4. 單元格寬與高『Cell Height』與『Cell Width』均輸入即每行16個單元格共16行.
  5. 跳過非打印字符『Start Characte』總是輸入32
  6. 字體高與寬『Font Height』『Font Height』均輸入
  7. 顏色『Color』文本白色(最常用顏色).背景黑色.
  8. 抗鋸齒『Anti-Aliasing』選無『None』即可
  9. 效准『Adjust Selection(255) Only』
  10. 字體位置『Position』x與y均輸入否則文本可能超出單元格
  11. 渲染單元格『Show Grid』與渲染寬度『Show Widths』
  12. 字體渲染『粗體』Bold與『斜體』Italic
  13. 輸出『圖像字符』File->Export->Bitmap(BMP).路徑一定要是英文不能漢文.否則不能保存.
  14. 使用Photoshop去除背景顏色.並保存為png圖檔.

 

合成音效發生器as3sfxr

合成音效發生器as3sfxr

最早8bit遊戲機非常適合使用芯片音(chip tunes).芯片音是一種音效通過合成器生成.而as3sfxr則是專業音效工具.可以通過www.bfxr.net下載WINDOWSMAC版本.跳躍音效生成簡介.

  1. 勾選『Create New Sound』自動新建音效
  2. 點擊左上側『Jump』按鍵.隨機生成跳躍『音效』.
  3. 點擊Synth有9種『合成器』可選
  4. 在左下側點選播放『音效』
  5. 點擊右側『Export Wave』按鍵.儲存wav音檔
音效 簡介
Pickup/Coin 拾取/硬幣
Laser/Shoot 激光/射擊
Explosion 爆炸
Powerup 加電
Hit/Hurt 命中/傷害
Jump 跳躍
Blip/Select 彈開/選擇
Randomize 隨機
Mutation 異變

 

合成器 簡介
Triangle 三角形濾波
Sin 正弦濾波
Square 平方濾波
Saw 聲表面波濾波器
Breaker 斷路
Tan 正切濾波
Whistle  
White  
Pink 粉紅噪聲

 

按扭 簡介
Export Wave 儲存單個wav『音效』
Export All Waves 儲存所有wav『音效』
Clear All 清除所有wav『音效』
Duplicate Synth 複製合成『音效』
Copy Link 複製『音效』鏈接

 

Android遊戲之精靈動畫

Android遊戲之精靈動畫

遊戲動畫由關鍵幀(keyframe)組成.將它地依次連續渲染產生運動效果.上圖每幀尺寸64*64像素一共四幀.為產生動畫效果需每隔若干毫秒渲染一幀.當渲染到最後一幀時可選擇重新播放或停止播放.通常要實現『行走』『跳躍』『攻擊』『倒下』需要定義動畫結構

public class ANIMATION {

保存紋理圖檔只能關鍵幀位置.並且其順序與動畫回放順序相同

public REGION[] frames = null;

保存每幀間隔時間,用於確定每幀切換時間.

public float     duration;

動畫播放模式,分為『循環播放』與『單次播放』

public static final int LOOPING = 0;

public static final int NONLOOPING = 1;

構建動畫輸入『每幀間隔』與每幀『紋理區域』

ANIMATION(float duration,REGION … frames){

this.duration = duration;

this.frames = frames;

}

輸入時間提取關鍵幀.播放模式是單次或循環,基於『狀態時間』除以『每幀間隔』計算幀索引.

public REGION GetKeyFrame(float stateTime,int mode){

int index = (int)(stateTime/duration);

if(mode == NONLOOPING)// 單次播放

index = Math.min(frames.length-1, index);

else

index = index % frames.length;

return frames[index];

}

Android遊戲之點陣字體

Android遊戲之點陣字體

在遊戲中渲染字符,數字.在這裡介紹『點陣字體』技術.每個子圖表示單個字符如0~9.如上圖.『點陣字體』遊戲中渲染文本已非常古老.它通常包含ASCII碼字符圖像.此圖像程為『圖像字符』(glyph).ASCII字符集有128個字符.但只有95個可打印字符.索引號從32到126個.為節約空間『點陣字體』只包含可打印字符.95個字符每行16個字符分6行.ASCII只適用於存儲和顯示標準『拉丁字母』.但已滿足大部分單機遊戲.首先創建96個紋理區域.每區域映射到『點陣字體』中某圖像字符.

public REGION[] array = new REGION[96];

因為ASCII頭32個字符非打印字符無在『圖像字符』中渲染.首字符是空格只要講String轉為char字符減去空格

c = text.charAt(i) – ‘ ‘;

即可獲得紋理區域數組索引.要注意索引值必需在0~95之間否則會越界訪問.

region = array[c];

渲染ASCII文本.這裡簡單起見字體只時用『固定寬度』.但現代文本渲染字體寬度是非固定.可為每個字符設定不同字寬.

BATCHER.Draw(x, y, width, height, region);

上圖我使用Photoshop生成『圖像字符』.但其實有專門免費工具Codehead’s Bitmap Font Generator簡稱CBFG.可從www.codehead.co.uk/cbfg/下載

Android遊戲之半透明混合處理

Android遊戲之半透明混合處理

2D遊戲紋理渲染必須將『背景色』去除.JPEG格式不支持存儲像素點alpha值.將透明色alpha值設為零.需使用PNG格式.若紋理圖像沒有alpha通道時OpenGL ES自動將alpha設為1.但混合開銷很大而目前手機上GPU都不能對大量像素禁行混合.所以在需要時才啟用Blend『混合』.在OpenGL ES中啟動半透明混合處理
gl.glEnable(GL10.GL_BLEND);
設定『來源色』和『目標色』組合方程.
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
啟用2D紋理渲染
gl.glEnable(GL10.GL_TEXTURE_2D);
渲染三角形

禁用2D紋理渲染
gl.glDisable(GL10.GL_TEXTURE_2D);
結束渲染後禁用混合
gl.glDisable(GL10. GL_BLEND);

Android遊戲之入口『屏幕』

Android遊戲之入口『屏幕』

遊戲主選單 『屏幕』通常有 『圖標』『選單 』.所要做是『觸摸』選單 時切換『屏幕』.計算出選單 項『矩形區域』與觸碰點重疊時切換『屏幕』在這裡設定四個選單 項.你需要繪畫『文本紋理』寬高相等並是2倍數.背景色設為透明色.並且保存為『.PNG』. 『文本紋理』好在於研發時用英文文本之後再漢化.

你需定義『2D相機』屏幕原點在左下角、VECTOR2D『點』把觸碰座標轉換屏幕座標、渲染『圖標』區域.定義四個按鈕『新遊戲』『繼續遊戲』『高分榜』『遊戲設定』每當更新屏幕update()對四個選單 區域進行overlap()『矩形碰撞測試』.而渲染『屏幕』時則先渲染『背景』後渲染『選單』

選單項 簡介
NEW 啟動新遊戲
PLAY 繼續遊戲按扭
Highscores 高分排名榜
Settings 遊戲設定

public class ScreenMain  extends SCREEN{

private CAMERA2D camera;

private VECTOR2D  touchPoint;

private    RECT2D Bounds_Logo;

private    RECT2D Bounds_New;

private    RECT2D Bounds_Play;

private   RECT2D Bounds_Highscores;

private   RECT2D Bounds_Settings;

購造入口屏幕

public ScreenMain(){

camera = new CAMERA2D(320, 480);// 相機

Bounds_Logo = new RECT2D(WORLD.PIXEL_WIDTH/2, WORLD.PIXEL_HEIGHT/2 + 160 , 256, 128);

Bounds_New = new RECT2D(WORLD.PIXEL_WIDTH/2, WORLD.PIXEL_HEIGHT/2 + 64,  128, 32);

Bounds_Play = new RECT2D(WORLD.PIXEL_WIDTH/2, WORLD.PIXEL_HEIGHT/2 + 32,  128, 32);

Bounds_Highscores = new RECT2D(WORLD.PIXEL_WIDTH/2, WORLD.PIXEL_HEIGHT/2 , 256, 32);

Bounds_Settings = new RECT2D(WORLD.PIXEL_WIDTH/2, WORLD.PIXEL_HEIGHT/2 – 32,  256, 32);

touchPoint        = new VECTOR2D();// 觸碰點

}

更新屏幕都觸碰座標

@Override

public void update(float deltaTime){

for(int i = 0; i < TOUCH.Point_Count; i++){

int action = TOUCH.Point_Action[i];

if(action != TOUCH.ACTION_UP)

continue;

float x = TOUCH.Point_X[i];

float y = TOUCH.Point_Y[i];

touchPoint.set(x, y);

camera.TouchToWorld(touchPoint);//觸摸坐標轉世界坐標

if(Bounds_New.overlap(touchPoint)){// 新遊戲按扭

TOUCH.clear();// 清空

SOUND.Play(ASSETS.sound_click);// 點擊

GAME.setScreen(GAME.getGameScreen());// 遊戲按扭

return;

}

else

if(Bounds_Play.overlap(touchPoint)){// 遊戲按扭

SOUND.Play(ASSETS.sound_click);// 點擊

GAME.setScreen(GAME.getGameScreen());// 遊戲按扭

TOUCH.clear();// 清空

break;

}

else

if(Bounds_Highscores.overlap(touchPoint) ){// 高分按扭

SOUND.Play(ASSETS.sound_click);// 點擊

GAME.setCurrentScreen(GAME.getScoreScreen());

TOUCH.clear();// 清空

break;

}

else

if(Bounds_Settings.overlap(touchPoint)){// 設定按鈕

SOUND.Play(ASSETS.sound_click);// 點擊

GAME.setScreen(GAME.getSettingsScreen());

TOUCH.clear();// 清空

break;

}

}

TOUCH.clear();// 清空

}

渲染屏幕

@Override

public void present(float deltaTime){

GL10            gl   = GRAPHICS.gl;

GLSurfaceView view   = GRAPHICS.gl_View;

gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

camera.SetViewportAndMatrices();

gl.glEnable(GL10.GL_TEXTURE_2D);

BATCHER.Begin(ASSETS.texture_background);

BATCHER.Draw(WORLD.PIXEL_WIDTH/2,WORLD.PIXEL_HEIGHT/2, WORLD.PIXEL_WIDTH, WORLD.PIXEL_HEIGHT, ASSETS.region_background);// 渲染背景

BATCHER.End();

// 設為透明

gl.glEnable(GL10.GL_BLEND);

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

BATCHER.Begin(ASSETS.texture_text);

BATCHER.Draw(Bounds_Logo,  ASSETS.region_logo);// 圖標按扭

BATCHER.Draw(Bounds_New,  ASSETS.region_new);// 圖標按扭

BATCHER.Draw(Bounds_Play,  ASSETS.region_play);// 主選單

BATCHER.Draw(Bounds_Highscores,ASSETS.region_highscores);// 高分按扭

BATCHER.Draw(Bounds_Settings, ASSETS.region_settings);// 設定按扭

BATCHER.End();

gl.glDisable(GL10.GL_TEXTURE_2D);// 禁用

}

暫停保存設置

@Override

public void pause(){

}

恢復

@Override

public void resume(){

}

清除/銷毀

@Override

public void dispose(){

}

返回鍵

@Override

public boolean back(){

SOUND.Shutdown();

MUSIC.Shutdown();

return  true;

}

}

 

 

Android遊戲之GLSurfaceView

Android遊戲之GLSurfaceView

遊戲設計中通常『更新』『渲染』放在同一線程中.在Windows可以在主線程將『消息驅動』改為『實時驅動』.把『更新』『渲染』放在主線程中.而Android卻無法做到這點.但提供GLSurfaceView可建立獨立線程在背後實現『更新』『渲染』.你需要實現監聽接口GLSurfaceView.Renderer.並註冊到GLSurfaceView中.監聽接口需要分別重寫『創建』『調整大細』『渲染』.GLSurfaceView.Renderer可獲得GL10.通過它方可訪問OpenGL ES API.而GL10中10代表OpenGL ES 1.0標準.可以將GLSurfaceView封裝成獨立控件.從而在layout『佈局』中嵌入.

public class RenderView extends GLSurfaceView implements GLSurfaceView.Renderer {

每當Activity恢復或啟動創建. EGLConfig設置Surface顏色與深度

public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig);

當view尺寸發生改變時調用,傳入寬與高

public void onSurfaceChanged(GL10 gl10, int width, int height);

調用『渲染』『更新』完成幀繪製.但每秒不超過60幀.

public void onDrawFrame(GL10 gl10);

令外還需重寫『恢復』『暫停』

『恢復』重啟渲染線程,在Activity恢復顯示時在Activity.onResume()中調用

public void onResume();

『暫停』退出渲染線程,當Activity進入後臺時在Activity.onPause()中調用

public void onPause();

}

編輯layout『佈局』文檔main.xml添加

<net.bookcard.aa.RenderView

android:id=”@+id/render_view”

android:layout_width=”fill_parent”

android:layout_height=”fill_parent” />

定義view狀態

public static final int       STATE_INIT       = 0;// 初此

public static final int  STATE_RUN       = 1;// 運行

public static final int  STATE_PAUSED    = 2;// 暫停

public static final int  STATE_FINISHED  = 3;// 結束

public static final int  STATE_IDLE       = 4;// 閒置

int view_width,view_height;// 寬與高

int state = STATE_INIT;// 初此狀態

long    startTime ;// 啟動時間

創建Surface獲取屏幕

public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig){

SCREEN  screen = GAME.getCurrentScreen();// 當前屏幕

if(state == STATE_INIT) {// 初此

Init(gl, this);

screen = GAME.getMainScreen();

GAME.setCurrentScreen(screen);

}

else {//  重新載入資源

ASSETS.reload();

}

screen = GAME.getCurrentScreen();

state = STATE_RUN;// 運行

startTime = System.nanoTime();// 獲取啟動時間

}

大小發生改變

public void onSurfaceChanged(GL10 gl, int width, int height){

this.view_width = width;// 寬

this.view_height = height;// 高

}

更新並渲染.System.nanoTime()返回納秒, 1000000000納秒=1秒.通過兩次時間測量計算間隔時間

public void onDrawFrame(GL10 gl){

SCREEN screen = GAME.getCurrentScreen();

if(state == STATE_RUN){// 運行

float deltaTime = (System.nanoTime()-startTime) / 1000000000.0f;

startTime = System.nanoTime();// 獲取當前時間

screen.update(deltaTime);// 更新

screen.present(deltaTime);// 渲染

}

else

if(state == STATE_PAUSED) {// 暫停

screen.pause();

}

else

if(state == STATE_FINISHED) {// 結束

screen.pause();

screen.dispose();

}

}

恢復渲染在Activity.onResume()中調用

public void onResume(){

super.onResume();

MUSIC.Resume();

}

暫停渲染在Activity.onPause()中調用

public void onPause(){

state = STATE_PAUSED;// 暫停

super.onPause();

MUSIC.Pause();

}

初此遊戲系統個部件

void Init(GL10 gl, GLSurfaceView view){

GRAPHICS.Init(gl,view);

SYSTEM.Init(context);// 系統

FileIO.Init(context);// 文件讀寫

BITMAP.Init(context);// 位圖

SOUND.Init(context,100);// 聲音

MUSIC.Init(context,100);// 音樂

TOUCH.Init(this);// 觸摸模塊

GAME.Init();//  屏幕切換系統

BATCHER.Init(1500);// 精靈批處理

ASSETS.load();// 資源

}

Android遊戲之設定讀寫與得分

Android遊戲之抽象『屏幕』

在遊戲啟動需從磁盤讀取遊戲選項與得分.在GLSurfaceView.Renderer.onSurfaceCreated()中讀取讀取.首先確立文檔名

String  filename = “settings.dat”;

打開文檔並返回輸入流

InputStream file = FileIO.ReadFile(filename);

打開讀取器

InputStreamReader stream = new InputStreamReader(file);

打開讀取緩存

BufferedReader in = new BufferedReader(stream);

String text;

讀取遊戲前五個最高得分

int[]   highscores = new int[] {0,0,0,0,0};// 高分榜

for(int i=0;i<5;++i){

讀取一行文本,並轉換為得分.

text = in.readLine();

highscores[i] = Integer.parseInt(text);

}

用戶可能關閉音量

text = in.readLine();

boolean soundEnabled = Boolean.parseBoolean(text);

讀取遊戲音量.值為浮點數(0~1)

text = in.readLine();

float soundVolume = Float.parseFloat(text);

遊戲關卡整數值大於1

text = in.readLine();

int     level = Integer.parseInt(text);

道具量整數值大於或等於零

text = in.readLine();

int     bombs = Integer.parseInt(text);

讀取完畢關閉讀取緩存

in.close();

 

在遊戲退出時需將所有選項與得分寫入磁盤.在GLSurfaceView.onPause()中保存.打開文檔並返回輸出流

OutputStream file = FileIO.WriteFile(filename);

打開寫入器

OutputStreamWriter stream = new OutputStreamWriter(file);

打開寫入緩存

BufferedWriter out = new BufferedWriter(stream);

寫入遊戲五個最高得分

for(int i=0;i<5; i++){

out.write(Integer.toString(highscores[i]));

寫入換行

out.write(“\r”);

}

寫入聲音開關

out.write(Boolean.toString(soundEnabled));

out.write(“\r”);

寫入音量值(0~1)浮點數

out.write(Float.toString(soundVolume));

out.write(“\r”);

寫入當前關卡整數值

out.write(Integer.toString(level));

out.write(“\r”);

寫入道具量整數值

out.write(Integer.toString(bombs));

out.write(“\r”);

關閉寫入緩存

out.close();

 

加入得分並進行高分排序

public static void addScore(int score){

for(int i=0;i<5; ++i){

if(highscores[i] < score){

for(int j=4; j>i; –j)

highscores[j] = highscores[j-1];// 往後移

highscores[i] = score;// 插入分數

break;

}

}

 

Android遊戲之抽象『屏幕』

Android遊戲之抽象『屏幕』

設計抽象『屏幕』SCREEN類.為以後屏幕設計提供模板.update()更新所有對像.而present()則負責渲染. deltaTime為每次調用時間間隔. pause()與resume()當遊戲『暫停』與『恢復』時調用. 而dispose()則在遊戲退出時銷毀所有資源.釋放『記憶體』並保存設置.

public abstract class SCREEN {

public abstract void update(float deltaTime);// 更新

public abstract void present(float deltaTime);// 渲染

public abstract void pause();// 暫停

public abstract void resume();// 恢復

public abstract void dispose();// 清除/銷毀

public abstract boolean back();//檢查返會鍵

}

另需要『屏幕切換系統』GAME.每當設換屏幕時首先『暫停』然後『銷毀』資源並保存設置.然後設定新屏幕並『恢復』與『更新』.

public class GAME {

static private SCREEN  screen = null;// 當前屏幕

設置當前屏幕

static public void setCurrentScreen(SCREEN newScreen){

if(screen != null){

screen.pause();// 暫停

screen.dispose();// 銷毀

}

screen = newScreen;

screen.resume();// 恢復

screen.update(0);// 更新

}

獲取當前屏幕

static public SCREEN getCurrentScreen() {

return screen;

}

}

WordPress之啟用Jetpack後控制臺載入慢

WordPress之啟用Jetpack後控制臺載入慢

近日Wordpress進入控制臺極慢.經常出現:

『正在連線到www.gstatic.com…』

但Android手機無此問題.此現像是更新Jetpack後出現. Jetpack版本是6.3.3解卻方法有二.禁用Jetpack或使用舊版.

  1. 手工下載Jetpack 6.3.2
  2. 手工刪除Jetpack 6.3.3
  3. 安裝外掛->上傳外掛->『指定路徑』->立即安裝
  4. 啟用外掛.使用com帳號登入

Android遊戲之紋理區域

Android遊戲之紋理區域

『紋理區域』指『紋理』中『矩形區域』.2D紋理通常尺寸較小.可以將多個2D紋理放在單一個紋理圖中.以提升OpenGL ES渲染性能.將其像素座標到紋理座標轉進行封裝.u1,v1為紋理座標左上角.u2,v2為紋理座標右下角.以確定紋理區域.值範圍0~1

public class REGION {

public TEXTURE texture;// 紋理

public float u1,v1,u2,v2;// 紋理坐標

像素坐標轉紋理坐標.輸入『像素』左上角與『寬和高』

public REGION(TEXTURE texture,float x,float y,float width,float height){

u1 = x/(float)texture.width;

v1 = y/(float)texture.height;

u2 = u1 + width/(float)texture.width;

v2 = v1 + height/(float)texture.height;

this.texture = texture;

}

}

Android遊戲之精靈批處理

Android遊戲之精靈批處理

OpenGL ES盡可能每次渲染多個精靈.以提高渲染性能.為此需要知道精靈『位置』『尺寸』『紋理區域』.『批處理』將多個渲染合拼在一起.這對GPU有利.批處理設立浮點數『緩存』保存頂點.該緩存區初此時需清空.定義『批處理』結構BATCHER.

public class BATCHER {

成員Buffer為浮點型數組用於存儲頂點.

private static float[] buffer;

成員indices為短整形索引.以三角形排列用於儲存頂點.

public static short[] indices ;

頂點列表用於批處理渲染

private static VERTICES vertices;

緩存寫入索引初此為零

private static int index = 0;

精零數量初此為零

public static int num = 0;

初次批處理.max精靈為最大量.

public static void Init(int max){

分配2D精靈頂點緩存,每個精靈有4頂點,每頂點要4個浮點數(空間坐標x,y兩個,紋理坐標u,v兩個)

buffer = new float[max44];

分配頂點緩存.『頂點』『紋理座標』『索引』

vertices = new VERTICES(max * 4, max*6, false,true);

分配索引每個精靈6個索引

indices = new short[max*6];

int len = indices.length;// 索引數組長度

index = 0;// 緩存寫入索引

num = 0;//  精零數量

生成頂點索引

for (int i=0,j=0; i < len; i += 6, j += 4) {

indices[i + 0] = (short)(j + 0);

indices[i + 1] = (short)(j + 1);

indices[i + 2] = (short)(j + 2);

indices[i + 3] = (short)(j + 2);

indices[i + 4] = (short)(j + 3);

indices[i + 5] = (short)(j + 0);

}

設置頂點索引

vertices.SetIndices(indices, 0, indices.length);

}

準備進行批處理渲染.首先綁定紋理.並將『精零數量』『緩存索引』置零

public static void Begin(TEXTURE texture){

texture.Bind();// 綁定紋理

num = 0;//  精零數量

index = 0;// 緩存寫入索引

}

結束批處理渲染.將頂點提交給OpenGL數組並觸發.綁定頂點數據後進形三角形渲染.然後取消數據綁定.每次調用繪畫時.向緩存區中添加4個頂點參數為『位置』『顏色』『索引』『紋理區域』

public void boolean End(){

vertices.SetVertices(buffer,0,index);

vertices.Bind();

vertices.Draw(GL10.GL_TRIANGLES, 0, num * 6);

vertices.Unbind();

}

批處理繪畫計算精靈中心『位置』及『寬和高』.和『紋理區域』.生成精靈『左下角』與『右上角』『空間座標』與『紋理座標』

public static void Draw(float x,float y,float width,float height,REGION region){

float halfWidth = width/2.0f;// 寬度一半

float halfHeight = height/2.0f;//高度一半

float x1 = x – halfWidth;

float y1 = y – halfHeight;

float x2 = x + halfWidth;

float y2 = y + halfHeight;

buffer[index++] = x1;

buffer[index++] = y1;

buffer[index++] = region.u1;

buffer[index++] = region.v2;

buffer[index++] = x2;

buffer[index++] = y1;

buffer[index++] = region.u2;

buffer[index++] = region.v2;

buffer[index++] = x2;

buffer[index++] = y2;

buffer[index++] = region.u2;

buffer[index++] = region.v1;

buffer[index++] = x1;

buffer[index++] = y2;

buffer[index++] = region.u1;

buffer[index++] = region.v1;

++num;

}

}

在調用時首先清理緩存並存入紋理.但只能對使用同一紋理精靈進行批處理.最後結束渲染.如下:

BATCHER.Begin(Texture);

BATCHER.Draw(X,Y,WIDTH,HEIGHT,Region);

BATCHER.End();

Android遊戲之頂點索引

Android遊戲之頂點索引

OpenGL均採用三角形列表進行渲染.每個三角形都有三個頂點.在有些情況下兩個或多個三角形會共用頂點.如上圖有兩個頂點具有相同『位置』『顏色』『紋理座標』.但甘浪費空間.更好解卻方法是將所有頂點保存在列表.而三角形頂點保存索引.OpenGL ES要求索引值使用短整數或字節.即OpenGL ES每次最多渲染65536個頂點.

我地需要一個Vertices類,用於存儲每個頂點『位置』『顏色』與『紋理座標』,並且它需要兩個選項.頂點是否『顏色』與『紋理座標』

public class VERTICES {

boolean color_have = false;//  擁有顏色

boolean texture_have =false;// 擁有紋理坐標

int vertex_size = 0;// 每個頂點所占大小

使用FloatBuffer保存頂點

FloatBuffer  vertex_array = null;

使用ShortBuffer頂點索引

ShortBuffer index_array = null;

頂點隊列分配記憶體,vertex_max為最大頂點量, index_max為最大索引量

VERTICES(int vertex_max,int index_max,boolean color_have,boolean texture_have){

this.color_have  = color_have;//  擁有頂點顏色

this.texture_have = texture_have;// 擁有紋理坐標

計算每頂點所占大小.顏色占4單元.紋理座標占2單元.2D座標占2單元.每個整數占4字節

int vertex_size = (2 + (color_have?4:0) + (texture_have?2:0) ) * 4;

因為OpenGL ES是以C API結口提供.無法直接使用JAVA數組.因此你需要C數組系統堆棧記憶體.而非JAVA虛擬機記憶體.需要 FloatBuffer分配頂點記憶體.

vertex_max為最大頂點量.

ByteBuffer buffer = ByteBuffer.allocateDirect(vertex_size * vertex_max);

將『網絡字節』改為『主機字節』或稱為『CPU字節』

buffer.order(ByteOrder.nativeOrder());

獲取整數數組

vertex_array = buffer.asIntBuffer();

每個短整形占兩個字節.index_max為最大索引量

buffer = ByteBuffer.allocateDirect(index_max * Short.SIZE/8);

將『網絡字節』改為『主機字節』

buffer.order(ByteOrder.nativeOrder());

頂點短整數數組

index_array = buffer.asShortBuffer();

}

將頂點提交給OpenGL數組並觸發

public void SetVertices(float[] vertices,int offset,int count){

vertex_array.clear();// 清空緩存.設定當前位置

int len = offset + count;

for(int i=offset, j=0; i < len; i++, j++)

vertex_Buffer[j] = Float.floatToRawIntBits(vertices[i]);

vertex_array.put(vertex_Buffer, 0, count); // 寫入數據.移動當前位置

vertex_array.flip();// 觸發

}

將頂點索引提交給OpenGL數組

public void SetIndices(short[] indices,int offset,int count) {

index_array.clear();// 清空緩存.設定當前位置

index_array.put(indices, offset, count); // 寫入數據.移動當前位置

index_array.flip();// 觸發

}

綁定數據

public void Bind(){

GL10  gl = GRAPHICS.gl;

啟用頂點數組

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

設置當前寫入位置0

vertex_array.position(0);

設置頂點指針,每個頂點兩個元素.xy兩分量

gl.glVertexPointer(2, GL10.GL_FLOAT, vertex_size, vertex_array);

if(color_have == true){//顏色

啟用頂點顏色數組

gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

設置當前寫入位置2

vertex_array.position(2);

設置顏色指針,RGBA四分量

gl.glColorPointer(4, GL10.GL_FLOAT, vertex_size, vertex_array);

}

if(texture_have ){// 紋理坐標

啟用紋理坐標數組

gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

vertex_array.position(color_have?6:2);// 寫入位置

設置紋理坐標指針,UV兩分量

gl.glTexCoordPointer(2, GL10.GL_FLOAT, vertex_size, vertex_array);

}

}

取消綁定數據

public void Unbind(){

GL10 gl = GRAPHICS.gl;

關閉頂點紋理數組

if(color_have)

gl.glDisableClientState(GL10.GL_COLOR_ARRAY );

關閉頂點顏色數組

if(texture_have)

gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

}

繪畫三角形

public void Draw(int mode,int offset,int count){

GL10 gl = GRAPHICS.gl;

繪畫頂點

if(index_array != null){// 繪畫

index_array.position(offset);//

gl.glDrawElements(mode, count, GL10.GL_UNSIGNED_SHORT, index_array);

}

else{

gl.glDrawArrays(mode, offset, count);

}

}

}

投幣式淨水機之濾芯效果分析

投幣式淨水機不但擁有七個以上濾芯.而且還裝有紫外線殺菌燈.只要定期更換濾芯制水品質便有保正.

過濾層級 濾芯
1 『5微米中空棉濾芯』也稱『PP棉濾芯』
2/3 『壓縮活性碳芯』兩個
4 『1微米中空棉濾芯』也稱『PP棉濾芯』
5 『反滲透膜濾芯』也稱『PR膜』
6 『後置活性碳慮芯』
7 『礦化慮芯』
8 紫外線殺菌燈

 

濾芯 功能簡介
『5微米中空棉濾芯』也稱『PP棉濾芯』 去除水中大於5微米懸浮物如『鐵銹』『砂石』
『壓縮活性碳芯』兩個 去除水中氯氣、異味、異色、有機物、改善水質口感.
『1微米中空棉濾芯』也稱『PP棉濾芯』 去除水中大於1微米懸浮物和雜質.
『反滲透膜濾芯』也稱『PR膜』 『PR膜』孔徑為0.0001微米,需經高壓泵進入『PR膜』.去除『細菌』『病毒』『有機物』『重金屬』『農藥』『膠體』只有純水能透過『PR膜』而廢水則被排出,廢水不能飲用.
『後置活性碳慮芯』 去除水中異味,水質甘甜.
『礦化慮芯』 加入各種微量礦物元素.並進入水箱存儲
『紫外線殺菌燈』 殺菌後出水

 

濾芯 更換週期
『5微米中空棉濾芯』 1到2個月或PP濾棉變褐色
『壓縮活性碳芯』兩個 2到3個月或水質有異味
『1微米中空棉濾芯』 2到3個月或水質有異味
『反滲透膜濾芯』也稱『PR膜』 18到24個月或PP濾棉變褐色
『後置活性碳慮芯』 夏季每月更換,東季每2個月更換.更換越頻繁口感
『礦化慮芯』 每半年更換.各種微量礦物元素含量越高.

 

投幣式净水機之耗水電量

投幣式净水機會耗電也繪水.所以要計算出成本.才能算出最終售價.因售水機內部設計統一所以其耗水電量均一至. 而且商業水電比家用要貴幾倍.

制水攻率 純水制水量 說明簡介
100W 63(L/H) 每小時制水63升.每度電可制升水630升.若每天售水1000升.則為1度電

 

純水與廢水比 說明簡介
1/3 每頓水喉水可制純水0.25頓.而廢水是0.75噸.因1噸=1000升.即每噸可制水250升.

 

每月售水 價格 商業水 商業電 成本/升 收益
1000升 5升2元 每頓5元 每度1.5元 0.0065 793.5

 

Android遊戲之『軸對齊邊界盒』碰撞

Android遊戲之『軸對齊邊界盒』碰撞

大部分模形都適合使用『圓形碰撞』.但若模形呈長條形則適合使用『矩形碰撞』.也稱為『軸對齊邊界盒碰撞』.特點是頂底邊與X軸平行,左右邊與Y軸平行.碰撞算法以包圍著對象最小矩形.但缺點是無法隨物體旋轉.速度快但精度較差.若定義矩形則由中心位置與長寬所組成.

public class RECT2D {

矩形中心位置

public VECTOR2D center;

矩形寬與高

public float  width;

public float  height;

購造『軸對齊邊界盒』輸入中心位置與寬高.

public RECT2D(float x,float y,float width,float height){

this.center = new VECTOR2D(x, y);    // 中心點

this.width  = width;

this.height = height;

}

『點』與『矩形』碰撞.若點為於四條邊之內則發生碰撞

public boolean overlap(VECTOR2D point){

if(point.x  < center.x + width/2 &&

point.x  > center.x – width/2 &&

point.y  < center.y + height/2 &&

point.y  > center.y – height/2 )

return true;

else

return false;

}

兩矩形碰撞測試,原點在左下角.算法睇上圖有D複雜.『矩形1左邊』在『矩形2右邊』之左則.『矩形1右邊』在『矩形2左邊』之右則.『矩形1底邊』在『矩形2頂邊』之下則.『矩形1頂邊』在『矩形2底邊』之上則.只要全部符合則兩矩形重疊.

public boolean overlap(RECT2D rect){

if(center.x – width/2 < rect.center.x + rect.width/2 &&

center.x + width/2 > rect.center.x – rect.width/2 &&

center.y – height/2 < rect.center.y + rect.height/2 &&

center.y + height/2 > rect.center.y – rect.height/2 )

return true;

else

return false;

}

『圓形』與『矩形』碰撞.原點在左下角.需先計算『矩形』與『圓心』之『最近點』.『圓心』在『矩形』之外.則『最近點』落在『矩形』邊緣之上.如果『圓心』在『矩形』之內.則『最近點』是『圓心』.然後計算『圓心』與『最近點』之距離.若小於『圓半徑』內則發生重疊.

public boolean overlap(CIRCLE2D circle){

float closestX = circle.center.x; // 圓心座標X

float closestY = circle.center.y;// 圓心座標Y

if(circle.center.x < center.x – width/2)

closestX = center.x – width/2;

else

if(circle.center.x > center.x + width/2)

closestX = center.x + width/2;

if(circle.center.y < center.y – height/2)

closestY = center.y – height/2;

else

if(circle.center.y > center.y + height/2)

closestY = center.y + height/2;

if(circle.center.DistSquared(closestX,closestY) < circle.radius * circle.radius)

return true; // 『圓』內則發生碰撞

else

return false; // 無發生碰撞

}

}

Android遊戲之2D圓形碰撞

Android遊戲之2D圓形碰撞

當物體移動並相互發生作用.需進行碰撞撿測.若重疊便發生碰撞.常見碰撞算法是通過『圓形邊界球』.它是包圍著對象最小圓. 無需隨物體旋轉而旋轉.所以速度最快之算法但精度較差.它由『圓心』與『半徑』所組成.

public class CIRCLE2D{

中心位置

public VECTOR2D center;

半徑

public float radius;

購造圓形邊界球,輸入中心位置與半徑.

public CIRCLE2D(float x,float y,float radius){

this.center = new VECTOR2D(x,y);

this.radius = radius;

}

『圓』與『點』碰撞檢測.計算『圓心』與『點』之距離.若距離小於『圓半徑』則發生碰撞.

public boolean overlap(VECTOR2D point){

float distance = center.Dist(point);

if(distance < radius  )

return true;// 發生碰撞

else

return false;// 無發生碰撞

}

兩圓形碰撞檢測.計算兩圓心『距離』.若『距離』小於兩圓半徑之和則發生碰撞

public boolean overlap(CIRCLE2D circle){

float distance = center.Dist(circle.center);// 兩圓之距

if(distance <= radius + circle.radius)

return true;// 發生碰撞

else

return false;// 無發生碰撞

}

『圓形』與『矩形』碰撞算法最為複雜.需先計算『矩形』與『圓心』最近之點.然後計算『圓心』與『最近點』之距離.若此點在『圓』內則發生重疊.

public boolean overlap(RECT2D rect){

float closestX = center.x; // 最接近X

float closestY = center.y;// 最接近Y

if(center.x < rect.center.x – rect.width/2)

closestX = rect.center.x – rect.width/2;

else

if(center.x > rect.center.x + rect.width/2)

closestX = rect.center.x + rect.width/2;

if(center.y < rect.center.y – rect.height/2)

closestY = rect.center.y – rect.height/2;

else

if(center.y > rect.center.y + rect.height/2)

closestY = rect.center.y + rect.height/2;

if(center.Dist(closestX,closestY) < radius)

return true; // 『圓』內則發生碰撞

else

return false; // 無發生碰撞

}

}

 

Android遊戲之FPS

Android遊戲之FPS

遊戲性能最重要指標FPS『每秒渲染幀量』遊戲越流暢FPS越高.不過所有Android手機都限制FPS最高60幀.若遊戲流暢FPS要高於30幀.下面代碼實現幀計數器

public class FPS {

返回納秒級時鐘.一納秒是一秒十億分之一

static private long startTime = System.nanoTime();

幀計數初此為零

static private int   frames = 0;

計算幀個數並在LOG『日誌』輸出.在GLSurfaceView.onDrawFrame(GL10 gl)中調用

static public void logFrame(){

幀個數加一

++frames;

每1秒輸出一次

if(System.nanoTime() – startTime >= 1000000000){

在LOG『日誌』輸出

Log.d(“FPS”,String.valueOf(frames));

幀個數清零

frames = 0;

更新納秒級時鐘

startTime = System.nanoTime();

}

}

}

 

 

Photoshop之繪畫遊戲地圖

Photoshop之繪畫遊戲地圖
Photoshop之繪畫遊戲地圖
Photoshop之繪畫遊戲地圖

在遊戲設計中『地圖』『背景』『人物動畫』都交給美術處理.若由程序員繪畫則成為噩夢.但『遊戲地圖生成器』Game Map Generator為一款Photoshop插件.可以幫助程序員在10分鐘內製作出專業級『地圖』.安裝Game Map Generator其實可直接拖入Photoshop空白位置完成安裝.

檔案->指令碼->瀏覽->載入『Game-Map-Generator-installer.jsx』

啟動Game Map Generator

視窗->延伸攻能-> Game Map Generator

新建地圖檔案

MAP->WIDTH『寬』填1200. HEIGHT『高』填800.按CREATE新建地圖檔案

渲染地面紋理

MAP->GROUND TEXTURE『地面紋理』有三款紋理可選『草地』、『荒地』、『雪地』

渲染網格

MAP->GRID『網格』有四款紋理可選『四邊網格』和『六邊網格』

設置等距變換

MAP->ISOMETRIC TRANSFORM『等距變換』選擇『圖層』後有五個方向可選.但每旋轉一次都會有變形損失.

渲染地形

ELEMENTS->ADD LAYER『+』新建圖層->BRUSHES『畫刷』有5款->繪畫任意地形->CHOOSE AN ELEMENT『選擇元素』

給地形繪畫紋理

TEXTURING『紋理』->BRUSHES『畫刷』有7款-> CHOOSE AN ELEMENT『選擇元素』18款地紋紋理可選『綠地』『草地』『荒地』『歸裂』『雪地』『地板』『熔岩』-> 給圖層繪畫任意形狀紋理

繪畫灌木

TEXTURING『紋理』-> BRUSHES『畫刷』->SPECIAL BRUSHES『灌木畫刷』可選『荊棘』『長草』『野花』-> 給圖層任意繪畫灌木

隨機生成紋理

TEXTURING『紋理』-> BRUSHES『畫刷』->RANDOM TEXTURES『隨機紋理』可選『蘑菇』『野花』『野草』

繪畫圖標『樹木』『岩石』『橋樑』『木屋』『金幣』

ICONS『圖標』-> CHOOSE AN ICON『選擇圖標』點選後可移動縮放

Android遊戲之2D矢量

Android遊戲之2D矢量

『矢量』Vector也稱『向量』它其實是『抽象量』.它可以有多種解析如『位置』『速度』『加速度』『方向』『距離』.因為用於2D遊戲開發定義2D『矢量』

public class VECTOR2D {

浮點數儲存2D矢量

public float x,y;

角度轉弧度

public static float DEGREES_TO_RADIANS = ((1.0f/180.0f)* (float)Math.PI);

弧度轉角度

public static float RADIANS_TO_DEGREES = ((1.0f/(float)Math.PI)*180.0f);

購造函式初此為0

public VECTOR2D(){

x=y=0;

}

購造函式並設定x與y

public VECTOR2D(float x,float y){

this.x = x;

this.y = y;

}

返回新2D『矢量』拷貝

public VECTOR2D Copy(){

VECTOR2D v;

v=new VECTOR2D(x,y);

return v;

}

重設2D矢量

public VECTOR2D set(VECTOR2D v){

this.x = v.x;

this.y = v.y;

return this;

}

2D矢量加法

public VECTOR2D Add(VECTOR2D v){

this.x = this.x + v.x;

this.y = this.y + v.y;

return this;

}

2D矢量減法

public VECTOR2D Sub(VECTOR2D v){

this.x = this.x – v.x;

this.y = this.y – v.y;

return this;

}

2D矢量乘法等於對矢量進行縮放.

public VECTOR2D Mul(float scalar){

this.x = this.x * scalar;

this.y = this.y * scalar;

return this;

}

計算2D矢量長度

public float Len(){

float len;

len = (float) Math.sqrt(xx+yy);

return len;

}

2D矢量單位化,長度為1

public VECTOR2D Normer(){

float len;

len = Len();

if(len != 0) {

x = x / len;

y = y / len;

}

return this;

}

計算2D矢量角度

public float Angle(){

float angle = 0;

angle = (float)Math.atan2(y,x)*RADIANS_TO_DEGREES;

if(angle<0)

angle += 360;

return angle;

}

計算兩2D矢量角度在(0~360)度之間

public float Angle(VECTOR2D v){

float angle = 0;

float distanceX,distanceY;

distanceX = this.x – v.x;

distanceY = this.y – v.y;

angle = (float)Math.atan2(distanceY,distanceX)*RADIANS_TO_DEGREES;

if(angle<0)

angle += 360;

return angle;

}

2D矢量繞原點旋轉, angle為旋轉角度

public VECTOR2D rotate(float angle){

float rad = angle * DEGREES_TO_RADIANS; // 角度轉弧度

float cos = (float) Math.cos(rad);

float sin = (float) Math.sin(rad);

float newX = this.x * cos – this.y * sin;

float newY = this.x * sin + this.y * cos;

this.x = newX;

this.y = newY;

return this;

}

計算兩個2D矢量之間距離

public float Dist(VECTOR2D v){

float distX = this.x – v.x;

float distY = this.y – v.y;

float dist = (float)Math.sqrt(distX*distX + distY * distY);

return dist;

}

計算兩2D矢量之間距離平方

public float DistSquared(VECTOR2D v){

float distX = this.x – v.x;

float distY = this.y – v.y;

float dist = distX*distX + distY * distY ;

return dist;

}

}

Android遊戲之2D相機

Android遊戲之2D相機

定義2D相機即設定『投影矩陣』與『視口』

『視口』用於控制輸出圖像尺寸與渲染幀緩存位置.OpenGL ES使用『視口』將投影到『近裁剪面』點座標變換為『幀緩存』像素座標

GL10.glViewport(int x,int y,int width,int height);

x和y座標為幀緩存區視口左上角.width和height為視口大小.單位為像素.幀緩存座標原點為屏幕左下角.通常將x和y設為0.width和height設為屏幕分辨率.即設為全屏.

gl.glViewport(0, 0, view.getWidth(), view.getHeight());

『投影矩陣』在2D相機中只使用『平行投影』.首先將當前矩陣設為『投影矩陣』

gl.glMatrixMode(GL10.GL_PROJECTION);

載入單位矩陣

gl.glLoadIdentity();

設置正交投影矩陣

GL10. glOrthof(int left,int right,int bottom,int top,int near,int far);

OpenGL ES座標系統正X軸指向右,正Y軸指向上.正Z軸指向我.left與right為X軸左右兩條邊.bottom與 top為Y軸上下兩條邊.near為近端裁剪面.far為遠端裁剪面.若設2D橫向相機左下角(0,0)右上角(480,320)視錐深度為2

gl.glOrthof(0,480,0,320,1, -1);

重設為模型視圖矩陣

gl.glMatrixMode(GL10.GL_MODELVIEW);

gl.glLoadIdentity();

2D相機將『觸屏』坐標轉『世界』坐標.首先設定視錐體寬為15高為10.

float frustum_width = 15;

float frustum_height = 10;

設縮放係數為1.用於放大屏幕大於1,縮小屏幕小於1

float zoom = 1;

首先將『觸屏』位置歸範圍(0~1).然後乘以視錐體寬和高

touch.x = (touch.x / view.getWidth()) * frustum_width * zoom;

因為觸屏座標原點位於屏幕左上角.需倒轉Y軸

touch.y = (1-touch.y /view.getHeight()) * frustum_height * zoom;

與相機位置相機

touch.add(position);

最後減於視錐體中心位置.得到遊戲『世界』坐標

touch.x = touch.x – frustum_width*zoom/2f;

touch.y = touch.y – frustum_height*zoom/2f;

 

Android遊戲之OpenGL ES

Android遊戲之OpenGL ES

OpenGL ES專為移動與嵌入設備設計之圖形編程接口. 它並非由ARB委員會定義.而是由Khronos組織定義.該組織包括ATI、NVIDIA、Intel等組成.雖然『OpenGL』與『OpenGL ES』來自兩個不同組織. 『OpenGL ES』係『OpenGL』刪減板.但你依然可寫出在兩種標準下都可運行之程式.這對於移植遊戲很重要.OpenGL ES同樣以C文檔發佈API.而代碼實現由硬件廠商完成.

如果AndroidManifest.xml中無配置glEsVersion,則表示支持OpenGL ES 1.0但所有Android系統都支持.若支持OpenGL ES 2.0需在AndroidManifest.xml中添加:

<uses-feature  android:required=”false”  android:glEsVersion=”0x00020000″ />

OpenGL ES版本號為32位整數.高16位表示OpenGL ES大版本,低16位表示OpenGL ES小版本.

required必須 簡介
true 必需支持否則不能運行
false 可選支持可能影響部分運行

 

OpenGL ES版本 glEsVersion
GLES 1.0 0x00010000
GLES 1.1 0x00010001
GLES 2.0 0x00020000
GLES 3.0 0x00030000
GLES 3.1 0x00030001
GLES 3.2 0x00030002

 

Photoshop之3D漢字

Photoshop之3D圖像
Photoshop之3D漢字
Photoshop之3D漢字

之前介紹『像素3D文字』效果須好.但在生成時『分辨率』要很大所以略有不便.這裡介紹『Ground Isometric Mock-Up』地面等距模型.『漢字』『英文』『圖像』『形狀』不論尺寸均支持.效果圖如上.安裝與使用方法如下:

  1. 最好用Adobe Photoshop CC 2014
  2. 轉換成英文版本
  3. 『Ground Isometric Mock-UP.atn』與『asl』兩個文檔直接拖入Photoshop空白位置即完成導入.在Actions窗口可查看
  4. 輸入『漢字』或『圖檔』並選定圖層
  5. 選定動作『Action』
  6. 按『動作播放』然後等待
動作Action 簡介
ONE Image::Depth-XX::Transform LEFT 左側3D高度1~5
ONE Image::Depth-XX::Transform RIGHT 右側3D高度1~5

 

Android遊戲之紋理映射

Android遊戲之紋理映射

將『Bitmap』加載給OpenGL ES然後加載到圖形卡記憶體重,並最終交給GPU渲染.因為OpenGL最終以三角形為單位進行渲染.而將『Bitmap』映射到三角形上.需要為三角形每個頂點設定紋理座標(texture coordinates).3D座標(x,y,z)和2D座標(x,y)對應紋理座標(u,v)位圖頂點.而(u,v)座標相當於(橫,縱)座標.紋理寬與高必需是2倍數.

紋理映射 (u,v)
左上角 (0,0)
右下角 (1,1)即使寬與高不相等
右上角 (1.0)
左下角 (0,1)

生成紋理隊列,用於保存紋理ID

int[] ids = new int[1];

生成紋理並獲取id.紋理依然為空

gl.glGenTextures(1, ids,0);

紋理id

int id = ids[0];

讀取位圖

Bitmap bitmap = BITMAP.Read(file_name);

獲取位圖寬度

int   width = bitmap.getWidth();

獲取位圖高度

int   height = bitmap.getHeight();

綁定2D紋理

gl.glBindTexture(GL10.GL_TEXTURE_2D, id);

上傳2D紋理

GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bitmap,0);

設置紋理屬性指定縮小倍數過濾器

gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);

設置紋理屬性指定放大倍數過濾器

gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);

 

過濾 簡介
GL10.GL_NEAREST 像素採樣點最接近中心點『清晰』
GL10.GL_LINEAR 像素採樣點線性插值平均加權『模糊』

取消綁定紋理ID

gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);

回收位圖.以免浪費記憶體

bitmap.recycle();

每當Activity被暫停(APP切換)GLSurfaceView都會被銷毀.每當Activity恢復時調用GLSurfaceView. onResume()讓GLSurfaceView重構渲染界面.但OpenGL ES中上傳紋理都會丟失.你需要在onSurfaceCreated()中需重新載入並上傳紋理.

重新載入代碼見上文

Texture.load(filen_ame);

重新綁定紋理後設置紋理屬性

gl.glBindTexture(GL10.GL_TEXTURE_2D, id);

gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);

gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);

取消綁定紋理

gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);

 

當遊戲退出.便要刪除紋理釋放記憶體.首先取消紋理邦定

gl.glBindTexture(GL10.GL_TEXTURE_2D, id);

刪除紋理

int[] ids = { id };

gl.glDeleteTextures(1,ids,0);

渲染三角形時要告知OpenGL要啟用紋理渲染

gl.glEnable(GL10.GL_TEXTURE_2D);

完成渲染後禁用紋理渲染

gl.glDisable(GL10.GL_TEXTURE_2D);

2D遊戲通常只佔用圖像一小片區域.需要將像素座標(x,y)轉換為紋理座標(u,v)

計算紋理座標左上角

u1 = x/texture.width;

v1 = y/texture.height;

計算紋理座標右下角

u2 = u1 + width/texture.width;

v2 = v1 + height/texture.height;

 

 

 

Android遊戲之Bitmap讀取

Android遊戲之Bitmap讀取

遊戲由『背景』與『角色』『植物』『房舍』等圖檔組成.在C時代要逐個寫圖檔分析器.而在java可以通過BitmapFactory讀取Bitmap『位圖』.幾乎支持所有常見圖檔『jpg』『png』『bmp』『png』.把所有『位圖』保存到『ASSETS』目錄下

資源管理器用於訪問『ASSETS』目錄

AssetManager asset_manager = context.getAssets();

指定『位圖名』並返回輸入流

InputStream input_stream = asset_manager.open(file_name);

讀取Bitmap默認轉換為RGB_565色

Bitmap bitamp = BitmapFactory.decodeStream(input_stream);

關閉輸入流

Input_Stream.close();

獲取位圖寬度

int width = bitmap.getWidth();

讀取位圖寬度

int height = bitmap.getHeight();

獲取位圖顏色格式.

Bitmap.Config config = bitamp.getConfig();

Bitmap.Config 位圖顏色格式
ALPHA_8 256色
ARGB_8888 32bit含ALPHA分量
RGB_565 16bit(默認)
ARGB_4444 16bit含透明度分量

以特定顏色格式進行讀取.但渲染時最終要與OpenGL ES顏色格式一致

設定顏色格式為ARGB_8888

BitmapFactory.Options options = new BitmapFactory.Options();

options.inPreferredConfig = Bitmap.Config.ARGB_8888;

指定『位圖名』並返回輸入流

InputStream Input_Stream = asset_manager.open(file_name);

讀取Bitmap並轉換為ARGB_8888色

Bitmap bitamp = BitmapFactory.decodeStream(Input_Stream, null, options);

關閉輸入流

Input_Stream.close();

Android Studio之Error running ‘app’ No target device found

Android Studio之Error running ‘app’ No target device found

剛啟動Android Studio運行app進行調試『Run->Debug』時彈出:

『Error running ‘app’ No target device found』運行app『應用』錯誤穩唔到目標設備.即穩唔到手機.之前已安裝『ADB 驅動』.肯定是ADB服務未啟動所以先未穩到部手機.

啟用ADB服務可按

『Run->Attach debuger to Android process』

或在CMD輸入

adb start-server

 

Android遊戲之全屏

Android遊戲之全屏

自『街機遊戲』到『電腦遊戲』所有遊戲都以全屏形態出現.所以Android遊戲也應全屏.在super.onCreate()調用之前設定全屏

去除APP標題欄

this.requestWindowFeature(Window.FEATURE_NO_TITLE);

去除系通通知欄

Window window = this.getWindow(); window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

創建Activity.需要

super.onCreate(savedInstanceState);

把圖形界面『佈局』填充給Activity

setContentView(R.layout.main);

 

Android遊戲之SharedPreferences『共享參數』

Android遊戲之SharedPreferences『共享參數』

遊戲運行中經常要將數據保在磁盤中.等有需要時讀取.Android提供輕量級存儲工具SharedPreferences它適用於小量數據保存.

獲得默認共享首選項

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);

獲得編輯器

Editor editor = sp.edit();

寫入文本.第一參數key文本.第二參數『value』文本

editor.putString(“text”,”data”);

寫入整數數值. 第一參數是key值.第二參數是整數

editor.putInt(“int”,1);

寫入浮點數. 第一參數key值.第二參數是浮點數

editor.putFloat(“float”,0.1);

提交保存數據

editor.commit();

讀取文本.若無該值則返回NULL

String value = sp.getString(“text”,null);

讀取整數.若無該值返回0

int value = sp.getInt(“int”,0);

讀取浮點數.若無該值返回0

float value = sp.getFloat(“float”,0);

Photoshop之繪畫像素3D文字

Photoshop之繪畫像素3D文字
Photoshop之繪畫像素3D文字

近日在網上購得專門用於生成『3D立體像素』3D Isometric shape Generator.它其實是Photoshop Action『動作』插件.其立體效果非常好.安裝與使用方法如下:

  1. 最好用Adobe Photoshop CC 2014
  2. 轉換成英文版本
  3. 『筆刷』『動作』『圖案』三個文檔全部都導入PS裡.直接拖入Photoshop空白位置即完成導入.在Actions窗口可查看
  4. 若圖案簡單分辨率可較小.反之分辨率需較大.
  5. 若插入文字像素一定要夠大.像上圖分辨率需3000*3000.(這點不便利)非常非常佔用磁盤空間.
  6. 選定『陰影方向』分別支持左右立體左右陰影.四種方向.
  7. 按『動作播放』然後靜靜等待
  8. 按1-12轉換顏色風格
Action 簡介
RV Right Shadow 右則立體,右陰影
RV Left Shadow 右則立體,左陰影
LV Right Shadow 左則立體,右陰影
LV Left Shadow 左則立體,左陰影
1-12 顏色風格轉換
Default 默認風格
Hand Drawn Stroke Style 手繪筆劃風格

 

Android遊戲之SDK版本

Android遊戲之SDK版本

在AndroidManifest.xml中修改< uses-sdk>以設置APP最低支持Android系統.以及編譯APP之SDK版本.設定Android版本需指定整數值也稱為SDK版本號.編譯版本『targetSdkVersion』應儘量使用最新SDK版本.而最低版本『minSdkVersion』應最量低,讓遊戲在更多Android設備上安裝.但也要避免使用低版SDK從而『不支持某些API』.例如下:

<uses-sdk android:minSdkVersion=”9″ android:targetSdkVersion=”28″ />

獲取當前android系統版本號

int   SDK = Integer.parseInt(android.os.Build.VERSION.SDK);

uses-sdk屬性 簡介
minSdkVersion APP最低支持Android系統
targetSdkVersion 編譯APP之SDK版本

 

Android版本 API Level『SDK版本號』
Android API 28
Android 8.1(Oreo) 27
Android 8.0(Oreo) 26
Android 7.1.1(Nougat) 25
Android 7.0(Nougat) 24
Android 6.0(Marshmallow) 23
Android 5.1(Lollipop) 22
Android 5.0(Lollipop) 21
Android 4.4W(KitKat Wear) 20
Android 4.4(KitKat) 19
Android 4.3(Jelly Bean) 18
Android 4.2(Jelly Bean) 17
Android 4.1(Jelly Bean) 16
Android 4.0.3(IceCreamSandwich) 15
Android 4.0(IceCreamSandwich) 14
Android 3.2(Honeycomb) 13
Android 3.1(Honeycomb) 12
Android 3.0(Honeycomb) 11
Android 2.3.3(Gingerbread) 10
Android 2.3(Gingerbread) 9
Android 2.2(Froyo) 8
Android 2.1(Eclair) 7
Android 2.0.1(Eclair) 6
Android 2.0(Eclair) 5
Android 1.6(Donut) 4
Android 1.5(Cupcake) 3
Android 1.1 2
Android 1.0 1

 

Windows10禁用休眠

Windows10禁用休眠

近日發現Photoshop經常報『暫存磁盤』不足.睇來C盤空間不足.一睇『設定->系統->本機C:->系統與保留->休眠檔案』佔用25.5GB. 『休眠』只是將記憶體保存在磁盤,開機時從磁盤載入以提高開機速度.其實Windows10開機速度還是要睇硬件驅動.現只要禁用『休眠』即可釋放大量磁盤空間以解燃眉之急.

  1. 系統管理員身份執行命令視窗CMD
  2. 禁用休眠系統『powercfg –h off』
  3. 重啟Windows10

 

重啟休眠系統『powercfg –h on』

休眠檔案壓縮50%『 powercfg –h size 50』

Android遊戲之縱向與橫向

Android遊戲之縱向與橫向

Android特點是每當改變手機旋轉方向時APP方向也隨之改變.『橫向』或『縱向』通過加速計傳感器確定.遊戲方向在設計時便確立.所以根本無需改變遊戲方向.只要指定Activity方向便可鎖定不變.在AndroidManifest.xml中修改<activity>屏幕方向屬性『screenOrientation』

強制屏幕縱向

<activity android:name=”.MainActivity”

android:screenOrientation=”portrait”>

強制屏幕橫向

<activity android:name=”.MainActivity”

android:screenOrientation=”landscape”>

在運行時更改屏幕為橫向

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

在運行時更改屏幕為縱向

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

screenOrientation屏幕方向 簡介
unspecified 默認值,由系統決定
landscape 強制屏幕橫屏顯示
portrait 強制屏幕豎屏顯示
behind 與前一個Activity方向相同
sensor 根據加速計傳感器轉動手機90度、180度、270度. Activity都更著變化
sensorLandscape 屏幕只可橫屏旋轉
sensorPortrait 屏幕只可豎屏旋轉
nosensor 忽略加速計傳感器.旋轉手機不會改變方向
user 用戶當前設置方向

 

Android遊戲之版本控制

Android遊戲之版本控制

Android遊戲發佈到Google Play需要追蹤遊戲『版本』.以便Google Play自動更新遊戲.要設定版本號需編輯 AndroidManifest.xml其根元素<manifest>添加versionCode和versionName屬性

versionCode:版本代碼(整數)大於等於1

versionName:版本名(字符).在Google Play上顯示.建議『versionName= versionCode/100.0f』如『versionCode=”2″』則『versionName=”0.02″』.因為任何遊戲都需要幾十次更新才可達置完善.如下:

<manifest xmlns:android=”http://schemas.android.com/apk/res/android”

package=”net.bookcard.aa”

android:versionCode=”1″

android:versionName=”0.01″>

獲取包管理器

PackageManager  package_manager = context.getPackageManager();

獲取Android應用包名這裡返回『net.bookcard.aa』

package_name = context.getPackageName();

獲取版本信息

PackageInfo package_info = Package_Manager.getPackageInfo(package_name,0);

獲取版本名

String version = Package_Info.versionName;

獲取版本代碼

int code = Package_Info.versionCode;

 

Android遊戲之喚醒鎖

Android遊戲之喚醒鎖

Android最耗電首當觸摸屏.為節約電能很多人都將亮度降低.但又耗神.折中之法是系統自動變暗進入睡眠狀態.觸屏後自動變明亮.如果想屏膜保持喚醒狀態可是WakeLock.但觸屏遊戲是不需WakeLock『喚醒鎖』.它只適用於通過『加速計』控制之遊戲.

首先在AndroidManifest.xml添加權限

<uses-permission android:name=”android.permission.WAKE_LOCK” />

獲取電源管理器

PowerManager power_manager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);

生成喚醒鎖. levelAndFlagsw為控制標記.tag為鎖名

PowerManager.newWakeLock(int levelAndFlags, String tag)

levelAndFlags: 屏幕燈 鍵盤燈
PARTIAL_WAKE_LOCK 關閉 關閉
SCREEN_DIM_WAKE_LOCK 低亮度 關閉
SCREEN_BRIGHT_WAKE_LOCK 高亮度 關閉
FULL_WAKE_LOCK 高亮度 開啟
ON_AFTER_RELEASE 延時關燈 關閉
ACQUIRE_CAUSES_WAKEUP 強制開啟 強制開啟

一般使用PARTIAL_WAKE_LOCK生成喚醒鎖

WakeLock wake_lock = power_manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,”LOCK”);

啟用喚醒鎖.在Activity.onResume()中調用

wake_lock.acquire();

釋放喚醒鎖.在Activity.onPause()中調用

wake_lock.release();

 

Photoshop之中英文快速切換

Photoshop之中英文快速切換

Photoshop常用于『修圖』『做圖』.但有工具卻只能在英文版下運作.下面之方法是在兩種語言之間快速切換,而且適合所有版本.

  1. 確定Photoshop安裝目錄查看其內容可睇到.如Photoshop2015『C:\Program Files\Adobe\Adobe Photoshop CC 2015』
  2. 要打開其中文語言包目錄『Locales\zh_TW\Support Files』
  3. 將『dat』文檔『拷貝幅本』.然後刪除.
  4. 重啟Photoshop即自動轉為英文版
  5. 若要重新改為中文只需將『拷貝幅本』重新命名為『dat』

Photoshop之無法完成『XX』指令因為暫存磁盤已滿

Photoshop之無法完成『XX』指令因為暫存磁盤已滿

在網上買左個ACTIONS『動作』但總是彈出

『無法完成『XX』指令因為暫存磁盤已滿』

睇C盤空間已耗盡.解決方法是為Photoshop設定更多暫存磁盤.

  1. 編輯->偏好設定->暫存磁盤
  2. 勾選更多『磁盤』
  3. 按『確定』

 

Android遊戲之背景音樂

Android遊戲之背景音樂

遊戲聲音分為『音樂』與『音效』.遊戲背景『音樂』播放時間通常達幾分鐘以上.音檔通常較大不能一次性載入記憶體.只能以『數據流』方式逐次讀入數據塊.並解碼為PCM數據交給音頻芯片上.Android系統提供MediaPlayer幫你解卻所有問題. 將所有『音樂』文檔存放在『\app\src\main\assets』目錄下.讓AssetManager能夠訪問.

生成MediaPlayer音頻播放器

MediaPlayer media_player = new MediaPlayer();

獲取ASSET文檔描述符

AssetFileDescriptor afd = asset_manager.openFd(file_name);

文檔描述符

FileDescriptor file_descriptor = afd.getFileDescriptor();

獲取音檔數據開此位置偏移量

long offset = afd.getStartOffset();

獲取音檔數據長度

long length = afd.getLength();

設定音檔數據

media_player.setDataSource(descriptor,offset,length);

每次啟動播放時.都需載入準備播放

media_player.prepare();

啟動播放

media_player.start();

播放中若暫停播放

media_player.pause();

播放中若停止播放

media_player.stop();

設定循環播放.

media_player.setLooping(true);

設定左右聲道音量.數值在0~1之間

media_player.setVolume(volume,volume);

判定時否播放中. isPlaying()若返回true則播放中否則返回false

media_player.isPlaying();

或用註冊OnCompletionListener簡聽器

media_player.setOnCompletionListener(listener);

若退出遊戲需釋放記憶體

media_player.release();

Android遊戲之音效模塊

Android遊戲之音效模塊

遊戲聲音分為『音樂』與『音效』.音效長度不應超過5秒.讓其可以載入『記憶體』中.並將所有音效文檔存放在『\app\src\main\assets』目錄下.讓AssetManager能夠訪問.並將所有『音效』文檔存為『OGG』格式.並且採用低採樣頻率.

Android提供SoundPool『音效池』實現音效載入與播放.

SoundPool(int maxStreams, int streamType, int srcQuality)

maxStreams:用時能播放音效量

streamType:使用音樂流輸出音頻.這裡使用AudioManager.STREAM_MUSIC

srcQuality:廢棄,總為0

構建音效播放

SoundPool sound_pool = new SoundPool(32, AudioManager.STREAM_MUSIC,0);

用於訪問Asset目錄

AssetManager asset_manager = context.getAssets();

獲取資源文檔描述符

AssetFileDescriptor afd = asset_manager.openFd(file_name);

把音效文檔載入『記憶體』中,讓AssetFileDescriptor傳給load()並返回整數ID句柄

int id = sound_pool.load(afd,1);

播放音效

public final int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)

soundID:音效ID句柄

leftVolume\rightVolume:左右聲道音量在0.0f – 1.0f之間

priority:優先級.值越大優先級越高,0優先級最低

loop:循環次數.0代表不循環

rate:播放速率取值0.5f – 2.0f之間.其中0.5f表示播放速度慢一半.1表示正常速率播放.

單次播放音效

sound_pool.play(id, 1.0f, 1.0f, 0, 0, 1);

當不需要音效時,需要釋放音效記憶體

sound_pool.unload(ID);

當退出遊戲時需釋放SoundPool『音效池』

sound_pool.release();

企業級雙頻千兆無線路郵器

企業級雙頻千兆無線路郵器
企業級雙頻千兆無線路郵器

近日無線(wifi)路郵壞左.剛好有只TP-LINK 150M無線路郵.但手機傳送速度很慢.在淘寶上睇到MERCURY-MER1200G『企業級千兆無線路郵』帶四條全向天線.個老細話與TP-Link同一間廠出.而且價格低廉所以馬上落單.

到手後所謂千兆只是『5G最高867Mbps』+『2.4G最高300Mbps』.並非正真千兆路郵.不過信號超強而且帶有TURBO按鈕.用於擴大路郵器無線覆蓋範圍並增強無線信號穩定性.設定時要啟用UPnP否則影響BT下載速度.而且無USB接口.是否能長時間運行還有待測試.

 

Android Studio之自定遊戲圖標

Android Studio之自定遊戲圖標

Android遊戲都有其icon圖標.而且該圖標也會Google Play上展示.要自定圖標需在遊戲項目『\app\src\main\res\mipmap-xxx』查找icon圖標.然後將其替換.若Eclipse則在drawable目錄下. 並且隨著手機屏幕分辨率不斷進化.遊戲需要提供不同密度圖標『自適應圖標』.圖標分為兩類『圓』與『方』.並且需要在AndroidManifest.xml添加icon圖標屬性.

<application  android:icon=”@mipmap/ic_launcher”

android:roundIcon=”@mipmap/ic_launcher_round”>

Android Studio帶有icon圖標生成器,全自動生成所有不同分辨率圖標.在Eclipse你需要用PS生成.

  1. 項目右擊『New->Image Asset』
  2. Icon Type:選Launcher Icons(Adaptive and Legacy)
  3. Name:填ic_launcher
  4. Asset Type:勾選Image
  5. Path:輸入自定圖標路徑
  6. Trim勾選Yes
  7. Resize拖到100%
  8. Legacy Icon勾選Yes
  9. Gound Icon Generate勾選Yes
  10. Google Play Store Icon勾選Yes
類型 文檔名
方形 ic_launcher.png
圓形 ic_launcher_round.png
前景 ic_launcher_foreground.png
背景 ic_launcher_background.png

 

目錄 簡介 分辨率
mipmap-mdpi 中密度圖標(必須有) 48*48
mipmap-hdpi 高密度圖標 72*72
mipmap-xhdpi 超高密度圖標 96*96
mipmap-xxhdpi 超超高密度圖標 144*144
mipmap-xxxhdpi 超超超高密度圖標 192*192

 

Android遊戲之文檔讀寫

Android遊戲之文檔讀寫

在Android遊戲開發時需要讀入大量Asset(資源).如『3D模型』『紋理』『音頻』『地型』等Asset(資源)文檔.Android建議把資源存放於『res』目錄,但它不適合存放原生資源. 在遊戲開發時使用『assets』目錄,所有遊戲資源文檔存放該目錄下.而且還可以指定目錄結構. 要訪問『assets』目錄需AssetManager資源管理器:

『assets』目錄位於『\app\src\main\assets』這點與Eclipse有所不同.

AssetManager asset_manager = context.getAssets();

打開Asset文檔並返回輸入流InputStream

InputStream input_stream = asset_manager.open(file_name);

讀取『外部緩存』SD卡

Asset只適合用於讀取遊戲資源.若在遊戲運行時讀寫文檔數據.若訪問SD卡需要加入度寫權限:

<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>

<uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”/>

然後需要確定手機是否裝有SD卡

獲取『外部緩存』SD卡裝態.其實現在手機載固態硬盤劃出部分空間作為『外部緩存』

String state = Environment.getExternalStorageState();

Environment.MEDIA_MOUNTED:SD卡插入並可正常讀寫

Environment.MEDIA_MOUNTED_READ_ONLY:SD卡已插入,但只能讀取

獲取『外部緩存』路徑

File file_path = Environment.getExternalStorageDirectory();

並不建議在『外部緩存』SD卡讀寫.一SD卡可能被彈出.二可能需要用戶授權.如果數據較小建議寫入『內部存儲』

APP內部存儲緩存目錄『/data/data/< package name >/files/』

File file_path = context.getFilesDir() ;

生成目錄

file_path.mkdir();

連接路徑

File file  = new File(file_path,file_name);

打開文檔並返回輸入流

InputStream input_stream = new FileInputStream(file);

打開文檔並返回輸出流

OutputStream output_stream = new FileOutputStream(file);

獲取指定寫入/讀取路徑 存儲位置
Environment.getExternalStorageDirectory() /mnt/sdcard/
context.getExternalFilesDir() /mnt/sdcard/Android/data/< package name >/files/
context.getExternalCacheDir() /mnt/sdcard/Android/data/< package name >/cach/
context.getFilesDir() /data/data/< package name >/files/
context.getCacheDir() /data/data/< package name >/cach/

 

獲取指定寫入/讀取路徑 簡介
Environment.getExternalStorageDirectory() 外部存儲
context.getExternalFilesDir() 外部存儲
context.getExternalCacheDir() 外部臨時存儲
context.getFilesDir() 內部存儲
context.getCacheDir() 內部臨時緩存

 

Android遊戲之按鍵

Android遊戲之按鍵

Android其實是支持標準鍵盤.大多數Android手機只支持軟鍵盤. 遊戲要捕足按鍵事件你需要實現OnKeyListener接口.它通過與接收鍵盤事件View相連並接收按鍵事件.

public boolean onKey(View view,int keyCode,KeyEvent event);

按鍵編碼keyCode為整數0~127一共128個按鍵.常量值形式為KeyEvent.KEYCODE_XXX

獲取按鍵字符:KeyEvent.getUnicodeChar();

獲取按鍵事件類型: KeyEvent.getAction();

獲取按鍵事件類型: KeyEvent.getAction(); 簡介
KeyEvent.ACTION_MULTIPLE 連續多個重複鍵事件
KeyEvent.ACTION_DOWN 按下按鍵時觸發
KeyEvent.ACTION_UP 鬆開按鍵時觸發

當鍵盤按下時其值被保存在鍵盤列狀態

public static int   MAX_KEY = 128;// 128個按鍵

public static int[] Key_Action  = new int[MAX_KEY];// 按鍵事件,按下/送開

public static int[] Key_Code   = new int[MAX_KEY];// 按鍵代碼

public static int[] Key_Char   = new int[MAX_KEY];// 按鍵字符

public static int  Key_Count  = 0; // 未處理按鍵量

private static boolean[] Key_State = new boolean[128];// 按鍵的當前狀態true按下.false鬆開

private static KeyboardListener Keyboard_Listener = new KeyboardListener();//按鍵監聽器

實現鍵盤監聽接口從View中接收鍵盤事件並處理

static class KeyboardListener implements View.OnKeyListener{

@Override

public boolean onKey(View view, int keyCode, KeyEvent event){

int index;

int Action;

if(Key_Count >= MAX_KEY)

return false;

index = Key_Count;

++Key_Count;

Key_Code[index] = keyCode;// 鍵代碼

Key_Char[index] = event.getUnicodeChar();// 鍵字符

Action = event.getAction();//  獲取按鍵事件類型

if(Action == KeyEvent.ACTION_MULTIPLE)// 多重

return false;

if(Action == KeyEvent.ACTION_DOWN)

{// 按下

if(keyCode >0 && keyCode < 127)

Key_State[keyCode] = true;// 按下

Key_Action[index] = KeyEvent.ACTION_DOWN;

}

else

if(Action == KeyEvent.ACTION_UP)

{// 鬆開

if(keyCode >0 && keyCode < 127)

Key_State[keyCode] = false;

Key_Action[index] = KeyEvent.ACTION_UP;

}

return false;

}

初此按鍵監聽器

public static boolean Init(View view)

{

for(int i=0;i<Key_State.length;++i)

Key_State[i] = false;

view.setOnKeyListener(Keyboard_Listener);// view對按鍵進行監聽

view.requestFocus();//請求焦點

return true;

}

}

電話鍵常量 數值
KEYCODE_CALL 撥號鍵
KEYCODE_ENDCALL 掛機鍵
KEYCODE_HOME Home鍵返回面
KEYCODE_MENU 菜單鍵
KEYCODE_BACK 返回鍵
KEYCODE_SEARCH 搜索鍵
KEYCODE_CAMERA 拍照鍵
KEYCODE_FOCUS 拍照對焦鍵
KEYCODE_POWER 電源鍵
KEYCODE_NOTIFICATION 通知鍵
KEYCODE_MUTE 話筒靜音鍵
KEYCODE_VOLUME_MUTE 揚聲器靜音鍵
KEYCODE_VOLUME_UP 音量增加鍵
KEYCODE_VOLUME_DOWN 音量減小鍵

 

控制鍵常量 數值
KEYCODE_ENTER ENTER回車鍵
KEYCODE_ESCAPE ESC鍵
KEYCODE_DPAD_CENTER 方向鍵/確定鍵
KEYCODE_DPAD_UP 方向鍵/向上鍵
KEYCODE_DPAD_DOWN 方向鍵/向下鍵
KEYCODE_DPAD_LEFT 方向鍵/向左鍵
KEYCODE_DPAD_RIGHT 方向鍵/向右鍵
KEYCODE_MOVE_HOME 光標移動到開始鍵
KEYCODE_MOVE_END 光標移動到末尾鍵
KEYCODE_PAGE_UP 向上翻頁鍵
KEYCODE_PAGE_DOWN 向下翻頁鍵
KEYCODE_DEL 退格鍵
KEYCODE_FORWARD_DEL 刪除鍵
KEYCODE_INSERT 插入鍵
KEYCODE_TAB Tab鍵/焦點切換鍵
KEYCODE_NUM_LOCK 小鍵盤鎖
KEYCODE_CAPS_LOCK 大寫鎖定鍵
KEYCODE_BREAK Break/Pause鍵
KEYCODE_SCROLL_LOCK 滾動鎖定鍵
KEYCODE_ZOOM_IN 放大鍵
KEYCODE_ZOOM_OUT 縮小鍵

 

組合鍵常量 簡介
KEYCODE_ALT_LEFT Alt+Left
KEYCODE_ALT_RIGHT Alt+Right
KEYCODE_CTRL_LEFT Control+Left
KEYCODE_CTRL_RIGHT Control+Right
KEYCODE_SHIFT_LEFT Shift+Left
KEYCODE_SHIFT_RIGHT Shift+Right

 

數字與字母鍵常量 簡介
KEYCODE_0 數字鍵0
KEYCODE_1 數字鍵1
KEYCODE_2 數字鍵2
KEYCODE_3 數字鍵3
KEYCODE_4 數字鍵4
KEYCODE_5 數字鍵5
KEYCODE_6 數字鍵6
KEYCODE_7 數字鍵7
KEYCODE_8 數字鍵8
KEYCODE_9 數字鍵9
KEYCODE_A 字母鍵A
KEYCODE_B 字母鍵B
KEYCODE_C 字母鍵C
KEYCODE_D 字母鍵D
KEYCODE_E 字母鍵E
KEYCODE_F 字母鍵F
KEYCODE_G 字母鍵G
KEYCODE_H 字母鍵H
KEYCODE_I 字母鍵I
KEYCODE_J 字母鍵J
KEYCODE_K 字母鍵K
KEYCODE_L 字母鍵L
KEYCODE_M 字母鍵M
KEYCODE_N 字母鍵N
KEYCODE_O 字母鍵O
KEYCODE_P 字母鍵P
KEYCODE_Q 字母鍵Q
KEYCODE_R 字母鍵R
KEYCODE_S 字母鍵S
KEYCODE_T 字母鍵T
KEYCODE_U 字母鍵U
KEYCODE_V 字母鍵V
KEYCODE_W 字母鍵W
KEYCODE_X 字母鍵X
KEYCODE_Y 字母鍵Y
KEYCODE_Z 字母鍵Z

 

符號鍵常量 簡介
KEYCODE_PLUS 加號+
KEYCODE_MINUS 減號-
KEYCODE_STAR 乘號*
KEYCODE_SLASH 除號/
KEYCODE_EQUALS 等號=
KEYCODE_AT 符號鍵@
KEYCODE_POUND 井號鍵#
KEYCODE_APOSTROPHE 單引號’
KEYCODE_BACKSLASH 斜杆\
KEYCODE_COMMA 逗號,
KEYCODE_PERIOD 句號.
KEYCODE_LEFT_BRACKET 左括號[
KEYCODE_RIGHT_BRACKET 右括號]
KEYCODE_SEMICOLON 分號;
KEYCODE_GRAVE `
KEYCODE_SPACE 空格鍵

 

小鍵盤常量 簡介
KEYCODE_NUMPAD_0 小鍵盤數字鍵0
KEYCODE_NUMPAD_1 小鍵盤數字鍵1
KEYCODE_NUMPAD_2 小鍵盤數字鍵2
KEYCODE_NUMPAD_3 小鍵盤數字鍵3
KEYCODE_NUMPAD_4 小鍵盤數字鍵4
KEYCODE_NUMPAD_5 小鍵盤數字鍵5
KEYCODE_NUMPAD_6 小鍵盤數字鍵6
KEYCODE_NUMPAD_7 小鍵盤數字鍵7
KEYCODE_NUMPAD_8 小鍵盤數字鍵8
KEYCODE_NUMPAD_9 小鍵盤數字鍵9
KEYCODE_NUMPAD_ADD 小鍵盤加號+
KEYCODE_NUMPAD_SUBTRACT 小鍵盤減號-
KEYCODE_NUMPAD_MULTIPLY 小鍵盤乘號*
KEYCODE_NUMPAD_DIVIDE 小鍵盤除號’/’
KEYCODE_NUMPAD_EQUALS 小鍵盤等號’=’
KEYCODE_NUMPAD_COMMA 小鍵盤逗號’,’
KEYCODE_NUMPAD_DOT 小鍵盤點號’.’
KEYCODE_NUMPAD_LEFT_PAREN 小鍵盤左括弧'(‘
KEYCODE_NUMPAD_RIGHT_PAREN 小鍵盤左括弧’)’
KEYCODE_NUMPAD_ENTER 小鍵盤回車鍵

 

功能鍵常量 簡介
KEYCODE_F1 按鍵F1
KEYCODE_F2 按鍵F2
KEYCODE_F3 按鍵F3
KEYCODE_F4 按鍵F4
KEYCODE_F5 按鍵F5
KEYCODE_F6 按鍵F6
KEYCODE_F7 按鍵F7
KEYCODE_F8 按鍵F8
KEYCODE_F9 按鍵F9
KEYCODE_F10 按鍵F10
KEYCODE_F11 按鍵F11
KEYCODE_F12 按鍵F12

 

多媒體鍵常量 簡介
KEYCODE_MEDIA_PLAY 播放鍵
KEYCODE_MEDIA_STOP 停止鍵
KEYCODE_MEDIA_PAUSE 暫停鍵
KEYCODE_MEDIA_PLAY_PAUSE 播放/暫停鍵
KEYCODE_MEDIA_FAST_FORWARD 快進鍵
KEYCODE_MEDIA_REWIND 快退鍵
KEYCODE_MEDIA_NEXT 下一首鍵
KEYCODE_MEDIA_PREVIOUS 上一首鍵
KEYCODE_MEDIA_CLOSE 關閉鍵
KEYCODE_MEDIA_EJECT 彈出鍵
KEYCODE_MEDIA_RECORD 錄音鍵

 

通用遊戲手柄按鈕按鍵常量 簡介
KEYCODE_BUTTON_1 #1
KEYCODE_BUTTON_2 #2
KEYCODE_BUTTON_3 #3
KEYCODE_BUTTON_4 #4
KEYCODE_BUTTON_5 #5
KEYCODE_BUTTON_6 #6
KEYCODE_BUTTON_7 #7
KEYCODE_BUTTON_8 #8
KEYCODE_BUTTON_9 #9
KEYCODE_BUTTON_10 #10
KEYCODE_BUTTON_11 #11
KEYCODE_BUTTON_12 #12
KEYCODE_BUTTON_13 #13
KEYCODE_BUTTON_14 #14
KEYCODE_BUTTON_15 #15
KEYCODE_BUTTON_16 #16
KEYCODE_BUTTON_A 手柄A
KEYCODE_BUTTON_B 手柄B
KEYCODE_BUTTON_C 手柄C
KEYCODE_BUTTON_X 手柄X
KEYCODE_BUTTON_Y 手柄 Y
KEYCODE_BUTTON_Z 手柄 Z
KEYCODE_BUTTON_L1 手柄 L1
KEYCODE_BUTTON_L2 手柄L2
KEYCODE_BUTTON_R1 手柄R1
KEYCODE_BUTTON_R2 手柄R2
KEYCODE_BUTTON_MODE 手柄Mode
KEYCODE_BUTTON_SELECT 手柄Select
KEYCODE_BUTTON_START 手柄Start
KEYCODE_BUTTON_THUMBL 左拇指鍵
KEYCODE_BUTTON_THUMBR 右拇指鍵

 

按鍵常量 簡介
KEYCODE_NUM Number modifier
KEYCODE_INFO Info
KEYCODE_APP_SWITCH App switch
KEYCODE_BOOKMARK Bookmark
KEYCODE_AVR_INPUT A/V Receiver input
KEYCODE_AVR_POWER A/V Receiver power
KEYCODE_CAPTIONS Toggle captions
KEYCODE_CHANNEL_DOWN Channel down
KEYCODE_CHANNEL_UP Channel up
KEYCODE_CLEAR Clear
KEYCODE_DVR DVR
KEYCODE_ENVELOPE Envelope special function
KEYCODE_EXPLORER Explorer special function
KEYCODE_FORWARD Forward
KEYCODE_FORWARD_DEL Forward Delete
KEYCODE_FUNCTION Function modifier
KEYCODE_GUIDE Guide
KEYCODE_HEADSETHOOK Headset Hook
KEYCODE_META_LEFT Left Meta modifier
KEYCODE_META_RIGHT Right Meta modifier
KEYCODE_PICTSYMBOLS Picture Symbols modifier
KEYCODE_PROG_BLUE Blue “programmable”
KEYCODE_PROG_GREEN Green “programmable”
KEYCODE_PROG_RED Red “programmable”
KEYCODE_PROG_YELLOW Yellow “programmable”
KEYCODE_SETTINGS Settings
KEYCODE_SOFT_LEFT Soft Left
KEYCODE_SOFT_RIGHT Soft Right
KEYCODE_STB_INPUT Set-top-box input
KEYCODE_STB_POWER Set-top-box power
KEYCODE_SWITCH_CHARSET Switch Charset modifier
KEYCODE_SYM Symbol modifier
KEYCODE_SYSRQ System Request / Print Screen
KEYCODE_TV TV鍵
KEYCODE_TV_INPUT TV input鍵
KEYCODE_TV_POWER TV power鍵
KEYCODE_WINDOW Window鍵
KEYCODE_UNKNOWN 未知按鍵