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

如何确保玩家不穿墙

上官砚文
2023-03-14

我正在编程我的第一个实际2D游戏(吃豆人)。我认为比赛看起来不错,但我有一个大问题--碰撞。对象仍然存在,我被困住了,所以我决定寻求有丰富经验的真正程序员的帮助。(我当然做了一些研究,但我不想做复制粘贴之类的事情,因为我没搞懂)。就像我说的,游戏差不多完成了,我所需要做的就是让帕克曼继续前进。像例子一样,我画大的白色矩形作为平台。我希望有人能帮助我。在这个项目中,我学到了很多东西,碰撞是我理解的东西,但不知道如何正确地编程它。我想我已经快弄明白了,但还是少了点什么。

PS:我在windowbuilder中创建了windows,所以编译可能会有问题:(

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;

public class Main extends JFrame implements ActionListener{
    JPanel contentPane;
    Rectangle packman ;
    Rectangle platform;
    Rectangle secondPlat;

    private int count = 0;
    private int x = 170, y = 50;
    private int xVel = 1, yVel = 1;
    Timer timer;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Main frame = new Main();
        frame.setVisible(true);
    }

    public Main() {
        // TODO Auto-generated constructor stub
        this.setSize(500,500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        getContentPane().setBackground(Color.gray);
        packman = new Rectangle(x,y,50,50);
        platform = new Rectangle(100,70,50,100);
        secondPlat = new Rectangle(220,50,50,100);
        timer = new Timer(0,this);
        timer.start();
        this.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
                // TODO Auto-generated method stub
            }

            @Override
            public void keyReleased(KeyEvent e) {
                // TODO Auto-generated method stub
                switch(e.getKeyCode()) {
                    case 37: //doleva
                    count = 1;  
                    repaint();
                    break;
                case 38: //nahorů       
                    count = 2;  
                    repaint();
                    break;
                case 39://doprava           
                    count = 3;          
                    repaint();
                    break;
                case 40://dolů      
                    count =4;   
                    repaint();
                    break;
                }
            }

            @Override
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub
                System.out.println("Char" + e.getKeyCode());
                System.out.println("Hod" + e.getKeyCode());
            }
        });
    }

    @Override
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
        super.paint(g);
        g.drawRect(x,y,packman.width,packman.height);
        g.setColor(Color.blue);
        g.fillRect(x,y,packman.width,packman.height);

        g.drawRect(platform.x,platform.y,platform.width,platform.height);
        g.setColor(Color.blue);
            
        g.drawRect(secondPlat.x,secondPlat.y,secondPlat.width,secondPlat.height);
        g.setColor(Color.blue);
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub
        if (count == 1) {
            x = x - xVel;
            repaint();
            zkontrolujKolizi();
        }
        
        if (count ==2) {
            y = y - yVel;
            repaint();
            zkontrolujKolizi();
        }
        if (count ==3) {
            x = x + xVel;
            repaint();
            zkontrolujKolizi();
        }
        if (count ==4) {
            y  = y+yVel; 
            repaint();
            zkontrolujKolizi();
        }
    }

    public void zkontrolujKolizi() {
        // TODO Auto-generated method stub
        if (packman.intersects(platform) || packman.intersects(secondPlat)) {
            System.out.println("Got ya!");
        }
    }
}

共有1个答案

饶志
2023-03-14

在您的代码中,您更新了x和y,但这并不是在“packman”对象中完成的,该对象总是位于其初始位置;所以当你检查与墙的交叉点时,包装员总是在(170,50);我同时更改了动画方法以反映packman和paint方法中的变化,以便您使用更新的packman坐标。

动画:

@Override
public void actionPerformed(ActionEvent arg0) {
    // TODO Auto-generated method stub
    if (count == 1) {
        packman.x = packman.x - xVel;
        repaint();
        zkontrolujKolizi();
        
    
    }
    
    if (count ==2) {
        packman.y = packman.y - yVel;
        repaint();
        zkontrolujKolizi();
    }
    if (count ==3) {
        packman.x = packman.x + xVel;
        repaint();
        zkontrolujKolizi();
    }
    if (count ==4) {
        packman.y  = packman.y+yVel; 
        repaint();
        zkontrolujKolizi();
    }
    
    
}

