如何在 Java intelliJ 中正确提取方法?

How to properly extract a method in Java intelliJ?

编辑

我正在尝试在 Java 中创建一个 2D 平台游戏。我有一个 Player-class 有一个 update()-method:

public class Player {
...
...
...

    public void update(TileBlock[][] tb, ArrayList<MovingBlock> movingBlocks) {

        // checkBlockCollision(TileBlock[][] tb)
        // checkMovingBlockCollision(ArrayList<MovingBlock> movingBlocks)

        // Bounds for collision
        int x1 = (int) (x + width + GameState.xOffset);
        int y1 = (int) (y + height + GameState.yOffset);
        int x2 = (int) (x + GameState.xOffset);
        int y2 = (int) (y + GameState.yOffset);

        // Tile Block Collision
        for (TileBlock[] tileBlocks : tb) {
            for (int x = 0; x < tb[0].length; x++) {
                if (tileBlocks[x].getID() == 1) {

                    // Right collision
                    if (Collision.playerBlocked(new Point(x1, y2 - 2), tileBlocks[x]) ||
                            Collision.playerBlocked(new Point(x1, y1 - 1), tileBlocks[x])) {
                        right = false;
                    }

                    // Left collision
                    if (Collision.playerBlocked(new Point(x2 - 1, y2 + 2), tileBlocks[x]) ||
                            Collision.playerBlocked(new Point(x2 - 1, y1 - 1), tileBlocks[x])) {
                        left = false;
                    }

                    // Top Collision
                    if (Collision.playerBlocked(new Point(x2 + 1, y2), tileBlocks[x]) ||
                            Collision.playerBlocked(new Point(x1 - 2, y2), tileBlocks[x])) {
                        jumping = false;
                        falling = true;
                    }

                    // Bottom collision
                    if (Collision.playerBlocked(new Point(x2 + 2, y1 + 1), tileBlocks[x]) ||
                            Collision.playerBlocked(new Point(x1 - 2, y1 + 1), tileBlocks[x])) {
                        y = tileBlocks[x].getY() - height - GameState.yOffset;
                        falling = false;
                        topCollision = true;
                    }
                    if (!topCollision && !jumping) {
                        falling = true;

                    }
                } else if (tileBlocks[x].getID() == 2) {

                    // Right collision
                    if (Collision.playerBlocked(new Point(x1, y2 - 2), tileBlocks[x]) ||
                            Collision.playerBlocked(new Point(x1, y1 - 1), tileBlocks[x])) {
                        reachedGoal = true;
                    }

                    // Left collision
                    if (Collision.playerBlocked(new Point(x2 - 1, y2 + 2), tileBlocks[x]) ||
                            Collision.playerBlocked(new Point(x2 - 1, y1 - 1), tileBlocks[x])) {
                        reachedGoal = true;
                    }

                    // Top Collision
                    if (Collision.playerBlocked(new Point(x2 + 1, y2), tileBlocks[x]) ||
                            Collision.playerBlocked(new Point(x1 - 2, y2), tileBlocks[x])) {
                        reachedGoal = true;
                    }

                    // Bottom collision
                    if (Collision.playerBlocked(new Point(x2 + 2, y1 + 1), tileBlocks[x]) ||
                            Collision.playerBlocked(new Point(x1 - 2, y1 + 1), tileBlocks[x])) {
                        reachedGoal = true;
                    }
                }
            }
        }

        // Moving Block Collision
        if (movingBlocks != null && !movingBlocks.isEmpty()){
            for (MovingBlock movingBlock : movingBlocks) {
                if (movingBlock.getID() != 0) {
                    // Right collision
                    if (Collision.playerMovingBlock(new Point(x1, y2 - 2), movingBlock) ||
                            Collision.playerMovingBlock(new Point(x1, y1 - 1), movingBlock)) {
                        right = false;
                    }
                    // Left collision
                    if (Collision.playerMovingBlock(new Point(x2 - 1, y2 + 2), movingBlock) ||
                            Collision.playerMovingBlock(new Point(x2 - 1, y1 - 1), movingBlock)) {
                        left = false;
                    }

                    // Top Collision
                    if (Collision.playerMovingBlock(new Point(x2 + 1, y2), movingBlock) ||
                            Collision.playerMovingBlock(new Point(x1 - 2, y2), movingBlock)) {
                        jumping = false;
                        falling = true;
                    }

                    // Bottom collision
                    if (Collision.playerMovingBlock(new Point(x2 + 2, y1 + 1), movingBlock) ||
                            Collision.playerMovingBlock(new Point(x1 - 2, y1 + 1), movingBlock)) {
                        y = movingBlock.getY() - height - GameState.yOffset;
                        falling = false;
                        topCollision = true;

                        // Move the player the same amount the block is moving
                        GameState.xOffset += movingBlock.getMove();
                    } else {
                        if (!topCollision && !jumping) {
                            falling = true;
                        }
                    }
                }
            }
        }

        topCollision = false;
        double moveSpeed = 2.5;

        if (right) {
            GameState.xOffset += moveSpeed;    // Move the tile-block to the left because the player is moving right
        }
         if (left){
             GameState.xOffset -= moveSpeed;    // Move the tile-block to the right because the player is moving left
         }
         if (jumping){
             GameState.yOffset -= currentJumpSpeed;
             currentJumpSpeed -= 0.1;           // Jump is slowing down at 0.1 pixel per call to update()
             if (currentJumpSpeed <= 0){
                 currentJumpSpeed = startSpeed;
                 jumping = false;
                 falling = true;
             }
         }
         if (falling){
             GameState.yOffset += currentFallSpeed;
             // Fall-speed
             double maxFallSpeed = 5;
             if (currentFallSpeed < maxFallSpeed){
                 currentFallSpeed += 0.1;
             }
         }
         if (!falling) { currentFallSpeed = 0.1; }  // So we fall again without going too fast in the start

        // Player/Enemy collision
        if (Collision.PECollision() && !invincible) {
            health--;
            invincible = true;
            startTime = System.currentTimeMillis();
        }
        if (invincible) {
            int deathDuration = 2000; //in milliseconds
            long duration = System.currentTimeMillis() - startTime;
            if (duration > deathDuration){
                invincible = false;
            }
        }
    }
}

