自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android 游戲開(kāi)發(fā)工具大升級(jí)

移動(dòng)開(kāi)發(fā) Android
通過(guò)這篇文章我們分享了高效開(kāi)發(fā) Android 游戲的一些工具和技巧: Android 游戲開(kāi)發(fā)套件中新增的 Android 游戲開(kāi)發(fā)擴(kuò)展、Android GPU 檢查器、GameActivity、軟鍵盤(pán)、游戲手柄和高性能音頻庫(kù)及 Android 性能調(diào)優(yōu)工具;另外向您展示了 Play Asset Delivery 格式在分發(fā)游戲資源方面展示出的強(qiáng)大能力。

不同的硬件廠商為 Android 用戶帶來(lái)了不同尺寸和體驗(yàn)的設(shè)備,因此,我們也一直努力地幫助開(kāi)發(fā)者們將游戲呈現(xiàn)到盡多的 Android 設(shè)備并使得開(kāi)發(fā)過(guò)程更加高效輕松。本文將向您介紹眾多新的 Android 游戲開(kāi)發(fā)工具以及游戲調(diào)試、打包和分發(fā)技巧。

更高效的游戲開(kāi)發(fā)工具

工欲善其事,必先利其器,我們針對(duì)開(kāi)發(fā)工具做出了大量?jī)?yōu)化。游戲引擎主要使用 C 和 C++ 語(yǔ)言編寫(xiě),而大多數(shù)的 Android API 都被設(shè)計(jì)成由 Kotlin 這樣的托管代碼來(lái)調(diào)用。所以我們?cè)?Android Studio 中實(shí)現(xiàn)了同時(shí)調(diào)試 C/C++ 代碼和托管代碼的能力,這樣一來(lái)您就可以像下圖那樣在 Kotlin 及 C/C++ 代碼中分別設(shè)置斷點(diǎn),然后在兩種編程環(huán)境內(nèi)分別跟蹤執(zhí)行情況。您甚至還可以在托管代碼和原生 (native) 代碼之間跳轉(zhuǎn)觀察執(zhí)行情況。

△ 演示通過(guò) Android Studio 同時(shí)調(diào)試托管代碼和 C/C++

另一方面,Android Studio 可以通過(guò)自動(dòng)代碼補(bǔ)全功能來(lái)加快您編寫(xiě)代碼的速度,也支持您快速插入 JNI 函數(shù)原型在兩種不同環(huán)境之中編程。此外,構(gòu)建過(guò)程中會(huì)使用 Cmake 和 Gradle,它們能讓您更好地利用可移植 build。

對(duì)于那些在 Microsoft Windows 操作系統(tǒng)上用 Visual Studio 編寫(xiě) C/C++ 跨平臺(tái)游戲的開(kāi)發(fā)者來(lái)說(shuō),我們?cè)?2021 年 7 月推出的 Android 游戲開(kāi)發(fā)套件 (Android Game Development Kit) 中提供了一個(gè) Android 游戲開(kāi)發(fā)擴(kuò)展 (AGDE, Android Game Development Extension)。它能夠進(jìn)一步簡(jiǎn)化您的開(kāi)發(fā)進(jìn)程,并且使用一系列支持 C 和 C++ 的調(diào)試器及性能分析工具幫助您在 Visual Studio 環(huán)境中直接針對(duì) Android 設(shè)備進(jìn)行構(gòu)建。并且 AGDE 可以很方便地與多種構(gòu)建系統(tǒng)集成起來(lái),還能非常方便地整合進(jìn)您使用虛幻引擎的工作流,如此一來(lái),您就不需要專門(mén)分別針對(duì)桌面設(shè)備、游戲主機(jī)、Android 設(shè)備各使用一套工具集和構(gòu)建系統(tǒng)了。

配置 AGDE 的過(guò)程也非常簡(jiǎn)單。擴(kuò)展安裝完成后,請(qǐng)切換到您的 Visual Studio 項(xiàng)目,然后添加 Android APK 模板。您可以在工具欄訪問(wèn)到各種常用的 Android 開(kāi)發(fā)工具,比如 SDK 和 NDK 管理器、虛擬設(shè)備管理器、設(shè)備文件管理器、Logcat 以及性能分析器等,如下圖所示:

△ Visual Studio 中的 Android 工具欄

