怎么把障碍物规划合理,让他可以让小鸟通过,并和矩形重合


package main;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;

import util.Constant;
import util.Gameutil;

public class Barrier {
    
    //矩形参数
    private Rectangle rect;
    
    //障碍物移动速度
    private int speed = 3;
    
    //定义障碍物需要的两个图片
    private static BufferedImage[] imgs;//定义一个数组来存放图片**imgs
    
    //障碍物的状态
    private boolean visible;
    
    //在静态代码块中初始化一些参数
    static {
        final int COUNT = 3;//先定义一个常量
        //类加载的时候将三个图片初始化
        imgs = new BufferedImage[COUNT];
        for (int i = 0; i < COUNT; i++) {
            imgs[i] = Gameutil.loadBufferedImage(Constant.BARRIER_IMG_PATH[i]);
        }//把图片加载进去
    }
    
    //障碍物的位置
    private int x,y;
    //障碍物的宽度和高度
    private int width,height;
    //障碍物的类型
    private int type;
    public static final int TYPE_TOP_NORMAL = 0;
    public static final int TYPE_BOTTOM_NORMAL = 2;
    public static final int TYPE_HOVER_NORMAL = 4;
    
    //获得障碍物的宽度和高度
    public static final int BARRIRE_WIDTH = imgs[0].getWidth();
    public static final int BARRIRE_HEIGHT = imgs[0].getHeight();
    public static final int BARRIRE_HEAD_WIDTH = imgs[1].getWidth();
    public static final int BARRIRE_HEAD_HEIGHT = imgs[1].getHeight();
    public static final int BARRIRE_H_WIDTH = imgs[2].getWidth();
    public static final int BARRIRE_H_HEIGHT = imgs[2].getHeight();
    
    //定义一个构造器
    public Barrier() {
        
        rect =new Rectangle();
        
    }
    
    public Barrier(int x,int y,int height,int type) {
        this.x = x;
        this.y = y;
        this.height = height;
        this.type = type;
        this.width = BARRIRE_WIDTH;
    }
    
    //根据不同的类型绘制障碍物
    public void draw(Graphics g) {
        switch(type){
            case TYPE_TOP_NORMAL:
                 drawTopMormal(g);
                 break;
            case TYPE_BOTTOM_NORMAL:
                 drawNomalTop(g);
                 break;
        }
        
    }
    
    //绘制从上向下的障碍物
    private void drawTopMormal(Graphics g) {
        
        //求出所需要的障碍物的块数
        int count = (height-BARRIRE_HEAD_HEIGHT)/BARRIRE_HEIGHT+1;
        //for循环绘制障碍物
        for (int i = 0; i < count; i++) {
            g.drawImage(imgs[0], x, y+i*BARRIRE_HEIGHT, null);
        }
        //绘制头
        int y = height-BARRIRE_HEAD_HEIGHT;
        g.drawImage(imgs[2], x-(BARRIRE_HEAD_WIDTH-BARRIRE_WIDTH)/2, y,null);
        x-=speed;
        if (x<-50) {
            visible = false;
        }
        rect(g);
    }
    
    //绘制从下向上的障碍物
    private void drawNomalTop(Graphics g) {
        //求出所需要的障碍物的块数
        int count = height/BARRIRE_HEIGHT+1;
        //for循环绘制障碍物
        for (int i = 0; i < count; i++) {
            g.drawImage(imgs[0], x, Constant.FRAM_HEIGNT-i*BARRIRE_HEIGHT, null);
        }
        
        //绘制头
        int y = Constant.FRAM_HEIGNT-height;
        g.drawImage(imgs[1], x-(BARRIRE_H_WIDTH-BARRIRE_WIDTH)/2, y, null);
        x-=speed;
        if (x<-50) {
            visible = false;
        }
        rect(g);
    }
    
    //绘制障碍物碰撞矩形
    public void rect(Graphics g) {
        int x1 = this.x;
        int y1 = this.y;
        int w1 = imgs[0].getWidth();
        g.setColor(Color.blue);
        g.drawRect(x1, y1, w1, height);
        setRecyangle(x1, y1, w1, height);
    }
    
    //障碍物碰撞矩形参数
    public void setRecyangle(int x,int y,int width,int height) {
        rect.x = x;
        rect.y = y;
        rect.width = width;
        rect.height = height;
    }
    
    //判断什么时候绘制下一组障碍物
    public boolean isInFrame () {return 600-x>150;}
    //
    public int getX() {
        return x;
    }
    
    public void setX(int x) {
        this.x = x;
    }
    
    public int getY() {
        return y;
    }
    
    public void setY(int y) {
        this.y = y;
    }
    
    public int getHeight() {
        return height;
    }
    
    public void setHeight(int height) {
        this.height = height;
    }
    
    public int getType() {
        return type;
    }
    
    public void setType(int type) {
        this.type = type;
    }
    
    public boolean isVisible() {
        return visible;
    }
    
    public void setVisible(boolean visible) {
        this.visible = visible;
    }
    
    public Rectangle getRect() {
        return rect;
    }
}
package main;

