I am trying to calculate the angle in degrees between tow points in java. This is the code i am using to calculate the angle.
public static double calcAngle(Point.Double p1, Point.Double p2)
{
double xDiff = p2.x - p1.x;
double yDiff = p2.y - p1.y;
return Math.toDegrees(Math.atan2(yDiff, xDiff));
}
Here is the rest of my code
double playerX = panel.getCharacter().getX();
double playerY = panel.getCharacter().getY();
int dispenserX = x*Block.WIDTH;
int dispenserY = y*Block.HEIGHT;
Point2D.Double player = new Point2D.Double(playerX, playerY);
Point2D.Double dispenser = new Point2D.Double(dispenserX, dispenserY);
double angle = calcAngle(dispenser, player);
System.out.println(angle);
panel.addEntity(newEntityFireball(x*Block.WIDTH,y*Block.HEIGHT,angle,1));//adds a fireball at a 45 degree angle
System.out.println(angle);
System.out.println(dispenser);
System.out.println(player);
The fireball fired from the dispenser is not aimed at the player why? And it seems to move at a random angle.
Edit here is the fireball class
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class EntityFireball extends Entity
{
private double angle;
private double speed;
private int life;
public EntityFireball(double x, double y, double angle, double speed)
{
super(x, y, 20, 20);
this.angle = angle;
this.speed = speed;
}
public void update(boolean inRange)
{
life++;
if(life>2500)
removeEntityFromGame(this);
if(inRange)
{
float xDirection = (float) (Math.sin((float) Math.toRadians(angle)) * speed);
float yDirection = (float) (Math.cos((float) Math.toRadians(angle)) * -speed);
double newX = getX() + xDirection;
double newY = getY() + yDirection;
setX(newX);
setY(newY);
}
}
public BufferedImage getImage()
{
try
{
return ImageIO.read(Main.class.getResourceAsStream("/images/Fireball.png"));
}
catch (IOException e)
{
return null;
}
}
}
change
float xDirection = (float) (Math.sin((float) Math.toRadians(angle)) * speed);
float yDirection = (float) (Math.cos((float) Math.toRadians(angle)) * -speed);
to
float xDirection = (float) (Math.cos((float) Math.toRadians(angle)) * speed);
float yDirection = (float) (Math.sin((float) Math.toRadians(angle)) * speed);
Also, you are changing the 2D course vector into an angle, and then changing it back to a 2D course vector. It's a decent amount of circular trig that lands you the same answer that you initially started with. Is there a reason you don't just leave it a vector?
public static Point2D.Double calcAngle(Point.Double p1, Point.Double p2){
double xDiff = p2.x - p1.x;
double yDiff = p2.y - p1.y;
return new Point2D.Double(xDiff,yDiff);
}
public class EntityFireball extends Entity {
private Point2D.Double course;
private double speed;
private int life;
public EntityFireball(double x, double y, double angle, Point2D.Double course){
super(x, y, 20, 20);
this.angle = angle;
this.course=course;
}
public void update(boolean inRange){
life++;
if(life>2500)
removeEntityFromGame(this);
if(inRange){
float xDirection = course.x;
float yDirection = course.y;
double newX = getX() + xDirection;
double newY = getY() + yDirection;
setX(newX);
setY(newY);
}
}
}
Just take the absolute values:
public static double calcAngle(Point.Double p1, Point.Double p2)
{
double xDiff = Math.abs(p2.x - p1.x);
double yDiff = Math.abs(p2.y - p1.y);
return Math.toDegrees(Math.atan2(yDiff, xDiff));
}
My guess is that you've converted the angle to degrees but are treating it later as a radian angle when you do your drawing. That would explain why it's in "random directions"
Related
I am trying to implement DDA algorithm in Java to draw a line. The Line Rasterizer implements an interface. Then I call the rasterizeLine function in class named Canva. The LineRasterizes successfully gets x and y points. No errors are thrown up, however there has to be some logical problem with the algorithm, because the line is not being drawed. Can you help me find the logical mistake?
Interface
package rasterops;
import rasterdata.RasterImage;
public interface LineRasterizer<PixelType> {
RasterImage<PixelType> rasterizeLine(RasterImage<PixelType> img,
double x1, double y1, double x2, double y2,
PixelType value);
}
Line Rasterizer
package rasterops;
import rasterdata.RasterImage;
public class LineRasterizerDDA<PixelType> implements LineRasterizer <PixelType> {
#Override
public RasterImage<PixelType> rasterizeLine(RasterImage<PixelType> img, double x1, double y1, double x2, double y2, PixelType value) {
double dy = y2-y1;
double dx = x2-x1;
double k = dy/dx;
double y = y1;
RasterImage<PixelType> result = img;
for( double x = x1; x <= x2; x++ ){
result = result.withPixel((int)x, (int)Math.round(y), value);
y = y1 + k;
}
return result;
}
}
Canva - calling the function
panel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
previousX = e.getX();
previousY = e.getY();
}
});
panel.addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
final double startX = previousX / (panel.getWidth() - 1.0); //k zamysleni: proc 1.0 a ne 1?
final double startY = 1 - previousY / (panel.getHeight() - 1.0);
final double endX = e.getX() / (panel.getWidth() - 1.0);
final double endY = 1 - e.getY() / (panel.getHeight() - 1.0);
clear(); // zkuste zakomentovat
rasterImage = liner.rasterizeLine(rasterImage,
startX, startY, endX, endY,
0xffff00);
panel.repaint();
}
});
This line:
y = y1 + k;
keeps assigning the same value to y, because y1 and k aren't changing.
Example output, drawing line between (0,0) and (10, 10):
O..........
.OOOOOOOOOO
...........
...........
...........
...........
...........
...........
...........
...........
...........
You may mean:
y = y + k;
or y += k;.
Example output, drawing line between (0,0) and (10, 10):
O..........
.O.........
..O........
...O.......
....O......
.....O.....
......O....
.......O...
........O..
.........O.
..........O
I am making a 2D top-down shooter in Java (uni project) but hit a problem with bullet aiming - I am unsure why the angle is incorrect, and how to correct it.
The player shoots bullets at the cursor location on mousedown. I am using dx/y = (x/ytarget - x/yorigin), normalising and incrementing the bullets x/y pos with dx each tick.
When the cursor is moved, the firing angle tracks the cursor - but the angle is off by 45 degrees or so The white circle is player, red is cursor and bullets the yellow dots.
I dont have rep to post images (first post), here is a link that shows the error of the angle.
http://i.imgur.com/xbUh2fX
Here is the bullet class:
note - update() is called by the main game loop
import java.awt.*;
import java.awt.MouseInfo;
public class Bullet {
private double x;
private double y;
private int r;
private double dx;
private double dy;
private double speed;
private double angle;
private Point c;
private Color color1;
public Bullet(int x, int y) {
this.x = x;
this.y = y;
r = 3;
speed = 30;
color1 = Color.YELLOW;
c = MouseInfo.getPointerInfo().getLocation();
// getting direction
dx = c.x - x;
dy = c.y - y;
double distance = Math.sqrt(dx*dx + dy*dy);
dx /= distance;
dy /= distance;
}
public boolean update() {
x += dx*speed;
y += dy*speed;
if(x < -r || x > GamePanel.WIDTH + r ||
y < -r || y > GamePanel.HEIGHT + r) {
return true;
}
return false;
}
public void draw(Graphics2D g) {
g.setColor(color1);
g.fillOval((int) (x - r), (int) (y - r), 2 * r, 2 * r);
}
}
I got a similar game and this is the code I used
import java.awt.Graphics2D;
import araccoongames.pongadventure.game.Entity;
import araccoongames.pongadventure.game.Game;
import araccoongames.pongadventure.game.MapLoader;
public class Ball extends Entity {
private float speed = 8;
private float speedx;
private float speedy;
private float degree;
public Ball(float posx, float posy, Game game) {
super(0, 0, game);
this.posx = posx;
this.posy = posy;
// posx = ball x position
// posy = ball y position
// game.input.MOUSEY = mouse y position
// game.input.MOUSEX = mouse x position
degree = (float) (270 + Math.toDegrees(Math.atan2(posy - game.input.MOUSEY, posx - game.input.MOUSEX))) % 360;
speedx = (float) (speed * Math.sin(Math.toRadians(degree)));
speedy = (float) (speed * Math.cos(Math.toRadians(degree)));
}
#Override
public void render(Graphics2D g) {
drawImage(game.texture.SPRITE[0][1], g);
}
#Override
public void update() {
posx += speedx;
posy -= speedy;
}
}
I'm trying to make an Asteroids remake using Java and I'm having problems making the player (which is a triangle) rotate when I press a button. I have looked up methods and the math to make the points of the triangle rotate but I haven't figured out how to use the formulas. Your help will be greatly appreciated. Thank You!
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import Main.GameObject;
import Main.ID;
public class Player extends GameObject {
public float x1 = 16 + xPos;
public float y1 = 0 + yPos;
public float x2 = 0 + xPos;
public float y2 = 48 + yPos;
public float x3 = 32 + xPos;
public float y3 = 48 + yPos;
public float centerX = xPos + 16;
public float centerY = yPos - 24;
public Point2D.Float center = new Point2D.Float(xPos + 16, yPos - 24);
public Point2D.Float p1 = new Point2D.Float(x1, y1);
public Point2D.Float p2 = new Point2D.Float(x2, y2);
public Point2D.Float p3 = new Point2D.Float(x3, y3);
public Player(float startX, float startY, ID id) {
super(startX, startY, id);
this.xPos = startX;
this.yPos = startY;
this.id = id;
}
public void tick() {
}
public void render(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.WHITE);
g2.draw(new Line2D.Float(p1, p2));
g2.draw(new Line2D.Float(p2, p3));
g2.draw(new Line2D.Float(p3, p1));
}
public Rectangle getBounds() {
return null;
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT) {
//Rotate triangle here
}
}
}
To rotate a single point around the origin (0,0).
float rot = 2.0; // angle in radians
Point2D.Float p1 = new Point2D.Float(10.0,10.0);
Point2D.Float p1Rotated = new Point2D.Float(0,0);
float dx = Math.cos(rot);
float dy = Math.sin(rot);
p1Rotated.x = p1.x * dx + p1.y * -dy;
p1Rotated.y = p1.x * dy + p1.y * dx;
So for a triangle that has its center at 0,0 do the above to each point then position the triangle by adding the offset to each point.
float rot = 2.0; // angle in radians
float x = 100.0; // space ship center at 100,100
float y = 100.0;
Point2D.Float p1 = new Point2D.Float(10.0,10.0);
Point2D.Float p2 = new Point2D.Float(-10.0,10.0);
Point2D.Float p3 = new Point2D.Float(0.0,-10.0);
Point2D.Float p1R = new Point2D.Float(0,0);
Point2D.Float p2R = new Point2D.Float(0,0);
Point2D.Float p3R = new Point2D.Float(0,0);
float dx = Math.cos(rot);
float dy = Math.sin(rot);
p1R.x = p1.x * dx + p1.y * -dy + x;
p1R.y = p1.x * dy + p1.y * dx + y;
p2R.x = p2.x * dx + p2.y * -dy + x;
p2R.y = p2.x * dy + p2.y * dx + y;
p3R.x = p3.x * dx + p3.y * -dy + x;
p3R.y = p3.x * dy + p3.y * dx + y;
I need to create a GUI for a game and I will need to display on the screen the weapon and the shield. I need to modify the program so it displays the weapon and shield, however their properties are in another class. I know I will have to extend the JPanel class and overrite its paintComponent() method.
public class GraphicsUtil {
private static final int MUZZLE_FRACTION = 3;
private static final Color MUZZLE_COLOR = Color.MAGENTA;
public static void drawShield(IShield shield, Graphics g, GameSpace gameSpace, double origHealth) {
drawPiece(shield, g, gameSpace, origHealth);
}
public static void drawWeapon(IWeapon weapon, Graphics g,
GameSpace gameSpace, double origHealth) {
Color oldColor = g.getColor();
drawPiece(weapon, g, gameSpace, origHealth);
double orientation = weapon.getOrientation();
int x1 = gameSpace.convertToScreenX(weapon.getXPos());
int y1 = gameSpace.convertToScreenY(weapon.getYPos());
int radius = gameSpace.convertToScreenDistance(weapon.getRadius());
int x2 = gameSpace.convertToScreenX(weapon.getXPos()
+ weapon.getRadius() * Math.cos(weapon.getOrientation()));
int y2 = gameSpace.convertToScreenY(weapon.getYPos()
+ weapon.getRadius() * Math.sin(weapon.getOrientation()));
double frac = 1 - 1f / MUZZLE_FRACTION;
int muzzleCentreX
= x1 + (int) Math.round(frac * radius * Math.cos(orientation));
int muzzleCentreY
= y1 - (int) Math.round(frac * radius * Math.sin(orientation));
int muzzleRadius = radius / MUZZLE_FRACTION;
int topMuzzleX = muzzleCentreX - muzzleRadius;
int topMuzzleY = muzzleCentreY - muzzleRadius;
g.setColor(MUZZLE_COLOR);
g.fillOval(topMuzzleX, topMuzzleY, 2 * muzzleRadius, 2 * muzzleRadius);
g.setColor(Color.BLACK);
g.drawLine(x1, y1, x2, y2);
g.setColor(oldColor);
}
public static boolean isInMuzzle(IPiece piece, double x, double y) {
boolean result;
if (piece instanceof IWeapon) {
IWeapon weapon = (IWeapon) piece;
double radius = weapon.getRadius();
double orientation = weapon.getOrientation();
double frac = 1 - 1f / MUZZLE_FRACTION;
double cx = piece.getXPos() + frac * radius * Math.cos(orientation);
double cy = piece.getYPos() + frac * radius * Math.sin(orientation);
double dx = x - cx;
double dy = y - cy;
double dist = Math.sqrt(dx * dx + dy * dy);
result = dist <= radius / MUZZLE_FRACTION;
} else {
result = false;
}
return result;
}
public static double getAngle(double x1, double y1, double x2, double y2) {
double dx = x2 - x1;
double dy = y2 - y1;
double hypotenuse = Math.sqrt(dx * dx + dy * dy);
double angle;
if (dy > 0) {
angle = Math.acos(dx / hypotenuse);
} else {
angle = 2 * Math.PI - Math.acos(dx / hypotenuse);
}
return angle;
}
private static void drawPiece(IPiece piece, Graphics g, GameSpace gameSpace,
double maxHealth) {
Color oldColor = g.getColor();
int centreX = gameSpace.convertToScreenX(piece.getXPos());
int centreY = gameSpace.convertToScreenY(piece.getYPos());
int displayRadius = gameSpace.convertToScreenDistance(piece.getRadius());
int topX = centreX - displayRadius;
int topY = centreY - displayRadius;
if (piece.getOwner() == 0) {
g.setColor(Color.CYAN);
} else {
g.setColor(Color.PINK);
}
g.drawOval(topX, topY, 2 * displayRadius, 2 * displayRadius);
int healthRadius
= (int) Math.round(displayRadius * piece.getHealth() / maxHealth);
int topHealthX = centreX - healthRadius;
int topHealthY = centreY - healthRadius;
g.fillOval(topHealthX, topHealthY, 2 * healthRadius, 2 * healthRadius);
String name = piece.getName();
if (name != null) {
g.setColor(Color.BLACK);
g.drawString(name, centreX, centreY);
}
g.setColor(oldColor);
}
}
This is my main method:
public class Main extends JPanel {
public Main(){
setSize(new Dimension(400,400));
setPreferredSize(new Dimension(400,400));
GraphicsUtil object = new GraphicsUtil();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
}
public static void main(String[] args) {
Main window = new Main();
JFrame frame = new JFrame("RICOCHET");
frame.add(window);
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
How do I call those methods? What do I need to do in order to they appear in my frame? Thanks.
Presumably you have created one or more weapons or pieces. In your paintComponent() method, just call
GraphicsUtil.drawWeapon( myWeapon, g, ... );
I have a two image that moves in a random direction. Now, if that images would bump each other I want it to disappear and that is my problem about making a collision detection. Could someone help me about this problem?
Here is the code:
public class HumanBeing extends Sprite implements ImageObserver
{
private java.awt.Image humanImage;
private final World world;
private double x;
private double y;
private double speed;
private double direction = 1;
private java.util.List<Sprite> objects = new ArrayList<Sprite>();
private double angle;
public HumanBeing(World world, double x, double y, double speed)
{
this.world =world;
this.x = x;
this.y = y;
this.speed = convertToMeterPerSecond(speed);
URL iU = this.getClass().getResource("human.jpg");
ImageIcon icon = new ImageIcon(iU);
humanImage = icon.getImage();
objects.add(this);
}
public Image getImage()
{
return humanImage;
}
#Override
public void move(long dt)
{
double dt_s = dt / 1e9;
double dx_m = speed * dt_s * Math.sin(angle);
double dy_m = speed * dt_s * Math.cos(angle);
final double right_wall = world.x1_world;
final double up_wall = world.y1_world;
final double down_wall = 0.0;
final double left_wall = 0.0;
x += dx_m;
y += dy_m;
if (x >= right_wall)
{
setRandomDirection();
}
if (y > up_wall)
{
setRandomDirection();
}
if (x <= left_wall)
{
setRandomDirection();
}
if (y < down_wall)
{
setRandomDirection();
}
}
public void setRandomDirection()
{
HumanBeing humanbeing = this;
humanbeing.setAngle(Math.PI * 2 * Math.random());
}
#Override
public void render(Graphics2D g2d)
{
AffineTransform t = g2d.getTransform();
final double humanHeight = 1.6;// meter
final double humanWidth = 1.8; //meter
final double foot_position_y = humanHeight;
final double foot_position_x = humanWidth / 2;
int xx = world.convertToPixelX(x - foot_position_x); // to find the upper-left corner
int yy = world.convertToPixelY(y + foot_position_y); // to find the upper-left corner
g2d.translate(xx, yy);
// ratio for actual Image size
double x_expected_pixels = humanHeight * board.meter;
double y_expected_pixels = humanWidth * board.meter;
double w = ((ToolkitImage) humanImage).getWidth();
double h = ((ToolkitImage) humanImage).getHeight();
double x_s = x_expected_pixels / w;
double y_s = y_expected_pixels / h;
g2d.scale(x_s, y_s);
g2d.drawImage(getImage(), 0, 0, this); // upper left corner
g2d.setColor(Color.BLACK);
g2d.setTransform(t);
}
#Override
public void moveAt(double distance_x, double distance_y)
{
this.x = distance_x;
this.y = distance_y;
}
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
return false;
}
public void setAngle(double angle)
{
this.angle = angle;
}
}
this is my HumanBeing class
public class Chicken extends Sprite implements ImageObserver
{
private java.awt.Image chickenImage;
private final World world;
private double x;
private double y;
private double speed;
private double angle;
public Chicken(World world, double x, double y, double speed)
{
this.world = world;
this.x = x;
this.y = y;
this.speed = convertToMeterPerSecond(speed);
URL iU = this.getClass().getResource("chicken.gif");
ImageIcon icon = new ImageIcon(iU);
chickenImage = icon.getImage();
}
public Image getImage()
{
return chickenImage;
}
public void move(long dt)
{
double dt_s = dt / 1e9;
double dx_m = speed * dt_s * Math.sin(angle);
double dy_m = speed * dt_s * Math.cos(angle);
final double right_wall = world.x1_world;
final double up_wall = world.y1_world;
final double down_wall = 0.0;
final double left_wall = 0.0;
x += dx_m;
y += dy_m;
if (x >= right_wall)
{
x = right_wall;
setRandomDirection();
}
if (y > up_wall)
{
y = up_wall;
setRandomDirection();
}
if (x <= left_wall)
{
x = left_wall;
setRandomDirection();
}
if (y < down_wall)
{
y = down_wall;
setRandomDirection();
}
}
public void setRandomDirection()
{
Chicken chicken = this;
chicken.setAngle(Math.PI * 2 * Math.random());
}
#Override
public void render(Graphics2D g2d)
{
AffineTransform t = g2d.getTransform();
double height = 0.3; //meter
double width = 0.3; //meter
double chicken_footy = height;
double chicken_footx = width/2;
int xx = world.convertToPixelX(x - chicken_footx);
int yy = world.convertToPixelY(y + chicken_footy);
g2d.translate(xx, yy);
double x_expected_pixels = width * board.meter;
double y_expected_pixels = height * board.meter;
double x_s = x_expected_pixels / ((ToolkitImage) chickenImage).getWidth();
double y_s = y_expected_pixels / ((ToolkitImage) chickenImage).getHeight();
g2d.scale(x_s, y_s);
g2d.drawImage(getImage(), 0, 0, this);
g2d.setColor(Color.BLACK);
g2d.setTransform(t);
}
public void moveAt(double distance_x, double distance_y)
{
this.x = (int) distance_x;
this.y = (int) distance_y;
}
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
return true;
}
public void setAngle(double angle)
{
this.angle = angle;
}
}
this is my chicken class
Draw invisible Rectangle around your sprites as like Box's and than use below method to check whether they are intersecting or not :)
http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Rectangle.html#intersects(java.awt.Rectangle)
if(rect.intersect(anotherRect))
{
disappear();
}
Good luck