在计时器到期后将动画重置为调整位置

时间:2015-11-10 03:21:24

标签: java animation timer keylistener paintcomponent

我正在重建游戏太空入侵者并且已经达到射击射弹的程度。我已成功使用KeyListener类,因此当按下空格键时,我的射弹会发射。问题在于它只是在它被触发后才更新它的位置,所以它从最后放置激光正典的位置开始而不是它当前的位置。

我的laserCanon课程

/*
*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 个答案:

答案 0 :(得分:0)

我发现通过添加一个moveLeft()和moveRight()方法,比如我的LaserCanon类中的那些方法,对于我的射弹类,它会随着正规移动,而不是依赖于移动的大炮。