Java游戏 - 如何从步行越过障碍停止播放器 [英] Java game - how to stop player from walking over obstacles

查看:178
本文介绍了Java游戏 - 如何从步行越过障碍停止播放器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经由一般的2D游戏的方法,如渲染和更新一个很简单的2D游戏的Java类,我已经建立了我所有的if语句,这样用键盘的箭头输入地图周围的球员动作。我现在想建立什么我已阅读是一种碰撞检测,我知道什么,我需要做的,因为我做了很多读书之前,我其实来这里问的问题,从基础做起我读它去是这样的:

请2矩形

 矩形rectOne =新的Rectangle(PlayerX的,playerY,40,40);
//记住,变量PlayerX的和playerY已经取得previously
矩形rectTwo =新的Rectangle(50,50,100,100);

然后在我的更新方法,我会说:

 如果(rectOne.intersects(rectTwo)){//改变播放器的方向,使他
不能再往前走}

我只是不明白是什么会去我的if语句里面,我需要的东西,从去任何进一步的停止我的球员,如果发生交集,但我怎么可以这样写,因为玩家可以在4个不同的方向(上移,下移, 左右)。这将是简单得多,如果这只是一维的,因为我可以只改变方向的这是什么,但它的两个维度所以这是一个有点混乱相反。

其他信息:

我的比赛是在出场的看法是类似以下内容:
http://www.2dplay.com/awesome-tanks/awesome-tanks -play.htm

编辑3:

 包javagame;                进口java.awt.Rectangle中;                进口HERE
公共类游戏扩展BasicGameState {    动画巴基,movingUp,movingDown,movingLeft,movingRight;
    影像世界地图;
    布尔退出= FALSE; //给用户退出游戏
    INT []持续时间= {200,200}; //框架多长时间熬夜
    INT buckyPositionX = 0;
    INT buckyPositionY = 0;
    INT X = buckyPositionX + 320; //保持用户在screem的中间
    INT Y = buckyPositionY + 160; //数字是屏幕尺寸的一半    矩形rectOne =新的Rectangle(X,Y,90,90);
    矩形rectTwo =新的Rectangle(500 + buckyPositionX,330 + buckyPositionY,210,150);私人诠释xSpeed​​,ySpeed​​; /////////////////////////// code碰撞
    公开播放(INT状态){
    }
    公共无效的init(GameContainer GC,StateBasedGame SBG)抛出SlickException {
          世界地图=新的图像(RES / world.png);
          图片[]摩天= {新的图像(RES / b.png),新形象(RES / b.png)}; //这些都在摩天动画中使用的图像
          图片[] = walkDown {新的图像(RES / f.png),新形象(RES / f.png)};
          图片[] = walkLeft {新的图像(RES / l.png),新形象(RES / l.png)};
          图片[] = walkRight {新的图像(RES / r.png),新形象(RES / r.png)};
    movingUp =新的动画(摩天,持续时间,虚假的);
    movingDown =新的动画(walkDown,持续时间,虚假的);
    movingLeft =新的动画(walkLeft,持续时间,虚假的);
    movingRight =新的动画(walkRight,持续时间,虚假的);    巴基= movingDown; //最初面对屏幕上启动
    }
    公共无效渲染(GameContainer GC,StateBasedGame SBG,图形g)抛掷SlickException {
    worldMap.draw(buckyPositionX,buckyPositionY); //位置0,0
    bucky.draw(X,Y); //使他出现在地图中心
    g.fillRect(X,Y​​,90,90);
    g.fillRect(500 + buckyPositionX,330 + buckyPositionY,210,150);
    如果(退出==真){
        g.drawString(继续(R),250,100);
        g.drawString(主(M),250,150);
        g.drawString(退出游戏(Q),250,200);
        如果(退出== FALSE){
            g.clear(); //擦掉一切从屏幕
        }
    }
    }公共无效setSpeed​​WithDirection(INT速度,诠释方向)//////////// code碰撞
{
xSpeed​​ =(INT)(Math.cos(方向)*速度); ////////////////////////// code碰撞
ySpeed​​ =(INT)(Math.sin(方向)*速度); ////////////////////////// code碰撞
}    公共无效更新(GameContainer GC,StateBasedGame SBG,INT三角洲)抛出SlickException {
    输入输入= gc.getInput();X + = xSpeed​​; ////////////////////////////////////////// code。对于碰撞
Y + = ySpeed​​; ////////////////////////////////////////// code。对于碰撞如果(rectOne.intersects(rectTwo))/////////////////////// code碰撞
{
xSpeed​​ = 0; //////////////////////////// code碰撞
ySpeed​​ = 0; //////////////////////////// code碰撞
}    //向上
    如果(input.isKeyDown(Input.KEY_UP)){
        巴基= movingUp; //将图像切换到他的背部
        buckyPositionY + = 2 ;; //增加巴基的Y坐标(动他了)
        如果(buckyPositionY> 162){//如果我到达山顶
            buckyPositionY - = 2; //停止在该方向上的任何进一步的移动
        }
    }    //下
    如果(input.isKeyDown(Input.KEY_DOWN)){
        巴基= movingDown;
        buckyPositionY - = 2;
        如果(buckyPositionY< -550){
            buckyPositionY + = 2; //根本上改变方向,如果使+ -
    }}
    //剩下
    如果(input.isKeyDown(Input.KEY_LEFT)){
        巴基= movingLeft;
        buckyPositionX + = 2;
        如果(buckyPositionX> 324){
            buckyPositionX - = 2; //增量* .1F
    }}
    //对
    如果(input.isKeyDown(Input.KEY_RIGHT)){
        巴基= movingRight;
        buckyPositionX - = 2;
        如果(buckyPositionX< -776){
            buckyPositionX + = 2;
    }}     //逃逸
    如果(input.isKeyDown(Input.KEY_ESCAPE)){
        退出= TRUE;
    }
    //当菜单可达
    如果(退出==真){//是菜单在屏幕上
        如果(input.isKeyDown(Input.KEY_R)){
            退出= FALSE; //重新开始比赛,使菜单dissapear
        }
        如果(input.isKeyDown(Input.KEY_M)){
            sbg.enterState(0); //带你到主菜单
        }
        如果(input.isKeyDown(Input.KEY_Q)){
            System.exit(0); //退出游戏
        }
    }}
    公众诠释的getID(){
        返回1;
    }
}


