日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android 模拟物品移动

發(fā)布時(shí)間:2023/12/20 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 模拟物品移动 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

上次寫了一個(gè)android模擬下雪的demo。

基本是模擬出來雪花飄落的效果了,但是并沒有達(dá)到真正的“下雪”。因?yàn)橐淮沃划a(chǎn)生了幾朵雪花而已。于是想改進(jìn)一下。

我原打算改進(jìn)的方法是:

? 定義一個(gè)雪花類,繼承runnable,只要在控制類里面啟動(dòng),就讓雪花自動(dòng)飄落,當(dāng)落到屏幕下方的時(shí)候,重新回到屏幕頂部,然后再次下落……

? 這樣設(shè)計(jì),是因?yàn)槲以茸鲞^一下SWT的游戲,讓物品自己繪制自己,自己控制自己的生命周期,這應(yīng)該是面向?qū)ο笤O(shè)計(jì)的第一反應(yīng)……

但是遇到了問題,因?yàn)樵赼ndroid中,界面顯示是靠View來控制的,如果讓需要View把自己的canvas傳遞給雪花,這樣還不如讓所有的界面顯示都交給VIEW來處理。

在不停的實(shí)驗(yàn)之后,發(fā)現(xiàn)我自己的設(shè)計(jì),我沒有走通……歸結(jié)原因,還是自己對android 2D方面的東西不了解。于是網(wǎng)上下載一些資料學(xué)習(xí)

-----------------------------------分割線,一下內(nèi)容來源互聯(lián)網(wǎng)---------------------------------------------------------

android中涉及到顯示的基本都要交給View處理,這里就不不得不提到兩個(gè)類:android.view.View和android.view.SurfaceView。

SurfaceView 是從View基類中派生出來的顯示類,直接子類有GLSurfaceView和VideoView,可以看出GL和視頻播放以及Camera攝像頭一般均使用SurfaceView。

surfaceView 到底有哪些優(yōu)勢呢?

?SurfaceView 可以控制表面的格式,比如大小,顯示在屏幕中的位置,最關(guān)鍵是的提供了SurfaceHolder類,使用getHolder方法獲取,相關(guān)的有

Canvas?lockCanvas()?,Canvas?lockCanvas(Rect?dirty)?、void?removeCallback(SurfaceHolder.Callback?callback)、void?unlockCanvasAndPost(Canvas?canvas)?控制圖形以及繪制,而在SurfaceHolder.Callback?接口回調(diào)中可以通過重寫下面方法實(shí)現(xiàn):

????????????? 使用的SurfaceView的時(shí)候,一般情況下要對其進(jìn)行創(chuàng)建,銷毀,改變時(shí)的情況進(jìn)行監(jiān)視,這就要用到?SurfaceHolder.Callback.?

class XxxView extends SurfaceView implements SurfaceHolder.Callback {public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){} //看其名知其義,在surface的大小發(fā)生改變時(shí)激發(fā) public void surfaceCreated(SurfaceHolder holder){} //同上,在創(chuàng)建時(shí)激發(fā),一般在這里調(diào)用畫圖的線程。 public void surfaceDestroyed(SurfaceHolder holder) {} //同上,銷毀時(shí)激發(fā),一般在這里將畫圖的線程停止、釋放。}
對于Surface相關(guān)的,Android底層還提供了GPU加速功能,所以一般實(shí)時(shí)性很強(qiáng)的應(yīng)用中主要使用SurfaceView而不是直接從View構(gòu)建,同時(shí)后來做android?3d?OpenGL中的GLSurfaceView也是從該類實(shí)現(xiàn)。

SurfaceView 和View 最本質(zhì)的區(qū)別在于,surfaceView 是在一個(gè)新起的單獨(dú)線程中可以重新繪制畫面,而View必須在UI的主線程中更新畫面。?

