草庐IT

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

coder 2023-12-09 原文

背景
所以最近我想为android开发一个游戏,并开始四处寻找一个好的库来帮助我。libgdx选中所有正确的复选框。但按照惯例(也可以理解),所有文档都只提到了使用eclipse和adt。以前,我使用ant来构建我的android项目,所以我认为我可以使用它,但是学习ant,虽然它可能很有用,但似乎有点考虑到,肯定不会有那么多命令来构建这个项目?
问题
那么,在不使用eclipse、ant或其他ide/build工具的情况下,创建、编译和运行一个至少面向桌面和android平台的libgdx项目需要哪些步骤呢?
我将回答我自己的问题,但我使用的方法,以创造最终产品可能不是最好的,所以批评是受欢迎的。

最佳答案

以下是从一个project on github我做的,其中有所有的代码和信息。
纸飞机
这是一个测试libgdx开发的简单应用程序,无需使用eclipse或ant构建项目。主要关注的是将libgdx与我的无蚂蚁、仅命令行的开发环境集成。
过程
我将经历一个简单的项目,从开始到获得一个可运行的构建,这个项目将包含我收集的知识,研究如何在不使用ant或eclipse的情况下设置libgdx项目。一般的过程是事后诸葛亮的,但我写这篇文章是因为我在网上苦苦寻找答案,特别是针对android版本。
在本指南中,项目名称将是paperplanes,因为它比键入“testgamelibgdx”更好。项目代码将包括将加载的纹理移动到单击/接触点。应用程序本身在很大程度上是不相关的,只是帮别人省去了找到一些代码来测试我使用的步骤的步骤。
我假设环境已经设置好,可以使用ant或eclipse构建和部署android应用程序。目前,您还需要Java 1.6,因为在Android中使用1.7和编译似乎有一些问题。
生成目录结构
第一件事是在使用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 

安装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

Aquire libgdx库文件
每晚下载libgdx并将所需的libs放在相关目录中。下面的代码片段是我如何更新库的。
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" )

但是,android应用程序从assets目录开始查找资产。因此,上面的代码将导致它在文件夹ROOT/assets/assets/plane.png中查找文件。
因此,我们可以分散根目录中的所有资产,也可以在ROOT/assets中创建指向ROOT/android/bin/assets/文件夹的链接。它看起来很愚蠢,但在平台上使资产引用保持一致。
我相信有更好的方法,但它是有效的。
无论如何,这个应用程序只使用一个名为assets/plane.png的纹理。
写些代码
您可以在libgdx存储库中找到许多示例。下面我将转储我在编写指南时用来测试指南的代码。
main/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命令。
# 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"`

然后制作达尔维克字节码。包括代码中使用的所有库文件。
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

关于android - 在没有Eclipse或Ant的情况下使用LibGDX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14079764/

有关android - 在没有Eclipse或Ant的情况下使用LibGDX的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  9. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  10. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

随机推荐