解决方案

作为prerequisite,您的播放器类(或它的超之一)应该有描述他们的速度(一对X-领域的几个字段速度和y速度工作得非常好,虽然你需要触发设置播放器在给定方向)。下面是一个简单的播放器类具有x和y速度场的例子:

 公共类播放器
{
     //坐标玩家的
     私人诠释的x,y;     //球员的速度的水平和垂直分量。
     私人诠释xSpeed​​,ySpeed​​;     //调用一个与此相似的方法您的每一次更新播放器的位置
     公共无效updatePosition()
     {
          X + = xSpeed​​;
          Y + = ySpeed​​;
     }     //速度和方向(更容易处理)转换
     //到一个X速度和Y速度(多为实际移动更容易)
     //并设定玩家的议案
     公共无效setSpeed​​WithDirection(INT速度,浮动方向)
     {
         xSpeed​​ = Math.cos(方向)*速度;
         ySpeed​​ = Math.sin(方向)*速度;
     }
}

为了这实际上反映了您的播放器的运行速度,加上X倍速玩家的x坐标每次添加的y速度球员的y坐标每次玩家更新。现在,有很多事情,当碰撞发生时可能发生的。最简单的一个是通过其X速度和Y速度设置为零来停止播放器。然而,这可以看作为出问题玩家将停止,无论他们要去哪个方向上行动。一个稍微好一点的方法是分析交叉口的形状(假设你使用 java.awt.Rectangle中您可以使用路口()方法pretty多所有矩形类有类似的东西),并确定是否在X速度,Y - 速度,或两者都应该被设置为零。例如,如果该交点更宽大于高度(在x轴比Y轴大),你应该设定的y速度为零,但是却的x速度的影响。如果你想玩家转身(180度),只需翻转X倍速和y速度的迹象。如果你希望玩家为反弹,而不是停止,分析了交集,就像在previous案件,但反转的速度,而不是将其设置为零。这里有几个code例子(可能并不象写的,因为我不知道你的类是如何设置都):

  //简单的stop
如果(rectOne.intersects(rectTwo))
{
    player.xSpeed​​ = 0;
    player.ySpeed​​ = 0;
}//可变轴停止
如果(rectOne.intersects(rectTwo))
{
    //视矩形的实现可能需要使用其他方法
    矩形重叠= rectOne.intersection(rectTwo);
    如果(overlap.height> = overlap.width)
    {
        player.xSpeed​​ = 0;
    }
    如果(overlap.width> = overlap.height)
    {
        player.ySpeed​​ = 0;
    }
}//简单的周转(约面)
如果(rectOne.intersects(rectTwo))
{
    player.xSpeed​​ * = -1;
    player.ySpeed​​ * = -1;
}//反弹(可变轴掉头)
如果(rectOne.intersects(rectTwo))
{
    矩形重叠= rectOne.intersection(rectTwo);
    如果(overlap.height> = overlap.width)
    {
        player.xSpeed​​ * = -1;
    }
    如果(overlap.width> = overlap.height)
    {
        player.ySpeed​​ * = -1;
    }
}

