2014-03-29 56 views
0

我試圖在鼠標方向上發射炮彈,但我遇到了麻煩。 角度是錯誤的,我的意思是它只會左上角或左上角。在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(); 
    } 
} 

我知道這是非常糟糕的編碼,我會嘗試修復它作爲盡我所能,但我真的堅持這一點。在網上搜索,嘗試了一些解決方案,但它不會工作。我想我錯了,把方法放在錯誤的地方,然後打電話給他們。

+0

請將您的代碼簡化爲一個小型自包含的版本,以說明基本問題。很少有人願意爲你瀏覽所有的代碼。 – Dave

+0

我看到的相關代碼(使用'atan2'後面的dx,dy在子彈創建中的計算)看起來很好,所以問題是如何檢測鼠標位置或如何定位子彈。 – Dave

回答

2

我知道這是非常糟糕的編碼,並且我會試圖在盡我所能,解決它......

下一次,考慮第一清理爛攤子,然後問這個問題。

(是否存儲由getMouseX()getMouseY()返回值的變量真正靜態?)

然而,對於實際問題的主要原因是xy值在Bullet類:

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, ...); 

但你真的應該打掃一下