好的,所以我正在尝试创建一个简单的游戏,在该游戏中,您发射导弹,并且如果它撞到了墙,则必须反弹,因为它会灭活导弹以允许我发射新导弹。

import java.awt.*;

public class Project2{
  public static final int PANEL_WIDTH = 300;
  public static final int PANEL_HEIGHT = 300;
  public static final int SLEEP_TIME = 50;
  public static final Color SHOOTER_COLOR = Color.RED;
  public static final Color BACKGROUND_COLOR = Color.WHITE;
  public static final int SHOOTER_SIZE = 20; //diameter of the shooter
  public static final int GUN_SIZE = 10; //length og the gun
  public static final int SHOOTER_POSITION_Y = PANEL_HEIGHT - SHOOTER_SIZE;
  public static final int SHOOTER_INITIAL_POSITION_X = 150;
  public static int shooterPositionX;
  public static int gunPositionX;
  public static int gunPositionY;
  public static int targetPositionX;
  public static final Color TARGET_COLOR = Color.BLUE;
  public static final int TARGET_POSITION_Y = 50;
  public static final int TARGET_SIZE = 20;
  public static final int KEY_SPACE =32;
  public static final int KEY_PAGE_UP = 33;
  public static final int KEY_HOME = 36;
  public static final int KEY_LEFT_ARROW = 37;
  public static final int KEY_UP_ARROW = 38;
  public static final int KEY_RIGHT_ARROW = 39;
  public static final int KEY_DOWN_ARROW = 40;
  public static double missilePositionX;
  public static double missilePositionY;
  public static double missileDeltaX;
  public static double missileDeltaY;
  public static boolean missileActive;
  public static final Color MISSILE_COLOR = Color.BLACK;
  public static final int MISSILE_SIZE =2;
  public static final double MISSILE_SPEED =1.0;
  public static int hitCount;
  public static final int TARGET_DELTA_X= 1;
  public static int targetDeltaX;
//  public static final Random.nextDouble();
  public static void initialize(){
    shooterPositionX = SHOOTER_INITIAL_POSITION_X;
    gunPositionX = 0;
    gunPositionY = GUN_SIZE;
    targetPositionX = 150;
    missileActive = false;
    hitCount = 0;
    targetDeltaX = 0;
  }

  public static void main(String[] args) {
    DrawingPanel panel = new DrawingPanel(PANEL_WIDTH, PANEL_HEIGHT);
    Graphics g = panel.getGraphics( );
    initialize();
    startGame(panel, g);

  }

  public static void drawAll(Graphics g){
    g.setColor(Color.BLACK);
    g.drawString("Project 2 by JR", 10, 15); // fix ""
    g.drawString("Hits: " + hitCount, 10, 30);
//    for(int i=0, i<=hitCount; i++){
//
//    }
    // Hits: followed by a number of stars corresponding to the hit count.
    //Do not do this by calling g.drawString in a loop. Instead, make a single string with a
    //for loop, appending the appropriate number of stars. Then call g.drawString once.
    drawShooter(g, SHOOTER_COLOR);
    drawTarget(g, TARGET_COLOR);

  }

  public static void startGame(DrawingPanel panel, Graphics g) {
    for (int i = 0; i <= 10000; i++) {
      panel.sleep(SLEEP_TIME);
      handleKeys(panel, g);
//      moveTarget(g);
      drawAll(g);
      moveMissile(g);

    }
  }

  public static void drawShooter(Graphics g, Color c){
    g.setColor(c);
    g.fillOval(shooterPositionX-SHOOTER_SIZE/2, SHOOTER_POSITION_Y-SHOOTER_SIZE, SHOOTER_SIZE, SHOOTER_SIZE);
    g.drawLine(shooterPositionX, SHOOTER_POSITION_Y-SHOOTER_SIZE, shooterPositionX+gunPositionX, SHOOTER_POSITION_Y-SHOOTER_SIZE - GUN_SIZE);
  }

  public static void drawTarget(Graphics g, Color c){
    g.setColor(c);
    g.fillOval(targetPositionX-TARGET_SIZE/2, TARGET_POSITION_Y-TARGET_SIZE, TARGET_SIZE, TARGET_SIZE);
    g.drawLine(targetPositionX-TARGET_SIZE, TARGET_POSITION_Y+TARGET_SIZE/2, targetPositionX+TARGET_SIZE, TARGET_POSITION_Y+TARGET_SIZE/2);
  }

