草庐IT

java - 了解 libgdx

coder 2023-11-28 原文

我明白这是一个框架;更是一个开源的跨平台游戏开发库。我去了libgdx homepage并按照视频教程中的说明进行操作。正确设置我的项目后,我能够在多个支持的平台上运行默认的 my-gdx-game 项目。很棒,很好,很花花公子……现在怎么办?

我一直在搜索论坛、wiki、javadoc 和更多网站,寻找体面的、直接的操作方法。不幸的是,我找不到任何帮助,那里的大部分帮助都假设您对这个库有一些基本的了解。

我觉得视频教程向我展示了如何正确设置项目,有效地弄湿我的脚,然后假设我知道如何游泳,然后让我离开了 300 英里的海里什么的。我在消化这个库时遇到了麻烦,因为我昨天才开始使用它,所以说到 libgdx,我是一个全新的人。

我想将我现有的项目转移到 libgdx,但我已经习惯了 BufferedImages、JFrames 和类似的东西。有经验的退伍军人的任何帮助都会很好。

顺便说一下,我在下面发布了我的核心项目,所以你们可以带我了解这里到底发生了什么......

<code>
package com.me.mygdxgame;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

public class MyGdxGame implements ApplicationListener {
    private OrthographicCamera camera;
    private SpriteBatch batch;
    private Texture texture;
    private Sprite sprite;

    @Override
    public void create() {

        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();

        camera = new OrthographicCamera(1, h/w);
        batch = new SpriteBatch();

        texture = new Texture(Gdx.files.internal("data/libgdx.png"));
        texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);

        TextureRegion region = new TextureRegion(texture, 0, 0, 512, 275);

        sprite = new Sprite(region);
        sprite.setSize(0.9f, 0.9f * sprite.getHeight() / sprite.getWidth());
        sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);
        sprite.setPosition(-sprite.getWidth()/2, -sprite.getHeight()/2);

        }

    @Override
    public void dispose() {
        batch.dispose();
        texture.dispose();
    }

    @Override
    public void render() {      
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        sprite.draw(batch);
        batch.end();
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}
</code>

最佳答案

