第一篇文章,所以我会尽量保持清晰。 基本上,我想要做的是创建一个小游戏,你有一艘船,你可以从它射击子弹。船使用切线公式相应地旋转到玩家的DeltaX和DeltaY。我使用的是标准的游戏循环像这样的:一个对象中的图形正在影响另一个对象的图形 - JAVA
public void run() {
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000/amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
@SuppressWarnings("unused")
int frames = 0;
while(running){
long now = System.nanoTime();
delta += (now - lastTime)/ns;
lastTime = now;
while(delta >=1){
tick();
delta--;
}
if(running)
repaint();
frames++;
if(System.currentTimeMillis() - timer > 1000)
{
timer += 1000;
frames = 0;
}
}
stop();
}
我的“游戏”运行在一个JPanel,一个名为董事会类的子类。在循环中,我调用更新信息的方法tick()和repaint(),该方法用作渲染方法。这是我的paintComponent(Graphics g)方法:
public void paintComponent(Graphics g) {
//This is for background
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
g2d.fill(new Rectangle(0, 0, Constants.width, Constants.height));
//This is where actual game rendering occurs
handler.render(g);
g.dispose();
}
可以看出,我没有渲染我的Board类中的所有东西。我对我的处理程序这样做。这是我如何处理处理程序:
public void render(Graphics g) {
for (int i = 0; i < handlerList.size(); i++) {
//handlerList is a LinkedList
handlerList.get(i).render(g);
}
}
LinkedList handlerList包含实体。 实体是一个抽象类,它是玩家和子弹的父亲的生物的父亲。 这是一个播放器实例的渲染代码:其跟踪的对象条件
public void render(Graphics g) {
float centerX = x + (width/2);
float centerY = y + (height/2);
double theta = findAngle(deltaX, deltaY);
Graphics2D g2d = (Graphics2D) g;
if(!stopped) g2d.rotate(theta, centerX, centerY);
else g2d.rotate(stoppedTheta, centerX, centerY);
g2d.drawImage(shipImage, (int)x, (int)y, (int)width, (int)height, null);
}
有一个布尔“停止”。由于我希望能够旋转我的飞船,因此我使用Graphics2D而不是Graphics。
下面是子弹的渲染代码:
public void render(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.yellow);
g2d.fillOval((int)x, (int)y, (int)width, (int)height);
}
它看起来正确的,据我所知。每当我没有子弹,游戏运行良好,你可以看到在this GIF: 免责声明:抱歉低质量和水印,我刚格式化电脑,没有时间安装适当的东西。 ...
当我添加一颗子弹this发生:
x和子弹不会改变的y位置,但子弹与船舶旋转。我假设它与滥用“dispose()”方法有关,但我不确定可以采取什么措施来修复它。
预先感谢您。
开始'的Graphics2D G2D =(Graphics2D的)克;''到的Graphics2D G2D =(Graphics2D的)g.create();' - 你不应该调用'在没有创建的上下文中处置 – MadProgrammer
如果修改上下文的转换,则必须撤消该上下文,方法是创建上下文的快照并在完成上下文处理时进行处理,或手动对其进行处理并记住,转换正在复合 – MadProgrammer
作为一般技巧,我会在它返回之前每次调用'render'方法和'g2d.dispose()'之前调用'Graphics2D g2d =(Graphics2D)g',因为我不相信其他的人们可能会这样做;) - 这意味着每个对象将获得它自己的'Graphics'上下文的快照 – MadProgrammer