【发布时间】:2016-02-10 21:02:38
【问题描述】:
我正在重建游戏太空入侵者,并且已经达到发射弹丸的地步。我一直在成功使用 KeyListener 类,这样当按下空格键时,我的弹丸就会开火。问题是它只在发射后更新它的位置,所以它从激光炮最后放置的位置而不是当前位置发射。
我的激光佳能课程
/*
*The properties and behaviors of the laser canon
*/
package spaceinvaders;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Polygon;
public class LaserCanon extends GameObject{
private int pnlWidth;//GamePanel width
private int pnlHeight;//GamePanel height
private final int moveInc = 15;//number of pixels moved when when arrow key is pressed
//Constructor
public LaserCanon(int pnlWidth, int pnlHeight){
super();
this.pnlWidth = pnlWidth;
this.pnlHeight = pnlHeight;
getLocation().x=pnlWidth;//sets initial location of canon
getLocation().y=pnlHeight;//sets intial location of canon
setColor(Color.green);//canon is green
setVisible(true);
}
public LaserCanon(){
super();
}
//draws laser canon using GamePanel height and width
@Override
public void draw(Graphics g){
g.setColor(this.getColor());
Polygon triangle = new Polygon();//canon is in shape of triangle
triangle.addPoint(getLocation().x, getLocation().y);//bottom right point
triangle.addPoint(getLocation().x-100, getLocation().y);//bottom right point
triangle.addPoint(getLocation().x-50, getLocation().y-75);//top point
g.fillPolygon(triangle);
}
//returns each property in a string
@Override
public String toString(){
String string = super.toString();
string = getPnlWidth() + "|" + getPnlHeight() + "|" + getMoveInc();
return string;
}
//moves canon left
public void moveLeft(){
if(getLocation().getX()>50){
System.out.println("Left key pressed\n" + getLocation().getX());
getLocation().x-=moveInc;
}
}
//moves canon right
public void moveRight(){
if(getLocation().getX()<pnlWidth){
System.out.println("Right key pressed\n" + getLocation().getX());
getLocation().x+=moveInc;
}
}
//accessor and mutator methods
我的射弹类
public class Projectile extends GameObject{
private int speed;//speed at which the projectile moves
private int locX;
private int locY;
private GamePanel gamePanel;
//constructor
public Projectile(int speed, GamePanel gp){
super();
this.speed = speed;
gamePanel = gp;
//sets location of projectile to same location as canon Starting at top point
this.locX = gamePanel.getLaserCanon().getLocation().x-50;
this.locY = gamePanel.getLaserCanon().getLocation().y-75;
setColor(Color.cyan);//projectile is cyan
setVisible(false);//not visible to start
}
public Projectile(){
super();
}
@Override
public void draw(Graphics g){
if(isVisible())
g.setColor(this.getColor());
else
g.setColor(Color.black);
Polygon triangle1 = new Polygon();
triangle1.addPoint(getLocX()-5, getLocY());//bottom left point
triangle1.addPoint(getLocX()+5, getLocY());//bottom right point
triangle1.addPoint(getLocX(), getLocY()-15);//top middle point
Polygon triangle2 = new Polygon();
triangle2.addPoint(getLocX(), getLocY()+3);//bottom middle point
triangle2.addPoint(getLocX()-5, getLocY()-10);//bottom left point
triangle2.addPoint(getLocX()+5, getLocY()-10);//bottom right point
g.fillPolygon(triangle1);
g.fillPolygon(triangle2);
}
public int move(){
setLocY(getLocY() - getSpeed());
return getLocY();
}
//accessor and mutators
而我的游戏面板类分别容纳前者:
package spaceinvaders;
import java.awt.Color;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import java.util.ArrayList;
import javax.swing.Timer;
import javax.swing.BorderFactory;
import java.awt.Graphics;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class GamePanel extends JPanel implements KeyListener{();
private LaserCanon laserCanon;
private Projectile projectile;
private Timer projectileTimer;//used to animate the projectile fired from LaserCanon
//constructor
public GamePanel(){
setSize(800,800);//size of panel
setBackground(Color.BLACK);//background
setBorder(BorderFactory.createLineBorder(Color.red, 3));//border
laserCanon = new LaserCanon(getWidth(), getHeight());
projectile = new Projectile(20,this);
projectileTimer = new Timer(50, new TimerListener());
//instantiate other GameObjects
//gives focus to this panel for KeyListener
this.setFocusable(true);
this.requestFocus();
this.addKeyListener(this);
repaint();
}
@Override
public void keyPressed(KeyEvent k){
int key = k.getKeyCode();
if(key == k.VK_LEFT){//if left arrow is pressed
getLaserCanon().moveLeft();
repaint();
}
else if(key == k.VK_RIGHT){//if right arrow is pressed
getLaserCanon().moveRight();
repaint();
}
else if(key == k.VK_SPACE){
System.out.println("fired!");
getProjectile().setVisible(true);
getProjectileTimer().start();
}
}
@Override
public void keyReleased(KeyEvent k){
//dummy method
}
@Override
public void keyTyped(KeyEvent k){
//dummy method
}
private class TimerListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
if(getProjectile().move()>-15){
repaint();
}
else{
getProjectileTimer().stop();
getProjectile().setVisible(false);
projectile.setLocX(laserCanon.getLocation().x-50);
projectile.setLocY(laserCanon.getLocation().y-75);
repaint();
}
}
}
//used to call draw methods
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
getLaserCanon().draw(g);
getProjectile().draw(g);
}
放置后
projectile.setLocX(laserCanon.getLocation().x-50);
projectile.setLocY(laserCanon.getLocation().y-75);
在我的 TimerListener 类中检测到弹丸不再出现在屏幕上后,我意识到我需要在其他地方使用另一组这些方法并且一直在使用它,但我似乎无法弄清楚在哪里。我将它们放置在其他任何地方都可以解决位置问题,但我会丢失动画。 基本上,无论我的激光炮走到哪里,我都需要我的弹丸跟随并从激光炮的位置发射。我怎样才能做到这一点?
旁注:有一个抽象类 GameObject 保存我的射弹和激光炮的可见性、位置(使用 Point 类)和颜色。
【问题讨论】:
-
1) M-V-C
-
大炮发射时弹丸的位置如何设置?
-
@MadProgrammer 弹丸设置为放置在卡农的初始位置。因此,即使我在第一次发射前移动了卡农,弹丸也会从初始位置发射
标签: java animation timer keylistener paintcomponent