在項(xiàng)目中配置好 Android 構(gòu)建目標(biāo)后,您只需要像開(kāi)發(fā)標(biāo)準(zhǔn)桌面 Visual Studio 目標(biāo)那樣操作就行了,所有關(guān)于構(gòu)建、部署、調(diào)試的操作都沒(méi)有差別。您可以很方便地在調(diào)試器中設(shè)置斷點(diǎn)、切換到反匯編代碼中查看寄存器和內(nèi)存塊中的值,還可以通過(guò)并行堆棧查看并發(fā)情況。

△ 使用 Visual Studio 調(diào)試 Android 構(gòu)建目標(biāo)

另外,您不僅可以在專門(mén)的 Logcat 面板搜索日志輸出、按照類型過(guò)濾,還可以通過(guò) AGDE 快速訪問(wèn)原本在 Android Studio 提供的獨(dú)立 CPU、內(nèi)存分析器,如下圖右所示:

△ 可供搜索的 Logcat 面板 (左);獨(dú)立的 CPU 和內(nèi)存分析器 (右)

我們?yōu)檫@些工具設(shè)計(jì)了新的界面,增強(qiáng)了若干功能并支持原生內(nèi)存采樣。Android Studio 和 Android 游戲開(kāi)發(fā)擴(kuò)展工具的結(jié)合,為您提供了一整套豐富的工具來(lái)高效地開(kāi)發(fā)游戲。

Android 游戲開(kāi)發(fā)套件

俗話說(shuō),好馬配好鞍。只有這些趁手的工具其實(shí)是不夠的,我們還需要將這些工具集成到 Android 的托管代碼 API 中。為此,我們?cè)?Android 游戲開(kāi)發(fā)套件 (AGDK) 中提供了全新的 C/C++ 庫(kù)供您使用。

GameActivity

GameActivity 幾乎就是用原生方式實(shí)現(xiàn) (C/C++) 的 Android 標(biāo)準(zhǔn) activity。它可以很好地與 Jetpack 庫(kù)以及各種 Android 界面庫(kù)結(jié)合使用。這樣您就可以完全使用 C/C++ 編寫(xiě)游戲循環(huán),同時(shí)充分利用基于 Jetpack 構(gòu)建的各種庫(kù)。另外,GameActivity 會(huì)被渲染到 SurfaceView 中,因此您可以很輕松地混用 Android 界面元素,比如 WebView、MapView 和廣告 SDK 等各種服務(wù)所需要用到的視圖。這樣一來(lái),您只需要在托管代碼中通過(guò)一個(gè)簡(jiǎn)單加載 C/C++ 游戲模塊的類,就能完成對(duì)游戲循環(huán)邏輯的整合了。有關(guān)代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/username"
android:layout_width="0dp"
android:layout_height="wrap_content">

△ 需要顯示的視圖

public class MyGameActivity extends GameActivity {
static {
// 加載您的游戲庫(kù)
System.loadLibrary("game");
}
}

△ 最少的托管代碼

您需要修改 AndroidManifest.xml 文件中的 meta-data,用來(lái)告知 GameActivity 需要從哪個(gè)庫(kù)開(kāi)始執(zhí)行游戲循環(huán)。

activity android:name=".MyGameActivity" android:label="@string/app_name">
<meta-data android:name="android.app.lib_name" android:value="game"/>

△ 修改 AndroidManifest.xml

GameActivity 為您提供了若干原生回調(diào)方法,它們與 Android 的生命周期事件是相匹配的,這些事件回調(diào)可以很方便地整合進(jìn)您的游戲循環(huán)中。

△ 與 Android 生命周期對(duì)應(yīng)的回調(diào)方法

下面是一段非常簡(jiǎn)單的代碼,我們會(huì)向您展示一個(gè)基于 native_app_glue 庫(kù)的案例。native_app_glue 庫(kù)提供了一種異于尋常的執(zhí)行模式。

void android_main(struct android_app *app) {
// 您的游戲引擎
NativeEngine *engine = new NativeEngine(app);
// 您的游戲循環(huán)
engine->GameLoop();
delete engine;
}

△ 基于 native_app_glue 的例子

在這里,android_main() 函數(shù)將在一個(gè)區(qū)別于主線程的新線程中被調(diào)用。您可以從與線程關(guān)聯(lián)的 ALooper 中獲取到 Android 的生命周期事件,就像這樣:

while(1) {
int events;
struct android_poll_source *source;
// 如果沒(méi)有動(dòng)畫(huà)發(fā)生,阻塞進(jìn)程直到捕獲某個(gè)事件
while ((ALooper_pollAll(IsAnimating() ? 0: -1, Null, &events, (void **) &source)) >= 0) {
// 處理事件
if (source != NULL) {
source->process(mApp, source);
}
}
}

