最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現(xiàn)矩形碰撞檢測

 更新時間:2021年06月17日 09:44:15   作者:二木成林  
這篇文章主要為大家詳細介紹了Java實現(xiàn)矩形碰撞檢測,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了Java實現(xiàn)矩形碰撞檢測的具體代碼,供大家參考,具體內(nèi)容如下

第1種方法:通過檢測一個矩形的4個頂點是否在另一個矩形的內(nèi)部來完成。

通常由x和y坐標以及長度和寬度來確定一個矩形,因此又可以利用這四個參數(shù)來確定是否發(fā)生了碰撞。

相交的情況下一定會發(fā)生碰撞,如下圖:

還有一類特殊的相交情況,就是重疊,如下圖:

所以開發(fā)的碰撞檢測類如下:

public class Actor {
    int x, y, w, h;// 分別是x和y坐標,寬度和高度,構(gòu)成一個矩形
 
    public Actor() {
    }
 
    public Actor(int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
    }
 
    public int getX() {
        return x;
    }
 
    public int getY() {
        return y;
    }
 
    public int getActorWidth() {
        return w;
    }
 
    public int getActorHeight() {
        return h;
    }
 
    @Override
    public String toString() {
        return "Actor{" +
                "x=" + x +
                ", y=" + y +
                ", w=" + w +
                ", h=" + h +
                '}';
    }
 
    public boolean isCollidingWith(int px, int py) {
        // px和py分別傳入的是x坐標和y坐標
        // 等號的情況就是考慮垂直重疊和水平重疊的情況
        // 考慮的情況就是傳入的坐標是否在當前的矩形范圍內(nèi),只要滿足下面所有條件就表示傳入的坐標在當前矩形范圍內(nèi),返回true
        if (px >= getX() && px < getX() + getActorWidth() && py >= getY() && py < getY() + getActorHeight()) {
            return true;
        }
        return false;
    }
 
    // 碰撞檢測,發(fā)生碰撞返回true,否則返回false
    public boolean isCollidingWith(Actor another) {
        // 判斷矩形只要有任何一個點在另一個Actor所表示的矩形范圍內(nèi),就表示發(fā)生了碰撞
        if (isCollidingWith(another.getX(), another.getY()) ||
                isCollidingWith(another.getX() + another.getActorWidth(), another.getY()) ||
                isCollidingWith(another.getX(), another.getY() + another.getActorHeight()) ||
                isCollidingWith(another.getX() + another.getActorWidth(), another.getY() + another.getActorHeight())) {
            return true;
        }
        return false;
    }
 
    public static void main(String[] args) {
        Actor actor = new Actor(10, 10, 100, 150);
        Actor another = new Actor(20, 50, 100, 150);
        boolean collidingWith = actor.isCollidingWith(another);
        System.out.println(collidingWith);
    }
}

上面測試代碼你不能很好的觀察是否發(fā)生矩形碰撞了,所以寫了下面這個界面,可以通過ASWD操作左邊的矩形進行移動,通過上下左右鍵操作右邊的矩形進行移動,效果如下圖:

代碼如下:

class TestPanel extends JPanel implements KeyListener {
    private int x1 = 20, y1 = 20, x2 = 160, y2 = 20, width = 100, height = 100;
 
    public TestPanel() {
        // 設(shè)置焦點并且添加鍵盤事件監(jiān)聽器
        setFocusable(true);
        addKeyListener(this);
    }
 
    @Override
    public void paint(Graphics g) {
        // 在進行繪制之前,一定要清除之前的圖形
        g.clearRect(0, 0, this.getWidth(), this.getHeight());// 先清除屏幕上原來的畫
        g.drawRect(x1, y1, width, height);
        g.drawRect(x2, y2, width, height);
    }
 
    @Override
    public void keyTyped(KeyEvent e) {
 
    }
 
