gpt4 book ai didi

java - 物体无法正确移动

转载 作者:行者123 更新时间:2023-12-02 13:38:29 25 4
gpt4 key购买 nike

我目前正在编写一款游戏,你必须躲避障碍并达到目标。根据玩家选择的难度,有许多障碍物以随机角度沿直线移动。如果它们到达屏幕边界,它们会在随机生成点重生(有三个,也是随机创建的)。当您玩一轮时,生成点应保持静止,并在您开始下一轮时在不同位置重新创建。

如果我现在开始游戏,生成点会与障碍物一起移动,在同一生成点生成时,障碍物会分组并使用组合的移动 vector 。

我现在将列出对于识别我的问题很重要的类:

  1. GamePanel(大部分游戏都发生在这里):

    public class GamePanel extends JPanel
    {
    private JFrame fenster; //Frame for the game
    private final Dimension prefSize=new Dimension(1180, 780); //preferred dimension
    private boolean gameOver=false,roundWin=false; //booleans for round win and game over
    private Timer t; //Timer
    private int c=0,p=0; //counter and points
    private int[][] max; //highscore Array
    private Player player=null; //playable game object
    private Goal goal=null; //the goal to end the round and earn points
    private int schwer=2; //difficulty
    private Obstacle[] obstacles; //obstacles to avoid
    private Spawn spawn0,spawn1,spawn2; //spawn points 1,2 and 3
    private Coordinate cSpawn0,cSpawn1,cSpawn2; //coordinates for the spawn points

    public GamePanel()
    {
    fenster = new JFrame();
    fenster.setTitle("Faster Course");
    fenster.setLocation(50,50);
    fenster.setResizable(false);
    fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    fenster.setVisible(true);
    fenster.setPreferredSize(prefSize);
    fenster.setSize(prefSize.width,prefSize.height);
    //fenster is specified

    JMenuBar Menü = new JMenuBar();
    JMenu file = new JMenu("File");
    JMenu game = new JMenu("Game");
    JMenu pref = new JMenu("Preferences");
    fenster.setJMenuBar(Menü);

    Menü.add(file);
    Menü.add(game);
    Menü.add(pref);
    //Menu for fenster is 'made'

    JMenuItem quit = new JMenuItem("Close");
    file.add(quit);
    quit.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    System.exit(0); //if this button is clicked, the game exits
    }
    });

    JMenuItem diff = new JMenuItem("Difficulty");
    pref.add(diff);
    diff.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    JFrame Schwierigkeit = new JFrame();
    Schwierigkeit.setLayout(null);
    Schwierigkeit.setTitle("Difficulty");
    Schwierigkeit.setLocation(200,200);
    Schwierigkeit.setVisible(true);
    Schwierigkeit.setSize(30,275);
    Schwierigkeit.setResizable(false);

    JButton kLeicht=new JButton("Easy");
    kLeicht.setBounds(20,10,90,25);
    JButton kNormal=new JButton("Normal");
    kNormal.setBounds(20,50,90,25);
    JButton kSchwer=new JButton("Hard");
    kSchwer.setBounds(20,90,90,25);
    JButton kProfi=new JButton("Pro");
    kProfi.setBounds(20,130,90,25);
    JButton kAlbtraum=new JButton("Nightmare");
    kAlbtraum.setBounds(20,170,90,25);
    JButton kQual=new JButton("Torture");
    kQual.setBounds(20,210,90,25);

    Schwierigkeit.add(kLeicht);
    kLeicht.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    Schwierigkeit.dispose();
    changeDiff(1);
    }
    });
    Schwierigkeit.add(kNormal);
    kNormal.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    Schwierigkeit.dispose();
    changeDiff(2);
    }
    });
    Schwierigkeit.add(kSchwer);
    kSchwer.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    Schwierigkeit.dispose();
    changeDiff(3);
    }
    });
    Schwierigkeit.add(kProfi);
    kProfi.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    Schwierigkeit.dispose();
    changeDiff(4);
    }
    });
    Schwierigkeit.add(kAlbtraum);
    kAlbtraum.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    Schwierigkeit.dispose();
    changeDiff(5);
    }
    });
    Schwierigkeit.add(kQual);
    kQual.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    Schwierigkeit.dispose();
    changeDiff(6);
    }
    });
    }
    }); //if difficulty is clicked, a window to choose the difficulty is opened
    //if a difficulty is chosen, the difficulty may be changed
    JMenuItem pause=new JMenuItem("Pause");
    game.add(pause);
    JMenuItem resume=new JMenuItem("Resume");
    game.add(resume);
    pause.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    pause.setEnabled(false);
    resume.setEnabled(true); //if pause is clicked, the game is paused and pause
    pauseGame(); //cannot be clicked anymore but resume now can be
    }
    });
    resume.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent e)
    {
    pause.setEnabled(true);
    resume.setEnabled(false); //if resume is clicked, the game continues and resume
    resumeGame(); //cannot be clicked anymore but pause now can be
    }
    });

    max=new int[5][3];
    //highscores: 5 scores with each points[x][0], rounds[x][1] and difficulty[x][2]

    fenster.add(this);
    fenster.setVisible(true); //now all is placed onto the JFrame
    initGame(); //all objects are initialized
    startGame(); //the game starts
    }

    public boolean isGameOver()
    {
    return gameOver;
    }

    public void setGameOver(boolean gameOver)
    {
    this.gameOver=gameOver;
    }

    public boolean isRoundWin()
    {
    return roundWin;
    }

    public void setRoundWin(boolean roundWin)
    {
    this.roundWin=roundWin;
    }

    public String schwerMax(int i) //to return the words for the difficulty numbers
    {
    if(i==1)
    {
    return "Easy";
    }
    else if(i==2)
    {
    return "Normal";
    }
    else if(i==3)
    {
    return "Hard";
    }
    else if(i==4)
    {
    return "Pro";
    }
    else if(i==5)
    {
    return "Nightmare";
    }
    else if(i==6)
    {
    return "Torture";
    }
    return "-";
    }

    private void initGame ()
    {
    createGameObjects();

    fenster.addKeyListener(new KeyAdapter() //controls and hotkeys
    {
    @Override
    public void keyReleased(KeyEvent e)
    {
    switch(e.getKeyCode())
    {
    case KeyEvent.VK_A:
    case KeyEvent.VK_LEFT:
    player.setAngleLeft(false);
    break;
    case KeyEvent.VK_D:
    case KeyEvent.VK_RIGHT:
    player.setAngleRight(false);

    case KeyEvent.VK_W:
    case KeyEvent.VK_UP:
    player.setAcc(false);
    break;
    case KeyEvent.VK_S:
    case KeyEvent.VK_DOWN:
    player.setDec(false);
    break;
    }
    }

    @Override
    public void keyPressed(KeyEvent e)
    {
    switch(e.getKeyCode())
    {
    case KeyEvent.VK_A:
    case KeyEvent.VK_LEFT:
    player.setAngleLeft(true);
    break;
    case KeyEvent.VK_D:
    case KeyEvent.VK_RIGHT:
    player.setAngleRight(true);
    break;

    case KeyEvent.VK_W:
    case KeyEvent.VK_UP:
    player.setAcc(true);
    break;
    case KeyEvent.VK_S:
    case KeyEvent.VK_DOWN:
    if(player.getMovingDistance()>0)
    {
    player.setDec(true);
    }
    else
    {
    player.setDec(false);
    player.setMovingDistance(-1);
    }
    break;

    case KeyEvent.VK_ESCAPE:
    if(isGameOver()||isRoundWin())
    {
    fenster.dispose();
    }
    if(t.isRunning())
    {
    pauseGame();
    }
    else if(!isGameOver())
    {
    resumeGame();
    }
    break;

    case KeyEvent.VK_E:
    endGame();
    break;

    case KeyEvent.VK_ENTER:
    if(isGameOver())
    {
    restartGame();
    }
    else if(isRoundWin())
    {
    continueGame();
    }
    break;

    case KeyEvent.VK_1:
    changeDiff(1);
    break;
    case KeyEvent.VK_2:
    changeDiff(2);
    break;
    case KeyEvent.VK_3:
    changeDiff(3);
    break;
    case KeyEvent.VK_4:
    changeDiff(4);
    break;
    case KeyEvent.VK_5:
    changeDiff(5);
    break;
    case KeyEvent.VK_6:
    changeDiff(6);
    break;
    }
    }
    });

    t=new Timer(20, new ActionListener() //timer to control the ticks
    {
    @Override
    public void actionPerformed(ActionEvent e)
    {
    doOnTick();
    }
    });
    }

    public void changeDiff(int schwer)
    {
    Object[] restart={"OK","No"}; //game has to be restarted to change the difficulty
    int chosenRestart=JOptionPane.showOptionDialog(fenster,"In order to change the difficulty, the game has to be restarted.\nDo you really want to change the difficulty?","Warning!",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,null,restart,restart[0]);
    if(chosenRestart==0) //if yes is chosen, the difficulty will change and the game restarts
    {
    this.schwer=schwer;
    restartGame();
    }
    }

    private void createGameObjects()
    {
    if(player==null) //if there is no player, there will be a new one
    {
    player=new Player(new Coordinate(900,150),20,Math.toRadians(180),5);
    }

    if(goal==null) //if there is no goal, there will be a new one
    {
    goal=new Goal(new Coordinate(prefSize.width-200,100),80,80);
    }

    initPlayer(); //player is initialized
    initSpawns(); //spawns are initialized
    obstacles=new Obstacle[schwer];
    initObstacles(); //objects are initialized
    }

    private void initPlayer() //player is initialized
    {
    player.setObjectPosition(new Coordinate(40,700));
    player.setMovingAngle(Math.toRadians(-90));
    }

    public void initObstacles() //objects are initialized
    {
    for(int i=0;i<obstacles.length;i++)
    {
    obstacles[i]=new Obstacle(new Coordinate(90,150),70,70,5);
    obstacles[i].setMovingDistance(schwer*2+c);
    obstacleSpawn(i);
    }
    }

    public void obstacleSpawn(int i) //objects spawn at a random spawn
    {
    double zufall=Math.random();
    if(zufall<=0.33)
    {
    obstacles[i].spawn(cSpawn0);
    }
    else if(zufall<=0.67)
    {
    obstacles[i].spawn(cSpawn1);
    }
    else
    {
    obstacles[i].spawn(cSpawn2);
    }
    }

    public void initSpawns() //spawns are initialized
    {
    cSpawn0=new Coordinate((Math.random()*prefSize.width-200)+100,(Math.random()*prefSize.height-200)+100);
    cSpawn1=new Coordinate((Math.random()*prefSize.width-200)+100,(Math.random()*prefSize.height-200)+100);
    cSpawn2=new Coordinate((Math.random()*prefSize.width-200)+100,(Math.random()*prefSize.height-200)+100);

    spawn0=new Spawn();
    spawn1=new Spawn();
    spawn2=new Spawn();
    }

    private void startGame() //timer starts
    {
    t.start();
    }

    public void pauseGame() //timer stops
    {
    t.stop();
    }

    public void resumeGame() //if game is not over, timer starts again
    {
    if(!isGameOver())
    {
    t.start();
    }
    }

    public void continueGame() //if the current round is won, a new one will start
    {
    if(isRoundWin())
    {
    setRoundWin(false);
    player.setMovingDistance(5);
    createGameObjects();
    startGame();
    }
    }

    public void restartGame() //if a round is lost, a new game will start
    {
    setGameOver(false);
    setRoundWin(false);
    c=0;
    p=0;
    player.setMovingDistance(5);
    createGameObjects();
    startGame();
    }

    private void endGame() //game is set to be over
    {
    setGameOver(true);
    pauseGame();
    }

    private void doOnTick() //every tick (controlled by the timer), this will happen:
    {
    if(player.getObjectPosition().getX() <=0||player.getObjectPosition().getX()>=prefSize.width||player.getObjectPosition().getY()<=0||player.getObjectPosition().getY()>=prefSize.height)
    {
    endGame();
    }
    //if a player leaves the window, the game is over

    for(int i=0;i<schwer;i++)
    {
    if(obstacles[i].getObjectPosition().getX() <=0||obstacles[i].getObjectPosition().getX()>=prefSize.width||obstacles[i].getObjectPosition().getY()<=0||obstacles[i].getObjectPosition().getY()>=prefSize.height)
    {
    obstacleSpawn(i);
    }
    //if an obstacle leaves the window, it will respawn

    if(player.touches(obstacles[i])||obstacles[i].touches(player))
    {
    endGame();
    }
    //if the player touches an obstacle, the game is over
    }

    if(player.touches(goal)||goal.touches(player))
    {
    setRoundWin(true);
    pauseGame();
    c=c+1;
    p=(int)(p+(player.getMovingDistance()*schwer));
    }
    //if the player touches the goal, the round is won and the new scores for round and points are
    //calculated

    player.makeMove(); //the player is moved

    for(int i=0;i<schwer;i++)
    {
    obstacles[i].makeMove();
    }
    //all obstacles are moved

    repaint(); //the game is repainted
    }

    @Override
    public void paintComponent(Graphics g)
    {
    super.paintComponent(g); //everything of the original paintComponent is done
    Graphics2D g2d = (Graphics2D) g; //g2d is g
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    //antialiasing is turned on -> Kantenglättung
    setBackground(Color.GRAY); //background is gray

    player.paintMe(g); //player is painted

    for(int i=0;i<schwer;i++)
    {
    obstacles[i].paintMe(g);
    }
    //all obstacles are painted

    spawn0.paintMe(g,cSpawn0);
    spawn1.paintMe(g,cSpawn1);
    spawn2.paintMe(g,cSpawn2);
    //all spawns are painted

    goal.paintMe(g); //goal is painted

    g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,30));
    g.setColor(Color.BLUE);
    g.drawString("Rounds: "+c,prefSize.width-200,30);
    g.setColor(Color.RED);
    g.drawString("Points: "+p,30,30);
    //rounds and points GUI are painted

    if(isGameOver())
    {
    for(int i=0;i<max.length;i++)
    {
    if(p>=max[i][0])
    {
    for(int j=max.length-1;j>i+1;j--)
    {
    max[j][0]=max[j-1][0];
    max[j][1]=max[j-1][1];
    max[j][2]=max[j-1][2];
    }
    max[i][0]=p;
    max[i][1]=c;
    max[i][2]=schwer;
    break;
    }
    }
    //if the game is lost, all highscores are sized

    g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,50));
    g.setColor(Color.RED);
    g.drawString("GAME OVER!",prefSize.width/2-170,prefSize.height/5);
    //the "GAME OVER!" is painted on the screen ...
    g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,20));
    g.setColor(Color.ORANGE);
    g.drawString("Highscores",prefSize.width/2-100,prefSize.height/4);
    for(int i=0;i<max.length;i++)
    {
    g.drawString(max[i][0]+" Points",200,300+30*i);
    g.drawString(max[i][1]+" Rounds",500,300+30*i);
    g.drawString(schwerMax(max[i][2]),700,300+30*i);
    }
    //... and all the highscores
    }
    if(isRoundWin())
    {
    g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,50));
    g.setColor(Color.BLUE);
    g.drawString("ROUND WON!",prefSize.width/2-130,prefSize.height/5);
    } //if the round is won, this is painted on the screen
    }
    }
  2. 抽象类 GameObject(玩家、障碍物和目标是游戏对象;我已经为生成尝试了不同的东西):

    public abstract class GameObject
    {
    private Coordinate objectPosition;
    private double width;
    private double height;
    private double movingAngle;
    private double movingDistance;

    public GameObject(Coordinate objectPosition,double width,double height)
    {
    this.objectPosition=objectPosition;
    this.width=width;
    this.height=height;

    movingAngle=0;
    movingDistance=0;
    }

    public Coordinate getObjectPosition()
    {
    return objectPosition;
    }

    public void setObjectPosition(Coordinate objectPosition)
    {
    this.objectPosition=objectPosition;
    }

    public double getWidth()
    {
    return width;
    }

    public void setWidth(double width)
    {
    this.width=width;
    }

    public double getHeight()
    {
    return height;
    }

    public void setHeight(double height)
    {
    this.height=height;
    }

    public double getMovingAngle()
    {
    return movingAngle;
    }

    public void setMovingAngle(double movingAngle)
    {
    this.movingAngle=movingAngle;
    }

    public double getMovingDistance()
    {
    return movingDistance;
    }

    public void setMovingDistance(double movingDistance)
    {
    this.movingDistance=movingDistance;
    }

    public boolean isLeftOf(GameObject that)
    {
    return this.getObjectPosition().getX()+this.getWidth()<that.getObjectPosition().getX();
    }

    public boolean isAbove(GameObject that)
    {
    return this.getObjectPosition().getY()+this.getHeight()<that.getObjectPosition().getY();
    }

    public boolean touches(GameObject that)
    {
    if(this.isLeftOf(that)) return false;
    if(that.isLeftOf(this)) return false;
    if(this.isAbove(that)) return false;
    if(that.isAbove(this)) return false;

    return true;
    }

    public static Coordinate polarToCartesianCoordinates(double angle)
    {
    double x=Math.cos(angle);
    double y=Math.sin(angle);

    return new Coordinate(x,y);
    }

    public void moveGameObject()
    {
    Coordinate direction=polarToCartesianCoordinates(movingAngle);
    objectPosition.setX(objectPosition.getX()+direction.getX()*movingDistance);
    objectPosition.setY(objectPosition.getY()+direction.getY()*movingDistance);
    }

    public void makeMove()
    {
    moveGameObject();
    }

    protected abstract void paintMe(Graphics g);
    }
  3. 障碍:

    public class Obstacle extends GameObject
    {
    private Shape transformedObstacle=new RoundRectangle2D.Double();

    public Obstacle(Coordinate position,double size,double MovingAngle,double MovingDistance)
    {
    super(position,size,size/3);

    this.setMovingAngle(MovingAngle);
    this.setMovingDistance(MovingDistance);
    }

    public Shape getTransformedObstacle()
    {
    return transformedObstacle;
    }

    public void setTransformedObstacle(Shape transformedObstacle)
    {
    this.transformedObstacle=transformedObstacle;
    }

    public void spawn(Coordinate spawn)
    {
    this.setObjectPosition(spawn);
    this.setMovingAngle(Math.toRadians(Math.random()*360));
    }

    public void paintMe(java.awt.Graphics g)
    {
    Graphics2D g2d=(Graphics2D) g;
    this.paintComponent(g2d);
    }

    public void paintComponent(Graphics2D g2d)
    {
    RoundRectangle2D quader=new RoundRectangle2D.Double(this.getObjectPosition().getX(),this.getObjectPosition().getY(),this.getWidth(),this.getHeight(),5,5);
    g2d.setColor(Color.GREEN);

    AffineTransform transform=new AffineTransform();
    transform.rotate(this.getMovingAngle(),quader.getCenterX(),quader.getCenterY());
    Shape transformed=transform.createTransformedShape(quader);
    g2d.fill(transformed);

    setTransformedObstacle(transformed);
    }
    }
  4. 衍生:

    public class Spawn
    {
    public void paintMe(java.awt.Graphics g,Coordinate position)
    {
    Graphics2D g2d=(Graphics2D) g;
    paintSpawn(g2d,position);
    }

    public void paintSpawn(Graphics2D g2d,Coordinate position)
    {
    RoundRectangle2D spawn=new RoundRectangle2D.Double(position.getX(),position.getY(),50,50,100,100);
    g2d.setColor(Color.DARK_GRAY);

    g2d.fill(spawn);
    }
    }

这里是一段关于障碍物和移动生成点的视频:https://youtu.be/N8Rq3yKblXk

我知道,这是很多代码,但我希望有人可以帮助我找到问题。

.

干杯

林龙

最佳答案

您将 spawn0(坐标)的引用传递给 Obstacle,然后当 Obstacle 移动时更新该引用,所以现在 Obstaclespawn0 具有相同的位置,因此彼此一起移动。

Spawn 应该用它自己的位置来构造(这不应该被共享),Spawn 应该负责 Obstacle< 的生命周期 并根据需要生成新的障碍(并删除旧的)

关于java - 物体无法正确移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42869034/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com