△ 使用 ALooper 獲取并處理 Android 生命周期事件

除了捕獲生命周期事件,您還可以用這個(gè)方法監(jiān)聽(tīng)文件描述符 (file descriptor)。

Frame Pacing API

幀數(shù)調(diào)步 (frame pacing) API 可以幫助開(kāi)發(fā)者解決由較短游戲幀造成的拖延現(xiàn)象,以及避免較長(zhǎng)游戲幀導(dǎo)致的拖延卡頓。如果設(shè)備支持選擇刷新率功能,則可以為玩家提供更靈活和流暢的顯示效果。

實(shí)現(xiàn) GameActivity 后,您可以選擇使用 OpenGL/ES 或者 Vulkan 將內(nèi)容渲染到表層。不論您選擇了哪種 API,Android Frame Pacing 庫(kù)都會(huì)幫您妥善處理渲染過(guò)程,它會(huì)將游戲的邏輯、渲染循環(huán)與 Android 的顯示子系統(tǒng)、底層顯示相關(guān)的硬件進(jìn)行同步,從而實(shí)現(xiàn)更流暢的渲染。

Oboe API

△ Oboe API

一款制作精良的游戲離不開(kāi)出色的音效,這也是 Oboe 音頻庫(kù)所提供的能力。您可以在 Android 4.1 及更高版本的系統(tǒng)上使用它的 API。在 API 級(jí)別 27 的設(shè)備上,Oboe 會(huì)通過(guò) AAudio 在設(shè)備上盡可能協(xié)調(diào)軟硬件而達(dá)到最低的音頻延遲。而對(duì)于較低版本的設(shè)備,Oboe 會(huì)使用 OpenSL ES 來(lái)盡可能保證兼容性。

Oboe 在引入重采樣、格式轉(zhuǎn)換、高性能的通道數(shù)轉(zhuǎn)換等多項(xiàng)新功能的同時(shí),還內(nèi)置了一些已知音頻問(wèn)題的解決方法。

游戲輸入

Android 游戲開(kāi)發(fā)套件還提供了兩個(gè)可以與 GameActivity 互操作的庫(kù),分別用于處理游戲中的軟鍵盤(pán)和手柄輸入信號(hào)。

游戲文本輸入

GameTextInput 在底層進(jìn)行了很多復(fù)雜的工作,它能將 Android 系統(tǒng)的軟鍵盤(pán)連接到您游戲內(nèi)的文本編輯器上,還包括了顯示和隱藏軟鍵盤(pán)的操作。

△ 游戲中的文本輸入邏輯

如果您將這個(gè)庫(kù)與 GameActivity 結(jié)合使用,那么無(wú)論有沒(méi)有使用 native_app_glue,系統(tǒng)都能自動(dòng)完成相關(guān)的配置。請(qǐng)看下面的代碼,GameTextInput 庫(kù)會(huì)將輸入狀態(tài)傳遞給您的游戲,這樣您的文本編輯器就能正確反映 IME 的狀態(tài)。

/**
* 獲取最后收到的文本輸入狀態(tài)
*/
void GameActivity_getTextInputState(
GameActivity *activity,
GameTextInputGetStateCallback callback,
void* context);

△ 修改 AndroidManifest.xml 文件

游戲手柄輸入

另一種游戲中常見(jiàn)的輸入設(shè)備是游戲手柄 (game controller)。您可以通過(guò)使用 Game Controller 庫(kù)來(lái)充分發(fā)揮實(shí)體游戲手柄的作用。這個(gè)庫(kù)會(huì)在手柄連接到設(shè)備或斷開(kāi)連接時(shí)向您的游戲發(fā)送通知,并且提供了關(guān)于按鈕布局、方向軸和其他按鍵控制器元數(shù)據(jù)的信息。

Game Controller 庫(kù)也在底層進(jìn)行了封裝,讓您不需要復(fù)雜的實(shí)現(xiàn)也能無(wú)縫與各種各樣的手柄輕松連接,甚至還接受鼠標(biāo)作為輸入設(shè)備。

支持大屏幕游戲

在智能電視暢玩游戲

如果您的游戲可以通過(guò)方向鍵來(lái)控制,并在橫屏模式下正常運(yùn)行,那么它就可以運(yùn)行在許多電視設(shè)備上。

