在没有Eclipse或Ant的情况下使用LibGDX

时间:2012-12-29 07:42:32

标签: android libgdx

背景

最近我想为Android构建一款游戏,并开始寻找一个好的图书馆来帮助解决这个问题。 LibGDX点击了所有正确的复选框。但是按照惯例(并且可以这么理解),所有文档都只提到使用Eclipse和ADT。以前,我使用Ant来构建我的Android项目,所以我假设我可以使用它但是学习Ant虽然可能很有用,但似乎有点考虑肯定没有那么多命令来构建项目?

问题

那么我需要做什么步骤来创建,编译和运行至少针对桌面和Android平台的LibGDX项目,而不使用Eclipse,Ant或其他IDE /构建工具?

我将回答我自己的问题,但我用来制作最终产品的方法可能不是最好的,所以欢迎批评。

1 个答案:

答案 0 :(得分:11)

以下内容取自我制作的project on github,其中包含所有代码和信息。

PaperPlanes

这是一个简单的应用程序,可以在不使用Eclipse或Ant构建项目的情况下测试libgdx开发。主要关注的是将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 

设置桌面目录

非常直接,与主要相同,但有bin目录。

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

设置Android目录

我们将使用android工具生成的skelton项目构建android目录。或者,您可以按照sources部分中提供的guide自行创建目录结构。请注意--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应用程序共享时,资产很奇怪。

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

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

但是,android应用程序会查找从assets目录开始的资产。因此,上述代码将使其在文件夹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() {
  }
}

<强>机器人/ 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

比桌面更复杂。我在很大程度上扼杀了this guy所做的工作。该指南非常有用,值得一读,以解释我将在下面介绍的每个步骤。

我们正在运行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

如果您没有钥匙,可以生成钥匙。以下是如何制作一个(取自the guide I've mentioned far too often):

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

来源

Building Android programs on the command line

An answer from SO that set me off

LibGDX github page

PaperPlanes (this project) github page

LibGDX API

LibGDX tutorial referenced when making the app

Another LibGDX tutorial referenced when making the app