【发布时间】:2017-07-19 05:44:02
【问题描述】:
第一次发帖,所以我会尽量说清楚。 基本上,我想做的是创造一个小游戏,你有一艘船,你可以从中发射子弹。船使用切线公式根据玩家的 deltaX 和 deltaY 旋转。我使用像这样的标准游戏循环:
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 的一个子类上,即一个名为 Board 的类。在循环中,我调用方法 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 包含实体。 Entities 是一个抽象类,它是 Creature 的父类,Creature 是 Player 和 Bullet 的父类。 这是播放器实例的渲染代码:
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) g;更改为Graphics2D g2d = (Graphics2D) g.create();- 您不应该在不是您创建的上下文中调用dispose -
如果您修改上下文的转换,您必须撤消它,方法是创建上下文的快照并在完成后处理它或手动反转它,请记住,转换是复合
-
作为一般提示,我会在每次调用
render方法之前调用Graphics2D g2d = (Graphics2D) g,并在它返回后调用g2d.dispose(),因为我不相信其他人会用它做什么;) - 这意味着每个对象都将获得它自己的Graphics上下文快照 -
非常感谢!现在可以使用了!
-
如何将其标记为已回答?
标签: java swing graphics concurrency