- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在JFrame中制作游戏,但遇到了问题。我创建了一个对象,该对象由四张图像组成,并被串成一张。我的问题是,如何在JFrame中绘制此对象?
这是代码:
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.*;
public class t4
{
static boolean running;
public static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
public static double width = screenSize.getWidth();
public static double height = screenSize.getHeight();
public static int x = ( 250 );
public static int y = ( 150 );
public static final int sx = (int)width;
public static final int sy = (int)height;
public static void main( String[] args ) throws IOException, InterruptedException
{
Image ur = new ImageIcon("redBlock.gif").getImage();
Image ll = new ImageIcon("redBlock.gif").getImage();
Image ul = new ImageIcon("blueBlock.gif").getImage();
Image lr = new ImageIcon("blueBlock.gif").getImage();
// Create game window...
JFrame app = new JFrame();
app.setIgnoreRepaint( true );
app.setUndecorated( true );
// Add ESC listener to quit...
app.addKeyListener( new KeyAdapter()
{
public void keyPressed( KeyEvent e )
{
if( e.getKeyCode() == KeyEvent.VK_ESCAPE )
running = false;
if((e.getKeyCode()==KeyEvent.VK_LEFT)||(e.getKeyCode()==KeyEvent.VK_KP_LEFT))
x-=10;
if((e.getKeyCode()==KeyEvent.VK_RIGHT)||(e.getKeyCode()==KeyEvent.VK_KP_RIGHT))
x+=10;
if((e.getKeyCode()==KeyEvent.VK_UP)||(e.getKeyCode()==KeyEvent.VK_KP_UP))
y-=10;
if((e.getKeyCode()==KeyEvent.VK_DOWN)||(e.getKeyCode()==KeyEvent.VK_KP_DOWN))
y+=10;
}
});
// Get graphics configuration...
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
// Change to full screen
gd.setFullScreenWindow( app );
if( gd.isDisplayChangeSupported() )
{
gd.setDisplayMode(new DisplayMode( sx, sy, 32, DisplayMode.REFRESH_RATE_UNKNOWN ));
}
// Create BackBuffer...
app.createBufferStrategy( 2 );
BufferStrategy buffer = app.getBufferStrategy();
// Create off-screen drawing surface
BufferedImage bi = gc.createCompatibleImage( sx, sy );
// Objects needed for rendering...
Graphics graphics = null;
Graphics2D g2d = null;
Color background = Color.BLACK;
Random rand = new Random();
// Variables for counting frames per seconds
int fps = 0;
int frames = 0;
long totalTime = 0;
long curTime = System.currentTimeMillis();
long lastTime = curTime;
running = true;
while( running )
{
try
{
// wait(500);
// count Frames per second...
lastTime = curTime;
curTime = System.currentTimeMillis();
totalTime += curTime - lastTime;
if( totalTime > 1000 )
{
totalTime -= 1000;
fps = frames;
frames = 0;
}
++frames;
// clear back buffer...
g2d = bi.createGraphics();
g2d.setColor( background );
g2d.fillRect( 0, 0, sx, sy );
// draw some rectangles...
/* int r = 45;
int g = 232;
int b = 163;
g2d.setColor( new Color(r,g,b) );
int w = ( 250 );
int h = ( 150 );
g2d.fillRect( x+25, y+25, w, h );*/
if(y<775)
{
y++;
}
else
{
y=0;
}
// display frames per second...
g2d.setFont( new Font( "Courier New", Font.PLAIN, 12 ) );
g2d.setColor( Color.GREEN );
g2d.drawString( String.format( "FPS: %s", fps ), 20, 20 );
// Blit image and flip...
graphics = buffer.getDrawGraphics();
graphics.drawImage( bi, 0, 0, null );
graphics.drawImage(ur,x,y,null);
graphics.drawImage(ll,x+50,y+50,null);
graphics.drawImage(ul,x,y+50,null);
graphics.drawImage(lr,x+50,y,null);
if( !buffer.contentsLost() )
buffer.show();
}
finally
{
// release resources
if( graphics != null )
graphics.dispose();
if( g2d != null )
g2d.dispose();
}
}
gd.setFullScreenWindow( null );
System.exit(0);
}
public static void wait(int x) throws InterruptedException
{
Thread.currentThread().sleep(x);
}
}
最佳答案
这是您应该做的:
修改类以使其扩展javax.swing.JComponent
。
覆盖paintComponent(Graphics)
。
创建一个javax.swing.Timer
来管理帧速率。
覆盖getPreferredSize()
。
首先(按照DavidB的要求),我将向您解释为什么您应该执行这些操作,然后再向您展示如何进行。
说明
由于您尝试将组件添加到JFrame,因此需要组件的类与JFrame的add
方法兼容(实际上,它属于Container
,但这无关紧要)。如果您查看the JavaDoc documentation for add
,您会发现它不会仅接受任何Object
;相反,它需要Component
(或其子类)的实例。您可以将Component
而不是JComponent
子类化,但是AWT应用程序中的Component
比Swing应用程序更多。
简而言之:子类JComponent
,以便JFrame.add
将其接受为参数。
子类化JComponent
后,您实际上需要告诉窗口管理器要绘制什么。您可以将绘图代码放在任何地方,但是请记住,除非有人实际调用该方法,否则不会调用(使用)该代码。图形环境调用以开始绘制过程的方法称为paintComponent
*。如果重写此方法,则图形环境将调用您的自定义绘画代码。
简而言之:覆盖paintComponent
,因为这是图形环境所关心的。
由于您最有可能在游戏中制作动画,因此您希望保持恒定的每秒帧数,对不对?如果不这样做,则有很多因素(计算机功率,其他应用程序正在运行,绘制复杂性等)可能会使帧速率陷入困境。为此,您需要每秒以指定次数(每帧一次)调用repaint
方法。这是Swing计时器的重点。您给它一个代码块和一个毫秒数,并且每次经过指定的时间间隔后它将运行该代码。
简而言之:使用Swing计时器,以便可以保持帧速率恒定并受到控制。
假设您有一个文字处理应用程序。它的顶部是菜单栏,中间是文档窗口,底部是工具栏。显然,您希望菜单栏和工具栏较小,并且文档要占用尽可能多的空间,对吗?这就是为什么您需要让每个组件告诉您其大小应为多少(称为首选大小)的原因。覆盖getPreferredSize
允许您返回所需的任意大小,从而控制组件的大小。**
简而言之:覆盖getPreferredSize
,以便窗口管理器和图形环境正确设置所有大小。
*实际上不是paintComponent
被调用;是paint
。但是,paint
方法调用paintComponent
,paintBorder
和paintChildren
:
此方法实际上将绘画工作委托给三个受保护的对象
方法:paintComponent,paintBorder和paintChildren。他们是
以列出的顺序调用,以确保孩子出现在
组件本身。一般而言,组件及其子组件
不应在分配给边框的插图区域上绘画。
子类可以像往常一样仅重写此方法。一个子类
只是想要专门化UI(外观)代表的绘画
方法应该只覆盖paintComponent。
(来源:the JavaDoc)
**覆盖getPreferredSize
并不能真正保证该尺寸是显示组件的尺寸。它仅指定显示它的大小。一些布局管理器将选择忽略此设置(例如BorderLayout)。但是,当您调用pack
正确调整窗口大小时,它应根据该大小计算首选大小。
程序
扩展JComponent
要使类扩展JComponent,只需将类签名更改为此:
import javax.swing.JComponent;
public class MyGameDisplay extends JComponent {
...
}
paintComponent
java.awt.Graphics
类。请参阅以下示例代码以了解如何使用
paintComponent
:
import javax.swing.JComponent;
import java.awt.Graphics;
public class MyGameDisplay extends JComponent {
// Some code here
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // this line is crucial; see below
g.drawString(100,100,"Hello world");
}
}
super.paintComponent
方法中调用
paintComponent
的必要性。这样做的原因是,它将(除其他事项外)清除您先前显示的所有图形。因此,例如,如果您的程序绘制了一个在屏幕上移动的圆,则除非您调用
super.paintComponent
,否则图形的每次迭代还将包含来自先前图形的圆轨迹。
Timer
// Include these imports:
import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MyGameDisplay extends JComponent {
private Timer t;
public MyGameDisplay() {
ActionListener al = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}
t = new Timer(1000 / 30 /* frame rate */, al);
t.start();
}
}
getPreferredSize
getPreferredSize
的原因是,布局管理器将知道如何正确调整容器的大小。
getPreferredSize
。这样做:
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400); // for example
}
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame();
MyGameDisplay mgd = new MyGameDisplay();
frame.add(mgd);
frame.pack();
frame.setVisible(true);
}
}
关于java - 如何将对象添加到JFrames,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10693520/
我创建了一个用户可以添加测试的字段。这一切运行顺利我只希望当用户点击(添加另一个测试)然后上一个(添加另一个测试)删除并且这个显示在新字段中。 所有运行良好的唯一问题是点击(添加另一个字段)之前添加另
String[] option = {"Adlawan", "Angeles", "Arreza", "Benenoso", "Bermas", "Brebant
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我正在努力将 jQuery 滚动功能添加到 nav-tab (Bootstrap 3)。我希望用户能够选择他们想要的选项卡,并在选项卡内容中有一个可以平滑滚动到 anchor 的链接。这是我的代码,可
我正在尝试在用户登录后再添加 2 个 ui 选项卡。首先,我尝试做一个之后。 $('#slideshow').tabs('remove', '4'); $("#slideshow ul li:last
我有一个包含选择元素的表单,我想通过选择添加和删除其中一些元素。这是html代码(这里也有jsfiddle http://jsfiddle.net/txhajy2w/):
正在写这个: view.backgroundColor = UIColor.white.withAlphaComponent(0.9) 等同于: view.backgroundColor = UICo
好的,如果其中有任何信息,我想将这些列添加到一起。所以说我有 账户 1 2 3 . 有 4 个帐户空间,但只有 3 个帐户。我如何创建 java 脚本来添加它。 最佳答案 Live Example H
我想知道是否有一种有效的预制算法来确定一组数字的和/差是否可以等于不同的数字。示例: 5、8、10、2,使用 + 或 - 等于 9。5 - 8 = -3 + 10 = 7 + 2 = 9 如果有一个预
我似乎有一个卡住的 git repo。它卡在所有基本的添加、提交命令上,git push 返回所有内容为最新的。 从其他帖子我已经完成了 git gc 和 git fsck/ 我认为基本的调试步骤是
我的 Oracle SQL 查询如下- Q1- select hca.account_number, hca.attribute3, SUM(rcl.extended_amou
我正在阅读 http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingG
我正在尝试添加一个“加载更多”按钮并限制下面的结果,这样投资组合页面中就不会同时加载 1000 个内容,如下所示:http://typesetdesign.com/portfolio/ 我对 PHP
我遇到这个问题,我添加了 8 个文本框,它工作正常,但是当我添加更多文本框(如 16 个文本框)时,它不会添加最后一个文本框。有人遇到过这个问题吗?提前致谢。 Live Link: JAVASCRIP
add/remove clone first row default not delete 添加/删除克隆第一行默认不删除&并获取正确的SrNo(例如:添加3行并在看到问题后删除SrNo.2)
我编码this ,但删除按钮不起作用。我在控制台中没有任何错误.. var counter = 0; var dataList = document.getElementById('materi
我有一个类似数组的对象: [1:数组[10]、2:数组[2]、3:数组[2]、4:数组[2]、5:数组[3]、6:数组[1]] 我正在尝试删除前两个元素,执行一些操作,然后将它们再次插入到同一位置。
使用的 Delphi 版本:2007 你好, 我有一个 Tecord 数组 TInfo = Record Name : String; Price : Integer; end; var Info
我使用了基本的 gridster 代码,然后我声明了通过按钮添加和删除小部件的函数它工作正常但是当我将调整大小功能添加到上面的代码中时,它都不起作用(我的意思是调整大小,添加和删除小部件) 我的js代
title 323 323 323 title 323 323 323 title 323 323 323 JS $(document).keydown(function(e){
我是一名优秀的程序员,十分优秀!