java - 2d平台游戏碰撞

标签 java collision-detection

好吧...所以我正在创建我的第一个 2d 平台游戏...不幸的是一切都是新的,但到目前为止我已经完成了其他所有工作,但我无法让碰撞工作。这有点长,所以我希望不会得到答案,但有人可以提供帮助......提前谢谢您。

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;

public class Expordium {
  private JFrame f = new JFrame("Expordium");
  private boolean win;
  private int level;
  private Display display;

  public boolean isR, isU, isL, isD;

  public static void main(String[] args) {
    Expordium game = new Expordium();
    game.play(game);
  }
  Expordium(){
    win=false;
    level=1;
  }
  private void play(Expordium game){
    display = new Display(game);
    f.getContentPane().add(display);
    f.addKeyListener(new MyKeyListener());
    f.setSize(980 , 360);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
  }
  private void advanceLevel() {
    level++;
  }
  public String getLevel() {
    String strLevel;
    strLevel=Integer.toString(level);
    return strLevel;
  }

  public class MyKeyListener extends KeyAdapter{
    public void keyPressed(KeyEvent e) {
      int keyCode = e.getKeyCode();
      switch( keyCode ) {
        case KeyEvent.VK_UP:
          isU=true;
          break;
        case KeyEvent.VK_DOWN:
          isD=true;
          break;
        case KeyEvent.VK_LEFT:
          isL=true;
          break;
        case KeyEvent.VK_RIGHT:
          isR=true;
          break;
        case KeyEvent.VK_SPACE :
          display.shoot();
      } 
    }
    public void keyReleased( KeyEvent e ) {
      int keyCode = e.getKeyCode();
      switch( keyCode ) {
        case KeyEvent.VK_UP:
          isU=false;
          break;
        case KeyEvent.VK_DOWN:
          isD=false;
          break;
        case KeyEvent.VK_LEFT:
          isL=false;
          break;
        case KeyEvent.VK_RIGHT:
          isR=false;
          break;
      } 
    }
  }
}

显示类

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.html.HTMLDocument.Iterator;

import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

public class Display extends JPanel implements Runnable{

  private static final int FPS = 1000 / 36;
  private JFrame f = new JFrame("Expordium");
  private Collection<Block> elements = new ArrayList<Block>();
  private Collection<Bullet> bullets = new ArrayList<Bullet>();
  private BufferedImage Bg;

  public Wall wall;
  public Guy guy;
  public End end;
  public Bullet bullet;

  private String file;
  private Expordium game;
  private String[][] strLevel = new String[30][10];
  private String[][] strWall = new String[30][10];