此代码有效,但 update() 非常大。所以我试图提取两种碰撞方法,以便我只在 update() 中调用它们。但是当我尝试将上面的代码更改为:

public void update(TileBlock[][] tb, ArrayList<MovingBlock> movingBlocks) {

    checkBlockCollision(tb);
    checkMovingBlockCollision(movingBlocks);

    topCollision = false;
    double moveSpeed = 2.5;

    if (right) {
        GameState.xOffset += moveSpeed;    // Move the tile-block to the left because the player is moving right
    }
     if (left){
         GameState.xOffset -= moveSpeed;    // Move the tile-block to the right because the player is moving left
     }
     if (jumping){
         GameState.yOffset -= currentJumpSpeed;
         currentJumpSpeed -= 0.1;           // Jump is slowing down at 0.1 pixel per call to update()
         if (currentJumpSpeed <= 0){
             currentJumpSpeed = startSpeed;
             jumping = false;
             falling = true;
         }
     }
     if (falling){
         GameState.yOffset += currentFallSpeed;
         // Fall-speed
         double maxFallSpeed = 5;
         if (currentFallSpeed < maxFallSpeed){
             currentFallSpeed += 0.1;
         }
     }
     if (!falling) { currentFallSpeed = 0.1; }  // So we fall again without going too fast in the start

    // Player/Enemy collision
    if (Collision.PECollision() && !invincible) {
        health--;
        invincible = true;
        startTime = System.currentTimeMillis();
    }
    if (invincible) {
        int deathDuration = 2000; //in milliseconds
        long duration = System.currentTimeMillis() - startTime;
        if (duration > deathDuration){
            invincible = false;
        }
    }
}

private void checkMovingBlockCollision(ArrayList<MovingBlock> movingBlocks) {
    // Moving Block Collision
    if (movingBlocks != null && !movingBlocks.isEmpty()){
        for (MovingBlock movingBlock : movingBlocks) {
            if (movingBlock.getID() != 0) {
                // Right collision
                if (Collision.playerMovingBlock(new Point(x1, y2 - 2), movingBlock) ||
                        Collision.playerMovingBlock(new Point(x1, y1 - 1), movingBlock)) {
                    right = false;
                }
                // Left collision
                if (Collision.playerMovingBlock(new Point(x2 - 1, y2 + 2), movingBlock) ||
                        Collision.playerMovingBlock(new Point(x2 - 1, y1 - 1), movingBlock)) {
                    left = false;
                }

                // Top Collision
                if (Collision.playerMovingBlock(new Point(x2 + 1, y2), movingBlock) ||
                        Collision.playerMovingBlock(new Point(x1 - 2, y2), movingBlock)) {
                    jumping = false;
                    falling = true;
                }

                // Bottom collision
                if (Collision.playerMovingBlock(new Point(x2 + 2, y1 + 1), movingBlock) ||
                        Collision.playerMovingBlock(new Point(x1 - 2, y1 + 1), movingBlock)) {
                    y = movingBlock.getY() - height - GameState.yOffset;
                    falling = false;
                    topCollision = true;

                    // Move the player the same amount the block is moving
                    GameState.xOffset += movingBlock.getMove();
                } else {
                    if (!topCollision && !jumping) {
                        falling = true;
                    }
                }
            }
        }
    }
}