  public static void moveShooter(Graphics g, int deltaX){
    drawShooter(g, BACKGROUND_COLOR);
    shooterPositionX += deltaX;
    drawShooter(g, SHOOTER_COLOR);
    //does not allow you to move any part of the shooter off the screen.
  }

  public static void handleKeys(DrawingPanel panel, Graphics g){
    int keyCode = panel.getKeyCode();
    if (keyCode == KEY_SPACE)
      reset(g);
    else if (keyCode == KEY_RIGHT_ARROW)
      moveShooter(g,1);
    else if (keyCode == KEY_LEFT_ARROW)
      moveShooter(g,-1);
    else if (keyCode == KEY_HOME)
      moveGun(g,1);
    else if (keyCode == KEY_PAGE_UP)
      moveGun(g,-1);
    else if(keyCode == KEY_UP_ARROW)
      shootMissile(g);
  }

  public static void reset(Graphics g){
    g.setColor(BACKGROUND_COLOR);
    g.fillRect(0,0, PANEL_WIDTH, PANEL_HEIGHT);
    initialize();
  }

  public static void moveGun(Graphics g, int deltaX){
    drawShooter(g, BACKGROUND_COLOR);
    gunPositionX += deltaX;
    drawShooter(g, SHOOTER_COLOR);
    //Do not let gunPositionX have an absolute value larger than SHOOTER_SIZE.
  }

  public static void shootMissile(Graphics g){
    if(missileActive == false){
      missileActive = true;
      missilePositionX = shooterPositionX;
      missilePositionY = SHOOTER_POSITION_Y-SHOOTER_SIZE;
      missileDeltaX = 0;
      missileDeltaY = 0;
      missilePositionX += missileDeltaX;
      missilePositionY += missileDeltaY;
    }
  }

  public static void moveMissile(Graphics g){
    if(missileActive){
      drawMissile(g, BACKGROUND_COLOR);
      missilePositionX += missileDeltaX;
      missilePositionY += missileDeltaY;
      drawMissile(g, MISSILE_COLOR);
      if(missilePositionY <= 0){
        missileDeltaY = -Math.abs(missileDeltaY);
        missilePositionY += missileDeltaY;
      }
      else if(missilePositionX >= 300){
        missilePositionX += missileDeltaX;
      }
      else if(missilePositionX <=0){
        missileDeltaX = -Math.abs(missileDeltaX);
        missilePositionX += missileDeltaX;
      }
      else if(missilePositionY >= 300){
        drawMissile(g, BACKGROUND_COLOR);
        missileActive = false;
      }
      if( detectHitTarget((int)missilePositionX, (int)missilePositionY, (int)MISSILE_SIZE/2, targetPositionX, TARGET_POSITION_Y, TARGET_SIZE/2)){
        hitCount ++;
        drawMissile(g, BACKGROUND_COLOR);//erase the missile;
        missileActive = false;
      }
    }
  }
  public static void drawMissile(Graphics g, Color c){
    g.setColor(c);
    g.fillOval((int)missilePositionX, (int)missilePositionY, MISSILE_SIZE, MISSILE_SIZE);
    missileDeltaY = - gunPositionY * MISSILE_SPEED;
    missileDeltaX = gunPositionX * MISSILE_SPEED;
  }
  public static boolean detectHitTarget(int x1, int y1, int r1, int x2, int y2, int r2){
     if(Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2)) <= r1 + r2){
      return true;
    }else{
      return false;}
  }
  public static void moveTarget(Graphics g){
//    drawTarget(g, BACKGROUND_COLOR);
//    targetPositionX += targetDeltaX;
//    if(targetPositionX >= 0){
//      targetPositionX = +Math.abs(targetDelta);
//    }
//    else if(targetPositionX <=300){
//      targetPositionX = -Math.abs(targetDelta);
//    }
//    if(Random >= .98){
//      targetDeltaX = 0;
//    }
//    else if(Random >= .96){
//      targetDeltaX =1;
//    }
//    else if(Random >= .94){
//      targetDleta = -1;
//    }
  }
}


到目前为止,球只是被“塞住”到顶壁上,或者甚至在侧壁刚从面板上掉下来的情况下也没有被“塞住”,而不是弹跳起来,我似乎无法弄清楚。

绘图面板

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.ArrayList;