如果你想移植你的 javax.swing游戏到 libgdx 你必须知道你是如何制作你的游戏的。你把逻辑和 View 分开了吗?如果是,那很好,你只需要重写 View 。如果没有,那么从头开始可能更好。
首先要了解的基础知识:游戏的入口点是 ApplicationListener界面。如果您不需要其中的每个方法,请扩展 Game ,这为您提供了一些默认行为。所以我建议使用它。 GameApplicationListener现在让您可以对某些应用程序事件使用react:

  • create() : 应用启动时调用
  • dispose() :当您的游戏关闭时调用(未崩溃:P)
  • pause() :在android上调用,当来电/主页按钮被按下时。在桌面上最小化窗口/游戏失去焦点时。
  • resume() : 在暂停状态后返回时调用。
  • resize() : 当您调整窗口大小和在 android 上,当屏幕旋转时调用(您必须在 list 文件中允许它)
  • render() : 调用每个游戏循环(如果启用),用于更新游戏中的对象,然后将它们绘制到屏幕上。
  • Game 中的默认 render() 实现类调用为您当前的渲染 Screen .

    屏幕?那是什么?
    想想一个普通的游戏。你启动它,它会显示一个菜单,有一些按钮,比如 Start Game , Settings ... 这是菜单屏幕。所以Screen s 是游戏中具有不同逻辑和 View 的部分,因此它们必须位于不同的类中。 Screen s 实现 Screen接口(interface),它再次为您提供了一些有用的方法:
  • show() : 调用,当你设置这个时 ScreenGame s ScreenMyGdxGame.setScreen() .
  • hide() : 调用,当另一个 Screen设置为 Game s Screen .

  • 所以如果当前 ScreenMenuScreen然后我按 Play Game按钮,show()PlayScreen被称为和 hide()MenuScreen叫做。Screen也有方法pause() , resume()resize() , 如果 Game 中的方法相同,则调用它们被调用(总是只针对当前屏幕)。如果您实现 ApplicationListener您必须自己编写此默认行为。
    请注意,dispose()Screen不会自动调用。

    接下来就是画图了。对于在 2d 中绘制,有:
  • ShapeRenderer ,大多数时候仅用于调试。它可以渲染简单的形状,如圆形、正方形...
  • SpriteBatch , 用于渲染 Texture s Sprite s...

  • 所以大多数时候你会使用 SpriteBatch 渲染.你在一个块中渲染:
  • SpriteBatch.begin() , 启动 SpriteBatch。在此调用之前设置他的视口(viewport)、矩阵...
  • SpriteBatch.draw() , 将你给它的东西作为参数(有很多不同的 draw() 方法,看 API)绘制到一个 Buffer 中,然后 flush()一旦 GPU 已满或 SpriteBatch.end()叫做。
  • SpriteBatch.end() , flush()缓冲区到 GPU,所以一切都绘制在屏幕上。

  • 笔记:
  • 在他们的 begin 中从来没有 2 个 SpriteBatch立即声明。所以之前begin()调用 SpriteBatch end()在另一个正在运行的 SpriteBatch
  • 如果可能,只使用 1 个 SpriteBatch 并尝试拨打 end()每个渲染循环仅一次,因为它会消耗一些性能。
  • 不要打电话draw()在开始结束块之外。

  • 最后但并非最不重要的是本“教程”:camera .它可以帮助你计算你的 Action ......以你自己的世界单位而不是像素。您也可以使用它通过四处移动来显示游戏世界的不同部分。
    首先:在构造函数中设置你的相机视口(viewport):
    camera = new OrthographicCamera(16, 9);
    

    这将设置一个 16 宽和 9 高的视口(viewport)。所以你的物理屏幕/显示器现在是 16 个单位宽度和 9 个单位高度。将此相机应用于您的 SpriteBatch 调用:
    `SpriteBatch.setProjectionMatrix(cam.combined)`
    

    通过这样做SpriteBatch渲染你的相机正在看的东西。
    默认情况下,相机 0,0 点位于其中间。所以现在要在中间画一些东西,请使用:
    batch.draw(yourTexture, 0, 0);
    

    要在右上角绘制,请使用:
     batch.draw(yourTexture, 16 / 2, 9 / 2);
    

    要移动您的相机,请使用:
    cam.translate(16/2, 9/2);
    

    请务必拨打 cam.update()改变位置后!

    现在相机的右上角是 16,9 而不是 16/2, 9/2。 0,0 点是左下角。

    我希望这在开始时不会太复杂。一些帮助我学习的教程:
  • StarAssault
  • Steigert's blog
  • 关于java - 了解 libgdx,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22295329/

    有关java - 了解 libgdx的更多相关文章

    1. java - 等价于 Java 中的 Ruby Hash - 2

      我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

    2. java - 从 JRuby 调用 Java 类的问题 - 2

      我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

    3. java - 我的模型类或其他类中应该有逻辑吗 - 2

      我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

    4. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

      什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

    5. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

      这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

    6. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

      HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

    7. 【Java入门】使用Java实现文件夹的遍历 - 2

      遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

    8. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

      我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

    9. java - Ruby 相当于 Java 的 Collections.unmodifiableList 和 Collections.unmodifiableMap - 2

      Java的Collections.unmodifiableList和Collections.unmodifiableMap在Ruby标准API中是否有等价物? 最佳答案 使用freeze应用程序接口(interface):Preventsfurthermodificationstoobj.ARuntimeErrorwillberaisedifmodificationisattempted.Thereisnowaytounfreezeafrozenobject.SeealsoObject#frozen?.Thismethodretur

    10. ruby - 了解在 Ruby 中与 lambda 一起使用的 inject 行为 - 2

      我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject

    随机推荐