  Display(Expordium g){
    game=g;
    readFile();
    for(int i=0; i<30; i++){
      for(int j=0; j<10; j++){
        if(strLevel[i][j].equals("W")){
          elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-T.PNG"));
          strWall[i][j]=strLevel[i][j];
        }
        if(strLevel[i][j].equals("A")){
          elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-L.PNG"));
          strWall[i][j]=strLevel[i][j];
        }
        if(strLevel[i][j].equals("S")){
          elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-B.PNG"));
          strWall[i][j]=strLevel[i][j];
        }
        if(strLevel[i][j].equals("D")){
          elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-R.PNG"));
          strWall[i][j]=strLevel[i][j];
        }
        if(strLevel[i][j].equals("s")){
          elements.add(guy=new Guy(i*32,j*32,false,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Guy/Guy-R.PNG"));
        }
        if(strLevel[i][j].equals("e")){
          elements.add(end=new End(i*32,j*32,false,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/End.PNG"));
        }
      }
    }
    new Thread(this).start();
  }

  public void run(){
    long tm = System.currentTimeMillis();

    while(true){
      update();
      repaint();

      try {
        tm += FPS;
        Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));
      }
      catch(InterruptedException e)
      {
        System.out.println(e);
      }
    }
  }

这是碰撞检测部分:

    public boolean collision() {
      java.util.Iterator<Block> iterator = elements.iterator();
      while(iterator.hasNext()){
        if(iterator.next().isSolid && guy.isColliding((Block)iterator.next())){
          return true;
        }
      }
      return false;
    }

结束

    public void update() {
      if(!guy.isJump && game.isU){
        guy.Jump();
      }
      if(game.isR){
        if(!collision()){
          guy.Move(2);
        }
      }
      if(game.isL){
        if(!collision()){
          guy.Move(1);
        }
      }
      if(guy.isJump){
        guy.Jump();
      }
    }

  public void paint(Graphics g){
    try {
      Bg = ImageIO.read(new File("C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Object/BackGround.PNG"));
    } catch (IOException e) {}
    g.drawImage(Bg, 0,0,null);
    java.util.Iterator<Block> iterator = elements.iterator();
    while(iterator.hasNext())
      ((Block) iterator.next()).draw(g);

    java.util.Iterator<Bullet> iterator1 = bullets.iterator();
    while(iterator1.hasNext())
      ((Block) iterator1.next()).draw(g);

  }

  private void readFile() {
    int num=0;
    String noFile = "";
    String loc ="C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Level/Level " + game.getLevel() + ".txt";
    File Level = new File(loc);
    file=TextFile.getContents(Level);
    for(int i=0; i<file.length(); i++){
      if(file.substring(num, num+1).equals("W") || file.substring(num, num+1).equals("A") || file.substring(num, num+1).equals("S") || file.substring(num, num+1).equals("D") || file.substring(num, num+1).equals("e") || file.substring(num, num+1).equals("s") ||  file.substring(num, num+1).equals(" ")){
        noFile=noFile+file.substring(num, num+1);
      }
      num++;
    }
    num=0;
    for(int j=0; j<10; j++){
      for(int i=0; i<30; i++){
        strLevel[i][j]=noFile.substring(num, num+1);
        num++;
      }
    }
  }

  public void shoot() {
    if(guy.dir==1){
      bullets.add(new Bullet(guy.getX(),guy.getY(),1,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Object/Bullet.PNG"));
    }
    if(guy.dir==2){
      bullets.add(new Bullet(guy.getX(),guy.getY(),2,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Object/Bullet.PNG"));
    }
  }

}

家伙类

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;


public class Guy extends Block{
  private int x, y, groundY;
  public boolean isSolid;
  private BufferedImage guy;
  public boolean isJump=false;
  private int accM, accJ;
  private String location;
  public int dir=2;

  public Guy(int startx, int starty, boolean solid, String loc) {
    super(startx, starty, solid, loc);
    try {                
      guy = ImageIO.read(new File(loc));
    }catch (IOException ex) {}
    x=startx;
    y=starty;
    isSolid=solid;
    location=loc;
  }

  public boolean isColliding(Block e){
    int leftSide = getX();
    int rightSide = getX() + 31;
    int top = getY();
    int bottom = getY() + 31;

    int eLeftSide = e.getX();
    int eRightSide = e.getX() + 31;
    int eTop = e.getY();
    int eBottom = e.getY() + 31;


    if(eLeftSide < rightSide)
      if(eRightSide > leftSide)
        if(eTop < bottom)
          if(eBottom > top)
            return true;

    return false;
  }

  public void draw(Graphics g) {
    try {
      guy = ImageIO.read(new File(location));
    } catch (IOException e) {}
    g.drawImage(guy,x,y,null);
  }
  public int getX(){
    return x;
  }
  public int getY(){
    return y;
  }
  public void setX(int x1){
    x=x1;
  }
  public void setY(int y1){
    y=y1;
  }
  public void Move(int i) {
    if(i==2){
      dir=2;
      location="C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Guy/Guy-R.PNG";
      x=x+2;
    }
    else{
      dir=1;
      location="C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Guy/Guy-L.PNG";
      x=x-2;
    }
  }
  public void Jump() {
    if(groundY==0){
      isJump=true;
      y=y+3;
      groundY=groundY+3;
    }
    else if(groundY!=0 && groundY<=48 && groundY!=96){
      y=y-3;
      groundY=groundY+3;
    }
    else if(groundY!=0 && groundY>=48 && groundY!=96){
      y=y+3;
      groundY=groundY+3;
    }
    else{
      isJump=false;
      groundY=0;
    }
  }
}

墙类

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;


public class Wall extends Block{
  private int x, y;
  public boolean isSolid;
  private BufferedImage wall;

  public Wall(int startx, int starty, boolean solid, String loc) {
    super(startx, starty, solid, loc);
    try {                
      wall = ImageIO.read(new File(loc));
    }catch (IOException ex) {}
    x=startx;
    y=starty;
    isSolid=solid;
  }

  public void draw(Graphics g) {
    g.drawImage(wall,x,y,null);
  }

  public int getX(){
    return x;
  }
  public int getY(){
    return y;
  }
}

下课

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;


public class End extends Block{
  private int x, y;
  public boolean isSolid;
  private BufferedImage end;

  public End(int startx, int starty, boolean solid, String loc) {
    super(startx, starty, solid, loc);
    try {                
      end = ImageIO.read(new File(loc));
    }catch (IOException ex) {}
    x=startx;
    y=starty;
    isSolid=solid;
  }

  public void draw(Graphics g) {
    g.drawImage(end,x,y,null);
  }

  public int getX(){
    return x;
  }
  public int getY(){
    return y;
  }
}

block 类

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;


public abstract class Block {
  private int x, y;
  public boolean isSolid;
  private BufferedImage block;
  private String location;

  public Block(int startx, int starty, boolean solid, String loc) {
    x=startx;
    y=starty;
    isSolid=solid;
    location=loc;
    try {
      block = ImageIO.read(new File(loc));
    } catch (IOException e) {
    }
  }

  public abstract void draw(Graphics g);

  public int getX(){
    return x;
  }
  public int getY(){
    return y;
  }
}

项目符号类

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;


public class Bullet extends Block{
  private int x, y;
  public boolean isSolid;
  private BufferedImage bullet;
  public int dir;

  public Bullet(int startx, int starty, int dir1, boolean solid, String loc) {
    super(startx, starty, solid, loc);
    try {                
      bullet = ImageIO.read(new File(loc));
    }catch (IOException ex) {}
    x=startx;
    y=starty;
    dir=dir1;
    isSolid=solid;
  }

  public void draw(Graphics g) {
    if(dir==1){
      x=x-5;
    }
    if(dir==2){
      x=x+5;
    }
    g.drawImage(bullet,x,y,null);
  }

  public int getX(){
    return x;
  }
  public int getY(){
    return y;
  }
}

最佳答案

这与你的问题无关,但你所做的事情太糟糕了,尤其是我的第一句话。

  • 每次渲染游戏时,都会从文件中加载“人物”的图像。您应该将它们全部加载(玩家左、玩家右),然后根据“人”的方向渲染正确的图像。

  • 您正在使用绝对路径指向图像。使用相对路径。

  • 不要使用 12 作为指示,而是使用更具逻辑性的内容,例如:
    • -2表示向左跑
    • -1表示不移动,但指向左侧
    • (0 表示没有移动)
    • +1表示没有移动,但指向右侧
    • +2表示向右跑
  • 变量名称确实以小写字符开头,例如:bg 而不是 Bg
  • 在您的下一个游戏项目中使用float作为坐标。

这是一些代码:

private BufferedImage player_left;
private BufferedImage player_right;

public Guy() { // Your consturctor:
    player_left = ImageIO.read(new File("resources/img/player-left.png"));
    player_right = ImageIO.read(new Fiel("resources/img/player-right.png"));
}

public void draw(Graphics g)
{
    if (direction == -1) { // left
        g.draw(player_left, .......);
    } else if (direction == 1) // right
    {
        g.draw(player_right, ......);
    } else if (direction == ...)
    {
        .....
    }
}

关于java - 2d平台游戏碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5563406/

相关文章:

java - hadoop mapreduce模型java

iphone - 如何在cocos2d中对多个 Sprite 进行像素完美碰撞?

c# - 图片框相交

java - 多分辨率 map 的碰撞检测

javascript - div 碰撞检测不起作用

Java 对象 makenew 对象覆盖当前对象

Java 正则表达式模式 连接模式

java - 在另一个 Activity 中启动 Activity

java - 使用 Java 线程创建测试碰撞检测的对象

Java 8 流化 groupby 并计算多个属性