import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class GameBarrierLayer {
    
    //用于生成随机数的函数
    private Random random = new Random();
    
    //定一个数组来存放障碍物
    private List<Barrier> barriers;
    
    //定义一个构造器
    public GameBarrierLayer() {
        barriers = new ArrayList<>();
    }
    
    //绘制障碍物
    public void draw(Graphics g,Bird bird) {
        //Barrier barrier = new Barrier(200,0,200,0);
        //barriers.add(barrier);
        //barriers.get(0).draw(g);
        //Barrier barrier1 = new Barrier(300,0,300,2);
        //barriers.add(barrier1);
        //barriers.get(1).draw(g);
        for (int i = 0; i < barriers.size(); i++) {
            Barrier barrier = barriers.get(i);
            if (barrier.isVisible()) {
                barrier.draw(g);
            } else {
                Barrier remove = barriers.remove(i);
                Barrierpool.setPool(remove);
                i--;
            }
        }
        collideBird(bird);
        logic();
    }
    
    //生成随机障碍物
    public void logic() {
        if (barriers.size()==0) {
            ran();
            //Barrier top = new Barrier(800,0,numberTop,0);
            //barriers.add(top);
            //Barrier down = new Barrier(800,500-numberDown,numberDown,2);
            //barriers.add(down);
            insert(600, 0, numberTop, 0);
            insert(600, 600-numberDown, numberTop, 2);
        }else {
            //判断最后一个障碍物是否完全进入屏幕内
            Barrier last = barriers.get(barriers.size()-1);
            if (last.isInFrame()) {
                ran();
                //Barrier top = new Barrier(800,0,numberTop,0);
                //barriers.add(top);
                //Barrier down = new Barrier(800,500-numberDown,numberDown,2);
                //barriers.add(down);
                insert(600, 0, numberTop, 0);
                insert(600, 600-numberDown, numberTop, 2);
            }
        }
    }
    
    //用于从池中获取对象,并把参数封装成barrier,存入barrier数组
    public void insert(int x,int y,int num,int type) {
        Barrier top = Barrierpool.getPool();
        top.setX(x);
        top.setY(y);
        top.setHeight(num);
        top.setType(type);
        top.setVisible(true);
        barriers.add(top);
    }
    
    //上方障碍物高度
    private int numberTop;
    //下方障碍物高度
    private int numberDown;
    //产生两个100~500之间的随机高度
    public void ran() {
        numberTop = random.nextInt(400)+100;
        numberDown = random.nextInt(400)+100;
        //如果管道重合,则重新随机
        if (numberTop+numberDown>500) {
            ran();
        }
    }

    //判断障碍物与小鸟发生碰撞
    public boolean collideBird(Bird bird) {
        for (int i = 0; i < barriers.size(); i++) {
            Barrier barrier = barriers.get(i);
            //判断矩形是否相交
            if (barrier.getRect().intersects(bird.getRect())) {
                System.out.println("撞上了");
                bird.life =false;
            }
        }
        return false;
    }
}

package main;

import java.util.ArrayList;
import java.util.List;

public class Barrierpool {
    
    //用于管理池中所有对象的容量
    private static List<Barrier>pool = new ArrayList<>();
    
    //池中初始的对象个数
    public static final int initCount = 16;
    
    //对象池中最大个数
    public static final int maxCount = 20;
    
    //静态代码块
    static {
        //初始化池中对象
        for (int i = 0; i < initCount; i++) {
            pool.add(new Barrier());
        }
    }
    
    //从池中获取一个对象的方法
    public static Barrier getPool() {
        int size = pool.size();
        //如果池中有对象才可以拿
        if (size>0) {
            //移除并返回对象
            System.out.println("拿走一个");
            return pool.remove(size-1);
        }else {
            //池中没有对象了,只能new
            System.out.println("新的对象");
            return new Barrier();
        }
    }
    
    //把对象归还给容器
    public static void setPool(Barrier barrier) {
        if (pool.size()<maxCount) {
            pool.add(barrier);
            System.out.println("容器归还了");
        }
    }

}

img

【以下回答由 GPT 生成】

解决方案

为了让障碍物与小鸟重叠并且允许小鸟通过,需要考虑以下几个步骤:

  1. 定义障碍物类的逻辑和数据结构
  2. 保证障碍物与小鸟重叠
  3. 允许小鸟通过障碍物

1. 定义障碍物类的逻辑和数据结构

在给定的代码中,已经有了障碍物类 Barrier。该类包含了障碍物的位置、大小、类型等信息。

2. 保证障碍物与小鸟重叠

要保证障碍物与小鸟重叠,可以通过以下步骤来实现:

  • 在障碍物类中,添加一个方法来判断障碍物与小鸟是否重叠。可以使用 Rectangle 类提供的 intersects 方法来判断两个矩形是否相交。
  • 在游戏主循环中,判断障碍物与小鸟是否重叠,如果重叠则游戏结束。

下面是代码示例:

// 障碍物类中添加方法判断是否与小鸟重叠
public boolean intersects(Bird bird) {
    Rectangle birdRect = bird.getRect();
    return this.rect.intersects(birdRect);
}

// 游戏主循环中判断障碍物与小鸟是否重叠
if (barrier.intersects(bird)) {
    gameOver();
}

3. 允许小鸟通过障碍物

要允许小鸟通过障碍物,可以通过以下步骤来实现:

  • 在障碍物类中,添加一个属性来表示是否已经通过(例如 passed)。
  • 在游戏主循环中,判断障碍物是否已经通过,如果没有通过,则判断小鸟是否到达障碍物的位置。如果小鸟到达障碍物的位置,则将障碍物的通过属性设置为 true
  • 障碍物类中的 update 方法中,根据通过属性判断是否绘制障碍物。

下面是代码示例:

// 障碍物类中添加通过属性
private boolean passed;

// 游戏主循环中判断小鸟是否到达障碍物的位置
if (!barrier.hasPassed() && barrier.getX() + barrier.getWidth() < bird.getX()) {
    barrier.setPassed(true);
}

// 障碍物类中的 update 方法根据通过属性判断是否绘制障碍物
public void update() {
    if (!passed) {
        // 绘制障碍物
    }
}

通过以上步骤的实现,我们可以合理规划障碍物,使其与小鸟重叠,并允许小鸟通过。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^