Java 如何使碰撞和动画在2d平台中工作?

Java 如何使碰撞和动画在2d平台中工作?,java,animation,collision-detection,Java,Animation,Collision Detection,我希望在我的碰撞检测/移动方面得到一些帮助,它正在工作,但有问题。 我无法在碰撞检测/移动过程中始终如一地重现错误。玩家只是有时候不能朝某个方向移动,我也不能复制你的脱臼——它似乎开始让你无缘无故地再次移动。重力并不总是在应该的时候起作用,有时你会被困在墙上。代码如下 我还想听听关于如何在游戏中实现动画(例如在移动时播放行走动画)的建议。我已经有一个动画工作,但它是混乱和使用定时器();我想找到更好的方法。任何建议都将不胜感激 出于学习的目的,我正在使用eclipse用java编写游戏,所以我不

我希望在我的碰撞检测/移动方面得到一些帮助,它正在工作,但有问题。 我无法在碰撞检测/移动过程中始终如一地重现错误。玩家只是有时候不能朝某个方向移动,我也不能复制你的脱臼——它似乎开始让你无缘无故地再次移动。重力并不总是在应该的时候起作用,有时你会被困在墙上。代码如下

我还想听听关于如何在游戏中实现动画(例如在移动时播放行走动画)的建议。我已经有一个动画工作,但它是混乱和使用定时器();我想找到更好的方法。任何建议都将不胜感激

出于学习的目的,我正在使用eclipse用java编写游戏,所以我不是在寻找2d游戏引擎

下面是所有的代码