请注意,无论你选择做什么样的冲突往往是很困难的工作顺利。我会考虑所有可能的总是的被建立后,这些选择好的出发点。我希望这有助于。

I have made a very simple 2D Java game class made up of the general 2D game methods such as render and update, I have set up all my if statements so that the player moves around the map with the keyboard arrow input. I am now trying to set up what I have read is a collision detection, I know the basics of what I need to do because I did a lot of reading before I actually came here to ask the question, from what I have read it goes something like this:

Make 2 rectangles

Rectangle rectOne = new Rectangle(playerX, playerY, 40, 40); 
//keep in mind that the variables playerX and playerY are already made previously
Rectangle rectTwo = new Rectangle(50, 50, 100,100);

Then under my update method I would say:

if(rectOne.intersects(rectTwo)){//change the player direction so that he 
can go no further}

I just do not understand what would go inside my if statement, I need something that stops my player from going any further if the intersection occurs but how can I write this because the player can move in 4 different directions (UP, DOWN, LEFT, RIGHT). It would be much simpler if it was just 1 dimensional because I could just change the direction to the opposite of what it was but its two dimensions so it is a bit confusing.

Additional information:

The view my game is played at is similar to the following: http://www.2dplay.com/awesome-tanks/awesome-tanks-play.htm

EDIT 3:

                package javagame;

                import java.awt.Rectangle;

                IMPORTS ARE HERE


public class Play extends BasicGameState{

    Animation bucky, movingUp, movingDown, movingLeft, movingRight;
    Image worldMap;
    boolean quit = false;//gives user to quit the game
    int[] duration = {200, 200};//how long frame stays up for
    int buckyPositionX = 0;
    int buckyPositionY = 0;
    int x = buckyPositionX + 320;//keeps user in the middle of the screem
    int y = buckyPositionY + 160;//the numbers are half of the screen size

    Rectangle rectOne = new Rectangle(x, y,90,90);
    Rectangle rectTwo = new Rectangle(500 + buckyPositionX, 330 + buckyPositionY, 210, 150);



private int xSpeed, ySpeed;///////////////////////////CODE FOR COLLISION


    public Play(int state){
    }   
    public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
          worldMap = new Image("res/world.png");
          Image[] walkUp = {new Image("res/b.png"), new Image("res/b.png")}; //these are the images to be used in the "walkUp" animation
          Image[] walkDown = {new Image("res/f.png"), new Image("res/f.png")};
          Image[] walkLeft = {new Image("res/l.png"), new Image("res/l.png")};
          Image[] walkRight = {new Image("res/r.png"), new Image("res/r.png")};


    movingUp = new Animation(walkUp, duration, false);
    movingDown = new Animation(walkDown, duration, false);  
    movingLeft = new Animation(walkLeft, duration, false);  
    movingRight = new Animation(walkRight, duration, false);

    bucky = movingDown;//facing screen initially on startup
    }


    public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
    worldMap.draw(buckyPositionX, buckyPositionY);//position 0,0
    bucky.draw(x, y);//makes him appear at center of map
    g.fillRect(x, y,90,90);
    g.fillRect(500 + buckyPositionX, 330 + buckyPositionY, 210, 150);


    if(quit==true){
        g.drawString("Resume(R)", 250, 100);
        g.drawString("Main(M)", 250, 150);
        g.drawString("Quit Game(Q)", 250, 200);      
        if(quit==false){
            g.clear();//wipe off everything from screen
        }
    }
    }

