在java中以鼠标方向射击抛射物

时间:2014-03-29 17:16:07

标签: java

我正试图向鼠标方向发射射弹,但我遇到了麻烦。 角度是错误的,我的意思是它只会向左或向左上角移动。

这是我发射子弹的Gun课程。

package assets;

import Reaper.Game;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

public class Gun
{
  public ArrayList<Bullet> bullets;
  protected double angle;
  Mouse mouse = new Mouse();
  private BufferedImage image;
  private int centerX = Game.WIDTH / 2;
  private int centerY = Game.HEIGHT;

  public Gun()
  {
    bullets = new ArrayList<Bullet>();
    image = null;

    try
    {
      image = ImageIO.read(new File("assets/gun.png"));
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  public BufferedImage loadImage()
  {
    return image;
  }

  public int getImageWidth()
  {
    return image.getWidth(null);
  }

  public int getImageHeight()
  {
    return image.getHeight(null);
  }

  public void rotate(Graphics g)
  {
    angle = Math.atan2(centerY - mouse.getMouseY(), centerX - mouse.getMouseX()) - Math.PI / 2;

    ((Graphics2D) g).rotate(angle, centerX, centerY);

    g.drawImage(image, Game.WIDTH / 2 - image.getWidth() / 2,
      900 - image.getHeight(), image.getWidth(), image.getHeight(),
      null);
  }

  public Image getImage()
  {
    return image;
  }

  public void update()
  {
    shoot();

    for (int i = 0; i < bullets.size(); i++)
    {
      Bullet b = bullets.get(i);
      b.update();
    }
  }

  public void shoot()
  {
    if (mouse.mouseB == 1)
    {
      double dx = mouse.getMouseX() - Game.WIDTH / 2;
      double dy = mouse.getMouseY() - Game.HEIGHT / 2;
      double dir = Math.atan2(dy, dx);
      bullets.add(new Bullet(Game.WIDTH / 2, Game.HEIGHT / 2, dir));
      mouse.mouseB = -1;
    }
  }

  public void render(Graphics g)
  {
    for (int i = 0; i < bullets.size(); i++)
    {
      bullets.get(i).render(g);
    }

    rotate(g);
  }
}

这是我的Bullet课程:

package assets;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Bullet
{
  private double dx, dy;
  private int x, y;
  private double dir;

  private BufferedImage image;

  public Bullet(int x, int y, double angle)
  {
    this.x = x;
    this.y = y;
    this.dir = angle;

    image = null;
    try
    {
      image = ImageIO.read(new File("assets/bolt.png"));
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }

    dx = Math.cos(dir);
    dy = Math.sin(dir);
  }

  public void update()
  {
    x += dx;
    y += dy;
    System.out.println("dx : " + dx + "  " + dy);
  }

  public void render(Graphics g)
  {
    g.drawImage(image, x, y, image.getWidth(), image.getHeight(), null);
  }

  public BufferedImage getImage()
  {
    return image;
  }
}

这是主要的Game类:

package Reaper;

import Reaper.graphics.Screen;
import assets.Gun;
import assets.Mouse;
import gameState.MenuState;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;

public class Game extends Canvas implements Runnable
{
  private static final long serialVersionUID = 1L;

  public static int WIDTH = 900;
  public static int HEIGHT = 900;

  public static int scale = 3;
  public int frames = 0;
  public int updates = 0;
  private boolean running = false;

  private Thread thread;
  private JFrame frame;

  @SuppressWarnings("unused")
  private Screen screen;
  private Gun gun;
  private MenuState mns;
  private Mouse mouse;

  public Game()
  {
    Dimension size = new Dimension(WIDTH, HEIGHT);
    setPreferredSize(size);

    screen = new Screen(WIDTH, HEIGHT);

    frame = new JFrame();
    gun = new Gun();
    mns = new MenuState();
    mouse = new Mouse();
    addMouseListener(mouse);
    addMouseMotionListener(mouse);
  }

  public static void main(String[] args)
  {
    Game game = new Game();

    game.frame.setResizable(false);
    game.frame.add(game);
    game.frame.pack();
    game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    game.frame.setVisible(true);
    game.frame.setLocationRelativeTo(null);

    game.strat();
  }

  public void strat()
  {
    running = true;
    thread = new Thread(this, "Reaper");
    thread.start();
  }

  public void stop()
  {
    running = false;

    try
    {
      thread.join();
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
  }

  public void run()
  {
    long timer = System.currentTimeMillis();
    long lastTime = System.nanoTime();
    double ns = 1000000000.0 / 60;
    double delta = 0;

    while (running)
    {
      long now = System.nanoTime();

      delta += (now - lastTime) / ns;
      lastTime = now;

      while (delta >= 1)
      {
        update();
        updates++;
        delta--;
      }

      render();
      frames++;

      if (System.currentTimeMillis() - timer > 1000)
      {
        timer = System.currentTimeMillis();

        frame.setTitle("Reaper! " + "  |  " + updates + " ups , " + frames + " fps");
        updates = 0;
        frames = 0;
      }
    }

    stop();
  }

  public void update()
  {
    if (mns.play)
    {
      gun.update();
    }
  }

  public void render()
  {
    BufferStrategy bs = getBufferStrategy();

    if (bs == null)
    {
      createBufferStrategy(3);
      return;
    }

    Graphics g = bs.getDrawGraphics();
    g.fillRect(0, 0, WIDTH, HEIGHT);

    if (mns.menu)
    {
      mns.draw(g);
    }

    if (mns.play)
    {
      g.clearRect(0, 0, WIDTH, HEIGHT);
      g.drawImage(mns.getImage(), 0, 0, mns.getImageWidth(), mns.getImageHeight(), this);
      gun.render(g);
    }

    if (mns.rules)
    {
      g.clearRect(0, 0, WIDTH, HEIGHT);
    }

    bs.show();
  }
}

我知道编码非常糟糕,我会尽可能多地修复它,但我真的很困惑。在网上搜索,尝试了一些解决方案,但它不会工作。我猜我把错误的方法放在错误的位置并且调用它们我做错了。

1 个答案:

答案 0 :(得分:2)

  

我知道编码非常糟糕,我会尽力修复它,...

下次,考虑第一次清理混乱,然后然后提出问题。

(存储getMouseX()getMouseY()返回的值的变量是否真的静态?)

但是,实际问题的主要原因是x类中的yBullet值:

class Bullet
{
  private double dx, dy;
  private int x, y;
  ....

  public void update()
  {
    x += dx;
    y += dy;
    System.out.println("dx : " + dx + "  " + dy);
  }
  ...
}

它们被声明为int值。想象一下update方法中会发生什么,例如x=0dx = 0.75:它会计算0+0.75 = 0.75,将其截断为int值,并且结果将是0

因此,xy值永远不会改变,除非dxdy值分别为>= 1.0

只需将xy的类型更改为double即可解决此问题。您必须相应地在render方法中添加强制转换:

g.drawImage(image, (int)x, (int)y, ...);

但你应该清理它