油漆:

@Override
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
        super.paint(g);
        g.drawRect(packman.x,packman.y,packman.width,packman.height);
        g.setColor(Color.blue);
        g.fillRect(packman.x,packman.y,packman.width,packman.height);
        
        g.drawRect(platform.x,platform.y,platform.width,platform.height);
        g.setColor(Color.blue);
        
        g.drawRect(secondPlat.x,secondPlat.y,secondPlat.width,secondPlat.height);
        g.setColor(Color.blue);
        
    }

为避免移动墙壁,计算新位置,检查冲突,如果为真,回滚位置更改:

@Override
public void actionPerformed(ActionEvent arg0) {
    int rollbackX=packman.x;
    int rollbackY=packman.y;

    switch (count) {
    case 1:
        packman.x = packman.x - xVel;
        break;
    case 2:
        packman.y = packman.y - yVel;
        break;
    case 3:
        packman.x = packman.x + xVel;
        break;
    case 4:
        packman.y  = packman.y+yVel;
        break;
    }

    //Collision found, rollback
    if (zkontrolujKolizi()) {
        packman.x=rollbackX;
        packman.y=rollbackY;
    } else {        
        repaint();
    }
}

public boolean zkontrolujKolizi() {
    return packman.intersects(platform) || packman.intersects(secondPlat);
}
 类似资料:
  • 快速笔记。这是我的高级NEA编程项目。有两个主要部分——一个是生成迷宫,用户必须在给定的时间段内通过它,该时间段当前没有实现,第二个部分是用户必须回答教育物理问题以获得最佳分数。问题从本地存储在我的系统上的文本文件中导入。然后,用户的分数和完成日期一起导出到本地文本文件中。 到目前为止,我的程序生成迷宫,用户可以自由移动。教育方面按预期工作。 我该从哪里开始,让墙壁充当物理屏障,而不仅仅是视觉屏障

  • 出于某种原因,我的玩家能够遍历不应该遍历的对象。我使用的是二维布尔数组,如果玩家左边的位置在网格中为真,那么他就不应该移动,右边也是如此。我知道碰撞处理程序正在工作,因为它所做的只是检查左边或右边是否有东西,如果有,它会写player.setCanMove左或右为假,代码在以前的版本中工作。当玩家左边或右边有东西时,我会打印一些东西,这样我就知道碰撞处理程序正在做它的工作。我只是不明白这里发生的是

  • 问题是: 所以我在制作这个2D平台游戏时遇到了一个问题。当玩家跳到一个平台上并离开它时,重力不会影响它,它不会掉下来,直到你再次按下跳跃键,就好像它认为它仍然在地面上,直到你更新他。我已经把问题缩小到重力或碰撞,但找不到问题。有人能帮忙吗?我在下面附上代码。 代码:

  • 问题内容: 我正在制作一个使用Redis存储游戏状态的游戏。它可以很好地跟踪位置和玩家,但是我没有清除闲置玩家的好方法。 每次玩家移动时(这是一种半慢速移动的游戏。以每秒1-5帧的速度思考),我将使用新位置更新哈希值并删除旧的位置键。 跟踪活跃玩家的最佳方法是什么?我想到了以下 为用户设置一些密钥以使其过期。更新每个心跳或动作。问题在于位置存储在哈希中,因此如果用户密钥过期,则播放器仍将位于同一位

  • 我正在尝试在我的Mac系统中安装Maven(Mac OS:High Siera,版本:10.13.3)。 我遵循了本文档中的所有步骤:安装Apache Maven < li >不从链接下载tar文件:apache-maven-3.5.2-bin.tar.gz解压缩到同一目录中 < Li > < code > echo$JAVA _ HOME/Library/JAVA/JavaVirtualMach

  • 我在libgdx中使用tiled。我正在做一个自上而下的rpg,类似于《最终幻想1》、《2》等等。 我使用setX(getX()速度)。x*delta);和setY(getY()速度)。y*delta);在地图上移动玩家。我怎样才能让玩家一块一块地移动呢。我该如何检查玩家在哪个磁贴中?谁能帮帮我吗。谢谢你。 我发现: } 来自:libGDX:如何实现基于平滑瓷砖/网格的游戏角色移动? 但是我似乎可