private void checkBlockCollision(TileBlock[][] tb) {
    // Tile Block Collision
    for (TileBlock[] tileBlocks : tb) {
        for (int x = 0; x < tb[0].length; x++) {
            if (tileBlocks[x].getID() == 1) {

                // Right collision
                if (Collision.playerBlocked(new Point(x1, y2 - 2), tileBlocks[x]) ||
                        Collision.playerBlocked(new Point(x1, y1 - 1), tileBlocks[x])) {
                    right = false;
                }

                // Left collision
                if (Collision.playerBlocked(new Point(x2 - 1, y2 + 2), tileBlocks[x]) ||
                        Collision.playerBlocked(new Point(x2 - 1, y1 - 1), tileBlocks[x])) {
                    left = false;
                }

                // Top Collision
                if (Collision.playerBlocked(new Point(x2 + 1, y2), tileBlocks[x]) ||
                        Collision.playerBlocked(new Point(x1 - 2, y2), tileBlocks[x])) {
                    jumping = false;
                    falling = true;
                }

                // Bottom collision
                if (Collision.playerBlocked(new Point(x2 + 2, y1 + 1), tileBlocks[x]) ||
                        Collision.playerBlocked(new Point(x1 - 2, y1 + 1), tileBlocks[x])) {
                    y = tileBlocks[x].getY() - height - GameState.yOffset;
                    falling = false;
                    topCollision = true;
                }
                if (!topCollision && !jumping) {
                    falling = true;

                }
            } else if (tileBlocks[x].getID() == 2) {

                // Right collision
                if (Collision.playerBlocked(new Point(x1, y2 - 2), tileBlocks[x]) ||
                        Collision.playerBlocked(new Point(x1, y1 - 1), tileBlocks[x])) {
                    reachedGoal = true;
                }

                // Left collision
                if (Collision.playerBlocked(new Point(x2 - 1, y2 + 2), tileBlocks[x]) ||
                        Collision.playerBlocked(new Point(x2 - 1, y1 - 1), tileBlocks[x])) {
                    reachedGoal = true;
                }

                // Top Collision
                if (Collision.playerBlocked(new Point(x2 + 1, y2), tileBlocks[x]) ||
                        Collision.playerBlocked(new Point(x1 - 2, y2), tileBlocks[x])) {
                    reachedGoal = true;
                }

                // Bottom collision
                if (Collision.playerBlocked(new Point(x2 + 2, y1 + 1), tileBlocks[x]) ||
                        Collision.playerBlocked(new Point(x1 - 2, y1 + 1), tileBlocks[x])) {
                    reachedGoal = true;
                }
            }
        }
    }
}

碰撞没有被记录下来,玩家只是掉进了地图并超出了界限,而不是像预期的那样落在地图上的方块上。在这里提取方法的正确方法是什么?感谢所有帮助!

我发现了一个可能导致您遇到问题的错误。

TLDR;解决方案

在已经重构的代码中,你似乎只初始化了你的边界值, 这部分:

// Bounds for collision
int x1 = (int) (x + width + GameState.xOffset);
int y1 = (int) (y + height + GameState.yOffset);
int x2 = (int) (x + GameState.xOffset);
int y2 = (int) (y + GameState.yOffset);

在原始代码中,您似乎每次进入 update() 方法时都会初始化它们。 所以我相信你只需要将这些 init 移动到它们所属的地方就可以让它工作。

在最新的 Intellij 中提取方法的正确方法

这是从 Intellij 的任何代码中提取方法的简单方法:

  • Select 您要提取的代码
  • 右键单击,然后展开Refactor
  • Refactor 下,您应该会看到 Extract Method...,左键单击它
  • 然后,你只需要按照向导设置方法名,每个参数等

编辑

你在我回复的时候添加了评论,不知道你已经尝试过自动方法提取;但我的消息的第一部分仍然有效以修复错误