    @Override
    public void keyPressed(KeyEvent e) {
        // 處理第一個矩形的移動
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A:// 'A'鍵
                x1 -= 5;
                break;
            case KeyEvent.VK_D:// 'D'鍵
                x1 += 5;
                break;
            case KeyEvent.VK_W:// 'W'鍵
                y1 -= 5;
                break;
            case KeyEvent.VK_S://'S'鍵
                y1 += 5;
                break;
            case KeyEvent.VK_LEFT://'LEFT'鍵
                x2 -= 5;
                break;
            case KeyEvent.VK_RIGHT:// 'RIGHT'鍵
                x2 += 5;
                break;
            case KeyEvent.VK_UP:// 'UP'鍵
                y2 -= 5;
                break;
            case KeyEvent.VK_DOWN:// 'DOWN'鍵
                y2 += 5;
                break;
        }
        repaint();// 修改坐標后,重繪圖形
        // 判斷是否碰撞,輸出信息
        Actor actor = new Actor(x1, y1, width, height);
        Actor another = new Actor(x2, y2, width, height);
        System.out.println("是否碰撞:" + (actor.isCollidingWith(another) || another.isCollidingWith(actor)) + "| " + actor + "| " + another);
    }
 
    @Override
    public void keyReleased(KeyEvent e) {
 
    }
}
 
public class Demo {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setLocation(200, 200);
        frame.setSize(500, 500);
 
        TestPanel panel = new TestPanel();
        frame.setContentPane(panel);
 
        frame.setVisible(true);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

第2種方法:從相反的角度考慮,以前是處理什么時候相交,現(xiàn)在處理什么時候不會相交。如兩個矩形a和b來判斷4條邊,假如a矩形在左邊,b矩形在右邊,那么可以判斷左邊a矩形的右邊界在b矩形的左邊界之外,同理,a的上邊界需要在b的下邊界以外,4條邊都判斷,則可以知道a矩形是否與b矩形相交。

方法如下:

/**
     * 判斷兩個矩形是否會發(fā)生碰撞
     *
     * @param ax 矩形a的x坐標
     * @param ay 矩形a的y坐標
     * @param aw 矩形a的寬度
     * @param ah 矩形a的高度
     * @param bx 矩形b的x坐標
     * @param by 矩形b的y坐標
     * @param bw 矩形b的寬度
     * @param bh 矩形b的高度
     * @return 如果發(fā)生碰撞則返回true,否則返回false
 */
    public boolean isCollidingWith(int ax, int ay, int aw, int ah, int bx, int by, int bw, int bh) {
        if (ay > by + bh || by > ay + ah || ax > bx + bw || bx > ax + aw) {
            return false;
        }
        return true;
    }

第3種方法:是方法2的變異,我們保存兩個矩形的左上和右下兩個坐標的坐標值,然后對兩個坐標的一個對比就可以得出兩個矩形是否相交。

/**
     * rect1[0]:矩形1左上角x坐標
     * rect1[1]:矩形1左上角y坐標
     * rect1[2]:矩形1右下角x坐標
     * rect1[3]:矩形1右下角y坐標
     * rect2[0]:矩形2左上角x坐標
     * rect2[1]:矩形2左上角y坐標
     * rect2[2]:矩形2右下角x坐標
     * rect2[3]:矩形2右下角y坐標
     *
     * @param rect1 第一個矩形的左上角坐標和右下角坐標數(shù)組
     * @param rect2 第二個矩形的左上角坐標和右下角坐標數(shù)組
     * @return 如果發(fā)生碰撞則返回true,否則返回false
     */
    public static boolean isCollidingWith(int rect1[], int rect2[]) {
        if (rect1[0] > rect2[2]) {
            return false;
        }
        if (rect1[2] < rect2[0]) {
            return false;
        }
        if (rect1[1] > rect2[3]) {
            return false;
        }
        if (rect1[3] < rect2[1]) {
            return false;
        }
        return true;
}

最后Actor類的完整代碼如下:

public class Actor {
    int x, y, w, h;// 分別是x和y坐標,寬度和高度,構(gòu)成一個矩形
 
