15

私が書いているゲームには、プレイヤーと敵の 2 人のキャラクターが表示されています。次のように定義されています。

public void player(Graphics g) {
    g.drawImage(plimg, x, y, this);
}

public void enemy(Graphics g) {
    g.drawImage(enemy, 200, 200, this);
}

次に、次のように呼び出します。

player(g);
enemy(g);

キーボードで player() を動かすことはできますが、2 つの間の衝突を検出しようとすると途方に暮れます。多くの人が Rectangles を使用すると言っていますが、初心者の私には、これを既存のコードにどのようにリンクすればよいかわかりません。誰か私にアドバイスをくれる人はいますか?

4

9 に答える 9

21

あなたの問題は、プレイヤーと敵に適切な OO 設計を使用していないことだと思います。2 つのクラスを作成します。

public class Player
{
    int X;
    int Y;
    int Width;
    int Height;

    // Getters and Setters
}

public class Enemy
{
    int X;
    int Y;
    int Width;
    int Height;

    // Getters and Setters
}

Player には、X、Y、Width、および Height 変数が必要です。

あなたの敵もそうすべきです。

ゲーム ループで、次のようにします (C#):

foreach (Enemy e in EnemyCollection)
{
    Rectangle r = new Rectangle(e.X,e.Y,e.Width,e.Height);
    Rectangle p = new Rectangle(player.X,player.Y,player.Width,player.Height);

    // Assuming there is an intersect method, otherwise just handcompare the values
    if (r.Intersects(p))
    {
       // A Collision!
       // we know which enemy (e), so we can call e.DoCollision();
       e.DoCollision();
    }
}

スピードアップするために、敵の座標が画面外にあるかどうかをチェックする必要はありません。

于 2008-12-02T23:35:25.547 に答える
5

まず、 Jonathan Hollandが説明したバウンディングボックスを使用して、衝突の可能性があるかどうかを確認します。

(マルチカラー)スプライトから、白黒バージョンを作成します。スプライトが透明である場合(つまり、バウンディングボックス内にある場所がありますが、背景は表示されている場合)、おそらくすでにこれらがあります。これらは「マスク」です。

Image.getRGB()マスクを使用してピクセルを取得します。透明でないピクセルごとに、整数配列(playerArrayおよびそれenemyArray以下)にビットを設定します。配列のサイズはheightifwidth <= 32ピクセル、(width+31)/32*heightそれ以外の場合です。以下のコードはのためのものwidth <= 32です。

バウンディングボックスが衝突する場合は、次のようにします。

// Find the first line where the two sprites might overlap
int linePlayer, lineEnemy;
if (player.y <= enemy.y) {
    linePlayer = enemy.y - player.y;
    lineEnemy = 0;
} else {
    linePlayer = 0;
    lineEnemy = player.y - enemy.y;
}
int line = Math.max(linePlayer, lineEnemy);

// Get the shift between the two
x = player.x - enemy.x;
int maxLines = Math.max(player.height, enemy.height);
for ( line < maxLines; line ++) {
    // if width > 32, then you need a second loop here
    long playerMask = playerArray[linePlayer];
    long enemyMask = enemyArray[lineEnemy];
    // Reproduce the shift between the two sprites
    if (x < 0) playerMask << (-x);
    else enemyMask << x;
    // If the two masks have common bits, binary AND will return != 0
    if ((playerMask & enemyMask) != 0) {
        // Contact!
    }

}

リンク:JGame小さなJavaゲームのフレームワーク

于 2008-12-03T09:28:11.060 に答える
3

ペイントコード内に衝突チェックコードを含めたくありません。絵は速くする必要があります。衝突はゲームループに入る可能性があります。したがって、スプライトに依存しないオブジェクトの内部表現が必要です。

于 2008-12-02T22:26:16.387 に答える
3

これが私の衝突検出プログラムのメイン クラスです。http://www.youtube.com/watch?v=JIXhCvXgjsQ
で実行を確認できます。

/**
 *
 * @author Tyler Griffin
 */
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.GraphicsDevice.*;
import java.util.ArrayList;
import java.awt.Graphics;
import java.awt.geom.Line2D;


public class collision extends JFrame implements KeyListener, MouseMotionListener, MouseListener
{
    ArrayList everything=new ArrayList<tile>();

    int time=0, x, y, width, height, up=0, down=0, left=0, right=0, mouse1=0, mouse2=0;
    int mouseX, mouseY;

    GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice screen = environment.getDefaultScreenDevice();
    DisplayMode displayMode = screen.getDisplayMode();

    //private BufferStrategy strategy;

    JLayeredPane pane = new JLayeredPane();

     tile Tile;
     circle Circle;
     rectangle Rectangle;

         textPane text;

    public collision()
    {
        setUndecorated(screen.isFullScreenSupported());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        setLayout(null);
        setResizable(false);
        screen.setFullScreenWindow(this);


        width=displayMode.getWidth();
        height=displayMode.getHeight();


          Circle=new circle(-(int)Math.round((double)height/7*2),-(int)Math.round((double)height/7*2),(int)Math.round((double)height/7*.85),this);
          Rectangle=new rectangle(-(int)Math.round((double)height/7*1.5),-(int)Math.round((double)height/7*1.5),(int)Math.round((double)height/7*1.5),(int)Math.round((double)height/7*1.5),this);
          Tile=Circle;
          Tile.move(mouseX-Tile.width/2, mouseY-Tile.height/2);
                  text=new textPane(0,0,width,height,this);

          everything.add(new circle((int)Math.round((double)width/100*75),(int)Math.round((double)height/100*15),(int)Math.round((double)width/100*10),this));
                  everything.add(new rectangle((int)Math.round((double)width/100*70),(int)Math.round((double)height/100*60),(int)Math.round((double)width/100*20),(int)Math.round((double)height/100*20),this));
                  //everything.add(new line(750,250,750,750,this));
                  /*everything.add(new line(width/700*419,height/700*68,width/700*495,height/700*345,this));
                  everything.add(new line(width/700*495,height/700*345,width/700*749,height/700*350,this));
                  everything.add(new line(width/700*749,height/700*350,width/700*549,height/700*519,this));
                  everything.add(new line(width/700*549,height/700*519,width/700*624,height/700*800,this));
                  everything.add(new line(width/700*624,height/700*800,width/700*419,height/700*638,this));
                  everything.add(new line(width/700*419,height/700*638,width/700*203,height/700*800,this));
                  everything.add(new line(width/700*203,height/700*800,width/700*279,height/700*519,this));
                  everything.add(new line(width/700*279,height/700*519,width/700*76,height/700*350,this));
                  everything.add(new line(width/700*76,height/700*350,width/700*333,height/700*345,this));
                  everything.add(new line(width/700*333,height/700*345,width/700*419,height/700*68,this));

                  everything.add(new line(width/950*419,height/700*68,width/950*624,height/700*800,this));
                  everything.add(new line(width/950*419,height/700*68,width/950*203,height/700*800,this));
                  everything.add(new line(width/950*76,height/700*350,width/950*624,height/700*800,this));
                  everything.add(new line(width/950*203,height/700*800,width/950*749,height/700*350,this));
                  everything.add(new rectangle(width/950*76,height/700*350,width/950*673,1,this));*/

                  everything.add(new line((int)Math.round((double)width/1350*419),(int)Math.round((double)height/1000*68),(int)Math.round((double)width/1350*624),(int)Math.round((double)height/1000*800),this));
                  everything.add(new line((int)Math.round((double)width/1350*419),(int)Math.round((double)height/1000*68),(int)Math.round((double)width/1350*203),(int)Math.round((double)height/1000*800),this));
                  everything.add(new line((int)Math.round((double)width/1350*76),(int)Math.round((double)height/1000*350),(int)Math.round((double)width/1350*624),(int)Math.round((double)height/1000*800),this));
                  everything.add(new line((int)Math.round((double)width/1350*203),(int)Math.round((double)height/1000*800),(int)Math.round((double)width/1350*749),(int)Math.round((double)height/1000*350),this));
                  everything.add(new rectangle((int)Math.round((double)width/1350*76),(int)Math.round((double)height/1000*350),(int)Math.round((double)width/1350*673),1,this));


        addKeyListener(this);
        addMouseMotionListener(this);
        addMouseListener(this);
    }

    public void keyReleased(KeyEvent e)
    {
        Object source=e.getSource();

        int released=e.getKeyCode();

        if (released==KeyEvent.VK_A){left=0;}
        if (released==KeyEvent.VK_W){up=0;}
        if (released==KeyEvent.VK_D){right=0;}
        if (released==KeyEvent.VK_S){down=0;}
    }//end keyReleased


    public void keyPressed(KeyEvent e)
    {
        Object source=e.getSource();

        int pressed=e.getKeyCode();

        if (pressed==KeyEvent.VK_A){left=1;}
        if (pressed==KeyEvent.VK_W){up=1;}
        if (pressed==KeyEvent.VK_D){right=1;}
        if (pressed==KeyEvent.VK_S){down=1;}

        if (pressed==KeyEvent.VK_PAUSE&&pressed==KeyEvent.VK_P)
        {
            //if (paused==0){paused=1;}
            //else paused=0;
        }
    }//end keyPressed

    public void keyTyped(KeyEvent e){}

//***********************************************************************************************

    public void mouseDragged(MouseEvent e)
    {
        mouseX=(e.getX());
        mouseY=(e.getY());

          //run();
    }

    public void mouseMoved(MouseEvent e)
    {
        mouseX=(e.getX());
        mouseY=(e.getY());

          //run();
    }

//***********************************************************************************************

    public void mousePressed(MouseEvent e)
    {
        if(e.getX()==0 && e.getY()==0){System.exit(0);}

    mouseX=(e.getX()+x);
        mouseY=(e.getY()+y);

        if(Tile instanceof circle)
        {
                Circle.move(0-Circle.width, 0-Circle.height);
                Circle.setBounds(Circle.x, Circle.y, Circle.width, Circle.height);
                Tile=Rectangle;
        }
        else
        {
                Rectangle.move(0-Rectangle.width, 0-Rectangle.height);
                Rectangle.setBounds(Rectangle.x, Rectangle.y, Rectangle.width, Rectangle.height);
                Tile=Circle;
        }

        Tile.move(mouseX-Tile.width/2, mouseY-Tile.height/2);
    }

    public void mouseReleased(MouseEvent e)
    {
         //run();
    }

    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}

    public void mouseClicked(MouseEvent e){}

//***********************************************************************************************

    public void run()//run collision detection
    {
        while (this == this)
        {
            Tile.move(Tile.x + ((mouseX - (Tile.x + (Tile.width / 2))) / 10), Tile.y + ((mouseY - (Tile.y + (Tile.height / 2))) / 10));
            //Tile.move((mouseX - Tile.width / 2), mouseY - (Tile.height / 2));

            for (int i = 0; i < everything.size(); i++)
            {
                tile Temp = (tile) everything.get(i);

                if (Temp.x < (Tile.x + Tile.width) && (Temp.x + Temp.width) > Tile.x && Temp.y < (Tile.y + Tile.height) && (Temp.y + Temp.height) > Tile.y)//rectangles collided
                {
                    if (Temp instanceof rectangle)
                    {
                        if (Tile instanceof rectangle){rectangleRectangle(Temp);}
                        else {circleRectangle(Temp);}//Tile instanceof circle
                    }
                    else
                    {
                        if (Temp instanceof circle)
                        {
                            if (Tile instanceof rectangle) {rectangleCircle(Temp);}
                            else {circleCircle(Temp);}
                        }
                        else//line
                        {
                            if (Tile instanceof rectangle){rectangleLine(Temp);}
                            else{circleLine(Temp);}
                        }
                    }
                }//end if
            }//end for

            try {Thread.sleep(16L);}
            catch (Exception e) {}

            Tile.setBounds(Tile.x, Tile.y, Tile.width, Tile.height);
            //Rectangle.setBounds(x, y, width, height);
            //Circle.setBounds(x, y, width, height);
            repaint();

            text.out=" ";
        }//end while loop
    }//end run

//***************************************special collision detection/handling functions************************************************

    void rectangleRectangle(tile Temp)
    {
        int lapTop, lapBot, lapLeft, lapRight, small, scootX=0, scootY=0;

        lapTop=(Temp.y+Temp.height)-Tile.y;
        lapBot=(Tile.y+Tile.height)-Temp.y;
        lapLeft=(Temp.x+Temp.width)-Tile.x;
        lapRight=(Tile.x+Tile.width)-Temp.x;

        small=999999999;

        if (lapTop<small){small=lapTop; scootX=0; scootY=lapTop;}
        if (lapBot<small){small=lapBot; scootX=0; scootY=lapBot*-1;}
                if (lapLeft<small){small=lapLeft; scootX=lapLeft; scootY=0;}
                if (lapRight<small){small=lapRight; scootX=lapRight*-1; scootY=0;}

        Tile.move(Tile.x+scootX, Tile.y+scootY);text.out="collision detected!";
    }



    void circleRectangle(tile Temp)
    {
        if((Tile.x+Tile.width/2<=Temp.x+Temp.width && Tile.x+Tile.width/2>=Temp.x)||(Tile.y+Tile.height/2>=Temp.y && Tile.y+Tile.height/2<=Temp.y+Temp.height))
        {
            rectangleRectangle(Temp);
        }
        else//push from nearest corner
        {
            int x,y;
            if(Tile.x+Tile.width/2>Temp.x+Temp.width && Tile.y+Tile.height/2<Temp.y){x=Temp.x+Temp.width; y=Temp.y;}
            else if(Tile.x+Tile.width/2<Temp.x && Tile.y+Tile.height/2<Temp.y){x=Temp.x; y=Temp.y;}
            else if(Tile.x+Tile.width/2>Temp.x+Temp.width && Tile.y+Tile.height/2>Temp.y+Temp.height){x=Temp.x+Temp.width; y=Temp.y+Temp.height;}
            else {x=Temp.x; y=Temp.y+Temp.height;}

            double distance = Math.sqrt(Math.pow(Tile.x+(Tile.width/2) - x, 2) + Math.pow(Tile.y+(Tile.height/2) - y, 2));

            if((int)Math.round(distance)<Tile.height/2)
            {
                             double normY = ((Tile.y+(Tile.height/2) - y) / distance);
                             double normX = ((Tile.x+(Tile.width/2) - x) / distance);

                            Tile.move(x-Tile.width/2+(int)Math.round(normX*((Tile.width/2))) , y-Tile.height/2+(int)Math.round(normY*((Tile.height/2))));text.out="collision detected!";
            }
        }
    }



    void rectangleCircle(tile Temp)
    {
        if((Temp.x+Temp.width/2<=Tile.x+Tile.width && Temp.x+Temp.width/2>=Tile.x)||(Temp.y+Temp.height/2>=Tile.y && Temp.y+Temp.height/2<=Tile.y+Tile.height))
        {
            rectangleRectangle(Temp);
        }
        else//push from nearest corner
        {
            int x,y;
            if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2<Tile.y){x=Tile.x+Tile.width; y=Tile.y;}
            else if(Temp.x+Temp.width/2<Tile.x && Temp.y+Temp.height/2<Tile.y){x=Tile.x; y=Tile.y;}
            else if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2>Tile.y+Tile.height){x=Tile.x+Tile.width; y=Tile.y+Tile.height;}
            else {x=Tile.x; y=Tile.y+Tile.height;}

            double distance = Math.sqrt(Math.pow(Temp.x+(Temp.width/2) - x, 2) + Math.pow(Temp.y+(Temp.height/2) - y, 2));

            if((int)Math.round(distance)<Temp.height/2)
            {
             double normY = ((Temp.y+(Temp.height/2) - y) / distance);
             double normX = ((Temp.x+(Temp.width/2) - x) / distance);

             if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2<Tile.y){Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2)))-Tile.width,(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2))));text.out="collision detected!";}
                else if(Temp.x+Temp.width/2<Tile.x && Temp.y+Temp.height/2<Tile.y){Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2))),(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2))));text.out="collision detected!";}
                else if(Temp.x+Temp.width/2>Tile.x+Tile.width && Temp.y+Temp.height/2>Tile.y+Tile.height){Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2)))-Tile.width,(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2)))-Tile.height);text.out="collision detected!";}
                else {Tile.move((Temp.x+Temp.width/2)-(int)Math.round(normX*((Temp.width/2))),(Temp.y+Temp.height/2)-(int)Math.round(normY*((Temp.height/2)))-Tile.height);text.out="collision detected!";}
            }
        }
    }




    void circleCircle(tile Temp)
    {
        double distance = Math.sqrt(Math.pow((Tile.x+(Tile.width/2)) - (Temp.x+(Temp.width/2)),2) + Math.pow((Tile.y+(Tile.height/2)) - (Temp.y+(Temp.height/2)), 2));

        if((int)distance<(Tile.width/2+Temp.width/2))
        {
                        double normX = ((Tile.x+(Tile.width/2)) - (Temp.x+(Temp.width/2))) / distance;
                        double normY = ((Tile.y+(Tile.height/2)) - (Temp.y+(Temp.height/2))) / distance;

            Tile.move((Temp.x+(Temp.width/2))+(int)Math.round(normX*(Tile.width/2+Temp.width/2))-(Tile.width/2) , (Temp.y+(Temp.height/2))+(int)Math.round(normY*(Tile.height/2+Temp.height/2))-(Tile.height/2));text.out="collision detected!";
        }
    }



    void circleLine(tile Temp)
    {
            line Line=(line)Temp;

            if (Line.x1 < (Tile.x + Tile.width) && (Line.x1) > Tile.x && Line.y1 < (Tile.y + Tile.height) && Line.y1 > Tile.y)//circle may be hitting one of the end points
            {
                rectangle rec=new rectangle(Line.x1, Line.y1, 1, 1, this);
                circleRectangle(rec);
                remove(rec);
            }

            if (Line.x2 < (Tile.x + Tile.width) && (Line.x2) > Tile.x && Line.y2 < (Tile.y + Tile.height) && Line.y2 > Tile.y)//circle may be hitting one of the end points
            {
                rectangle rec=new rectangle(Line.x2, Line.y2, 1, 1, this);
                circleRectangle(rec);
                remove(rec);
            }


            int x1=0, y1=0, x2=Tile.x+(Tile.width/2), y2=Tile.y+(Tile.height/2);

            x1=Tile.x+(Tile.width/2)-Line.height;//(int)Math.round(Line.xNorm*1000);
            x2=Tile.x+(Tile.width/2)+Line.height;
            if(Line.posSlope)
            {
                y1=Tile.y+(Tile.height/2)-Line.width;
                y2=Tile.y+(Tile.height/2)+Line.width;
            }
            else
            {
                y1=Tile.y+(Tile.height/2)+Line.width;
                y2=Tile.y+(Tile.height/2)-Line.width;
            }

            Point point=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection

            if (point.x < (Line.x + Line.width) && point.x > Line.x && point.y < (Line.y + Line.height) && point.y > Line.y)//line intersects within line segment
            {
                //if(point!=null){System.out.println(point.x+","+point.y);}
                double distance = Math.sqrt(Math.pow((Tile.x+(Tile.width/2)) - point.x,2) + Math.pow((Tile.y+(Tile.width/2)) - point.y, 2));

                if((int)distance<Tile.width/2)
                {
                    //System.out.println("hit");
                    double normX = ((Tile.x+(Tile.width/2)) - point.x) / distance;
                    double normY = ((Tile.y+(Tile.height/2)) - point.y) / distance;

                    Tile.move((point.x)+(int)Math.round(normX*(Tile.width/2))-(Tile.width/2) , (point.y)+(int)Math.round(normY*(Tile.height/2))-(Tile.height/2));text.out="collision detected!";
                    //System.out.println(point.x+","+point.y);
                }
            }

            //new bullet(this, (int)Math.round(tryX), (int)Math.round(tryY));
    }

        void rectangleLine(tile Temp)
    {
            line Line=(line)Temp;
            if(new Line2D.Double(Line.x1,Line.y1,Line.x2,Line.y2).intersects(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height)))
            {
                if (Line.x1 < (Tile.x + Tile.width) && (Line.x1) > Tile.x && Line.y1 < (Tile.y + Tile.height) && Line.y1 > Tile.y)//circle may be hitting one of the end points
                {
                    rectangle rec=new rectangle(Line.x1, Line.y1, 1, 1, this);
                    rectangleRectangle(rec);
                    remove(rec);
                }

                if (Line.x2 < (Tile.x + Tile.width) && (Line.x2) > Tile.x && Line.y2 < (Tile.y + Tile.height) && Line.y2 > Tile.y)//circle may be hitting one of the end points
                {
                    rectangle rec=new rectangle(Line.x2, Line.y2, 1, 1, this);
                    rectangleRectangle(rec);
                    remove(rec);
                }

                if(Line.posSlope)//positive sloped line
                {
                    //first we'll do the top left corner
                    int x1=Tile.x-Line.height;
                    int x2=Tile.x+Line.height;
                    int y1=Tile.y-Line.width;
                    int y2=Tile.y+Line.width;
                    Point topPoint=new Point(-99,-99), botPoint=new Point(-99,-99);
                    double topDistance=0, botDistance=0;

                    topPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection

                    topDistance = Math.sqrt(Math.pow(Tile.x - topPoint.x,2) + Math.pow(Tile.y - topPoint.y, 2));

                    //new let's do the bottom right corner
                    x1=Tile.x+Tile.width-Line.height;
                    x2=Tile.x+Tile.width+Line.height;
                    y1=Tile.y+Tile.height-Line.width;
                    y2=Tile.y+Tile.height+Line.width;

                    botPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection

                    botDistance = Math.sqrt(Math.pow((Tile.x+Tile.width) - botPoint.x,2) + Math.pow((Tile.y+Tile.height) - botPoint.y, 2));


                    if(topDistance<botDistance)
                    {
                        if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(topPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(topPoint))
                        {
                            Tile.move(topPoint.x,topPoint.y);text.out="collision detected!";
                        }
                    }
                    else
                    {
                        if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(botPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(botPoint))
                        {
                            Tile.move(botPoint.x-Tile.width,botPoint.y-Tile.height);text.out="collision detected!";
                        }
                    }
                }
                else//negative sloped lne
                {
                    //first we'll do the top right corner
                    int x1=Tile.x+Tile.width-Line.height;
                    int x2=Tile.x+Tile.width+Line.height;
                    int y1=Tile.y+Line.width;
                    int y2=Tile.y-Line.width;
                    Point topPoint=new Point(-99,-99), botPoint=new Point(-99,-99);
                    double topDistance=0, botDistance=0;

                    topPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection

                    topDistance = Math.sqrt(Math.pow(Tile.x + Tile.width - topPoint.x,2) + Math.pow(Tile.y - topPoint.y, 2));

                    //new let's do the bottom left corner
                    x1=Tile.x-Line.height;
                    x2=Tile.x+Line.height;
                    y1=Tile.y+Tile.height+Line.width;
                    y2=Tile.y+Tile.height-Line.width;

                    botPoint=intersection((double)x1,(double)y1,(double)x2,(double)y2,(double)Line.x1,(double)Line.y1,(double)Line.x2,(double)Line.y2);//find intersection

                    botDistance = Math.sqrt(Math.pow(Tile.x - botPoint.x,2) + Math.pow((Tile.y+Tile.height) - botPoint.y, 2));


                    if(topDistance<botDistance)
                    {
                        if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(topPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(topPoint))
                        {
                            Tile.move(topPoint.x-Tile.width,topPoint.y);text.out="collision detected!";
                        }
                    }
                    else
                    {
                        if(new Rectangle(Tile.x,Tile.y,Tile.width,Tile.height).contains(botPoint) && new Rectangle(Line.x,Line.y,Line.width,Line.height).contains(botPoint))
                        {
                            Tile.move(botPoint.x,botPoint.y-Tile.height);text.out="collision detected!";
                        }
                    }
                }
            }
    }

       public Point intersection(double x1, double y1, double x2, double y2,double x3, double y3, double x4, double y4)//I didn't write this. got it from http://www.ahristov.com/tutorial/geometry-games/intersection-lines.html (I altered it)
       {
            double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);

            double xi = ((x3 - x4) * (x1 * y2 - y1 * x2) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
            double yi = ((y3 - y4) * (x1 * y2 - y1 * x2) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;

            int x=(int)Math.round(xi);
            int y=(int)Math.round(yi);

            return new Point(x, y);
        }

//***************************************************************************************

    public static void main(String[] args)
    {
        final collision Collision=new collision();
          Collision.run();
    }//end main
}//end class
于 2011-06-02T01:11:57.333 に答える
2

