背景
所以最近我想为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
bin目录。cd desktop
mkdir -pv bin/classes libs src/com/jeff/bucket
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
rm build.xml local.properties project.properties ant.properties proguard-project.txt
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
areabi*目录。所以在bin/lib目录中建立一些指向这些文件夹的链接。你也可以复制实际的文件夹,但libs进入libs目录该死!cd android/bin/lib
ln -s ../../libs/armeabi
ln -s ../../libs/armeabi-v7a
Gdx.files.internal( "assets/plane.png" )
assets目录开始查找资产。因此,上面的代码将导致它在文件夹ROOT/assets/assets/plane.png中查找文件。ROOT/assets中创建指向ROOT/android/bin/assets/文件夹的链接。它看起来很愚蠢,但在平台上使资产引用保持一致。assets/plane.png的纹理。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 );
}
}
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() {
}
}
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 );
}
}
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 );
}
}
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目录运行命令。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
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 -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 - 在没有Eclipse或Ant的情况下使用LibGDX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14079764/
我正在学习如何使用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
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类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
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用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请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为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