    public Actor() {
    }
 
    public Actor(int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
    }
 
    public int getX() {
        return x;
    }
 
    public int getY() {
        return y;
    }
 
    public int getActorWidth() {
        return w;
    }
 
    public int getActorHeight() {
        return h;
    }
 
    @Override
    public String toString() {
        return "Actor{" +
                "x=" + x +
                ", y=" + y +
                ", w=" + w +
                ", h=" + h +
                '}';
    }
 
    public boolean isCollidingWith(int px, int py) {
        // px和py分別傳入的是x坐標和y坐標
        // 等號的情況就是考慮垂直重疊和水平重疊的情況
        // 考慮的情況就是傳入的坐標是否在當前的矩形范圍內(nèi),只要滿足下面所有條件就表示傳入的坐標在當前矩形范圍內(nèi),返回true
        if (px >= getX() && px < getX() + getActorWidth() && py >= getY() && py < getY() + getActorHeight()) {
            return true;
        }
        return false;
    }
 
    // 碰撞檢測,發(fā)生碰撞返回true,否則返回false
    public boolean isCollidingWith(Actor another) {
        // 判斷矩形只要有任何一個點在另一個Actor所表示的矩形范圍內(nèi),就表示發(fā)生了碰撞
        if (isCollidingWith(another.getX(), another.getY()) ||
                isCollidingWith(another.getX() + another.getActorWidth(), another.getY()) ||
                isCollidingWith(another.getX(), another.getY() + another.getActorHeight()) ||
                isCollidingWith(another.getX() + another.getActorWidth(), another.getY() + another.getActorHeight())) {
            return true;
        }
        return false;
    }
 
    /**
     * 判斷兩個矩形是否會發(fā)生碰撞
     *
     * @param ax 矩形a的x坐標
     * @param ay 矩形a的y坐標
     * @param aw 矩形a的寬度
     * @param ah 矩形a的高度
     * @param bx 矩形b的x坐標
     * @param by 矩形b的y坐標
     * @param bw 矩形b的寬度
     * @param bh 矩形b的高度
     * @return 如果發(fā)生碰撞則返回true,否則返回false
     */
    public boolean isCollidingWith(int ax, int ay, int aw, int ah, int bx, int by, int bw, int bh) {
        if (ay > by + bh || by > ay + ah || ax > bx + bw || bx > ax + aw) {
            return false;
        }
        return true;
    }
 
    /**
     * isCollidingWith方法的重載方法
     *
     * @param a
     * @param b
     * @return
     */
    public boolean isCollidingWith(Actor a, Actor b) {
        return isCollidingWith(a.getX(), a.getY(), a.getActorWidth(), a.getActorHeight(), b.getX(), b.getY(), b.getActorWidth(), b.getActorHeight());
    }
 
    /**
     * rect1[0]:矩形1左上角x坐標
     * rect1[1]:矩形1左上角y坐標
     * rect1[2]:矩形1右下角x坐標
     * rect1[3]:矩形1右下角y坐標
     * rect2[0]:矩形2左上角x坐標
     * rect2[1]:矩形2左上角y坐標
     * rect2[2]:矩形2右下角x坐標
     * rect2[3]:矩形2右下角y坐標
     *
     * @param rect1 第一個矩形的左上角坐標和右下角坐標數(shù)組
     * @param rect2 第二個矩形的左上角坐標和右下角坐標數(shù)組
     * @return 如果發(fā)生碰撞則返回true,否則返回false
     */
    public static boolean isCollidingWith(int rect1[], int rect2[]) {
        if (rect1[0] > rect2[2]) {
            return false;
        }
        if (rect1[2] < rect2[0]) {
            return false;
        }
        if (rect1[1] > rect2[3]) {
            return false;
        }
        if (rect1[3] < rect2[1]) {
            return false;
        }
        return true;
    }
 
 
    public static void main(String[] args) {
        Actor actor = new Actor(10, 10, 100, 150);
        Actor another = new Actor(20, 50, 100, 150);
        boolean collidingWith = actor.isCollidingWith(another);
        System.out.println(collidingWith);
    }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • spring boot中interceptor攔截器未生效的解決

