JFrame向帧顶部添加22像素偏移量(java.awt.Insets)
我正在创建一个简单的爆发式游戏。主游戏扩展了JFrame,我在框架中添加了一个JPanel 当我使用paint()绘制游戏图形时,项目按预期放置在窗口内(即通过其x,y坐标) 我已经更新了代码以使用BufferStrategy,因为我正在闪烁。由于,渲染的图形偏移了22px 这意味着砖块离开了屏幕的顶部 代码如下:JFrame向帧顶部添加22像素偏移量(java.awt.Insets),java,swing,jframe,jpanel,awt,Java,Swing,Jframe,Jpanel,Awt,我正在创建一个简单的爆发式游戏。主游戏扩展了JFrame,我在框架中添加了一个JPanel 当我使用paint()绘制游戏图形时,项目按预期放置在窗口内(即通过其x,y坐标) 我已经更新了代码以使用BufferStrategy,因为我正在闪烁。由于,渲染的图形偏移了22px 这意味着砖块离开了屏幕的顶部 代码如下: package BreakOut; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent
package BreakOut;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
public class Game extends JPanel implements KeyListener{
GameStateManager gsm = new GameStateManager();
BufferStrategy strategy;
public Game() {
//add menu state to GameStateManager
gsm.add(new MenuState(gsm));
createFrame();
while(true)
{
gsm.update();
//repaint();
render();
try{
Thread.sleep(10);
}
catch(InterruptedException e)
{
}
}
}
public void createFrame()
{
JFrame frame = new JFrame("Mini Tennis");
frame.setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(400,400));
frame.add(this);
frame.pack();
frame.setBackground(Color.BLACK);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(this);
this.setFocusable(true);
frame.createBufferStrategy(2);
strategy = frame.getBufferStrategy();
frame.setVisible(true);
System.out.println(frame.getInsets());
}
public void render()
{
Graphics g = strategy.getDrawGraphics();
super.paint(g);
gsm.render(g);
g.dispose();
strategy.show();
}
public void keyPressed(KeyEvent k) {
switch(gsm.getState())
{
case MAIN_MENU:
if(k.getKeyCode()==KeyEvent.VK_ENTER)
{
//add the PlayState to the Stack and update enum value
gsm.add(new PlayState(gsm, this));
}
break;
case PLAYING:
if(k.getKeyCode()==KeyEvent.VK_P)
{
//add the PlayState to the Stack and update enum value
gsm.add(new PauseState(gsm));
}
break;
case PAUSE:
if(k.getKeyCode()==KeyEvent.VK_P)
{
gsm.pop();
}
break;
case GAME_OVER:
if(k.getKeyCode()==KeyEvent.VK_ENTER)
{
gsm.pop();
}
break;
}
//send input to GameStateManager
gsm.keyPressed(k.getKeyCode());
}
public void keyReleased(KeyEvent k) {
gsm.keyReleased(k.getKeyCode());
}
public void keyTyped(KeyEvent k) {
gsm.keyTyped(k.getKeyCode());
}
public static void main(String[] args) {
new Game();
}
}
当我输出System.out.println(frame.getInsets())时;我明白了
我显然做错了什么,但不明白为什么添加BufferStrategy会使JPanel被22px抵消
任何帮助都将不胜感激:)从您使用MacOS的外观来看,框架有边框和装饰,这些边框和装饰包含在框架的边界内(它们不会添加到外部),顶部的22像素是窗口标题 最好的解决方案是,不要使用帧作为渲染曲面,而是使用
游戏
类。这意味着它需要从java.awt.Canvas
扩展,而不是从javax.swing.JPanel
扩展,您需要从它创建BufferStrategy
如果您覆盖Canvas
的getPreferredSize
方法,您可以在框架上使用pack
,它将围绕此框架打包窗口,因此物理框架将比内容大,但内容将是您喜欢的大小
您还需要将主/游戏循环移动到单独的线程,因为这是当前阻止事件调度线程的风险,这可能会导致您无休止的问题(例如从未获得关键事件)太好了,谢谢:)线程是我列表中的下一个事项。在游戏循环中使用线程的最佳方法是什么?我会实现Runnable吗?通常,是的,通常建议使用
Runnable
,并将其传递给线程的实例(通过其构造函数)。请记住,Swing不是线程安全的,但由于您使用的是缓冲策略
,这不应该成为问题,因为缓冲策略
和Swing组件不能很好地配合使用。再次感谢:)因此,对于游戏,您通常会使用画布渲染游戏图形吗?像libgdx这样的游戏库是否有自己创建窗口和绘制屏幕的方法,或者是否使用Swing和AWT?游戏工具包可能依赖于画布和缓冲策略,或者提供自己的本地对等方,这些对等方将连接到画布,具体取决于那里实现
java.awt.Insets[top=22,left=0,bottom=0,right=0]