我遇到了MouseEvent getPoint()方法,Math.asin()方法的问题,而且通常只有坐标。我正在尝试创建多个名为" Laser"从" playerRobot"中被解雇。在playerRobot周围创建一个矩形,tempR.getCenterX和tempR.getCenterY用于构建playerRobot位置中心的点。 MouseEvent getPoint()用于获取鼠标相对于焦点组件的位置。在Laser类中,两个名为getPointX(int y)和getPointY(int x)的方法返回一个点,其中x和y值对应于给定的y或x值。即,getPointX(int y)返回带有y及其对应x值的点。这些方法通过找到playerRobot的给定点和鼠标之间的线性方程来做到这一点。然后,激光应该在playerRobot点绘制并重新绘制以跟随其线性方程到鼠标点并继续线性方程直到它到达组件的边界。但是,根据激光器发射的角度,它似乎并不总是如此。此外,有时激光根本不会发射,有时它会以错误的方向或以错误的角度发射,有时它会超过50像素,这总是应该是激光的长度。
TL; DR:激光并不总是从玩家机器人发射并且并不总是沿着直线到达鼠标的点,有时会以错误的方向或以错误的角度发射,有时比50像素。
以下是GameCanvas类中创建新Laser对象的代码,后跟Laser类中的代码:
的GameCanvas:
package application;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.scene.shape.Line;
import javax.swing.*;
public class GameCanvas extends JPanel implements ActionListener, KeyListener, MouseListener {
Timer t = new Timer(5, this);
double x = 0, y = 0, velX = 0, velY = 0;
boolean keyPress = false;
int code = 0;
long time = 1;
int currAIDelete = -1;
int currPlayerDelete = -1;
Graphics gr;
Point mousePoint = new Point();
AffineTransform oldTransform = new AffineTransform();
public GameCanvas() {
t.start();
addKeyListener(this);
addMouseListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
if(GameGUI.startScreen != null) {x = GameGUI.startScreen.imageLocationList.get(4).x; y = GameGUI.startScreen.imageLocationList.get(4).y; velX = 0; velY = 0;}
}
public void paintComponent(Graphics g) {
gr = g;
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if(!GameGUI.getGameOver()) {
if(g2 != null) {
g2.drawImage(new javax.swing.ImageIcon(getClass().getResource(GameGUI.startScreen.imageList.get(7))).getImage(), (int) (x + 0.5), (int) (y + 0.5 + 64), GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(7).width, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(7).height, this);
g2.drawImage(new javax.swing.ImageIcon(getClass().getResource(GameGUI.startScreen.imageList.get(6))).getImage(), (int) (x + 0.5), (int) (y + 0.5 + 16), GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(6).width, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(6).height, this);
g2.drawImage(new javax.swing.ImageIcon(getClass().getResource(GameGUI.startScreen.imageList.get(5))).getImage(), (int) (x + 0.5), (int) (y + 0.5 + 16), GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(5).width, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(5).height, this);
g2.drawImage(new javax.swing.ImageIcon(getClass().getResource(GameGUI.startScreen.imageList.get(4))).getImage(), (int) (x + 0.5), (int) (y + 0.5), GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(4).width, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(4).height, this);
for(int i = 3; i >= 0; i--)
g2.drawImage(new javax.swing.ImageIcon(getClass().getResource(GameGUI.startScreen.imageList.get(i))).getImage(), GameGUI.startScreen.imageLocationList.get(i).x, GameGUI.startScreen.imageLocationList.get(i).y, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(i).width, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(i).height, this);
Color tempColor = g2.getColor();
g2.setColor(tempColor);
GameGUI.startScreen.healthBar();
tempColor = g2.getColor();
GameGUI.startScreen.healthBarGlyphVector = new Font("Tahoma", 0, 11).createGlyphVector(new FontRenderContext(null, true, false), String.valueOf(GameGUI.startScreen.playerHealth));
g2.setColor(GameGUI.startScreen.playerHealthBarColor);
g2.drawGlyphVector(GameGUI.startScreen.healthBarGlyphVector, (int) (x + 40 - GameGUI.startScreen.healthBarGlyphVector.getNumGlyphs() * (double) GameGUI.startScreen.healthBarGlyphVector.getFont().getSize() / 2 + 0.5), (long) (y + 0.5) - 20);
GameGUI.startScreen.playerHealthBar.setLocation((int) (x + 0.5), (int) (y + 0.5) - 10);
g2.draw(GameGUI.startScreen.playerHealthBar);
g2.fill(GameGUI.startScreen.playerHealthBar);
GameGUI.startScreen.healthBarGlyphVector = new Font("Tahoma", 0, 11).createGlyphVector(new FontRenderContext(null, true, false), String.valueOf(GameGUI.startScreen.aiHealth));
g2.setColor(GameGUI.startScreen.aiHealthBarColor);
g2.drawGlyphVector(GameGUI.startScreen.healthBarGlyphVector, (int) (GameGUI.gameResources.getAIRobot().getLocation().get(0).x + 40 - GameGUI.startScreen.healthBarGlyphVector.getNumGlyphs() * (double) GameGUI.startScreen.healthBarGlyphVector.getFont().getSize() / 2 + 0.5), GameGUI.gameResources.getAIRobot().getLocation().get(0).y - 20);
GameGUI.startScreen.aiHealthBar.setLocation(GameGUI.gameResources.getAIRobot().getLocation().get(0).x, GameGUI.gameResources.getAIRobot().getLocation().get(0).y - 10);
g2.draw(GameGUI.startScreen.aiHealthBar);
g2.fill(GameGUI.startScreen.aiHealthBar);
g2.setColor(tempColor);
if(GameGUI.gameResources.playerLaserList != null) {
for(int i = GameGUI.gameResources.playerLaserList.size() - 1; i >= 0; i--) {
tempColor = g2.getColor();
oldTransform = g2.getTransform();
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(10));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawLine((int) (GameGUI.gameResources.playerLaserList.get(i).getCurrentLine().getStartX() + 0.5), (int) (GameGUI.gameResources.playerLaserList.get(i).getCurrentLine().getStartY() + 0.5), (int) (GameGUI.gameResources.playerLaserList.get(i).getCurrentLine().getEndX() + 0.5), (int) (GameGUI.gameResources.playerLaserList.get(i).getCurrentLine().getEndY() + 0.5));
g2.setTransform(oldTransform);
g2.setColor(tempColor);
}
}
if(GameGUI.gameResources.aiLaserList != null) {
for(int i = GameGUI.gameResources.aiLaserList.size() - 1; i >= 0; i--) {
tempColor = g2.getColor();
oldTransform = g2.getTransform();
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(10));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawLine((int) (GameGUI.gameResources.aiLaserList.get(i).getCurrentLine().getStartX() + 0.5), (int) (GameGUI.gameResources.aiLaserList.get(i).getCurrentLine().getStartY() + 0.5), (int) (GameGUI.gameResources.aiLaserList.get(i).getCurrentLine().getEndX() + 0.5), (int) (GameGUI.gameResources.aiLaserList.get(i).getCurrentLine().getEndY() + 0.5));
g2.setTransform(oldTransform);
g2.setColor(tempColor);
}
}
}
}
else try {
if(GameGUI.startScreen.checkGameOver() && GameGUI.startScreen.getGameOverVector() != null) {
g2.drawGlyphVector(GameGUI.startScreen.getGameOverVector(), (int) (380 - GameGUI.startScreen.getGameOverVector().getNumGlyphs() * (double) GameGUI.startScreen.healthBarGlyphVector.getFont().getSize() / 2 + 0.5), 250 - 29);
GameGUI.startScreen.imageList = new ArrayList <String> (Arrays.asList());
}
} catch (GameResourceException ex) {
Logger.getLogger(GameCanvas.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void actionPerformed(ActionEvent e) {
if((code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN || code == KeyEvent.VK_LEFT || code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_W || code == KeyEvent.VK_S || code == KeyEvent.VK_A || code == KeyEvent.VK_D) && keyPress && x >= 0 && x <= 680 && y >= 0 && y <= 400) {
x += velX;
y += velY;
GameGUI.gameResources.getPlayerRobot().setLocation(new Point((int) (x + 0.5), (int) (y + 0.5)), new Point((int) (x + 0.5 + 37), (int) (y + 0.5 + 99)));
}
else {
if(x < 0) x++;
if(x > 680) x--;
if(y < 0) y++;
if(y > 400) y--;
}
if(GameGUI.gameResources.playerLaserList != null) {
for(int i = GameGUI.gameResources.playerLaserList.size() - 1; i >= 0; i--) {
Rectangle tempRectAI = new Rectangle(GameGUI.gameResources.getAIRobot().getLocation().get(0).getLocation().x, GameGUI.gameResources.getAIRobot().getLocation().get(0).getLocation().y, GameGUI.gameResources.getAIRobot().getLocation().get(1).getLocation().x, GameGUI.gameResources.getAIRobot().getLocation().get(1).getLocation().y);
Line line = GameGUI.gameResources.playerLaserList.get(i).getCurrentLine();
if(GameGUI.gameResources.playerLaserList.get(i).getLocation().x + 50 < 0 || GameGUI.gameResources.playerLaserList.get(i).getLocation().x > 762 || GameGUI.gameResources.playerLaserList.get(i).getLocation().y + 50 < 0 || GameGUI.gameResources.playerLaserList.get(i).getLocation().y > 500 || tempRectAI.intersectsLine(line.getStartX(), line.getStartY(), line.getEndX(), line.getEndY()))
GameGUI.gameResources.playerLaserList.remove(i);
else {
GameGUI.gameResources.playerLaserList.get(i).move(time);
}
}
}
if(GameGUI.gameResources.aiLaserList != null) {
for(int i = GameGUI.gameResources.aiLaserList.size() - 1; i >= 0; i--) {
Rectangle tempRectPlayer = new Rectangle(GameGUI.gameResources.getPlayerRobot().getLocation().get(0).getLocation().x, GameGUI.gameResources.getPlayerRobot().getLocation().get(0).getLocation().y, GameGUI.gameResources.getPlayerRobot().getLocation().get(1).getLocation().x, GameGUI.gameResources.getPlayerRobot().getLocation().get(1).getLocation().y);
Line line = GameGUI.gameResources.aiLaserList.get(i).getCurrentLine();
if(GameGUI.gameResources.aiLaserList.get(i).getLocation().x + 50 < 0 || GameGUI.gameResources.aiLaserList.get(i).getLocation().x > 762 || GameGUI.gameResources.aiLaserList.get(i).getLocation().y + 50 < 0 || GameGUI.gameResources.aiLaserList.get(i).getLocation().y > 500 || tempRectPlayer.intersectsLine(line.getStartX(), line.getStartY(), line.getEndX(), line.getEndY()))
GameGUI.gameResources.aiLaserList.remove(i);
else {
GameGUI.gameResources.aiLaserList.get(i).move(time);
}
}
}
repaint();
}
public void up() {
velY = -1.5;
velX = 0;
}
public void down() {
velY = 1.5;
velX = 0;
}
public void left() {
velX = -1.5;
velY = 0;
}
public void right() {
velX = 1.5;
velY = 0;
}
public void keyPressed(KeyEvent e) {
keyPress = true;
code = e.getKeyCode();
if(code == KeyEvent.VK_UP || code == KeyEvent.VK_W) {
up();
}
if(code == KeyEvent.VK_DOWN || code == KeyEvent.VK_S) {
down();
}
if(code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_D) {
right();
}
if(code == KeyEvent.VK_LEFT || code == KeyEvent.VK_A) {
left();
}
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {
keyPress = false;
}
public void mouseExited(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseClicked(MouseEvent evt) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent evt) {
mousePoint = evt.getPoint();
if(GameGUI.getGameOver()) GameGUI.gameResources.resetForNextLevel();
else {
GameGUI.gameResources.getPlayerRobot().setLocation(new Point((int) (x + 0.5), (int) (y + 0.5)), new Point((int) (x + 0.5 + 37), (int) (y + 0.5 + 99)));
Rectangle tempR = new Rectangle(GameGUI.gameResources.getPlayerRobot().getLocation().get(0).x, GameGUI.gameResources.getPlayerRobot().getLocation().get(0).y, GameGUI.gameResources.getPlayerRobot().getLocation().get(1).x, GameGUI.gameResources.getPlayerRobot().getLocation().get(1).y);
GameGUI.gameResources.playerLaserList.add(new Laser(new Point((int) (tempR.getCenterX() + 0.5), (int) (tempR.getCenterY() + 0.5)), evt.getPoint(), GameGUI.gameResources));
}
}
}
激光:
package application;
import java.awt.Point;
import javafx.scene.shape.Line;
public class Laser {
private Point point1;
private Point point2;
private Point currentPoint;
private double angle;
private Line laserLine;
private Point farEnd;
private Point farStart;
private double x1, x2, y1, y2, m, y3, x3;
private GameResources gameResources;
public Laser(Point tempPoint1, Point tempPoint2, GameResources tempGR) {
gameResources = tempGR;
currentPoint = point1 = tempPoint1;
point2 = tempPoint2;
double leg1 = point2.x - point1.x;
double leg2 = point2.y - point1.y;
double hyp = Math.sqrt(Math.pow(leg1, 2) + Math.pow(leg2, 2));
angle = Math.asin(leg2 / hyp);
if(angle < 0) angle = 2 * Math.abs(angle);
farEnd = getPointX(460);
farStart = getPointX(0);
laserLine = new Line(farStart.x, farStart.y, farEnd.x, farStart.y);
x1 = tempPoint1.x;
y1 = tempPoint1.y;
x2 = tempPoint2.x;
y2 = tempPoint2.y;
m = (y2 - y1) / (x2 - x1);
x3 = 0;
y3 = 0;
}
public Point getInitialLocation() {
return point1;
}
public Point getLocation() {
return currentPoint;
}
public double getAngle() {
return angle;
}
public Line getLine() {
return laserLine;
}
public Line getCurrentLine() {
Line currentLine = new Line();
if(getAngle() < Math.PI && getAngle() > 0)
currentLine = new Line((int) (currentPoint.x + 0.5), (int) (currentPoint.y + 0.5), (int) (getPointX((int) (currentPoint.y + 0.5) + (int) (Math.sin(angle) * 50 + 0.5)).x + 0.5), (int) (currentPoint.y + 0.5) + (int) (Math.sin(angle) * 50 + 0.5));
else if(getAngle() > Math.PI && getAngle() < 2 * Math.PI)
currentLine = new Line((int) (currentPoint.x + 0.5), (int) (currentPoint.y + 0.5), (int) (getPointX((int) (currentPoint.y + 0.5) - (int) (Math.sin(angle) * 50 + 0.5)).x + 0.5), (int) (currentPoint.y + 0.5) - (int) (Math.sin(angle) * 50 + 0.5));
System.out.println(currentLine.getStartX() + " " + currentLine.getStartY() + " " + point1);
return currentLine;
}
public void setLocation(Point tempLocation) {
currentPoint = tempLocation;
}
public Point getPointY(int x) {
if(x1 == x2 && y1 != y2) return null;
else if(m < 0) y3 = ((y2 - y1) / (x2 - x1)) * (double) x - (x2 * ((y2 - y1) / (x2 - x1)) - y2);
else if(m > 0) y3 = ((y2 - y1) / (x2 - x1)) * (double) x + (x2 * ((y2 - y1) / (x2 - x1)) - y2);
else if(m == 0) y3 = ((y2 - y1) / (x2 - x1)) * (double) x;
return new Point(x, (int) (y3 + 0.5));
}
public Point getPointX(int y) {
if(x1 == x2 && y1 != y2) return new Point((int) (x1 + 0.5), y);
else if(m < 0) x3 = ((double) y + (x2 * ((y2 - y1) / (x2 - x1)) - y2)) / ((y2 - y1) / (x2 - x1));
else if(m > 0) x3 = ((double) y - (x2 * ((y2 - y1) / (x2 - x1)) - y2)) / ((y2 - y1) / (x2 - x1));
else if(m == 0) x3 = (double) y / (((y2 - y1) / (x2 - x1)));
return new Point((int) (x3 + 0.5), (int) (y + 0.5));
}
public Line move(double time) {
//old algorithm
/*double x = 0, y = 0;
if(y2 > y1) {
y = currentPoint.y + gameResources.getLaserSpeed() * time;
currentPoint = getPointX((int) y);
}
else if(y2 < y1) {
y = currentPoint.y - gameResources.getLaserSpeed() * time;
currentPoint = getPointX((int) y);
}
else if(y2 == y1 && x2 > x1) {
x = currentPoint.x + gameResources.getLaserSpeed() * time;
currentPoint = getPointY((int) x);
}
else if(y2 == y1 && x2 < x1) {
x = currentPoint.x - gameResources.getLaserSpeed() * time;
currentPoint = getPointY((int) x);
}*/
//new algorithm
if(getAngle() < Math.PI / 2 && getAngle() > 0) {
System.out.println("(1) First quad");
setLocation(getPointY((int) (getLocation().x + 1 + 0.5)));
}
else if(getAngle() < Math.PI && getAngle() > Math.PI / 2) {
System.out.println("(2) Second quad");
setLocation(getPointY((int) (getLocation().x - 1 - 0.5)));
}
else if(getAngle() > Math.PI && getAngle() < 3 * Math.PI / 2) {
System.out.println("(3) Third quad");
setLocation(getPointY((int) (getLocation().x - 1 - 0.5)));
}
else if(getAngle() > 3 * Math.PI / 2 && getAngle() < 2 * Math.PI) {
System.out.println("(4) Fourth quad");
setLocation(getPointY((int) (getLocation().x + 1 + 0.5)));
}
else if(getAngle() == 2 * Math.PI || getAngle() == 0)
setLocation(new Point((int) (getLocation().x + 1 + 0.5), (int) (getLocation().y + 0.5)));
else if(getAngle() == Math.PI)
setLocation(new Point((int) (getLocation().x - 1 - 0.5), (int) (getLocation().y + 0.5)));
else if(getAngle() == Math.PI / 2)
setLocation(new Point((int) (getLocation().x + 0.5), (int) (getLocation().y + 1 + 0.5)));
else if(getAngle() == 3 * Math.PI / 2)
setLocation(new Point((int) (getLocation().x + 0.5), (int) (getLocation().y - 1 - 0.5)));
return getCurrentLine();
}
public void setGameResources(GameResources tempGR) {
gameResources = tempGR;
}
}