【问题标题】:Resetting animation to adjusted position after Timer has expired计时器到期后将动画重置到调整后的位置
【发布时间】: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


【解决方案1】:

我发现通过在我的 LaserCanon 类中添加 moveLeft() 和 moveRight() 方法,我的射弹类将随佳能移动,而不是依赖于大炮移动。

【讨论】:

    猜你喜欢
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 2018-01-24
    • 2020-10-31
    • 1970-01-01
    相关资源
    最近更新 更多