当前位置: 首页 > 知识库问答 >
问题:

Java马里奥游戏敌人和方块之间的碰撞

谢涵煦
2023-03-14

我是java游戏编程的初学者,对于游戏我有一个小小的实际上很大的问题。我试着在敌人和街区之间制造碰撞,但是不起作用,我不知道为什么。它应该工作,但它只是缓慢的游戏每秒一帧,不做任何事情。

我有一个名为Game的主类,带有这个主Init()函数

public void init(){
    WIDTH = getWidth();
    HEIGHT = getHeight();
    tex = new Texture();

    BufferImageLoader loader = new BufferImageLoader();
    level = loader.loadImage("/level.png"); // loading level
    cloud = loader.loadImage("/cloud.png"); // loading clouds

    handler = new Handler();
    cam = new Camera(0,0);
    LoadImageLevel(level);

    this.addKeyListener(new KeyInput(handler));
}

而不是LoadImageLevel函数,其中我读取级别。png逐像素和不同颜色设置每个对象的位置。

private void LoadImageLevel (BufferedImage image){
    int w = image.getWidth();
    int h = image.getHeight();
    //System.out.println(w + " , " + h);

    for(int xx = 0; xx < h; xx++){
        for(int yy = 0; yy < w ; yy++){
            int pixel = image.getRGB(xx, yy);
            int red = (pixel >> 16) & 0xff;
            int green = (pixel >> 8) & 0xff;
            int blue = (pixel) & 0xff;

            if(red == 255 && green == 255 && blue == 255) 
                handler.addObject(new Block(xx*32,yy*32,1,ObjectId.Block));
            if(red == 0 && green == 0 && blue == 255) 
                handler.addObject(new Player(xx*32,yy*32,1,handler,ObjectId.Player));
            if(red == 0 && green == 255 && blue == 0) 
                handler.addObject(new Enemy(xx*32,yy*32,handler,ObjectId.Enemy));
        }
    }

}

在类中,Player是两个重要的函数,其中在刻度中称为勾结。

