Java 将图像移动到新位置后擦除图像
我正在制作小行星游戏。所有功能都正常工作,但最初我将背景颜色设置为黑色,并将对象表示为在Java 将图像移动到新位置后擦除图像,java,animation,user-interface,sprite,Java,Animation,User Interface,Sprite,我正在制作小行星游戏。所有功能都正常工作,但最初我将背景颜色设置为黑色,并将对象表示为在画布上移动的形状。此后,我将背景更改为图像,并正在努力更改由图像表示的对象 但是,无论背景如何,我都无法在新位置重新绘制图像。将每个对象移动到每个新位置后,可以看到其路径。我主要关注的是射击,我注意到如果我在屏幕周围射击,背景会刷新,但看起来几乎完全是随机的。如果有人能帮我指引正确的方向,那就太好了!我阅读了一些文件、教科书,并观看了一些视频试图理解 package comets; import java
画布上移动的形状。此后,我将背景更改为图像
,并正在努力更改由图像表示的对象
但是,无论背景如何,我都无法在新位置重新绘制图像。将每个对象移动到每个新位置后,可以看到其路径。我主要关注的是射击,我注意到如果我在屏幕周围射击,背景会刷新,但看起来几乎完全是随机的。如果有人能帮我指引正确的方向,那就太好了!我阅读了一些文件、教科书,并观看了一些视频试图理解
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();
}
}
package彗星;
导入java.awt.*;
导入java.awt.event.*;
导入java.awt.geom.AffineTransform;
导入java.awt.image.AffineTransformOp;
导入java.awt.image.buffereImage;
导入javax.imageio.imageio;
导入javax.sound.sampled.*;
导入javax.swing.*;
导入java.util.*;
导入java.io.*;
导入java.net.URL;
//这个班主要负责组织彗星游戏
公共类ComestMain扩展了JPanel实现了KeyListener
{
//图形用户界面数据
private JFrame;//窗口本身
private JPanel playArea;//游戏发生的区域
private final int playWidth=500;//播放区域的宽度(以像素为单位)
private final int playHeight=500;//播放区域的高度(以像素为单位)
//游戏数据
私人空间物体空间物体;
私人船只;//游戏中的船只
私有快照s=新快照(0,0,0,0);
private LargeComet large=新的LargeComet(0,0,0,0);
私有媒体Comet媒体=新媒体Comet(0,0,0,0);
私有SmallComet small=新SmallComet(0,0,0,0);
私有向量射击;//玩家发射的射击
私有向量彗星;//四处漂浮的彗星
private boolean shipDead;//船是否被炸毁
私人长船死亡时间;//船爆炸的时间
//键盘数据
//指示玩家当前是否正在进行加速转弯
//分别按向左、向右或向右按钮
私有布尔加速字段=false;
私有布尔值TurnLeftHold=false;
私有布尔turnRightHold=false;
私有布尔值slowdownhold=false;
//指示玩家是否按了点火键
私有布尔触发=假;
//创建图像
私有图像背景;//背景图像
私有缓冲区图像太空船=null;
private BuffereImage largeComet=null;
private BuffereImage mediumComet=null;
私有缓冲区映像smallComet=null;
private BuffereImage bullet=null;
private int type=AlphaComposite.SRC_OVER;
私有浮动alpha=0;
//设置游戏并开始游戏!
公众舆论
{
//把一切都准备好
configureGUI();
配置游戏数据();
//显示窗口以便开始播放
frame.setVisible(true);
//使用双缓冲
框架策略(2);
//演奏音乐
播放音乐();
//开始游戏
游戏();
}
私人音乐{
试一试{
URL URL=this.getClass().getClassLoader().getResource(“BackgroundMusic.wav”);
AudioInputStream audioIn=AudioSystem.getAudioInputStream(url);
Clip Clip=AudioSystem.getClip();
夹子。打开(音频输入);
clip.start();
卡环(5);
}捕获(例外e){
e、 printStackTrace();
}
}
//设置所有空间对象的初始位置
私有void configureGameData()
{
//配置游戏区大小
SpaceObject.playfieldWidth=播放宽度;
SpaceObject.playfieldHeight=游戏高度;
//创建飞船
船舶=新船舶(游隙宽度/2,游隙高度/2,0,0);
//创建快照向量(最初,屏幕上不应有任何快照)
快照=新向量();
//从comets.cfg读取comets
彗星=新向量();
尝试
{
Scanner fin=新扫描仪(新文件(“comets.cfg”);
//循环文件的每一行以读取comet
while(fin.hasNext())
{
字符串cometType=fin.next();
double xpos=fin.nextDouble();
double ypos=fin.nextDouble();
double xvel=fin.nextDouble();
double yvel=fin.nextDouble();
if(cometType.equals(“大”))
彗星.add(新的大彗星(xpos、ypos、xvel、yvel));
else if(cometType.equals(“Medium”)){
comets.add(新媒体Comet(xpos、ypos、xvel、yvel));
}
其他的
comets.add(新的小型彗星(xpos、ypos、xvel、yvel));
}
}
//如果由于任何原因无法正确读取文件,请中止
//节目
catch(filenotfounde异常)
{
System.err.println(“无法定位comets.cfg”);
系统出口(0);
}
捕获(例外e)
{
System.err.println(“comets.cfg格式不正确”);
系统出口(0);
}
}
//设置游戏窗口
私有void配置GUI()
{
//加载图像和图标
//背景图像
试一试{
background=ImageIO.read(this.getClass().getClassLoader().getResource(“galaxy.jpg”);
}捕获(IOE异常){
}
//太空船图像
试一试{
spaceShip=ImageIO.read(this.getClass().getClassLoader().ge