2017-01-16 92 views
0

好吧,所以我正在开发一个Java2D游戏,并且我已经接近正确地处理碰撞了。我有一个玩家类,一个块类,以及玩家的xvel,yvel等等。 y碰撞是正确的,但是当我尝试让X碰撞起作用时,它就完全搞砸了。而且,即使Y碰撞正常,玩家只是在区块上方轻微摆动。 我已经为我的玩家设置了一个碰撞盒。我究竟做错了什么? 这里是我的代码(我知道这是不是最好的):Java 2D游戏:不能碰撞正确

编辑: 好了,我已成功地阻止玩家从上下摆动,我已经改变了碰撞检查的方式。我删除了播放器的hitbox,并使用了.png精灵,并调整了大小,以便运行良好。所以,问题在于,即使玩家没有水平进入该块,“if(player.xvel < 0){}”和“if(player.xvel> 0){}”仍然在执行。我怎样才能让代码在玩家水平运行/走进代码块时执行?

Block.java:

import java.awt.*; 
import javax.imageio.ImageIO; 
import java.io.*; 
import java.awt.Rectangle; 
class Block { 
    Image block_sprite; 
    Image dirt; 
    int x; 
    int y; 
    int height; 
    int width; 
    int i = 0; 
    public Block(int X, int Y, int Width, int Height, int block_type) { 
     x = X * 32; 
     y = Y * 32; 
     width = Width; 
     height = Height; 
     try { 
      dirt = ImageIO.read(new File("img/dirt.png")); 
     } catch(IOException e) { 
      e.printStackTrace(); 
     } 
     if (block_type == 1) { 
      block_sprite = dirt; 
     } 
    } 

    void draw(Graphics g) { 
     g.fillRect(x + Display.graphics_panel.WorldX, y, width, height); 
    } 
    void collide(Player player) { 
     Rectangle player_hb = new Rectangle((int) player.x, (int) player.y, (int) player.width, (int) player.height); 
     Rectangle block_hb = new Rectangle(x + Display.graphics_panel.WorldX, y, width, height); 

     if (player_hb.intersects(block_hb)) { 
      Rectangle intersection = (Rectangle) player_hb.createIntersection(block_hb); 

      if (player.yvel > 0) { 
       player.jumping = false; 
       player.y -= intersection.getHeight(); 
      } 
      if (player.yvel < 0) { 
       player.y += intersection.getHeight(); 
      } 
      if (player.xvel > 0) { 
       System.out.println("You shouldn't see this unless you run into a block!" + i++); 
      } 
      if (player.xvel < 0) { 
       System.out.println("You shouldn't see this unless you run into a block!" + i--); 
      } 
     } 
    } 
} 

Player.java:

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import javax.imageio.*; 
import java.io.*; 
class Player extends Entity { 

    float x = Display.WINDOW_WIDTH/2; 
    float y = 430; 
    float width = 48; 
    float height = 103; 

    float xvel = 0; 
    float yvel = 0; 
    float gravity = 0.4f; 

    float xvel_max = 2; 
    float yvel_max = 8; 

    float xvel_min = -2; 
    float yvel_min = -8; 

    String dir = "left"; 

    float sword_offsetX = 49; 
    float sword_offsetY = 32; 

    Boolean jumping = false; 

    Image sprite; 
    Image sword_sprite; 
    Image sprite_r; 
    Image sprite_r_a1; 
    Image sprite_r_a2; 

    Image sprite_l; 
    Image sprite_l_a1; 
    Image sprite_l_a2; 

