简体   繁体   English

如何在我的2d平台游戏机中使用碰撞和动画?

[英]How do I get collision and animation to work in my 2d platformer?

I was hoping to get some help with my collision detection/movement, It is working but buggy. 我希望在碰撞检测/移动方面获得一些帮助,它正在工作,但有故障。 I cant reproduce the bugs with the collision detection/movement consistently. 我无法始终如一地复制碰撞检测/移动中的错误。 The player just sometimes cant move in certain directions, I also can't reproduce getting unstuck it just seems to start letting you move again for no reason. 播放器有时无法朝某些方向移动,我也无法复制被卡住的感觉,它似乎开始无缘无故地让您再次移动。 gravity doesn't always take effect when it should and sometimes you can get stuck in the wall. 重力不一定总能起作用,有时甚至会卡在墙上。 The code is below. 代码如下。

I also wanted to hear any suggestions on how I should implement animation(for example playing a walking animation while moving.) into the game. 我还想听听有关如何在游戏中实现动画的任何建议(例如,在移动时播放步行动画)。 I have gotten one animation to work but it was messy and used Timer(); 我已经制作了一个动画,但是它很混乱并且使用了Timer(); and I wanted to find a better way of doing it. 我想找到一种更好的方法。 any advice is appreciated. 任何建议表示赞赏。

I am coding the game in java using eclipse for learning purposes so I'm not looking for a 2d game engine. 我出于学习目的使用eclipse在Java中对游戏进行编码,因此我没有在寻找2D游戏引擎。

Here is all of the code. 这是所有代码。

MarioLikeGame.java 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
    }

}

Player.java 播放器

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;


public class Player 
{ 
int xPos;
int yPos;
int height;
int width;
Image img1;
Image img2;
Rectangle rect;
double velocityX = 0.08;
double velocityY = 0.08;
boolean movingRight = false;
boolean movingLeft = false;
boolean hitRight = false;
boolean hitLeft = false;
boolean hitUp = false;
boolean gravity = true;
boolean jumping = false;
int startYPos;
boolean gravityOff = false;




public Player(final int xPos, final int yPos, final String img1, final String img2)
{
    this.xPos = xPos;
    this.yPos = yPos;
    this.height = 32;
    this.width = 32;
    this.img1 = getImage(img1);
    this.img2 = getImage(img2);
    this.rect = new Rectangle(xPos, yPos, width, height);


}

public void draw(Graphics g)
{

    g.drawImage(img1, xPos , yPos, width, height, null);

}

public void checkForPlayerMovement(long timePassed, boolean scrollingRight, boolean     
 scrollingLeft)
{
    if(movingRight == true)
    {
        if(hitRight == false)
        {
            if(scrollingRight == false)
            {
                moveRight(timePassed);
            }
        }
    }

    if(movingLeft == true)
    {
        if(hitLeft == false)
        {
            if(scrollingLeft == false)
            {
                moveLeft(timePassed);
            }
        }
    }

    if(gravity == true)
    {
        moveDown(timePassed);
    }

    if(jumping == true)
    {

            jump(timePassed, startYPos);
    }

}

public void jump(long timepassed,int startYPos)
{   
    if(this.yPos > startYPos - 63 && hitUp == false)//63 so you cant jumpe 2 blocks but it is easier jump onto a block = level to your start pos
    {
        moveUp(timepassed);
        gravityOff = true;
    }
    else
    {
        gravity = true;
        jumping = false;
        gravityOff = false;
    }

}

public void moveRight(long timePassed)
{
    //had to change velocity manualy because moving right is slower than moving left with same velocity. WTF!
    xPos += 0.12 * timePassed;
    this.rect.x += 0.12 * timePassed;
}

public void moveLeft(long timePassed)
{
    xPos -= velocityX * timePassed;
    this.rect.x -= velocityX * timePassed;

}

public void moveDown(long timePassed)
{
    yPos += velocityY * timePassed;
    this.rect.y += velocityY * timePassed;
}

public void moveUp(long timePassed)
{
    yPos -= velocityY * timePassed;
    this.rect.y -= velocityY * timePassed;
}

public void setMovingRight(boolean moving)
{
    movingRight = moving;
}

public void setMovingLeft(boolean moving)
{
    movingLeft = moving;
}

public void setHitRight(boolean hit)
{
    hitRight = hit;
}

public void setHitLeft(boolean hit)
{
    hitLeft = hit;
}

public void setHitUp(boolean hit)
{
    hitUp = hit;
}

public void setGravity(boolean onSolid)
{
    gravity = onSolid;
}


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



}

PlayingBoard.java 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;
}

}

Tile.java Tile.java

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);
}


}

ReadLevelFile.java 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();
}
}

There are packages that do this type of stuff-- you really need one! 有些软件包可以执行此类操作-您真的需要一个!

I would post a question about what a good 2D game framework is. 我会问一个关于什么是好的2D游戏框架的问题。

Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM