- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在编写一款游戏,你必须躲避障碍并达到目标。根据玩家选择的难度,有许多障碍物以随机角度沿直线移动。如果它们到达屏幕边界,它们会在随机生成点重生(有三个,也是随机创建的)。当您玩一轮时,生成点应保持静止,并在您开始下一轮时在不同位置重新创建。
如果我现在开始游戏,生成点会与障碍物一起移动,在同一生成点生成时,障碍物会分组并使用组合的移动 vector 。
我现在将列出对于识别我的问题很重要的类:
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
}
}
抽象类 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);
}
障碍:
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);
}
}
衍生:
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
移动时更新该引用,所以现在 Obstacle
和 spawn0
具有相同的位置,因此彼此一起移动。
Spawn
应该用它自己的位置来构造(这不应该被共享),Spawn
应该负责 Obstacle< 的生命周期
并根据需要生成新的障碍
(并删除旧的)
关于java - 物体无法正确移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42869034/
我通过 spring ioc 编写了一些 Rest 应用程序。但我无法解决这个问题。这是我的异常(exception): org.springframework.beans.factory.BeanC
我对 TestNG、Spring 框架等完全陌生,我正在尝试使用注释 @Value通过 @Configuration 访问配置文件注释。 我在这里想要实现的目标是让控制台从配置文件中写出“hi”,通过
为此工作了几个小时。我完全被难住了。 这是 CS113 的实验室。 如果用户在程序(二进制计算器)结束时选择继续,我们需要使用 goto 语句来到达程序的顶部。 但是,我们还需要释放所有分配的内存。
我正在尝试使用 ffmpeg 库构建一个小的 C 程序。但是我什至无法使用 avformat_open_input() 打开音频文件设置检查错误代码的函数后,我得到以下输出: Error code:
使用 Spring Initializer 创建一个简单的 Spring boot。我只在可用选项下选择 DevTools。 创建项目后,无需对其进行任何更改,即可正常运行程序。 现在,当我尝试在项目
所以我只是在 Mac OS X 中通过 brew 安装了 qt。但是它无法链接它。当我尝试运行 brew link qt 或 brew link --overwrite qt 我得到以下信息: ton
我在提交和 pull 时遇到了问题:在提交的 IDE 中,我看到: warning not all local changes may be shown due to an error: unable
我跑 man gcc | grep "-L" 我明白了 Usage: grep [OPTION]... PATTERN [FILE]... Try `grep --help' for more inf
我有一段代码,旨在接收任何 URL 并将其从网络上撕下来。到目前为止,它运行良好,直到有人给了它这个 URL: http://www.aspensurgical.com/static/images/a
在过去的 5 个小时里,我一直在尝试在我的服务器上设置 WireGuard,但在完成所有设置后,我无法 ping IP 或解析域。 下面是服务器配置 [Interface] Address = 10.
我正在尝试在 GitLab 中 fork 我的一个私有(private)项目,但是当我按下 fork 按钮时,我会收到以下信息: No available namespaces to fork the
我这里遇到了一些问题。我是 node.js 和 Rest API 的新手,但我正在尝试自学。我制作了 REST API,使用 MongoDB 与我的数据库进行通信,我使用 Postman 来测试我的路
下面的代码在控制台中给出以下消息: Uncaught DOMException: Failed to execute 'appendChild' on 'Node': The new child el
我正在尝试调用一个新端点来显示数据,我意识到在上一组有效的数据中,它在数据周围用一对额外的“[]”括号进行控制台,我认为这就是问题是,而新端点不会以我使用数据的方式产生它! 这是 NgFor 失败的原
我正在尝试将我的 Symfony2 应用程序部署到我的 Azure Web 应用程序,但遇到了一些麻烦。 推送到远程时,我在终端中收到以下消息 remote: Updating branch 'mas
Minikube已启动并正在运行,没有任何错误,但是我无法 curl IP。我在这里遵循:https://docs.traefik.io/user-guide/kubernetes/,似乎没有提到关闭
每当我尝试docker组成任何项目时,都会出现以下错误。 我尝试过有和没有sudo 我在这台机器上只有这个问题。我可以在Mac和Amazon WorkSpace上运行相同的容器。 (myslabs)
我正在尝试 pip install stanza 并收到此消息: ERROR: No matching distribution found for torch>=1.3.0 (from stanza
DNS 解析看起来不错,但我无法 ping 我的服务。可能是什么原因? 来自集群中的另一个 Pod: $ ping backend PING backend.default.svc.cluster.l
我正在使用Hibernate 4 + Spring MVC 4当我开始 Apache Tomcat Server 8我收到此错误: Error creating bean with name 'wel
我是一名优秀的程序员,十分优秀!