2017-01-16 121 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; 
    } 
} 

希望它可以幫助你。