    Image ssprite_r; 
    Image ssprite_l; 
    Player() { 
     try { 
      sprite_r = ImageIO.read(new File("img/player_r.png")); 
      sprite_r_a1 = ImageIO.read(new File("img/player_r_a1.png")); 
      sprite_r_a2 = ImageIO.read(new File("img/player_r_a2.png")); 

      sprite_l = ImageIO.read(new File("img/player_l.png")); 
      sprite_l_a1 = ImageIO.read(new File("img/player_l_a1.png")); 
      sprite_l_a2 = ImageIO.read(new File("img/player_l_a2.png")); 
     ssprite_r = ImageIO.read(new File("img/sword_r.png")); 

      ssprite_l = ImageIO.read(new File("img/sword_l.png")); 
      if (dir == "left") { 
       sprite = sprite_r; 
      } 
      sword_sprite = ssprite_r; 
     } catch(IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    Graphics2D g2d; 
    void draw(Graphics g) { 
     g2d = (Graphics2D) g; 

     g2d.drawImage(sprite, (int) x, (int) y, null); 
     g2d.drawImage(sword_sprite, (int) x + (int) sword_offsetX, (int) y + (int) sword_offsetY, null); 
    } 

    void update() { 

     jumping = true; 
     yvel += gravity; 
     Display.graphics_panel.WorldX += xvel; 
     y += yvel; 

     for (int i = 0; i < Display.graphics_panel.world.blocks.length; i++) { 
      Display.graphics_panel.world.blocks[i].collide(this); 
     } 

     if (Display.keys[65] == 65 || Display.keys[68] == 68) { 
       if (dir == "left") { 
        sprite = sprite_r; 
        sword_sprite = ssprite_r; 
        sword_offsetX = 49; 
       } else if (dir == "right") { 
        sprite = sprite_l; 
        sword_sprite = ssprite_l; 
        sword_offsetX = -18; 
       } 
       if (xvel < 0) { 
        if (Display.graphics_panel.frameCount/10 % 2 == 0) { 
         sprite = sprite_r_a1; 
        } else { 
         sprite = sprite_r_a2; 
        } 
       } 
       if (xvel > 0) { 
        if (Display.graphics_panel.frameCount/10 % 2 == 0) { 
         sprite = sprite_l_a1; 
        } else { 
         sprite = sprite_l_a2; 
        } 
       } 
     } 
     if (xvel == 0 && dir == "left") { 
      sprite = sprite_r; 
     } 
     if (xvel == 0 && dir == "right") { 
      sprite = sprite_l; 
     } 
     if (Display.keys[65] == 65) { 
      xvel += 0.25; 
      dir = "right"; 
     } else if (Display.keys[68] == 68) { 

      xvel -= 0.25; 
      dir = "left"; 
     } else { 
      xvel = 0; 
     } 

    if (Display.keys[87] == 87 && jumping == false) { 
     jumping = true; 
     yvel = -8; 
    } 
     if (xvel > xvel_max) { 
      xvel = xvel_max; 
     } else if (xvel < xvel_min) { 
      xvel = xvel_min; 
     } 
     if (yvel > yvel_max) { 
      yvel = yvel_max; 
     } else if (yvel < yvel_min) { 
      yvel = yvel_min; 
     } 
    } 
} 
+1

请提供一个最小的,完整的和可验证的例子,以便我们可以轻松地重现您的问题。 http://stackoverflow.com/help/mcve – marstran

+0

好吧,从这里开始,我将如何启用X轴碰撞(我使用的是WorldX,它是相机的替代品,所以世界移动而不是玩家); – javaprogammer23

回答

0

所以,我实际上是由我击中格一个小平台游戏。你可能需要的部分是在事件发生之前知道碰撞。 也许我的游戏中的这个例子可以帮助你。

  level.material=array of points from the level 
     w=width of hitbox 
     h=height of hitbox 
     x=upper left x 
     y=upper left y 
     onground=false; 
     double maxy=1000; 

     for (Point p:level.material) { 
       if (p.x >= (int)x && p.x <= (int)x+w) { //Is the player over the point ? (is the point between player x and player x+w) 
         if (p.y >= (int)(y+h) && (int)(y+h+yvel) >= p.y && p.y-h-1 < maxy) { //Would he go through a platform if the yvel would be added ? And is this the earliest point where this happens ? 
          maxy=p.y-p2.y-1d; //Set new earliest point 
          onground=true; //He is onground 
         } 
        } 
       } 
     } 

     if (onground==true) { 
      y=maxy; //Dont fall through the floor ! Stop at the earliest point ! 
      yvel=0; //There isnt any velocity downwards anymore. 
      xvel=xvel-xvel/4; //Friction 
     } 

您应该可以很容易地将其复制到所有其他路线(左,右,下)。这是“onground”(over)。所以玩家能够站在平台上。

+0

*叹*我只是不知道该怎么做......我已经尝试了很多东西,包括那些。感谢您的帮助,虽然 – javaprogammer23

+0

嗯,对我来说,它只是正常工作... – user7185318

0

如果你只是想rects之间的碰撞检查,这里是一个矩形类:

class Rect { 
    public Point[] points=new Point[4]; 
    public Point start; 
    public Point dim; 
    public Rect(double x,double y,double w,double h) { 
     start=new Point((int)x,(int)y); 
     dim=new Point((int)w,(int)h); 
     points[0]=new Point((int)x,(int)y); 
     points[1]=new Point((int)x+(int)w,(int)y); 
     points[2]=new Point((int)x+(int)w,(int)y+(int)h); 
     points[3]=new Point((int)y,(int)y+(int)h); 
    } 
    public boolean collidepoint(Point p) { 
     if (p.x >= start.x && p.x <= start.x+dim.x && p.y >= start.y && p.y <= start.y+dim.y) { 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 
    public boolean colliderect(Rect rect2) { 
     boolean retvar=false; 
     for (Point p:rect2.points) { 
       if (collidepoint(p)==true) { 
        retvar=true; 
       } 
     } 
     if (retvar==false) { 
     for (Point p:points) { 
       if (rect2.collidepoint(p)==true) { 
        retvar=true; 
       } 
     } 
     } 
     if (retvar==false) { 
     if (rect2.start.y >= start.y && rect2.start.y <= start.y+dim.y || rect2.start.y+rect2.dim.y >= start.y && rect2.start.y+rect2.dim.y <= start.y+dim.y) { 
      if (rect2.start.x >= start.x && rect2.start.x <= start.x+dim.x || rect2.start.x+rect2.dim.x >= start.x && rect2.start.x+rect2.dim.x <= start.x+dim.x) { 
       retvar=true; 
      } 
     } 
     } 
     if (retvar==false) { 
     if (start.y >= rect2.start.y && start.y <= rect2.start.y+rect2.dim.y || start.y+dim.y >= rect2.start.y && start.y+dim.y <= rect2.start.y+rect2.dim.y) { 
      if (start.x >= rect2.start.x && start.x <= rect2.start.x+rect2.dim.x || start.x+dim.x >= rect2.start.x && start.x+dim.x <= rect2.start.x+rect2.dim.x) { 
       retvar=true; 
      } 
     } 
     } 
     return retvar; 
    } 
} 

希望它可以帮助你。