5

背景

所以最近我想为 Android 构建一个游戏,并开始四处寻找一个好的库来帮助解决这个问题。LibGDX 选中了所有正确的复选框。但是像往常一样(并且可以理解)所有文档只提到了使用带有 ADT 的 Eclipse。以前,我使用 Ant 构建我的 Android 项目,所以我认为我可以使用它,但是学习 Ant,虽然它可能很有用,但考虑到肯定不会有那么多命令来构建项目,这似乎有点多?

问题

那么,在不使用 Eclipse、Ant 或其他一些 IDE/构建工具的情况下,我需要执行哪些步骤来创建、编译和运行至少针对桌面和 Android 平台的 LibGDX 项目?

我将回答我自己的问题,但我用来创建最终产品的方法可能不是最好的,因此欢迎批评。

4

1 回答 1

11

以下内容来自我在 github 上创建的一个项目,其中包含所有代码和信息。

纸飞机

这是一个测试 libgdx 开发的简单应用程序,无需使用 Eclipse 或 Ant 来构建项目。主要关注点是将 libgdx 与我的无 Ant、仅命令行的开发环境集成。

过程

我将通过一个简单的项目,从开始到获得可运行的构建,将结合我收集的知识,研究如何在不使用 Ant 或 Eclipse 的情况下设置 libgdx 项目。事后看来,一般过程是直截了当的,但我写这篇文章是因为我很难在网上找到答案,特别是针对 android 构建。

出于本指南的目的,项目名称将是PaperPlanes,因为它比键入“TestGameLibGdx”更好。项目代码将包括将加载的纹理移动到单击/触摸点。该应用程序本身在很大程度上无关紧要,只是为某人节省了查找一些代码来测试我使用的步骤的步骤。

我假设环境已经设置为使用 Ant 或 Eclipse 构建和部署 android 应用程序。目前您还需要java 1.6,因为使用 1.7 和为 android 编译似乎存在一些问题。

制作目录结构

第一件事是在使用 libgdx 时像往常一样为不同的目标创建文件夹。稍后我们将单独处理每个文件夹。我没有 iOS 或 HTML5 目标的目录,因为我还没有尝试构建它们。

mkdir -v PaperPlanes
cd PaperPlanes
mkdir -v main desktop android assets

设置主目录

这是大部分代码的去向。

cd main
mkdir -pv libs src/com/jeff/paperplanes 

设置桌面目录

非常简单,与 main 相同,但有一个bin目录。

cd desktop
mkdir -pv bin/classes libs src/com/jeff/bucket 

设置安卓目录

我们将使用该工具生成的 skelton 项目构建 android 目录android。或者,您可以按照源代码部分中提供的指南自行创建目录结构。请注意--target--path标志,因为它们特定于您的设置。

cd android
android create project --target 1 --name PaperPlanes --path /home/jeff/playground/PaperPlanes/android --activity PaperPlanesActivity --package com.jeff.paperplanes
mkdir -pv bin/classes bin/lib

删除我们不需要的文件。我删除了 progaurd 文件,因为这个项目不需要它。

rm build.xml local.properties project.properties ant.properties proguard-project.txt

获取 libgdx库文件

每晚下载 libgdx 并将所需的库放在相关目录中。下面的片段是我如何更新我的库。

LIBGDX_ZIP="libgdx-nightly-latest.zip"
wget http://libgdx.badlogicgames.com/nightlies/$LIBGDX_ZIP

unzip -o $LIBGDX_ZIP gdx.jar gdx-natives.jar gdx-backend-android.jar gdx-backend-lwjgl.jar gdx-backend-lwjgl-natives.jar extensions/gdx-tools.jar 'armeabi/*' 'armeabi-v7a/*'
rm -v $LIBGDX_ZIP

mv -v gdx.jar main/libs/
cp -Rv extensions main/libs
mv -v gdx-natives.jar gdx-backend-lwjgl.jar gdx-backend-lwjgl-natives.jar  desktop/libs/
mv -v gdx-backend-android.jar android/libs/
cp -Rv armeabi-v7a armeabi android/libs/

