2

レンダリングや更新などの一般的な2Dゲームメソッドで構成される非常に単純な2DJavaゲームクラスを作成しました。プレーヤーがキーボードの矢印入力でマップ内を移動するように、すべてのifステートメントを設定しました。私は今、私が読​​んだものを衝突検出として設定しようとしています。実際にここに来て質問をする前にたくさんの読書をしたので、私は何をする必要があるかについての基本を知っています。このようなもの:

2つの長方形を作成します

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);

それから私の更新方法の下で私は言うでしょう:

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

ifステートメントの内部に何が入るのかわかりません。交差が発生した場合にプレーヤーがそれ以上進まないようにするものが必要ですが、プレーヤーは4つの異なる方向(上、下、左、右)。1次元の場合は、方向を反対方向に変更できますが、2次元であるため、少し混乱します。

追加情報:

私のゲームがプレイされるビューは次のようになります: http ://www.2dplay.com/awesome-tanks/awesome-tanks-play.htm

編集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;
    }
}
4

2 に答える 2

4

前提条件として、プレーヤークラス(またはそのスーパークラスの1つ)には、速度を説明するいくつかのフィールドが必要です(x-speedとy-speedのフィールドのペアは非常にうまく機能しますが、プレーヤーを設定するにはトリガーが必要です与えられた方向)。x速度フィールドとy速度フィールドを持つ単純なプレーヤークラスの例を次に示します。

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;
     }
}

これが実際にプレーヤーの速度を反映するようにするには、プレーヤーのx座標にx速度を毎回追加し、プレーヤーが更新するたびにy速度をプレーヤーのy座標に追加します。さて、衝突が起こったときに起こり得ることがたくさんあります。最も簡単な方法は、x速度とy速度をゼロに設定してプレーヤーを停止することです。ただし、これは、プレーヤーがどの方向に進んでいるかに関係なく移動を停止するため、グリッチに見える可能性があります。少し良いアプローチは、交差点の形状を分析することです(使用しているjava.awt.Rectangle場合は、intersection()メソッドでは、ほとんどすべてのRectangleクラスに類似したものがあります)、x-speed、y-speed、またはその両方をゼロに設定する必要があるかどうかを判断します。たとえば、交差点の幅が高さよりも広い場合(x軸の方がy軸よりも大きい場合)、おそらくy速度をゼロに設定する必要がありますが、x速度は影響を受けません。プレーヤーを振り返らせたい場合(180度)、x-speedとy-speedの符号を反転させるだけです。プレーヤーを停止する代わりに「バウンス」させたい場合は、前の場合と同じように交差点を分析しますが、速度をゼロに設定するのではなく、速度を逆にします。以下にいくつかのコード例を示します(クラスがどのように設定されているかわからないため、おそらく記述どおりに機能しないでしょう)。

//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;
    }
}

何を選択しても、衝突をスムーズに行うのは非常に難しい傾向があることに注意してください。私は、これらのオプションのすべてを、常に構築できる良い出発点と見なします。これがお役に立てば幸いです。

于 2012-12-26T22:11:15.360 に答える
0

列挙型を作成することをお勧めします。彼が今行っWayていることを知っている必要があります。Way次に、Wayを反対Wayに変更するか、現在をロックしWayてランダムに選択しますWay

于 2012-12-26T22:04:16.153 に答える