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