MarioLikeGame.java

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class MarioLikeGame extends JFrame implements KeyListener
{
    private static Graphics graphics;
    private Image image;
    private static boolean running = true;
    private static Player player = new Player(4 * 32, 6 * 32 + 24,                             
    "images/playerStill.png", "images/playerWalking.png");
    private static PlayingBoard board = new PlayingBoard(player);
    private static ReadLevelFile readLevel = new ReadLevelFile();
    private static boolean scrollingRight = false;//To let player know to stop moving
    private static boolean scrollingLeft = false;


    public static void main(String[] args)
    {
        new MarioLikeGame();
        readLevel.openFile();
        readLevel.readFile(board);
        readLevel.closeFile();
        gameLoop();
    }

    public MarioLikeGame()
    {
        setTitle("SideSCroIIer");
        setResizable(false);
        setSize(448, 320 + 24);// 32*32 tiles 14 wide  10 high
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBackground(Color.BLACK);
        this.addKeyListener(this);
        setVisible(true);

    }

    public void paint(Graphics g)
    {
        image = createImage(getWidth(), getHeight());
        graphics = image.getGraphics();

        paintComponent(graphics);
        g.drawImage(image, 0, 0, null);
        repaint();
    }

    public void paintComponent(Graphics g)
    {   
        g.drawImage(image, 0, 0, null);
        for(int row = 0; row < board.gameTiles.length; row++)
        {
            for(int column = 0; column < board.gameTiles[row].length; column++)
            {
                board.gameTiles[row][column].draw(g);
            }
        }

        player.draw(g);

    }

    public static void gameLoop()
    {
        long startTime = System.currentTimeMillis();
        long cumTime = startTime;

        while(running)
        {
            long timePassed = System.currentTimeMillis() - cumTime;
            cumTime += timePassed;

            checkForCollision(timePassed);

            player.checkForPlayerMovement(timePassed, scrollingRight, scrollingLeft);
            board.checkForScroll(timePassed);

            try
            {
                Thread.sleep(20);
            }
            catch(Exception ex){}

        }
    }

    public static void checkForCollision(long timePassed)
    {
        //scroll if player tries to walk to the edge of the screen
        //check for scrollingRight
        if(player.xPos + 31 >= 11 * 32)
        {

            board.setScrollingRight(true);
            scrollingRight = true;


        }

        if(player.xPos + 31 < 11 * 32)
        {
            board.setScrollingRight(false);
            scrollingRight = false;
        }
        //Make sure to not scroll everything off screen
        //stop scrolling when the right walls right side is at the ride side of
             the screen
        if(board.gameTiles[board.gameTiles.length -1][0].xPos + 31 <= 448)
        {
            board.setScrollingRight(false);
            scrollingRight = false;
        }

        //check for scrollingLeft
        if(player.xPos <= 3 * 32)
        {

            board.setScrollingLeft(true);
            scrollingLeft = true;


        }

        if(player.xPos > 4 * 32)
        {
            board.setScrollingLeft(false);
            scrollingLeft = false;
        }

        //Make sure to not scroll everything off screen
        //stop scrolling when the left walls left side is at the ride left 
            of the screen
        if(board.gameTiles[0][0].xPos >= 0)
        {
            board.setScrollingLeft(false);
            scrollingLeft = false;
        }

        //check for collision with tiles while moving right
        if(player.movingRight == true)
        {
            for(int row = 0; row < board.gameTiles.length; row++)
            {
                for(int column = 0; column < board.gameTiles[row].length; 
                                column++)
                {
                    if((board.gameTiles[row]  
 [column].rect.contains(player.xPos + 32, player.yPos) 
|| board.gameTiles[row][column].rect.contains(player.xPos + 32, player.yPos + 31))  && 
board.gameTiles[row][column].isSolid == true)
                    {
                        player.setHitRight(true);
                    }

                    else if((board.gameTiles[row]
[column].rect.contains(player.xPos + 32, player.yPos) && board.gameTiles[row]
[column].rect.contains(player.xPos + 32, player.yPos + 31)) && board.gameTiles[row]
[column].isSolid == false)
                    {
                        player.setHitRight(false);
                    }

                }
            }
        }

        //Check for collision with tiles while moving left
        if(player.movingLeft == true)
        {
            for(int row = 0; row < board.gameTiles.length; row++)
            {
                for(int column = 0; column < board.gameTiles[row].length; 
column++)
                {
                    if((board.gameTiles[row]
[column].rect.contains(player.xPos - 1, player.yPos) || board.gameTiles[row]
[column].rect.contains(player.xPos - 1, player.yPos + 31)) && board.gameTiles[row]
[column].isSolid == true)
                    {
                        player.setHitLeft(true);
                    }
                    else if((board.gameTiles[row]  
[column].rect.contains(player.xPos - 1, player.yPos) && board.gameTiles[row]
[column].rect.contains(player.xPos - 1, player.yPos + 31)) && board.gameTiles[row]
[column].isSolid == false)
                    {
                        player.setHitLeft(false);
                    }
                }
            }
        }

        //only use gravity if there is nothing solid below player       
        for(int row = 0; row < board.gameTiles.length; row++)
        {
            for(int column = 0; column < board.gameTiles[row].length; column++)
            {
                if((board.gameTiles[row][column].rect.contains(player.xPos,
 player.yPos + 32) || board.gameTiles[row][column].rect.contains(player.xPos + 31, 
 player.yPos + 32)) && board.gameTiles[row][column].isSolid == true)
                {
                    player.setGravity(false);
                }
                else if((board.gameTiles[row]
[column].rect.contains(player.xPos, player.yPos + 32) && board.gameTiles[row]
[column].rect.contains(player.xPos + 31, player.yPos + 32)) && board.gameTiles[row]
[column].isSolid == false)
                {
                    if(player.gravityOff == false)//wtf? delete?
                    {
                        player.setGravity(true);
                    }
                }

            }
        }   


        //Jumping collision
        if(player.jumping == true)
        {

            player.setHitUp(false);//Set false time every works fine - see
 commented code below

            for(int row = 0; row < board.gameTiles.length; row++)
            {
                for(int column = 0; column < board.gameTiles[row].length;
 column++)
                {
                    if((board.gameTiles[row]
[column].rect.contains(player.xPos, player.yPos - 1) || board.gameTiles[row]
[column].rect.contains(player.xPos + 31, player.yPos - 1)) && board.gameTiles[row]
[column].isSolid == true)
                    {
                        player.setHitUp(true);
                    }
//                  else if((board.gameTiles[row]
[column].rect.contains(player.xPos, player.yPos - 1) && board.gameTiles[row]
[column].rect.contains(player.xPos + 31, player.yPos - 1)) && board.gameTiles[row]
[column].isSolid == false)

//                  {
//                      player.setHitUp(false);
//                  }//couldnt get this to set false properly fixed up 
top




                }
            }
        }


    }


    public void keyPressed(KeyEvent e) 
    {

        int keyCode = e.getKeyCode();

        if(keyCode == KeyEvent.VK_D)
        {

            player.setMovingRight(true);

        }

        if(keyCode == KeyEvent.VK_A)
        {
            player.setMovingLeft(true);
        }

        if(keyCode == KeyEvent.VK_W)
        {
            if(player.jumping == false)
            {
                if(player.gravity == false)
                {
                    player.jumping = true;
                    player.startYPos = player.yPos;
                }
            }
        }
    }


    public void keyReleased(KeyEvent e) 
    {
        int keyCode = e.getKeyCode();

        if(keyCode == KeyEvent.VK_D)
        {
            player.setMovingRight(false);

        }

        if(keyCode == KeyEvent.VK_A)
        {
            player.setMovingLeft(false);
        }


    }


    public void keyTyped(KeyEvent e) 
    {
        //does nothing
    }

}
PlayingBoard.java