rm -rf extensions armeabi armeabi-v7a

apk 需要areabi*在安装时包含目录。因此,在bin/lib目录中创建一些指向这些文件夹的链接。您也可以只复制实际文件夹,但 libs 进入 libs 目录该死的!

cd android/bin/lib
ln -s ../../libs/armeabi
ln -s ../../libs/armeabi-v7a

获取一些资产

与 Android 应用程序共享时,资产很奇怪。

桌面应用程序从应用程序的根目录开始查找资产,因此您可以像这样引用资产:

Gdx.files.internal( "assets/plane.png" )

assets但是,android 应用程序会从目录中开始查找资产。因此,上面的代码会导致它在文件夹中查找文件ROOT/assets/assets/plane.png

所以我们既可以分散根目录中的所有资产,也可以ROOT/assetsROOT/android/bin/assets/. 它看起来很愚蠢,但使资产引用在整个平台上保持一致。

我确信有更好的方法可以做到这一点,但它确实有效。

无论如何,这个应用程序只使用一种名为assets/plane.png.

写一些代码

您可以在libgdx存储库中找到大量示例。下面我将在编写本指南时转储我用来测试本指南的代码。

主/src/.../PaperPlanesGame.java

package com.jeff.paperplanes;

import com.badlogic.gdx.Game;


public class PaperPlanesGame extends Game {
  private MainScreen ms; 

  @Override
  public void create() {
    ms = new MainScreen( this );
    this.setScreen( ms );
  }
}

主/src/.../MainScreen.java

package com.jeff.paperplanes;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.Screen;

public class MainScreen implements Screen {

  PaperPlanesGame g;
  Texture planeImage;
  Rectangle planeRect;
  SpriteBatch spb;
  Vector3 touchPos;
  OrthographicCamera cam;

  public MainScreen( PaperPlanesGame g ) {
    this.g = g;

    // load assets
    planeImage = new Texture( Gdx.files.internal( "assets/plane.png" ) );

    // initialize rectangle
    planeRect = new Rectangle();

    // initialize spritebatch for drawing
    spb = new SpriteBatch();    

    // initialize our camera
    cam = new OrthographicCamera();
    cam.setToOrtho( false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight() );
    cam.update( true );

    // touch location
    touchPos = new Vector3();

  }

  @Override
  public void show() {
  }
  @Override
  public void render( float delta ) {
    // clear screen
    Gdx.gl.glClear( GL10.GL_COLOR_BUFFER_BIT );

    // update camera
    cam.update();


    // begin draw
    spb.setProjectionMatrix( cam.combined );
    spb.begin();

    // move our plane and center it
    spb.draw( planeImage, planeRect.x - ( planeImage.getWidth() / 2 ) , planeRect.y - ( planeImage.getHeight() / 2 ) );
    //spb.draw( planeImage, planeRect.x, planeRect.y );
    spb.end();

    // update touch position
    if( Gdx.input.isTouched() ) {
      touchPos.set( Gdx.input.getX(), Gdx.input.getY(), 0 );

      // only unproject if screen is touched duh!
      cam.unproject( touchPos );

      // converts the coord system of the touch units ( origin top left ) to camera coord ( origin bottom left )
      planeRect.x = touchPos.x;
      planeRect.y = touchPos.y;
    }

    Gdx.app.log( "X + Y", planeRect.x + " + " + planeRect.y );

  }

  @Override
  public void resize( int width, int height ) {
  }
  @Override
  public void hide() {
  }
  @Override
  public void pause() {
  }
  @Override
  public void resume() {
  }
  @Override
  public void dispose() {
  }
}

android/src/.../PaperPlanesActivity.java

package com.jeff.paperplanes;

import android.app.Activity;
import android.os.Bundle;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;

