java - 当运动来自数组时制作平滑的动画

标签 java

我正处于为计算机科学课制作吃 bean 人游戏的最后阶段。除了一件关键的事情之外,我的游戏功能正常。很不稳定。我知道它不稳定的原因,但我不知道如何解决它。我的问题是我将吃 bean 人和幽灵坐标的数组(如下)乘以 21。我有 100 毫秒的延迟,这意味着 pacman 每 100 毫秒移动 21 个像素,这并不平滑。

下面是数组的样子,以防万一:

public int board[][] =
  {{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}, //1
    {2, 0, 3, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 3, 0, 2}, //2
    {2, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 2}, //3
    {2,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2}, //4
    {2,0,1,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,1,0,2}, //5
    {2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,0,2}, //6
    {2,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,2}, //7
    {2,2,2,2,0,1,0,1,1,1,1,1,1,1,0,1,0,2,2,2,2}, //8
    {0,0,0,0,0,1,0,1,0,0,-1,0,0,1,0,1,0,0,0,0,0}, //9
    {5,2,2,2,2,1,1,1,0,2,2,2,0,1,1,1,2,2,2,2,6}, //10
    {0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0}, //11
    {2,2,2,2,0,1,0,1,1,1,2,1,1,1,0,1,0,2,2,2,2}, //12
    {2,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,2}, //13
    {2,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,2}, //14 - pacman on this row
    {2,0,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,2}, //15
    {2,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,2}, //16 
    {2,0,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,0,2}, //17
    {2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,0,2}, //18
    {2,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,2}, //19
    {2,0,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,0,2}, //20
    {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2}}; //21

基本上每一行都是一行。董事会就是从中得出的。例如,对于向上移动,只需检查当前位置上方的点是否清晰,以及是否向数组添加 1 并将其乘以 21 以获得新位置。

我想做的是减慢吃 bean 人的移动速度,同时使其平滑。如果您需要任何其他信息,我也可以提供更多代码片段。

编辑:根据要求,这里是代码。我知道这可能不是全部需要的,但我不知道需要哪些部分才能最大限度地提供帮助。而且它几乎已经得到了充分的评论。

这里有一个链接,因为它太长了,无法满足字符限制: Pastebin - Pacman

最佳答案

如何绘制可能比抽象模型更重要。例如 BitSets 作为替代方案就不多说了。

如何实现重绘:repaint(20L, x, y, width, height)(仅限于更改的区域,能够随着时间的推移收集多个更改)?你怎么画?改变 BufferedImage 就可以了。可以在 BufferedImage 上写入(获取 Graphics2D),因此可以在其上绘制 Sprite 。

不稳定也可能源于缺少 setDoubleBuffered(true) 的使用。顺便说一下,每秒 50 帧将是重绘(20L)。

您可能有一个计时器循环来为模型设置动画,并在事件线程中绘制 View 组件 - 例如一个完整的或 21x21 BufferedImages,以及一些用于更改 View 的信号量。这些信号量可能是瓶颈,而 21x21 组件可能更细粒度。

<小时/>

收到代码后: 重新设计会更好,但可能不实用。

FontColor应该在paintComponent之外创建,尤其是字体速度很慢。 样式:if (up == true) 应该简单地为 if (up);类名通常以大写字母开头:Draw

getResource 和 getResourceAsStream 都在类路径上搜索,而不是 Windows 反斜杠,需要斜杠。 (类路径可以位于 jar 内。)同样可以加载字体。

            sound.open(AudioSystem.getAudioInputStream(
                getClass().getResourceAsStream("Sounds/pac_chomp.wav")));

声音管理似乎有点简单,可能应该像字体一样全局保存,因此运行循环看起来更“异步”,只需调用开始,而不加载。

没那么重要,但是:

    for (int r = 0; r < board.length; r++) {
        System.arraycopy(newboard[r], 0, board[r], 0, board[r].length);
        // Replaces:
        //for (int c = 0; c < board[0].length; c++) {
        //    board[r][c] = newboard[r][c];
        //}
    }

更聪明的方法是交换别名:

int[][] physicalBoard0 = new int[21][21];
int[][] physicalBoard1 = new int[21][21];
boolean boardIs0 = true;
int[][] board = physicalBoard0;
int[][] newboard = physicalBoard1;

private void swapBoards() {
    boardIs0 = !boardIs0;
    if (boardIs0) {
        board = physicalBoard0;
        newBoard = physicalBoard1;
    } else {
        board = physicalBoard1;
        newBoard = physicalBoard0;
    }
}

关于java - 当运动来自数组时制作平滑的动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8640499/

相关文章:

java - Eclipse 继续运行我的旧 Web 应用程序

java - Android:从 PagerAdapter 获取 fragment

java - 奇数相加的递归方法

java - 找不到符号 - 方法错误

java - 在finally block 中重新抛出异常

java - Tomcat 在启动时不会从 eclipse 启动 : Several ports (8005, 8080) 本地主机上的 Tomcat 服务器所需的已在使用中

java - 如何使用 TornadoFx 将组合框添加到 Kotlin 中的表格 View

java - 是否可以在 java 应用程序中使用 jQAssistant 作为工具?

java - ConstraintViolationException 处理程序未在 Micronaut 中执行

java - 如何在运行时更改 ATM 类(Java 反射)