- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在制作小行星游戏。一切功能都正常工作,但最初我将背景颜色设置为黑色,并用在 Canvas
上移动的形状表示对象。此后,我将背景更改为Image
,并正在努力更改由图像表示的对象。
但是,无论背景如何,我都无法在新位置重新绘制图像。您可以看到每个对象移动到每个新位置后的路径。我主要关注的是射击,我注意到如果我在屏幕周围射击,背景就会刷新,但它看起来几乎是完全随机的。如果有人可以帮助引导我朝正确的方向前进,那就太好了!我阅读了一些文档、教科书,并观看了一些视频来试图理解。
package comets;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.sound.sampled.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
import java.net.URL;
// This class is primarily responsible for organizing the game of Comets
public class CometsMain extends JPanel implements KeyListener
{
// GUI Data
private JFrame frame; // The window itself
private JPanel playArea; // The area where the game takes place
private final int playWidth = 500; // The width of the play area (in pixels)
private final int playHeight = 500; // The height of the play area (in pixels)
// Game Data
private SpaceObject spaceObject;
private Ship ship; // The ship in play
private Shot s = new Shot(0, 0, 0, 0);
private LargeComet large = new LargeComet(0, 0, 0, 0);
private MediumComet medium = new MediumComet(0, 0, 0, 0);
private SmallComet small = new SmallComet(0, 0, 0, 0);
private Vector<Shot> shots; // The shots fired by the player
private Vector<Comet> comets; // The comets floating around
private boolean shipDead; // Whether or not the ship has been blown up
private long shipTimeOfDeath; // The time at which the ship blew up
// Keyboard data
// Indicates whether the player is currently holding the accelerate, turn
// left, or turn right buttons, respectively
private boolean accelerateHeld = false;
private boolean turnLeftHeld = false;
private boolean turnRightHeld = false;
private boolean slowDownHeld = false;
// Indicates whether the player struck the fire key
private boolean firing = false;
// Create Images
private Image background; // background image
private BufferedImage spaceShip = null;
private BufferedImage largeComet = null;
private BufferedImage mediumComet = null;
private BufferedImage smallComet = null;
private BufferedImage bullet = null;
private int type = AlphaComposite.SRC_OVER;
private float alpha = 0;
// Set up the game and play!
public CometsMain()
{
// Get everything set up
configureGUI();
configureGameData();
// Display the window so play can begin
frame.setVisible(true);
//Use double buffering
frame.createBufferStrategy(2);
//play music
playMusic();
// Start the gameplay
playGame();
}
private void playMusic(){
try {
URL url = this.getClass().getClassLoader().getResource("BackgroundMusic.wav");
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
Clip clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
clip.loop(5);
} catch (Exception e) {
e.printStackTrace();
}
}
// Set up the initial positions of all space objects
private void configureGameData()
{
// Configure the play area size
SpaceObject.playfieldWidth = playWidth;
SpaceObject.playfieldHeight = playHeight;
// Create the ship
ship = new Ship(playWidth/2, playHeight/2, 0, 0);
// Create the shot vector (initially, there shouldn't be any shots on the screen)
shots = new Vector<Shot>();
// Read the comets from comets.cfg
comets = new Vector<Comet>();
try
{
Scanner fin = new Scanner(new File("comets.cfg"));
// Loop through each line of the file to read a comet
while(fin.hasNext())
{
String cometType = fin.next();
double xpos = fin.nextDouble();
double ypos = fin.nextDouble();
double xvel = fin.nextDouble();
double yvel = fin.nextDouble();
if(cometType.equals("Large"))
comets.add(new LargeComet(xpos, ypos, xvel, yvel));
else if(cometType.equals("Medium")){
comets.add(new MediumComet(xpos, ypos, xvel, yvel));
}
else
comets.add(new SmallComet(xpos, ypos, xvel, yvel));
}
}
// If the file could not be read correctly for whatever reason, abort
// the program
catch(FileNotFoundException e)
{
System.err.println("Unable to locate comets.cfg");
System.exit(0);
}
catch(Exception e)
{
System.err.println("comets.cfg is not in a proper format");
System.exit(0);
}
}
// Set up the game window
private void configureGUI()
{
// Load Images & Icons
// Background Image
try {
background = ImageIO.read(this.getClass().getClassLoader().getResource("galaxy.jpg"));
} catch (IOException e) {
}
// Space Ship Image
try {
spaceShip = ImageIO.read(this.getClass().getClassLoader().getResource("ship.png"));
} catch (IOException e) {
}
// Large Comet Image
try {
largeComet = ImageIO.read(this.getClass().getClassLoader().getResource("largecomet.png"));
} catch (IOException e) {
}
// Medium Comet Image
try {
mediumComet = ImageIO.read(this.getClass().getClassLoader().getResource("mediumcomet.png"));
} catch (IOException e) {
}
// Medium Comet Image
try {
smallComet = ImageIO.read(this.getClass().getClassLoader().getResource("smallcomet.png"));
} catch (IOException e) {
}
// bullet Image
try {
bullet = ImageIO.read(this.getClass().getClassLoader().getResource("bullet.png"));
} catch (IOException e) {
}
// Create the window object
frame = new JFrame("Comets");
frame.setSize(playWidth+20, playHeight+35);
frame.setResizable(false);
// The program should end when the window is closed
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(playWidth, playHeight);
// Set the window's layout manager
frame.setLayout(new FlowLayout());
// Create background
JLabel bgLabel = new JLabel( new ImageIcon(background.getScaledInstance(playWidth, playHeight, 0) ) );
bgLabel.setSize(playWidth, playHeight);
frame.setContentPane(bgLabel);
frame.pack();
// Create the play area
playArea = new JPanel();
playArea.setSize(playWidth, playHeight);
playArea.setFocusable(false);
playArea.setOpaque(false);
frame.add(playArea);
// Make the frame listen to keystrokes
frame.addKeyListener(this);
}
// The main game loop. This method coordinates everything that happens in
// the game
private void playGame()
{
while(true)
{
// Measure the current time in an effort to keep up a consistent
// frame rate
long time = System.currentTimeMillis();
// If the ship has been dead for more than 3 seconds, revive it
if(shipDead && shipTimeOfDeath + 3000 < time)
{
shipDead = false;
ship = new Ship(playWidth/2, playHeight/2, 0, 0);
}
// Process game events, move all the objects floating around,
// and update the display
if(!shipDead)
handleKeyEntries();
handleCollisions();
moveSpaceObjects();
// Sleep until it's time to draw the next frame
// (i.e. 32 ms after this frame started processing)
try
{
long delay = Math.max(0, 32-(System.currentTimeMillis()-time));
Thread.sleep(delay);
}
catch(InterruptedException e)
{
}
}
}
// Deal with objects hitting each other
private void handleCollisions()
{
// Anything that is destroyed should be erased, so get ready
// to erase stuff
Graphics g = playArea.getGraphics();
Graphics2D g2d = (Graphics2D) g;
g2d.setComposite(AlphaComposite.getInstance(type, alpha));
// Deal with shots blowing up comets
for(int i = 0; i < shots.size(); i++)
{
Shot s = shots.elementAt(i);
for(int j = 0; j < comets.size(); j++)
{
Comet c = comets.elementAt(j);
// If a shot has hit a comet, destroy both the shot and comet
if(s.overlapping(c))
{
// Erase the bullet
shots.remove(i);
i--;
repaint((int)shots.elementAt(i).getXPosition(), (int)shots.elementAt(i).getYPosition(), (int)(2*shots.elementAt(i).getRadius()), (int)(2*shots.elementAt(i).getRadius()));
// If the comet was actually destroyed, replace the comet
// with the new comets it spawned (if any)
Vector<Comet> newComets = c.explode();
if(newComets != null)
{
paintComponent(g);
comets.remove(j);
j--;
comets.addAll(newComets);
}
break;
}
}
}
// Deal with comets blowing up the ship
if(!shipDead)
{
for(Comet c : comets)
{
// If the ship hit a comet, kill the ship and mark down the time
if(c.overlapping(ship))
{
shipTimeOfDeath = System.currentTimeMillis();
shipDead = true;
spaceObject=ship;
paintComponent(g);
}
}
}
}
// Check which keys have been pressed and respond accordingly
private void handleKeyEntries()
{
// Ship movement keys
if(accelerateHeld)
ship.accelerate();
if(slowDownHeld)
ship.slowDown();
// Shooting the cannon
if(firing)
{
firing = false;
shots.add(ship.fire());
}
}
// Deal with moving all the objects that are floating around
private void moveSpaceObjects()
{
Graphics g = playArea.getGraphics();
// Handle the movements of all objects in the field
if(!shipDead)
updateShip(g);
updateShots(g);
updateComets(g);
}
// Move all comets and draw them to the screen
private void updateComets(Graphics g)
{
for(Comet c : comets)
{
spaceObject=c;
paintComponent(g);
// Move the comet to its new position
c.move();
paintComponent(g);
}
}
// Move all shots and draw them to the screen
private void updateShots(Graphics g)
{
for(int i = 0; i < shots.size(); i++)
{
Shot s = shots.elementAt(i);
// Erase the shot at its old position
paintComponent(g);
// Move the shot to its new position
s.move();
// Remove the shot if it's too old
if(s.getAge() > 180)
{
shots.remove(i);
i--;
}
// Otherwise, draw it at its new position
else
{
moveImage(g, s, (int)s.getXPosition(), (int)s.getYPosition());
paintComponent(g);
}
}
}
// Moves the ship and draws it at its new position
private void updateShip(Graphics g)
{
// Erase the ship at its old position
paintComponent(g);
// Ship rotation must be handled between erasing the ship at its old position
// and drawing it at its new position so that artifacts aren't left on the screen
if(turnLeftHeld)
ship.rotateLeft();
if(turnRightHeld)
ship.rotateRight();
ship.move();
// Draw the ship at its new position
moveImage(g, ship, (int)ship.getXPosition(), (int)ship.getYPosition());
paintComponent(g);
}
// Draws this ship s to the specified graphics context
private void drawShip(Graphics g, Ship s)
{
Graphics2D ship = (Graphics2D) spaceShip.getGraphics();
double x = Math.sin(s.getAngle());
double y = Math.cos(s.getAngle());
AffineTransform transformsave = AffineTransform.getRotateInstance(x, y, spaceShip.getWidth()/2, spaceShip.getHeight()/2);
AffineTransformOp transform = new AffineTransformOp( transformsave, AffineTransformOp.TYPE_BILINEAR );
// Figure out where the ship should be drawn
int xCenter = (int)s.getXPosition();
int yCenter = (int)s.getYPosition();
// Draw the ship body
g.drawImage(transform.filter(spaceShip, null), xCenter-10, yCenter-20, null);
ship.setTransform(transformsave);
}
public void setSpaceObject(SpaceObject s){
spaceObject=s;
}
public SpaceObject getSpaceObject(){
return spaceObject;
}
@Override
protected void paintComponent( Graphics g ){
super.paintComponent(g);
spaceObject=getSpaceObject();
int radius = (int)s.getRadius();
int xCenter = (int)s.getXPosition();
int yCenter = (int)s.getYPosition();
// Draw the object
if(spaceObject==s)
g.drawImage( bullet, xCenter-radius, yCenter-radius, this );
else if(spaceObject==large)
g.drawImage( largeComet, xCenter-radius, yCenter-radius, this );
else if(spaceObject==medium)
g.drawImage( mediumComet, xCenter-radius, yCenter-radius, this );
else if(spaceObject==small)
g.drawImage( smallComet, xCenter-radius, yCenter-radius, this );
else if(spaceObject==ship)
drawShip(g, ship);
}
public void moveImage(Graphics g, SpaceObject s, int x, int y){
int radius = (int)s.getRadius();
int xCenter=0, yCenter=0;
if(xCenter!=x || yCenter!=y){
xCenter= (int)s.getXPosition();
yCenter = (int)s.getYPosition();
repaint(xCenter, yCenter, radius*2, radius*2);
}
}
// Deals with keyboard keys being pressed
public void keyPressed(KeyEvent key)
{
// Mark down which important keys have been pressed
if(key.getKeyCode() == KeyEvent.VK_UP)
this.accelerateHeld = true;
if(key.getKeyCode() == KeyEvent.VK_LEFT)
this.turnLeftHeld = true;
if(key.getKeyCode() == KeyEvent.VK_RIGHT)
this.turnRightHeld = true;
if(key.getKeyCode() == KeyEvent.VK_SPACE)
this.firing = true;
//ADD DOWN TO SLOW DOWN SHIP!!!
if(key.getKeyCode() == KeyEvent.VK_DOWN)
this.slowDownHeld = true;
}
// Deals with keyboard keys being released
public void keyReleased(KeyEvent key)
{
// Mark down which important keys are no longer being pressed
if(key.getKeyCode() == KeyEvent.VK_UP)
this.accelerateHeld = false;
if(key.getKeyCode() == KeyEvent.VK_LEFT)
this.turnLeftHeld = false;
if(key.getKeyCode() == KeyEvent.VK_RIGHT)
this.turnRightHeld = false;
//ADD DOWN TO SLOW DOWN SHIP!!!
if(key.getKeyCode() == KeyEvent.VK_DOWN)
this.slowDownHeld = false;
}
// This method is not actually used, but is required by the KeyListener interface
public void keyTyped(KeyEvent arg0)
{
}
public static void main(String[] args)
{
// A GUI program begins by creating an instance of the GUI
// object. The program is event driven from that point on.
new CometsMain();
}
}
最佳答案
不要使用getGraphics
。问题是,这只是最后绘制的快照。
这就像拿一张纸并在上面反复绘画,很快就会变得一团糟。
getGraphics
还可以返回null
.
在 Swing 中绘画是由 RepaintManager
控制的它决定应该绘制什么以及何时绘制事物。
您应该尝试遵循的基本概念是...
这可以通过几种不同的方式来实现,但首先,如果您想更新 UI,您应该覆盖 paintComponent
从类似 JComponent
扩展的组件的方法.
接到电话时,请调用 super.paintComponent
这将自动准备 Graphics
绘画的背景。
更新 View ...
paintComponent
方法,重新绘制模型这是一种相对简单的方法,但如果控制不好,可能会导致 View 和模型不同步。您还需要确保更新 View 时模型不会更改...
BufferedImages
paintComponent
方法,只需绘制“Activity 屏幕”这是一个更复杂的过程,需要您确保缓冲区的大小与 View 相同,但这意味着模型可以独立于 View 重绘进行更新。仍然存在这样的危险:在绘制 View 时您可能会更改“关闭”和“Activity ”屏幕缓冲区。
您可以通过使用某种队列来稍微提升此过程,在其中放置 BufferedImage
可用于渲染(通过将它们从队列中弹出)并让“ View ”在渲染后再次将它们推回...
或者这些的某种组合,您可以锁定“Activity ”和“关闭”屏幕缓冲区的切换,以确保“Activity ”缓冲区不会被绘制。
看看Performing Custom Painting和Painting in AWT and Swing了解更多详情
例如...
关于java - 将图像移动到新位置后删除图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20292891/
我正在尝试获取从过去的 startposition/location 到当前移动的 currentposition/location 的距离(以米为单位)。 我确实有工作正常的currentposit
所以我有一堆绝对覆盖的 div。用户通过在叠加层上拖动来创建方形 div。如果您要创建一个 div,然后放大和缩小,div 会保持在同一位置,因为它对叠加层是绝对的,如前所述。 然而问题就出在这里。您
我想找到 View 在显示屏幕上的位置。 为此,我使用了 view.getLeft() 、view.getBottom() 、view.getRight() 等方法> , view.getTop()。
我有一个看起来像这样的 View 层次结构(基于其他答案和 Apple 的使用 UIScrollView 的高级 AutoLayout 指南): ScrollView 所需的2 个步骤是: 为 Scr
所以我有一个名为 MARKS 的表,我有这些列 STUDENT_ID, CLASSFORM_NAME, ACADEMIC_YEAR, TERM, SUBJECT_NAME, TOTAL_MARKS
我有一个问题我无法理解,请帮助: 我开发了带有图像的 html 页面,并使用 jQuery UI 帮助使它们可拖动,我将这些图像位置设置为相对位置并给出了左侧和顶部像素,这是页面的链接 http://
我正在尝试创建一个 CSS 动画,它在 sprite 表中循环播放 16 个图像,给人一种幽灵“漂浮”的错觉。动画通过在 background-position 位置之间移动以显示不同状态的幽灵来实现
我正在创建这个网站的 WebView https://nearxt.com/打开时询问位置但是当我使用此链接在 flutter 中创建 webview 时那么它就无法定位我还在应用程序中定义了位置,但
我正在以编程方式创建一个需要跨越 2 个屏幕的窗口。正在创建的窗口的大小是正确的,但窗口大约从第一个屏幕的一半开始。我可以将它拖回第一个屏幕的开头,NSWindow 非常适合。 我只需要知道在窗口的起
位置“/”的匹配叶路由没有元素。这意味着默认情况下它将呈现一个空值,从而导致一个“空”页面 //App.js File import { BrowserRouter as Router, Routes
我有一个运行 Ubuntu 和 Apache 的 VPS 例如,假设地址是:5.5.5.5 在 VPS 上,我有一个名为 eggdrop 的用户(除了我的 root 用户)。 用户 eggdrop 有
我有一个 JLabel与 ImageIcon ,我使用 setIcon() JLabel中的函数. ImageIcon然后上来,坐在我的JLabel 的文字左侧.是否有可能拥有 ImageIcon在文
我的图中有节点,它们的 xlabels 位于它们的左上方。我怎样才能改变这个位置?我希望 xlabels 正好位于节点本身的旁边。 最佳答案 xlp是你想要的属性,但它没有做任何事情。 你不能改变位置
我对基本的 VIM 功能有疑问:(我尝试谷歌搜索但找不到答案) 如何列出所有自定义功能。(我做了 :function 并且不能找到我的自定义函数) 如何获得自定义函数列表中的函数(或它们的存储位置)。
我是 PHP 的新手,虽然我一直在搜索,但我不知道该怎么做。 我知道可以使用 Location("some page") 进行重定向。我还读到,只要没有向用户显示任何内容,它就可以工作。 我想做的是:
如果在 jgrowl.css 中位置更改为“center”,我如何将其覆盖为默认值,即“top-right” $.jGrowl(data, { header: 'data', an
我需要根据用户是否滑动屏幕顶部、屏幕中间或屏幕底部来触发不同的事件。我正在尝试找出最好/最简单的方法来做到这一点,因为我很确定没有办法从 UISwipeGestureRecognizer 获取位置。
我需要枚举用delphi编写的外部应用程序中使用的类 ,因此我需要访问VMT表以获取该信息,但是我找不到任何有关如何在exe(由delphi生成)文件中找到VMT(虚拟方法表)的位置(地址)的文档。
在 D2010 (unicode) 中是否有像 Pos 这样不区分大小写的类似函数? 我知道我可以使用 Pos(AnsiUpperCase(FindString), AnsiUpperCase(Sou
我正在尝试为我的reveal.js 演示文稿制作一个标题,该标题会粘贴在屏幕顶部。标题中的内容在每张幻灯片的基础上都是动态的,因此我必须将标记放在 section 标记中。 显然,如果标记在 sect
我是一名优秀的程序员,十分优秀!