那么在UI的主線程中更新畫面?可能會引發(fā)問題,比如你更新畫面的時(shí)間過長,那么你的主UI線程會被你正在畫的函數(shù)阻塞。那么將無法響應(yīng)按鍵,觸屏等消息。?
當(dāng)使用surfaceView?由于是在新的線程中更新畫面所以不會阻塞你的UI主線程。但這也帶來了另外一個(gè)問題,就是事件同步。比如你觸屏了一下,你需要surfaceView中thread處理,一般就需要有一個(gè)event?queue的設(shè)計(jì)來保存touch?event,這會稍稍復(fù)雜一點(diǎn),因?yàn)樯婕暗骄€程同步。

所以基于以上,根據(jù)游戲特點(diǎn),一般分成兩類。

1?被動(dòng)更新畫面的。比如棋類,這種用view就好了。因?yàn)楫嬅娴母率且蕾囉?onTouch?來更新,可以直接使用?invalidate。?因?yàn)檫@種情況下,這一次Touch和下一次的Touch需要的時(shí)間比較長些,不會產(chǎn)生影響。

2?主動(dòng)更新。比如一個(gè)人在一直跑動(dòng)。這就需要一個(gè)單獨(dú)的thread不停的重繪人的狀態(tài),避免阻塞main?UI?thread。所以顯然view不合適,需要surfaceView來控制。

3.Android中的SurfaceView類就是雙緩沖機(jī)制。因此,開發(fā)游戲時(shí)盡量使用SurfaceView而不要使用View,這樣的話效率較高,而且SurfaceView的功能也更加完善。

---------------------------------------------分割線---------------------------------------------


于是就寫了一個(gè)簡單的demo,讓一個(gè)物體(我用的是一朵花),在屏幕中不停的移動(dòng)。選擇使用surfaceView

@Overridepublic void surfaceCreated(SurfaceHolder holder) {SH = this.getHeight();SW = this.getWidth();th.start();}
這里我們重載,surfaceCrate方法,獲得屏幕的高度和寬度,啟動(dòng)繪制線程……因?yàn)橹挥挟?dāng)執(zhí)行surfaceCreate的時(shí)候,界面才真正繪制出來,如果在構(gòu)造函數(shù)中獲得屏幕的高度和寬度,就只能為0;


public void draw() {canvas = sfh.lockCanvas();if (canvas == null) {// 防止在按返回鍵的時(shí)候,報(bào)空指針異常return;}canvas.drawRect(0, 0, SW, SH, p); // 刷屏canvas.save();canvas.drawBitmap(bmp, bmp_x, bmp_y, p);Log.v("DEBUG", bmp_x + " |" + bmp_y + " | " + speed_x + " |" + speed_y);canvas.restore();sfh.unlockCanvasAndPost(canvas);} 這個(gè)方法會被線程不停的調(diào)用,讓物體有移動(dòng)的效果。其中 canvas.drawRect(0, 0, SW, SH, p); // 刷屏負(fù)責(zé)清理上一次繪制留下的圖片,讓物體“動(dòng)起來”。

為了防止當(dāng)用戶點(diǎn)擊放回按鈕的時(shí)候,線程仍在繪制,會報(bào)空指針異常,所以每次繪制前,要檢查canvas是否為空。

private void path() {if (bmp_x >= SW - 20) {speed_x += 1;if(speed_x>15){speed_x = 3;}speed_x = -speed_x;} else if (bmp_x <= 20) {speed_x -=1;if(speed_x<-15){speed_x = -3;}speed_x = -speed_x;}if (bmp_y >= SH - 20) {speed_y+=5;if(speed_y>15){speed_y = 3;}speed_y = -speed_y;} else if (bmp_y <= 10){speed_y -=5;if(speed_y<-15){speed_y = -3;}speed_y = -speed_y;}bmp_x += speed_x;bmp_y += speed_y;}
path這個(gè)方法控制著物體移動(dòng)的速度,方向……

代碼下載地址:點(diǎn)擊打開鏈接


總結(jié)

以上是生活随笔為你收集整理的android 模拟物品移动的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。