public class PaperPlanesActivity extends AndroidApplication {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    AndroidApplicationConfiguration cf = new AndroidApplicationConfiguration();

    cf.useGL20 = true;
    cf.useAccelerometer = true;
    cf.useCompass = false;

    initialize( new PaperPlanesGame(), cf );
  }
}

桌面/src/.../PaperPlanesDesktop.java

package com.jeff.paperplanes;

import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;

public class PaperPlanesDesktop {

  public static void main( String[] args ) {
    LwjglApplicationConfiguration cf = new LwjglApplicationConfiguration();
    cf.title = "PaperPlanes";
    cf.useGL20 = true;
    cf.width = 800;
    cf.height = 480;

    new LwjglApplication( new PaperPlanesGame(), cf );
  } 
}

记住在处理 android 目标时要进行审查AndroidManifest.xml

为桌面编译

这是容易的一点。我们正在从ROOT目录运行编译命令。

# Compile
javac -verbose -classpath "desktop/libs/*:main/libs/*:desktop/bin/classes" -sourcepath desktop/src/com/jeff/paperplanes:main/src/com/jeff/paperplanes -d desktop/bin/classes desktop/src/com/jeff/paperplanes/*.java main/src/com/jeff/paperplanes/*.java 

# Run
java -classpath "desktop/libs/*:main/libs/*:desktop/bin/classes" com.jeff.paperplanes.PaperPlanesDesktop

编译安卓

比桌面复杂一点。我在很大程度上抄袭了这个人所做的工作。该指南非常有用,值得一读,以解释我将在下面执行的每个步骤。

我们正在从android目录运行命令。

首先我们制作 R.java,我并没有真正使用其中的任何资产,因为这超过了跨平台点,但似乎我无法删除它而不会在运行时出现错误。

aapt package -v -f -m -M AndroidManifest.xml -I /opt/android-sdk/platforms/android-10/android.jar -S res -J src/ 

现在我们编译我们的源文件。请注意-classpath确保它与您的库所在的位置一致。

javac -verbose -d bin/classes -classpath "bin/classes:/opt/android-sdk/platforms/android-10/android.jar:bin/lib/*:../main/libs/*:libs/*" -target 1.6 `find ./src -iname "*.java"` `find ../main/src -iname "*.java"`

然后制作 Dalvik 字节码。包括代码中使用的所有库文件。

dx --dex --output bin/classes.dex bin/classes libs/gdx-backend-android.jar ../main/libs/gdx.jar

在这里,我们制作未签名的 apk 文件。

aapt package -v -f -M AndroidManifest.xml -S res -I /opt/android-sdk/platforms/android-10/android.jar -F bin/paperplanes.unsigned.apk bin/ 

然后我们用密钥签名。

jarsigner -verbose -keystore debugkey.keystore -storepass debug123 -keypass debug123 -signedjar bin/paperplanes.signed.apk bin/paperplanes.unsigned.apk debugkey

如果您没有密钥,您可以生成一个。以下是制作方法(摘自我经常提到的指南):

JAVA_HOME/bin/keytool
                -genkeypair
                -validity 10000
                -dname "CN=company name,
                        OU=organisational unit,
                        O=organisation,
                        L=location,
                        S=state,
                        C=country code"
                -keystore DEV_HOME/AndroidTest.keystore
                -storepass password
                -keypass password
                -alias AndroidTestKey
                -keyalg RSA
                -v

最后我们运行 zipalign 并将其安装到设备上。

zipalign -v -f 4 bin/paperplanes.signed.apk bin/paperplanes.apk

# First time install
adb -d install bin/paperplanes.apk

# Reinstall
adb -d install -r bin/paperplanes.apk

来源

在命令行上构建 Android 程序

SO的回答让我失望

LibGDX github页面

PaperPlanes(这个项目)github页面

LibGDX API

制作应用时参考的LibGDX教程

制作应用程序时参考的另一个 LibGDX 教程

于 2012-12-29T07:42:31.580 回答