public class DrawingPanel implements ActionListener {
 private static final String versionMessage =
    "Drawing Panel version 1.1, January 25, 2015";
 private static final int DELAY = 100;  // delay between repaints in millis
 private static final boolean PRETTY = false;  // true to anti-alias
 private static boolean showStatus = false;
 private static final int MAX_KEY_BUF_SIZE = 10;

 private int width, height;    // dimensions of window frame
 private JFrame frame;         // overall window frame
 private JPanel panel;         // overall drawing surface
 private BufferedImage image;  // remembers drawing commands
 private Graphics2D g2;        // graphics context for painting
 private JLabel statusBar;     // status bar showing mouse position
 private volatile MouseEvent click;     // stores the last mouse click
 private volatile boolean pressed;      // true if the mouse is pressed
 private volatile MouseEvent move;      // stores the position of the mouse
 private ArrayList<KeyInfo> keys;

 // construct a drawing panel of given width and height enclosed in a window
 public DrawingPanel(int width, int height) {
   this.width = width;
   this.height = height;
   keys = new ArrayList<KeyInfo>();
   image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

   statusBar = new JLabel(" ");
   statusBar.setBorder(BorderFactory.createLineBorder(Color.BLACK));
   statusBar.setText(versionMessage);

   panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
   panel.setBackground(Color.WHITE);
   panel.setPreferredSize(new Dimension(width, height));
   panel.add(new JLabel(new ImageIcon(image)));

   click = null;
   move = null;
   pressed = false;

   // listen to mouse movement
   MouseInputAdapter listener = new MouseInputAdapter() {
     public void mouseMoved(MouseEvent e) {
       pressed = false;
       move = e;
       if (showStatus)
          statusBar.setText("moved (" + e.getX() + ", " + e.getY() + ")");
     }

     public void mousePressed(MouseEvent e) {
       pressed = true;
       move = e;
       if (showStatus)
          statusBar.setText("pressed (" + e.getX() + ", " + e.getY() + ")");
     }

     public void mouseDragged(MouseEvent e) {
       pressed = true;
       move = e;
       if (showStatus)
          statusBar.setText("dragged (" + e.getX() + ", " + e.getY() + ")");
     }

     public void mouseReleased(MouseEvent e) {
       click = e;
       pressed = false;
       if (showStatus)
          statusBar.setText("released (" + e.getX() + ", " + e.getY() + ")");
     }

     public void mouseEntered(MouseEvent e) {
//       System.out.println("mouse entered");
       panel.requestFocus();
     }

   };
   panel.addMouseListener(listener);
   panel.addMouseMotionListener(listener);
   new DrawingPanelKeyListener();

   g2 = (Graphics2D)image.getGraphics();
   g2.setColor(Color.BLACK);
   if (PRETTY) {
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
     g2.setStroke(new BasicStroke(1.1f));
   }

   frame = new JFrame("Drawing Panel");
   frame.setResizable(false);
   try {
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // so that this works in an applet
   } catch (Exception e) {}
   frame.getContentPane().add(panel);
   frame.getContentPane().add(statusBar, "South");
   frame.pack();
   frame.setVisible(true);
   toFront();
   frame.requestFocus();

   // repaint timer so that the screen will update
   new Timer(DELAY, this).start();
 }

 public void showMouseStatus(boolean f) {
   showStatus = f;
 }

 public void addKeyListener(KeyListener listener) {
   panel.addKeyListener(listener);
   panel.requestFocus();
 }

 // used for an internal timer that keeps repainting
 public void actionPerformed(ActionEvent e) {
   panel.repaint();
 }

 // obtain the Graphics object to draw on the panel
 public Graphics2D getGraphics() {
   return g2;
 }

 // set the background color of the drawing panel
 public void setBackground(Color c) {
   panel.setBackground(c);
 }

 // show or hide the drawing panel on the screen
 public void setVisible(boolean visible) {
   frame.setVisible(visible);
 }

 // makes the program pause for the given amount of time,
 // allowing for animation
 public void sleep(int millis) {
   panel.repaint();
   try {
     Thread.sleep(millis);
   } catch (InterruptedException e) {}
 }

 // close the drawing panel
 public void close() {
   frame.dispose();
 }

 // makes drawing panel become the frontmost window on the screen
 public void toFront() {
   frame.toFront();
 }

 // return panel width
 public int getWidth() {
    return width;
 }

 // return panel height
 public int getHeight() {
    return height;
 }

 // return the X position of the mouse or -1
 public int getMouseX() {
   if (move == null) {
     return -1;
   } else {
     return move.getX();
   }
 }

