Slick2D和JBox2D如何绘制

如何解决Slick2D和JBox2D如何绘制

如果您要做的只是在2D世界中绘制精灵,则基本上需要跟踪两件事,以便确定在屏幕上绘制哪些精灵以及在屏幕上绘制它们的位置。您必须将自己的精灵想象为存在于世界的某个位置,并且您在屏幕上看到的只是世界的一个视图,重点放在一个区域上。

您需要跟踪的两件事是:

  1. 每个精灵都需要在世界范围内有自己的位置
  2. 您的“相机”需要跟踪其相对于世界的位置。

因此,假设您拥有一个很大的世界,其2D坐标(x,y)空间为1,000,000 x 1,000,000像素(我在这里使用像素作为度量单位,但这是一个任意选择,其大小为世界无所谓,我只是选择了一个大世界)。然后,假设您有一个指向该世界的“摄像机”,并且该摄像机的视图就是屏幕上显示的内容。相机为您提供的显示为1024x768像素。

假设您使用箭头键在世界各地移动该相机。

因此,您的世界的坐标空间将这样映射到屏幕:

(0, 0)        +x
      +------------------>
      |
   +y |
      |      *  <= example sprite in your world @ coordinates (x=200, y=200)
      |
     \ /

当子画面“向右”移动时,它们会增加其x坐标。当他们“向左”移动时,它们会减小x坐标。当“向上” 移动精灵时,它们会 其y坐标(因为y在监视器显示中向下增大),而当“向下”移动精灵时它们会 其y坐标。

现在,再次,您在我们的屏幕上看到的只是相机的世界观。因此,让我们将相机的左上角设置为(x=500, y=500)。看起来像:

(0, 0)        +x
      +---------------------------------->
      |
   +y |
      |      *  <= example sprite in your world @ coordinates (x=200, y=200)
      |
      |
      |         +===================+
      |         |     the area      |
      |         |  that the camera  |
      |         |    "sees" and     |
      |         |   shows on your   |
      |         |       screen      |
      |         +===================+
     \ /

有了这个设置,我们可以说相机位于(500,500)(即此示例所示相机视图的左上角位于世界坐标(500,500))。相机会显示一个大小为1024x768的区域,然后右下角的对角是(500 + 1024,500 + 768)= (x=1524, y=1268)

请注意,我们这个世界中的子画面 该相机的查看区域内。这意味着,当我们在屏幕上渲染摄像机的视图时,我们将不会看到精灵。

相反,如果将摄影机移至(200,200),则摄影机的查看区域将覆盖左上角@(200,200)到右下角@(1224,968)的世界坐标,并看起来像像这样:

(0, 0)        +x
      +---------------------------------->
      |   
   +y |  +===================+
      |  |                   |
      |  |   * <= sprite     |
      |  |                   |
      |  |                   | <= camera's view of the world
      |  +===================+
      |
      |
      |
      |
     \ /

当相机处于此位置时,可以看到精灵。如果精灵是@(500,500),而相机位于(200,200),则当我们在屏幕上绘制精灵时,该精灵将出现 上的坐标300、300处。

为什么?

因为,这是真正的回答你的问题, 你在屏幕上画一些东西是精灵的 (500,500),减去 (200,200),它等于(300,300)。

所以,来回顾一下:

您可以使用箭头键(或鼠标或任何其他所需的控制方案)在全球范围内移动相机的位置,并通过获取精灵的位置并 相机的位置来渲染相对于相机位置的精灵位置,以及您得到的是精灵应该出现的 。

但是还有一件事…

绘制世界上的每一个精灵都是非常低效的。您只需要绘制相机视图内的子画面,否则就绘制了屏幕上看不到的东西,因此浪费了渲染/ CPU / GPU时间。

因此,在渲染摄影机视图时,需要遍历子画面,检查它们是否在“摄影机上”(即它们是否在摄影机视图内),并且仅绘制如果他们在此视图中。

为此,必须获取相机的 (在我们的示例中为1024x768),并检查精灵的位置是否在相机视图的矩形内- 这是相机左上角的位置角落,再加上相机的宽度和高度。

因此,如果我们的相机向我们显示了一个1024x768像素的视图,并且其左上角位于(200,200),则视图矩形为:

(200, 200)                      (1224, 200)
           +===================+
           |                   |
           |    *              |
           |                   |
           |                   |
           +===================+
(200, 968)                      (1224, 968)

在这种情况下,子画面的位置@(500,500)在摄影机的视图内。

如果您需要更多示例,我有一个运行中的Slick2D技术演示,称为Pedestrians,其中包含您可以查看的代码。对于我如何计算出应呈现的世界面积,看细节render里面方法这个文件,并要特别注意startXstartYstopXstopY变量,这对我来说控制的精灵,我要绘制的区域。还应注意,我的子画面(或“行人”)位于上TileMap,因此它们的大小不是1像素- 它们具有自己的宽度和高度。这增加了如何决定绘制内容的复杂性,但是基本上可以归结为:“绘制相机视图中的内容,以及边缘周围的一些额外内容”。

在您自己的计算机上克隆Pedeestrians存储库,通过将与其他任何Slick2D项目相同的依赖项添加到项目中来使其工作,并播放/修改渲染代码,直到您了解发生了什么。只有通过实践和学习,您才能了解其工作原理的所有细节。好消息是,一旦您确定了如何使用这种基本的2D世界与摄影机方法进行渲染,您将几乎知道如何为所有2D应用程序渲染图形,因为这些概念可以翻译成所有语言。

我还在YouTube频道上播放了各种行人视频(最相关的视频可能是视频,该视频显示了我的基本行人正在渲染,并且摄像机在四处移动),因此您无需看这一切就可以看到一切首先构建项目。

解决方法

在问这个之前,我在网上做了很多搜索。我就是做不到。我有点难以理解。那么,如何在与处于世界位置的物体相对应的正确屏幕位置绘制图像?谢谢

如果其他人在同一障碍物前面找到了他,我会发布一个HOW
TO,对正常性的很好解释。您可以在这里找到它:http : //romeo.akademx.ro/2012/04/06/slick-and-
box2d/

这是渲染功能:

public void render(GameContainer container,StateBasedGame game,Graphics g)
        throws SlickException {
    g.setBackground(Color.white);

    g.pushTransform();
    g.translate(worldToScreen(body.getPosition()).x,worldToScreen(body.getPosition()).y);
    g.rotate(15,15,(float) Math.toDegrees(body.getAngle()));
    part.draw();
    g.popTransform();

    g.drawString("Count: " + cont,5,40);
    //world.drawDebugData();
}

这些是我用来转换世界屏幕协调的功能:

public Vec2 screenToWorld(Vec2 screenV) {
    return new Vec2((screenV.x - offset.x) / scaleFactor,yFlip
            * (screenV.y - offset.y) / scaleFactor);
}

public Vec2 worldToScreen(Vec2 worldV) {
    return new Vec2(worldV.x * scaleFactor + offset.x,yFlip * worldV.y
            * scaleFactor + offset.y);
}

我也碰巧使用在此链接上找到的SlickDebugDraw:http
://slick.javaunlimited.net/viewtopic.php?f=19&t=3610&sid=69614ac53aaf5724b808b75173e8e48e

但是他的DebugDraw绘制了一个完全不同于我的render函数的东西。我有点困惑。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-