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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android自定义游戏闯关图,Android自定义View(四) -- Canvas

發(fā)布時間:2023/12/15 Android 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android自定义游戏闯关图,Android自定义View(四) -- Canvas 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文計劃根據(jù)HenCoder系列文章進行學習,所以代碼風格及博文素材可能會摘自其中。

1 范圍裁切

范圍裁切有兩個方法: clipRect() 和 clipPath()。裁切方法之后的繪制代碼,都會被限制在裁切范圍內(nèi)。

1.1 clipRect()

使用很簡單,直接應用:

canvas.clipRect(100,100,400,400);

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.snoopy);

canvas.drawBitmap(bitmap,100,100,paint);

原圖 對比 裁切

記得要加上 Canvas.save() 和 Canvas.restore() 來及時恢復繪制范圍。

1.2 clipPath()

其實和 clipRect() 用法完全一樣,只是把參數(shù)換成了 Path ,所以能裁切的形狀更多一些:

canvas.save();

path.addCircle(500,500,400, Path.Direction.CCW);

canvas.clipPath(path);

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.snoopy);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

image.png

2. 幾何變換

幾何變換的使用大概分為三類:

使用 Canvas 來做常見的二維變換;

使用 Matrix 來做常見和不常見的二維變換;

使用 Camera 來做三維變換。

2.1 使用 Canvas 來做常見的二維變換:

2.1.1 Canvas.translate(float dx, float dy) 平移

參數(shù)里的 dx 和 dy 表示橫向和縱向的位移。

canvas.save();

canvas.translate(300,100);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

image.png

2.1.2 Canvas.rotate(float degrees, float px, float py) 旋轉(zhuǎn)

參數(shù)里的 degrees 是旋轉(zhuǎn)角度,單位是度(也就是一周有 360° 的那個單位),方向是順時針為正向; px 和 py 是軸心的位置。

canvas.save();

canvas.rotate(200);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

2.1.3 Canvas.scale(float sx, float sy, float px, float py) 放縮

參數(shù)里的 sx sy 是橫向和縱向的放縮倍數(shù); px py 是放縮的軸心。

canvas.save();

canvas.scale(1.5f,0.8f,100,100);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

2.1.4 skew(float sx, float sy) 錯切

參數(shù)里的 sx 和 sy 是 x 方向和 y 方向的錯切系數(shù)。

canvas.save();

canvas.skew(0.3f,0.3f);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

2.2 使用 Matrix 來做變換

2.2.1 使用 Matrix 來做常見變換

Matrix 做常見變換的方式:

創(chuàng)建 Matrix 對象;

調(diào)用 Matrix 的 pre/postTranslate/Rotate/Scale/Skew() 方法來設置幾何變換;

使用 Canvas.setMatrix(matrix) 或 Canvas.concat(matrix) 來把幾何變換應用到 Canvas。

平移

matrix.reset();

matrix.postTranslate(300,300);

canvas.save();

canvas.concat(matrix);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

.png

其他效果就不一一展示,和Canvas方法一樣。

把 Matrix 應用到 Canvas 有兩個方法: Canvas.setMatrix(matrix) 和 Canvas.concat(matrix)。

Canvas.setMatrix(matrix):用 Matrix 直接替換 Canvas 當前的變換矩陣,即拋棄 Canvas 當前的變換,改用 Matrix 的變換(注:根據(jù)下面評論里以及我在微信公眾號中收到的反饋,不同的系統(tǒng)中 setMatrix(matrix) 的行為可能不一致,所以還是盡量用 concat(matrix) 吧);

Canvas.concat(matrix):用 Canvas 當前的變換矩陣和 Matrix 相乘,即基于 Canvas 當前的變換,疊加上 Matrix 中的變換。

2.2.2 使用 Matrix 來做自定義變換

Matrix 的自定義變換使用的是 setPolyToPoly() 方法。

2.2.2.1 Matrix.setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) 用點對點映射的方式設置變換

private float[] pointSrc = {20,50,200,400, 80,90,300,50};

private float[] pointsDst = {10, 70, 320, 310, 200, 100, 310, 200};

matrix.reset();

matrix.setPolyToPoly(pointSrc , 0,pointsDst,0,3);

canvas.save();

canvas.concat(matrix);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

image.png

參數(shù)里,src 和 dst 是源點集合目標點集;srcIndex 和 dstIndex 是第一個點的偏移;pointCount 是采集的點的個數(shù)(個數(shù)不能大于 4,因為大于 4 個點就無法計算變換了)。

2.3 使用 Camera 來做三維變換

Camera 的三維變換有三類:旋轉(zhuǎn)、平移、移動相機。

2.3.1 Camera.rotate*() 三維旋轉(zhuǎn)

Camera.rotate*() 一共有四個方法: rotateX(deg) rotateY(deg) rotateZ(deg) rotate(x, y, z)。這四個方法的區(qū)別不用我說了吧?

canvas.save();

camera.save();

camera.rotate(0,0,20);

camera.applyToCanvas(canvas);

camera.restore();

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

image.png

如果你需要圖形左右對稱,需要配合上 Canvas.translate(),在三維旋轉(zhuǎn)之前把繪制內(nèi)容的中心點移動到原點,即旋轉(zhuǎn)的軸心,然后在三維旋轉(zhuǎn)后再把投影移動回來:

canvas.save();

canvas.translate(100,100);

camera.save();

camera.rotate(-20,0,20);

camera.applyToCanvas(canvas);

camera.restore();

canvas.translate(-100,-100);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

Canvas 的幾何變換順序是反的,所以要把移動到中心的代碼寫在下面,把從中心移動回來的代碼寫在上面。

2.3.2 Camera.translate(float x, float y, float z) 移動

它的使用方式和 Camera.rotate*() 相同,而且我在項目中沒有用過它,所以就不貼代碼和效果圖了。

2.3.3 Camera.setLocation(x, y, z) 設置虛擬相機的位置

注意!這個方法有點奇葩,它的參數(shù)的單位不是像素,而是 inch,英寸。

image

我 TM 的真沒逗你,我也沒有胡說八道,它的單位就。是。英。寸。

這種設計源自 Android 底層的圖像引擎 Skia 。在 Skia 中,Camera 的位置單位是英寸,英寸和像素的換算單位在 Skia 中被寫死為了 72 像素,而 Android 中把這個換算單位照搬了過來。是的,它。寫。死。了。

image

吐槽到此為止,俗話說看透不說透,還是好朋友。

在 Camera 中,相機的默認位置是 (0, 0, -8)(英寸)。8 x 72 = 576,所以它的默認位置是 (0, 0, -576)(像素)。

如果繪制的內(nèi)容過大,當它翻轉(zhuǎn)起來的時候,就有可能出現(xiàn)圖像投影過大的「糊臉」效果。而且由于換算單位被寫死成了 72 像素,而不是和設備 dpi 相關的,所以在像素越大的手機上,這種「糊臉」效果會越明顯。

image

而使用 setLocation() 方法來把相機往后移動,就可以修復這種問題。

camera.setLocation(0, 0, newZ);

image

Camera.setLocation(x, y, z) 的 x 和 y 參數(shù)一般不會改變,直接填 0 就好。

好了,上面這些就是本期的內(nèi)容:范圍裁切和幾何變換。

總結(jié)

以上是生活随笔為你收集整理的android自定义游戏闯关图,Android自定义View(四) -- Canvas的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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