 // return the Y position of the mouse or -1
 public int getMouseY() {
   if (move == null) {
     return -1;
   } else {
     return move.getY();
   }
 }

 // return the X position of the last click or -1
 public int getClickX() {
   if (click == null) {
     return -1;
   } else {
     return click.getX();
   }
 }

 // return the Y position of the last click or -1
 public int getClickY() {
   if (click == null) {
     return -1;
   } else {
     return click.getY();
   }
 }

 // return true if a mouse button is pressed
 public boolean mousePressed() {
   return pressed;
 }

 public synchronized int getKeyCode() {
   if (keys.size() == 0)
     return 0;
   return keys.remove(0).keyCode;
 }

  public synchronized char getKeyChar() {
   if (keys.size() == 0)
     return 0;
   return keys.remove(0).keyChar;
 }

  public synchronized int getKeysSize() {
    return keys.size();
  }

 private synchronized void insertKeyData(char c, int code) {
   keys.add(new KeyInfo(c,code));
   if (keys.size() > MAX_KEY_BUF_SIZE) {
     keys.remove(0);
//     System.out.println("Dropped key");
   }
 }

 private class KeyInfo {
   public int keyCode;
   public char keyChar;

   public KeyInfo(char keyChar, int keyCode) {
     this.keyCode = keyCode;
     this.keyChar = keyChar;
   }
 }

 private class DrawingPanelKeyListener implements KeyListener {

   int repeatCount = 0;

   public DrawingPanelKeyListener() {
     panel.addKeyListener(this);
     panel.requestFocus();
   }

   public void keyPressed(KeyEvent event) {
//     System.out.println("key pressed");
     repeatCount++;
     if ((repeatCount == 1) || (getKeysSize() < 2))
        insertKeyData(event.getKeyChar(),event.getKeyCode());
   }

   public void keyTyped(KeyEvent event) {
   }

   public void keyReleased(KeyEvent event) {
     repeatCount = 0;
   }

 }

}

最佳答案

您每次在drawMissile方法内部调用的moveMissile方法都会重新初始化missileDeltaYmissileDeltaX变量。

missileDeltaY = - gunPositionY * MISSILE_SPEED;
missileDeltaX = gunPositionX * MISSILE_SPEED;


因此,无论在moveMissile方法的其余主体中进行什么计算,这些变量都将采用其默认值,因此,在触及边界时不会改变轨迹。

我对您的方法进行了一些更改,以帮助您找出解决方案,如果您将导弹射向左边界,则看起来它正在工作

射击导弹

public static void shootMissile(Graphics g){
    if(missileActive == false){
        missileActive = true;
        missilePositionX = shooterPositionX;
        missilePositionY = SHOOTER_POSITION_Y-SHOOTER_SIZE;
        missileDeltaX = 0;
        missileDeltaY = 0;
        missilePositionX += missileDeltaX;
        missilePositionY += missileDeltaY;
        missileDeltaY = - gunPositionY * MISSILE_SPEED;
        missileDeltaX = gunPositionX * MISSILE_SPEED;
    }
}


移动导弹

public static void moveMissile(Graphics g){
    if(missileActive){
        drawMissile(g, BACKGROUND_COLOR);
        missilePositionX += missileDeltaX;
        missilePositionY += missileDeltaY;
        drawMissile(g, MISSILE_COLOR);
        if(missilePositionY <= 0){
            missileDeltaY = Math.abs(missileDeltaY);
            missilePositionY += missileDeltaY;
        }
        if(missilePositionX >= 300){
            missilePositionX += -Math.abs(missileDeltaX);
        }
        if(missilePositionX <=0){
            missileDeltaX = Math.abs(missileDeltaX);
            missilePositionX += missileDeltaX;
        }
        if(missilePositionY >= 300){
            drawMissile(g, BACKGROUND_COLOR);
            missileActive = false;
        }
        if( detectHitTarget((int)missilePositionX, (int)missilePositionY, (int)MISSILE_SIZE/2, targetPositionX, TARGET_POSITION_Y, TARGET_SIZE/2)){
            hitCount ++;
            drawMissile(g, BACKGROUND_COLOR);//erase the missile;
            missileActive = false;
        }
    }
}


绘制导弹

public static void drawMissile(Graphics g, Color c){
    g.setColor(c);
    g.fillOval((int)missilePositionX, (int)missilePositionY, MISSILE_SIZE, MISSILE_SIZE);
}

09-26 04:03
查看更多