我希望能通过我的碰撞检测/运动获得一些帮助,它正在工作但是有缺陷。 我无法通过碰撞检测/运动一致地重现错误。玩家有时候无法在某些方向上移动,我也无法重现,它似乎开始让你无缘无故再次移动。重力并不总是在应有的时候生效,有时候你会卡在墙上。代码如下。
我还想听听有关如何在游戏中实现动画(例如在移动时播放行走动画)的任何建议。我有一个动画工作,但它很乱,并使用Timer();我想找到一种更好的方法。任何建议表示赞赏。
我正在使用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
}
}
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
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
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
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();
}
}
答案 0 :(得分:0)
有些包可以做这种类型的东西 - 你真的需要一个!
我会发布一个关于什么是好的2D游戏框架的问题。
祝你好运。