Javaには交差関数がないため(本当に!?)、衝突する可能性のある各オブジェクトの境界ボックス(長方形)のXとY、幅と高さの値を比較するだけで、衝突検出を行うことができます。

つまり、衝突する各オブジェクトのベースオブジェクトに...つまり、プレーヤーと敵が共通のベースを持っている場合は、BoundingBoxのような単純なRectangleオブジェクトを配置できます。共通ベースが組み込みのJavaクラスである場合は、組み込みのクラスを拡張するクラスを作成し、プレーヤーと敵のオブジェクトに新しいクラスを拡張させるか、そのクラスのインスタンスにする必要があります。

作成時(および各ティックまたは更新時)に、プレーヤーと敵の両方にBoundingBoxパラメーターを設定する必要があります。目の前にRectangleクラスはありませんが、X、Y、Width、そして最後にHeightのようなものである可能性があります。XとYは、ゲームワールド内のオブジェクトの場所です。幅と高さは自明だと思います。ただし、プレイヤーの場所の右側から出てくる可能性が高いので、XとYが両方とも0で、幅と高さが両方とも256の場合、キャラクターは左上にあるため、何も表示されません。画面の外。

とにかく...衝突を検出するには、プレイヤーと敵のBoundingBoxの属性を比較する必要があります。だからこのようなもの...

 if( Player.BoundingBox.X = Enemy.BoundingBox.X && If( Player.BoundingBox.Y = Enemy.BoundingBox.Y )
 {
      //Oh noes!  The enemy and player are on top of eachother.
 }

ロジックは複雑になる可能性がありますが、各BoundingBox間の距離を比較し、場所を比較する必要があります。

于 2008-12-02T22:57:35.873 に答える
2

問題はありますか:

Rectangle box1 = new Rectangle(100,100,100,100);
Rectangle box2 = new Rectangle(200,200,100,100);

// what this means is if any pixel in box2 enters (hits) box1
if (box1.contains(box2)) 
{
     // collision occurred
}

// your code for moving the boxes 


これは円にも適用できます。

Ellipse2D.Double ball1 = new Ellipse2D.Double(100,100,200,200);
Ellipse2D.Double ball2 = new Ellipse2D.Double(400,100,200,200);

// what this means is if any pixel on the circumference in ball2 touches (hits)
// ball1
    if (ball1.contains(ball2)) 
    {
         // collision occurred
    }

    // your code for moving the balls



画面の端にぶつかったかどうかを確認するには、次を使用できます。

Rectangle screenBounds = jpanel.getBounds();
Ellipse2D.Double ball = new Ellipse2D.Double(100,100,200,200);  // diameter 200
Rectangle ballBounds = ball.getBounds();

if (!screenBounds.contains(ballBounds))
{
// the ball touched the edge of the screen
}
于 2014-10-27T12:04:17.573 に答える
2

これは、多くの衝突を使用するオープン ソース ゲームの便利な例です: http://robocode.sourceforge.net/

コードを見て、ここに書かれている回答を補足してください。

于 2008-12-02T23:28:12.923 に答える
1

四角形を使用して各プレイヤーと敵を囲みます。四角形の高さと幅は、囲んでいるオブジェクトに対応する必要があります。それが収まるだけの大きさのボックスに入っていると想像してください。

次に、これらの長方形をオブジェクトと同じように移動して、「バウンディング ボックス」を作成します。

Javaにこれがあるかどうかはわかりませんが、長方形オブジェクトに.intersects()というメソッドがある可能性があるため、if(rectangle1.intersectS(rectangle2)を実行して、オブジェクトが別のオブジェクトと衝突したかどうかを確認します。

それ以外の場合は、ボックスの x 座標と y 座標を取得し、ボックスの高さ/幅を使用して、自分自身と交差したかどうかを検出できます。

とにかく、それを使用して、交差点でイベントを実行したり (1 つを爆発させるなど)、動きが描画されないようにすることができます。(前の座標に戻す)

編集:どうぞ

ブール値

intersects(Rectangle r) この Rectangle と指定された Rectangle が交差するかどうかを判断します。

だから私はそうするでしょう(そしてこのコードを貼り付けないでください。おそらく動作しません.Javaを長い間やっていなかったし、使用したときにグラフィックスをしていませんでした.)

Rectangle rect1 = new Rectangle(player.x, player.y, player.width, player.height);

Rectangle rect2 = new Rectangle(enemy.x, enemy.y, enemy.width, enemy.height);

//detects when the two rectangles hit
if(rect1.intersects(rect2))
{

System.out.println("game over, g");
}

明らかに、それをどこかに合わせる必要があります。

于 2008-12-02T22:04:07.477 に答える