要支持在智能電視上運(yùn)行,您需要對(duì) AndroidManifest.xml 文件做一些修改:

// 您需要在多個(gè) uses-feature 標(biāo)簽內(nèi)聲明這些權(quán)限:

android.hardware.touchscreen
android.hardware.faketouch
android.hardware.telephony
android.hardware.camera
android.hardware.nfc
android.hardware.location.gps
android.hardware.microphone
android.hardware.sensor

// 如果有必要的話,請(qǐng)?zhí)砑?android.required="false"

△ 修改 AndroidManifest.xml 文件

您需要在清單中聲明這些權(quán)限是非必要的,即 required="false"。這是由于很多您在 AndroidManifest 中提到的權(quán)限、功能都不是必須的,智能電視上往往不支持這些功能,比如觸摸屏、攝像頭、加速度傳感器等。您可以通過(guò)添加如下代碼,聲明游戲支持使用遙控器作為手柄:

<uses-feature
android:name="android.hardware.gamepad"
android:required="false"/>

△ 聲明游戲支持使用遙控器作為手柄

在需要時(shí),可以聲明 android:required="true",來(lái)表示在啟動(dòng)應(yīng)用前電視需要先檢查遙控器是否可用。

在 Chrome OS 運(yùn)行

Chrome OS 如今已經(jīng)成為了第二大桌面操作系統(tǒng),并且擁有非常多的游戲玩家。它可以直接運(yùn)行 Android 游戲,并內(nèi)置了 Google Play 商店。玩家可以在運(yùn)行 Chrome OS 的設(shè)備上暢玩支持橫屏的游戲。大多數(shù)設(shè)備提供了觸摸屏供玩家操作,對(duì)于某些沒(méi)有觸摸屏的設(shè)備,通常會(huì)通過(guò)鼠標(biāo)或觸控板來(lái)模擬觸摸屏操作。當(dāng)然,直接支持鼠標(biāo)和鍵盤(pán)輸入的游戲往往會(huì)給玩家?guī)?lái)更好的游戲體驗(yàn)。

您可以在游戲中使用類似下面的代碼捕捉鼠標(biāo)或觸控板事件:

fun onClick(view: View) {
view.requestPointerCapture()
}

override fun onCapturedPointerEvent(motionEvent: MotionEvent): Boolean {
// 捕獲到的指針事件往往提供相對(duì)位置
val horizontalOffset: Float = motionEvent.x
val verticalOffset: Float = motionEvent.y
return true
}

△ 捕捉鼠標(biāo)或觸控板事件代碼示例

您可以在 API 級(jí)別 26 或更高的 Android 上,使用上述代碼捕獲鼠標(biāo)或觸控板光標(biāo),來(lái)實(shí)現(xiàn)更精準(zhǔn)的控制。比如,大多數(shù)場(chǎng)景下,您可能會(huì)希望能夠讓與用戶交互的虛擬控件在尺寸更大的屏幕上也能保持合適的相對(duì)大小。這就需要您將不同的屏幕尺寸和屏幕顯示密度納入考慮,通過(guò)計(jì)算得到虛擬控件的大小。按照下面的代碼,您可以獲取當(dāng)前顯示屏的顯示度量指標(biāo),然后獲取 X 軸和 Y 軸的密度以及每英寸像素?cái)?shù),然后計(jì)算出虛擬控件的縮放比例。

val dm = resources.displayMetrics
// 用于精確縮放
val xdpi = dm.xdpi
val ydpi = dm.ydpi

// 用縮放因子計(jì)算 DPI
val densityDpi = dm.density * 160.0f
val scaledDensityDpi = dm.scaledDensity * 160.0f

△ 在托管代碼中獲取屏幕的 DisplayMetrics

您還可以使用 dm.density 和 dm.scaledDensity 獲得近似的縮放系數(shù)。其中 1.0 對(duì)應(yīng)著 DPI 值 160。ScaleDensity 用于根據(jù)用戶偏好縮放 Android 應(yīng)用的字體,所以,當(dāng)您的游戲支持這一功能,必然會(huì)給用戶帶來(lái)更佳的體驗(yàn)。

有時(shí)出于性能考慮,您可能會(huì)想要設(shè)定一個(gè)顯示密度的上限。如果您愿意,可以使用 surfaceHolder.setFixedSize 來(lái)自動(dòng)且經(jīng)濟(jì)地縮放界面。這樣不僅可以節(jié)省內(nèi)存 (RAM),還可以減少需要著色的像素,并進(jìn)一步節(jié)省電量和減少發(fā)熱。具體參照下面這段代碼:

