第一篇文章,所以我會盡量保持清晰。 基本上,我想要做的是創建一個小遊戲,你有一艘船,你可以從它射擊子彈。船使用切線公式相應地旋轉到玩家的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