    spring boot中interceptor攔截器未生效的解決

    這篇文章主要介紹了spring boot中interceptor攔截器未生效的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot操作spark處理hdfs文件的操作方法

    SpringBoot操作spark處理hdfs文件的操作方法

    本文介紹了如何使用Spring Boot操作Spark處理HDFS文件,包括導(dǎo)入依賴、配置Spark信息、編寫Controller和Service處理地鐵數(shù)據(jù)、運行項目以及觀察Spark和HDFS的狀態(tài),感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Java如何計算兩個時間段內(nèi)的工作日天數(shù)

    Java如何計算兩個時間段內(nèi)的工作日天數(shù)

    這篇文章主要介紹了Java如何計算兩個時間段內(nèi)的工作日天數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • java批量插入數(shù)據(jù)的幾種方法

    java批量插入數(shù)據(jù)的幾種方法

    這篇文章主要給大家介紹了關(guān)于java批量插入數(shù)據(jù)的幾種方法,大家在Java項目中經(jīng)常會出現(xiàn)大量向數(shù)據(jù)庫中插入的情況,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • Java使用釘釘創(chuàng)建企業(yè)內(nèi)部機器人的實現(xiàn)

    Java使用釘釘創(chuàng)建企業(yè)內(nèi)部機器人的實現(xiàn)

    釘釘?shù)某霈F(xiàn)為企業(yè)節(jié)約了大量人力成本,其中也開放了大量的外部api接口方便企業(yè)使用。本文主要介紹了Java使用釘釘創(chuàng)建企業(yè)內(nèi)部機器人的實現(xiàn),感興趣的可以了解一下
    2021-11-11
  • Springboot2以代碼的方式統(tǒng)一配置Jackson教程

    Springboot2以代碼的方式統(tǒng)一配置Jackson教程

    這篇文章主要介紹了Springboot2以代碼的方式統(tǒng)一配置Jackson教程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • mybatis-plus雪花算法生成Id使用詳解

    mybatis-plus雪花算法生成Id使用詳解

    本文主要介紹了mybatis-plus雪花算法生成Id使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • spring boot中controller的使用及url參數(shù)的獲取方法

    spring boot中controller的使用及url參數(shù)的獲取方法

    這篇文章主要介紹了spring boot中controller的使用及url參數(shù)的獲取方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-01-01
  • FeignClient如何共享Header及踩坑過程記錄

    FeignClient如何共享Header及踩坑過程記錄

    這篇文章主要介紹了FeignClient如何共享Header及踩坑過程記錄,
    2022-03-03
  • Java使用FastExcel導(dǎo)入支持多種時間格式

    Java使用FastExcel導(dǎo)入支持多種時間格式

    FastExcel 是一個采用純 java 開發(fā)的 excel 文件讀寫組件,支持 Excel'97(-2003)(BIFF8)文件格式,本文主要介紹了如何使用FastExcel導(dǎo)入支持多種時間格式,感興趣的可以了解
    2024-12-12

最新評論

辛集市| 马公市| 安达市| 兖州市| 定陶县| 长汀县| 南投县| 慈利县| 永泰县| 香格里拉县| 芒康县| 聊城市| 井研县| 浑源县| 浦县| 阿坝| 慈溪市| 皮山县| 富裕县| 齐河县| 德保县| 桃江县| 胶州市| 揭阳市| 通渭县| 当雄县| 龙山县| 澄城县| 大理市| 深水埗区| 汾西县| 马公市| 内乡县| 金阳县| 拉孜县| 修文县| 建昌县| 姜堰市| 鸡东县| 长宁县| 江山市|