var width = mSurfaceView.width
var height = mSurfaceView.height
val dm = resources.displayMetrics

if (dm.density > maxDensity) {
val newScaleFactor = maxDensity / dm.density
if (newScaleFactor != scaleFactor) {
width = (newScaleFactor * width).toInt()
height = (newScaleFactor * height).toInt()
mSurfaceView.holder.setFixedSize(width, height)
}
}

△ 使用 surfaceHolder.setFixedSize 縮放界面

您還可以使用 C/C++ 代碼來(lái)自動(dòng)實(shí)現(xiàn)縮放,比如下面的代碼:

int32_t ret = ANativeWindow_setBuffersGeometry(
window, width, height, 0);

△ 使用 C/C++ 實(shí)現(xiàn)自動(dòng)縮放

由于觸控事件始終發(fā)生在屏幕坐標(biāo)內(nèi),所以無(wú)論是用托管代碼還是 C/C++ 實(shí)現(xiàn),您都需要調(diào)整觸控事件來(lái)匹配新的界面。

不同的游戲引擎有不同的后緩沖區(qū)縮放方式,如下圖列舉的 Unity、Unreal Engine、Godot 在這方面就有明顯的區(qū)別。

△ 不同游戲引擎縮放后緩沖區(qū)的方法比較

Unity 可以通過(guò)多種方式縮放后緩沖區(qū)。您可以在 Android Player 設(shè)置中調(diào)整最大 DPI 值: 先選擇 Fixed DPI,并拖動(dòng)選擇一個(gè)適當(dāng)?shù)?DPI 閾值。Unreal Engine 4 支持移動(dòng)內(nèi)容縮放系數(shù),它提供了設(shè)備原生分辨率之外的幾個(gè)額外選項(xiàng)。Godot 允許您通過(guò)多種方式縮放渲染的內(nèi)容,同時(shí)您可以使用基本窗口寬度 (base window width) 來(lái)避免渲染時(shí) DPI 過(guò)高。另外,Godot 還支持通過(guò)腳本的方式獲得屏幕的 DPI 值。

如果您需要游戲支持運(yùn)行在更多體系結(jié)構(gòu)的 Chrome OS 設(shè)備,那么還需要在構(gòu)建腳本中添加更多 ABI 項(xiàng):