public class Player extends GameObject{

private float width = 32, // 48
        height = 64; // 96

private float gravity = 0.5f;
private final float MAX_SPEED = 10; 
private int facing = 1;
private int last = 0; // last position left or right
private Handler handler;

Texture tex = Game.getInstance();
private int type;

private Animation playerWalk, playerWalkLeft,jump;

public Player(float x, float y,int type , Handler handler ,ObjectId id) {
    super(x, y, id);
    this.handler = handler;
    this.type = type;

    playerWalk = new Animation(2,tex.player[2],tex.player[3],
            tex.player[4],tex.player[5]);
    playerWalkLeft = new Animation(2,tex.player[7],tex.player[8],
            tex.player[9],tex.player[10]);
    jump = new Animation(2,tex.player[11],tex.player[12]);
}

public void tick(LinkedList<GameObject> object) {
    x += velX;
    y += velY;

    if(velX < 0) facing = -1;
    else if(velX > 0) facing = 1;

    if(falling || jumping){
        velY += gravity;

        if(velY > MAX_SPEED){
            velY = MAX_SPEED;
        }
    }
    Collision(object);
    //System.out.println(velX + " " + velY);

    playerWalk.runAnimation();
    playerWalkLeft.runAnimation();
    jump.runAnimation();
}

private void Collision(LinkedList<GameObject> object){
    for(int i = 0; i < handler.object.size();i++){
        GameObject tempObject = handler.object.get(i);
        if(tempObject.getId() == ObjectId.Block ){

            if(getBoundsTop().intersects(tempObject.getBounds())){
                y = tempObject.getY() + 32;
                velY = 0;
            }


            if(getBounds().intersects(tempObject.getBounds())){
                y = tempObject.getY() - height;
                velY = 0;
                falling = false;
                jumping = false;
            }else 
                falling = true;

            if(getBoundsRight().intersects(tempObject.getBounds())){
                x = tempObject.getX() - width;
            }


            if(getBoundsLeft().intersects(tempObject.getBounds())){
                x = tempObject.getX() + 35;
            }
        }

        /* new */

    }

}


public void render(Graphics g) {

    /*
    g.setColor(Color.blue);
    g.fillRect((int)x,(int)y,(int)width,(int)height);

    Graphics2D g2d = (Graphics2D) g;
    g.setColor(Color.red);
    g2d.draw(getBounds());
    g2d.draw(getBoundsRight());
    g2d.draw(getBoundsLeft());
    g2d.draw(getBoundsTop());
    */

    if(velX != 0){
        if (facing == 1){
        playerWalk.drawAnimation(g,(int) x, (int)y,32,64);
        last = 1;
        }
        else{
            playerWalkLeft.drawAnimation(g,(int) x, (int)y,32,64);
            last =  0;
        }   
    }


    else
        if (last == 1)
        g.drawImage(tex.player[1], (int)x,(int) y,32,64,null);
        else
        g.drawImage(tex.player[6], (int)x,(int) y,32,64,null); // 6 ,32,64

    //System.out.println("Y: " + y); // 513 je max
    if (y >= 513){
        g.setColor(Color.red);
        g.drawString("Game Over", (int) x, 200);
    }
}

public Rectangle getBounds() {
    return new Rectangle((int) ((int)x+(width/2)-((width/2)/2)),(int) ((int)y+(height/2)),(int)width/2,(int)height/2);
}

public Rectangle getBoundsTop() {
    return new Rectangle((int) ((int)x+(width/2)-((width/2)/2)),(int)y,(int)width/2,(int)height/2);
}

public Rectangle getBoundsRight() {
    return new Rectangle((int) ((int)x+width-5),(int)y+5,(int)5,(int)height-10);
}
public Rectangle getBoundsLeft() {
    return new Rectangle((int)x,(int)y+5,(int)5,(int)height-10);
}

玩家没有块碰撞的任何问题。

public class Block extends GameObject {

Texture tex = Game.getInstance();
private int type;


public Block(float x, float y,int type,ObjectId id) {
    super(x, y, id);
    this.type = type;
}

public void tick(LinkedList<GameObject> object) {

}

public void render(Graphics g) {
    if(type == 0)
        g.drawImage(tex.block[0], (int) x, (int) y ,null);
    if(type == 1)
        g.drawImage(tex.block[1], (int) x, (int) y ,null);
}


public Rectangle getBounds() {
    return new Rectangle((int)x,(int)y,32,32);
}
}

但是当我试着创造敌人职业,让它和玩家职业一样的时候,我的意思是碰撞只会让游戏变慢。

public class Enemy extends GameObject{

private Handler handler;
public Enemy(float x, float y,Handler handler, ObjectId id) {
    super(x, y, id);
    this.handler = handler;
}

public void tick(LinkedList<GameObject> object) {
    for(int i = 0; i < handler.object.size();i++){
        GameObject tempObject = handler.object.get(i);
        if(tempObject.getId() == ObjectId.Block ){

            if(getBoundsTop().intersects(tempObject.getBounds())){

            }


            if(getBounds().intersects(tempObject.getBounds())){

            }

            if(getBoundsRight().intersects(tempObject.getBounds())){

            }


            if(getBoundsLeft().intersects(tempObject.getBounds())){

            }
        }
    }
}

public void render(Graphics g) {
    g.setColor(Color.red);
    g.fillRect((int)x,(int) y, 32, 32);
}

public Rectangle getBoundsTop() {
    return new Rectangle((int)x,(int)y,32,32);
}

public Rectangle getBoundsLeft() {
    return new Rectangle((int)x,(int)y,32,32);
}

public Rectangle getBoundsRight() {
    return new Rectangle((int)x,(int)y,32,32);
}

public Rectangle getBounds() {
    return new Rectangle((int)x,(int)y,32,32);
}}

我知道边界不应该返回相同的“新矩形”,而且当我设置勾选方法x时,无论如何都没有敌人的任何移动——;只是尝试如果敌人在块边缘停下来,但它不起作用,我不知道它有什么问题,我花了两天多的时间来修复它。如果它可以帮助您,那么整个项目都有一个链接(Eclipse)您可以从dropbox下载它

我只是想有一个左右移动的敌人,并与块碰撞。这意味着,当他从左侧“触碰”块时,他会“转身”并移动到右侧,直到他从右侧“触碰”,等等。玩家和敌人之间的其他碰撞对我来说不是问题。但只是这样。我非常感谢你的建议:)