public void setSpeedWithDirection(int speed, int direction)////////////CODE FOR COLLISION
{
xSpeed = (int) (Math.cos(direction) * speed);//////////////////////////CODE FOR COLLISION
ySpeed = (int) (Math.sin(direction) * speed);//////////////////////////CODE FOR COLLISION
}

    public void update(GameContainer gc, StateBasedGame sbg, int delta)throws SlickException{
    Input input = gc.getInput();



x += xSpeed;//////////////////////////////////////////CODE FOR COLLISION
y += ySpeed;//////////////////////////////////////////CODE FOR COLLISION

if(rectOne.intersects(rectTwo))///////////////////////CODE FOR COLLISION
{
xSpeed = 0;////////////////////////////CODE FOR COLLISION
ySpeed = 0;////////////////////////////CODE FOR COLLISION
}



    //up
    if(input.isKeyDown(Input.KEY_UP)){
        bucky = movingUp;//changes the image to his back
        buckyPositionY += 2;;//increase the Y coordinates of bucky (move him up)
        if(buckyPositionY>162){//if I reach the top 
            buckyPositionY -= 2;//stops any further movement in that direction
        }
    }

    //down
    if(input.isKeyDown(Input.KEY_DOWN)){
        bucky = movingDown;
        buckyPositionY -= 2;
        if(buckyPositionY<-550){
            buckyPositionY += 2;//basically change the direction if + make -
    }}
    //left
    if(input.isKeyDown(Input.KEY_LEFT)){
        bucky = movingLeft;
        buckyPositionX += 2;
        if(buckyPositionX>324){
            buckyPositionX -= 2;//delta * .1f
    }}
    //right
    if(input.isKeyDown(Input.KEY_RIGHT)){
        bucky = movingRight;
        buckyPositionX -= 2;
        if(buckyPositionX<-776){
            buckyPositionX += 2;
    }}



     //escape
    if(input.isKeyDown(Input.KEY_ESCAPE)){
        quit=true;
    }
    //when the menu is up
    if(quit==true){//is the menu on the screen
        if(input.isKeyDown(Input.KEY_R)){
            quit = false;//resumes the game, makes menu dissapear
        }
        if(input.isKeyDown(Input.KEY_M)){
            sbg.enterState(0);//takes you to the main menu
        }
        if(input.isKeyDown(Input.KEY_Q)){
            System.exit(0);//quits the game
        }
    }

}   


    public int getID(){
        return 1;
    }
}

解决方案

As a prerequisite, your player class (or one of its superclasses) should have a few fields describing their speed (a pair of fields for x-speed and y-speed works very well, although you'll need trig to set the player in a given direction). Here is an example of a simple player class with x- and y-speed fields:

public class Player
{
     //coordinates of the player 
     private int x, y;

     //horizontal and vertical components of the player's speed.
     private int xSpeed, ySpeed; 

     //call a method similar to this one every time your player updates its position
     public void updatePosition()
     {
          x += xSpeed;
          y += ySpeed;
     }

     //Converts a speed and a direction (much easier to deal with)
     //to an x speed and a y speed (much easier for actually moving) 
     //and sets the player's motion
     public void setSpeedWithDirection(int speed, float direction)
     {
         xSpeed = Math.cos(direction) * speed;
         ySpeed = Math.sin(direction) * speed;
     }
}

In order for this to actually reflect your player's speed, add the x-speed to the player's x-coordinate every and add the y-speed to the player's y-coordinate every time the player updates. Now, there are a lot of things that could happen when the collision occurs. The simplest one is to stop the player by setting its x-speed and y-speed to zero. However, this can look glitchy as the player will stop moving regardless of what direction they are going in. A slightly better approach is to analyze the shape of the intersection (assuming you're using java.awt.Rectangle you can use the intersection() method, pretty much all Rectangle classes have something similar) and determine whether the x-speed, y-speed, or both should be set to zero. For instance, if the intersection is wider than it is tall (larger in the x-axis than the y-axis), you should probably set the y-speed to zero but but the x-speed unaffected. If you want the player to turn around (180 degrees), simply flip the sign of x-speed and y-speed. If you want the player to "bounce" instead of stop, analyze the intersection just as in the previous case but reverse the speed rather than set it to zero. Here are a few code examples (probably won't work exactly as written because I don't know how your classes are set up):

//simple stop
if(rectOne.intersects(rectTwo))
{
    player.xSpeed = 0;
    player.ySpeed = 0;
}

//variable-axis stop
if(rectOne.intersects(rectTwo))
{
    //depending on Rectangle implementation may need to use other method
    Rectangle overlap = rectOne.intersection(rectTwo);
    if (overlap.height >= overlap.width)
    {
        player.xSpeed = 0;
    }
    if (overlap.width >= overlap.height)
    {
        player.ySpeed = 0;
    }
}

//simple turn-around (about face)
if(rectOne.intersects(rectTwo))
{
    player.xSpeed *= -1;
    player.ySpeed *= -1;
}

//bounce (variable-axis turn around)
if(rectOne.intersects(rectTwo))
{
    Rectangle overlap = rectOne.intersection(rectTwo);
    if (overlap.height >= overlap.width)
    {
        player.xSpeed *= -1;
    }
    if (overlap.width >= overlap.height)
    {
        player.ySpeed *= -1;
    }
}

Note that regardless of what you choose to do collisions tend to be very difficult to get working smoothly. I would consider all of these options good starting points that could always be built upon. I hope this helps.

这篇关于Java游戏 - 如何从步行越过障碍停止播放器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