externalNativeBuild {
cmake {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
}

△ 在 Gradle 構(gòu)建腳本中添加 x86/x86_64

這是由于很多運(yùn)行 Chrome OS 的設(shè)備都采用了 x86 或者 x86_64 架構(gòu)。如果您使用某一游戲引擎來(lái)開(kāi)發(fā) Android 游戲,那么您可以從圖中查看目前已知的支持 x86/x86_64 的引擎版本:

△ 在支持 x86/x86_64 的引擎版本舉例

當(dāng)您準(zhǔn)備好在 Google Play 商店分發(fā)游戲時(shí),只需選擇這些額外的架構(gòu),然后上傳到同一個(gè) Play 商品詳情下即可。這種統(tǒng)一分發(fā)的方式能最大程度簡(jiǎn)化您分發(fā)游戲的流程。

Android App Bundle 是一種專門(mén)為 Android 平臺(tái)設(shè)計(jì)的應(yīng)用打包發(fā)布的文件格式。它允許您在不增加文件大小的情況下,在同一個(gè)打包中包含各種體系結(jié)構(gòu)的二進(jìn)制庫(kù)文件。隨后 Google Play 會(huì)自動(dòng)為所包含的各種平臺(tái)生成一個(gè)專門(mén)的 APK 文件用于分發(fā)下載。

處理更龐大的素材

使用 PAD 分發(fā)游戲資源

△ 使用基于 Android App Bundle 的 PAD 格式

很多游戲都需要加載巨量的資源、素材文件,比如 3D 模型、貼圖、音效、視頻過(guò)場(chǎng)等等。Play Asset Delivery (PAD) 是一種針對(duì) Android App Bundle 的擴(kuò)展格式 。有了它,您可以向 Google Play 商店發(fā)布單個(gè)工件,而其中同時(shí)包含了游戲的代碼部分和資源部分。

△ 使用 Play Asset Delivery

PAD 這種格式經(jīng)過(guò)大量的改進(jìn)和優(yōu)化,能為您提供更高效的游戲分發(fā)體驗(yàn)。當(dāng)您使用 PAD 交付游戲資源時(shí),它會(huì)確保代碼和資源的版本一致,從而讓用戶一打開(kāi)游戲就能獲得最新的二進(jìn)制文件和資源,不再需要等待資源更新。并且 Google Play 的自動(dòng)更新功能還可以幫您自動(dòng)處理增量更新,使得用戶可以在現(xiàn)有游戲版本上直接下載更新產(chǎn)生變化的部分,而不需要重新下載整個(gè)游戲。使用 PAD 的另一好處是內(nèi)容下載的優(yōu)化,也就是用戶可以在首次運(yùn)行游戲時(shí)加載必要的資源,隨后需要新內(nèi)容時(shí)又繼續(xù)按需加載。

使用紋理壓縮區(qū)分設(shè)備

您可以使用紋理壓縮格式 (texture compression format) 將這些內(nèi)容進(jìn)行劃分,而 Google Play 會(huì)幫助您選擇最合適的紋理分發(fā)到不同設(shè)備上,從而保證您的游戲在大部分設(shè)備上都能實(shí)現(xiàn)最高的渲染效率和最佳的渲染效果。

△ 使用紋理壓縮劃分內(nèi)容分發(fā)

使用設(shè)備類別劃分

△ 使用設(shè)備類別進(jìn)行區(qū)分

我們當(dāng)前正努力實(shí)現(xiàn)按照設(shè)備類別進(jìn)行定向分發(fā)的功能,這樣一來(lái)您只需在每一套資源中分別提供不同類別所需要的資源文件即可。您可以根據(jù) RAM 大小、設(shè)備型號(hào)等信息,以及物理屏幕大小等硬件特征進(jìn)行劃分,實(shí)現(xiàn)用更小的安裝包覆蓋更龐大的設(shè)備群體。

總結(jié)

提高 Android 游戲開(kāi)發(fā)的效率不僅是每個(gè)開(kāi)發(fā)者的期望,也是我們這些年來(lái)堅(jiān)持不懈的理想。通過(guò)這篇文章我們分享了高效開(kāi)發(fā) Android 游戲的一些工具和技巧: Android 游戲開(kāi)發(fā)套件中新增的 Android 游戲開(kāi)發(fā)擴(kuò)展、Android GPU 檢查器、GameActivity、軟鍵盤(pán)、游戲手柄和高性能音頻庫(kù)及 Android 性能調(diào)優(yōu)工具;另外向您展示了 Play Asset Delivery 格式在分發(fā)游戲資源方面展示出的強(qiáng)大能力。希望這些內(nèi)容能加深您對(duì) Android 開(kāi)發(fā)的理解,并幫助您開(kāi)發(fā)出廣受歡迎的游戲作品!

責(zé)任編輯:未麗燕 來(lái)源: 谷歌開(kāi)發(fā)者
相關(guān)推薦

2021-07-14 09:56:27

谷歌Android游戲開(kāi)發(fā)工具包

2013-09-10 10:44:39

移動(dòng)開(kāi)發(fā)工具游戲引擎

2023-05-05 18:32:04

React開(kāi)發(fā)工具

2011-02-28 10:34:45

Android

2015-09-06 09:51:02

html5開(kāi)發(fā)經(jīng)驗(yàn)開(kāi)發(fā)工具

2015-09-06 13:26:41

HTML5游戲開(kāi)發(fā)工具手游開(kāi)發(fā)

2015-09-07 14:17:44

HTML5游戲開(kāi)發(fā)工具

2010-05-28 13:38:29

Linux開(kāi)發(fā)工具

2011-05-30 14:36:06

Android 在線開(kāi)發(fā) App Invent

2012-03-07 09:47:42

Android開(kāi)發(fā)工具

2017-01-16 13:13:51

DevOps開(kāi)發(fā)工具

2022-03-16 23:17:57

React JS前端工具

2020-02-04 09:31:43

Vue JS開(kāi)發(fā)工具

2011-05-03 09:41:42

Android開(kāi)發(fā)工具Android SDK

2011-07-19 09:15:42

GoogleAndroid 3.2開(kāi)發(fā)工具

2020-06-24 08:24:09

Web開(kāi)發(fā)工具

2013-04-25 13:12:16

unity3D手機(jī)游戲引擎

2016-01-05 09:39:32

HTML5游戲開(kāi)發(fā)工具

2010-04-19 11:23:26

Oracle開(kāi)發(fā)工具

2009-03-26 09:17:22

Linux調(diào)試Linux開(kāi)發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)