共有1个答案

阎智
2023-03-14

问题出在你的 getBounds() 方法上。

您在<code>getBounds()方法中说,返回一个宽度为32返回高度和宽度的交集。

换句话说,尽量不要将返回的左上角下限或右边界与自身碰撞。

敌人()中,您正在声明 set.color = 红色,而在加载时,您正在使用绿色。尝试红色==255,绿色==0,蓝色==0而不是if(红色== 0

 类似资料:
  • 我正在用C /SFML制作一个类似超级马里奥的游戏,在试图为马里奥碰撞编写一些代码时,我遇到了一些问题:当角色在沿着水平轴移动的同时与一堆垂直的积木碰撞时,他会卡在积木的一边,就像是在一个看不见的积木上行走一样。我试图修改碰撞功能,就像让马里奥只有在他与块相关的位置包含在块坐标中时,才能与块水平碰撞。 我包含了一些运动代码(keyPree是一个返回按下的键的函数): 以及碰撞函数,其中块类在块精灵

  • 我将保持简短,我正在做一个塔防御游戏作为一个迷你项目,而我有一些空闲时间,我正在试图弄清楚如何我可以实现的塔,以能够射击敌军时,他们进入射程使用dist但我只是不知道如何实现一个方法,使用敌军的位置和塔的位置。我有一个爬行精灵和塔的数组列表 如果有人能给我一些指导,告诉我如何让高塔能够射杀这些怪物,那将是很棒的,即使它不能摆脱它们,只是能够射杀它们也是很棒的。 干杯

  • 我已经和LWJGL一起开发这个游戏几个星期了。自从我增加了跳跃的能力后,向上的碰撞给我带来了很多问题。 这个游戏是一个基于2D瓷砖的侧翻游戏。总的来说,除了玩家跳跃时,碰撞几乎是完美的。起初我想“哦,也许我只需要改变跳跃机制”,但后来我意识到只有当玩家通过某个x坐标时才会发生这种情况。 现在,对于实际问题本身:如果玩家在传递某个x坐标时跳转,他们将通过平铺,并测试顶部碰撞返回false。 这是整个

  • 1. 自我介绍,我的项目都是go后端,加k8s相关。公司技术栈是java 2. 数组和链表区别 3. 深度优先和广度优先 4. java问了一个synchronized关键字修饰普通方法和静态方法的区别,但我太久没用java了,后面就没问了 5. 设计模式,我说学的不是很好 6. 问了kafka,我说没用过,用过其他的消息队列。然后就问为什么要加消息队列这一层,其实这是一个观察者模式,作用就是解耦

  • 我正在尝试制作我的第一个Pacman游戏,但我遇到了一堵我自己似乎无法打破的墙:( 这是关于如何在我的游戏中检测碰撞,所以步行者不能穿过障碍物/墙壁。我已经使它不能去屏幕外与此代码: ,但如果我在屏幕中间的电路板上有一个矩形,我不知道如何编程,这样它就会在墙前停止。 我需要阻止我的pacman移动到竞技场内的墙上,如你所见(左上方的矩形) 我的Board类代码: 希望有人能告诉我该怎么做...似乎

  • 没多久,绝影干脆在学校外面租了房子自己搬了出去。 超薄早在上上学期就在外面租了房子,本来超薄话不多,看起来又热爱学习,大家都以为他是个老实人,根本没想到他居然是寝室第一个谈恋爱的,更没想到他居然会租房子同居。上学期王江也出去租了房子,他有足够的理由:要搞音乐,搞乐队,还要搞平面设计,比如搞音乐的搞设计的标志是什么?当然是有一家属于自己的工作室。――所以租间房子作工作室是很让人信服的。 绝影也想出去