public class PlayingBoard 
{
public Tile[][] gameTiles = new Tile[28][10];
public boolean scrollingRight = false;
public boolean scrollingLeft = false;
double velocityX = 0.05;
Player player;

public PlayingBoard(Player player)
{
    this.player = player;
    setUpBlankBoard();
}

public void setUpBlankBoard()
{
    for(int row = 0; row < gameTiles.length; row++)
    {
        for(int column = 0; column < gameTiles[row].length; column++)
        {
            gameTiles[row][column] = new Tile(row * 32, column * 32 + 24, 0);
        }

    }

}

public void checkForScroll(long timePassed)
{
    if(scrollingRight == true)
    {
        if(player.movingRight == true)
        {
            if(player.hitRight == false)
            {
                scrollRight(timePassed);
            }
        }
    }

    if(scrollingLeft == true)
    {
        if(player.movingLeft == true)
        {
            if(player.hitLeft == false)
            {
                scrollLeft(timePassed);
            }
        }
    }
}

public void scrollRight(long timePassed)
{
    for(int row = 0; row < gameTiles.length; row++)
    {
        for(int column = 0; column < gameTiles[row].length; column++)
        {
            gameTiles[row][column].xPos -= velocityX * timePassed;
            gameTiles[row][column].rect.x -= velocityX * timePassed;

        }

    }
}

public void scrollLeft(long timePassed)
{
    for(int row = 0; row < gameTiles.length; row++)
    {
        for(int column = 0; column < gameTiles[row].length; column++)
        {
            gameTiles[row][column].xPos += velocityX * timePassed;
            gameTiles[row][column].rect.x += velocityX * timePassed;

        }

    }
}

public void setScrollingRight(boolean scrolling)
{
    scrollingRight = scrolling;
}

public void setScrollingLeft(boolean scrolling)
{
    scrollingLeft = scrolling;
}

}
ReadLevelFile.java

import java.io.File;
import java.util.Scanner;


public class ReadLevelFile 
{
Scanner input;
int column = 0;
int row = 0;
public void openFile()
{
    try
    {
        input = new Scanner(new File("level1.txt"));
    }
    catch(Exception ex){}
}

public void readFile(PlayingBoard board)
{

    for(int column = 0; column < board.gameTiles[column].length; column++)
    {
        for(int row = 0; row < board.gameTiles.length; row++)
        {
            int x = input.nextInt();
            board.gameTiles[row][column].setTileType(x);
        }

    }
}

public void closeFile()
{
    input.close();
}
}
导入java.io.File;
导入java.util.Scanner;
公共类ReadLevelFile
{
扫描仪输入;
int列=0;
int行=0;
公共void openFile()
{
尝试
{
输入=新扫描仪(新文件(“level1.txt”);
}
捕获(例外情况除外){}
}
公共无效读取文件(播放板)
{
对于(int column=0;column
有些软件包可以做这类事情——你真的需要一个

我会发布一个关于什么是好的2D游戏框架的问题


祝你好运。

当相机滚动时,你不应该弄乱瓷砖的位置。这些应该是相对不变的。请使用绘图计算中使用的偏移量。谢谢Chris。这很有道理,不过我不知道怎么做。我看看能不能弄明白。我想我不明白。我试图做的不是移动矩形的瓷砖,而是只显示瓷砖和播放器,就好像它们在滚动一样。这是一个错误的想法还是我只是没有正确地编码它?只有当你使用一个精灵框架,即使这样精灵也可以作为一个组移动(使用组偏移量)。你应该只关心相机,以及如何与相机相关地画图。这似乎更多的是一个评论,而不是一个答案。好的,下次我将使用一个评论:)我对框架的理解是已经完成的,我只是使用,witch不是我要找的,谢谢。如果我错了,请告诉我。
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;

public class Tile 
{
int xPos;
int yPos;
int height;
int width;
boolean isSolid = false;
boolean isHazard = false;
boolean isDeadly = false;
Image img1;
Rectangle rect;
int tileType;


public Tile(final int xPos, final int yPos, final int tileType)
{
    this.tileType = tileType;
    this.xPos = xPos;
    this.yPos = yPos;
    width = 32;
    height = 32;
    this.rect =  new Rectangle(xPos, yPos, width, height);
    defineTile();

}

public void draw(Graphics g)
{
    if(tileType != 0)
    {   
        g.drawImage(img1, xPos, yPos, width, height, null); 

    }

}

public void defineTile()
{
    if(tileType == 0)
    {
        blankTile();
    }
    if(tileType == 1)
    {
        groundTile();
    }
}

public void groundTile()
{
    img1 = getImage("images/ground.png");
    isSolid = true;

}

public void blankTile()
{

}

public void setTileType(int type)
{
    tileType = type;
    defineTile();
}




Image getImage(String img) 
{
    return Toolkit.getDefaultToolkit().getImage(img);
}


}
import java.io.File;
import java.util.Scanner;


public class ReadLevelFile 
{
Scanner input;
int column = 0;
int row = 0;
public void openFile()
{
    try
    {
        input = new Scanner(new File("level1.txt"));
    }
    catch(Exception ex){}
}

public void readFile(PlayingBoard board)
{

    for(int column = 0; column < board.gameTiles[column].length; column++)
    {
        for(int row = 0; row < board.gameTiles.length; row++)
        {
            int x = input.nextInt();
            board.gameTiles[row][column].setTileType(x);
        }

    }
}

public void closeFile()
{
    input.close();
}
}