I'm creating a 2d game and I wanted to implement shooting. However, bullets for some reason shoot only at a -45° angle. Provided below is my code. The if statement is also important and needs to know when the bullet goes out of range. I've looked up answers for the issue and none of them seem to work.
Also, .getEntity returns the JLabel of the entity.
public class Bullet extends Entity
{
private double speed, dmg, dist, vX, vY, xDest, yDest;
private double traveledDist = 0;
private JLabel bullet;
private String img;
public Bullet(double nSpeed, double nDmg, double xDest, double yDest, double nDistance, String img, double vX,
double vY)
{
super(80, 80, "res/img/bullet.png");
speed = nSpeed;
dmg = nDmg;
dist = nDistance;
this.xDest = xDest;
this.yDest = yDest;
this.img = img;
this.vX = vX;
this.vY = vY;
Image image = new ImageIcon("res/img/bullet.png").getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT);
ImageIcon imageicon = new ImageIcon(image);
JLabel bullet = new JLabel(imageicon);
bullet.setSize(80, 80);
bullet.setVisible(true);
}
public String toString()
{
return ("[Speed: " + speed + ", Damage: " + dmg + ", xDest: " + xDest + ", yDest: " + yDest + ", vX:" + vX
+ ", vY" + vY + ", Distance: " + dist + ", Traveled Distance: " + traveledDist + ", Image Path: " + img
+ "]");
}
public double getxDest()
{
return xDest;
}
public double getyDest()
{
return yDest;
}
public double getvX()
{
return vX;
}
public double getvY()
{
return vY;
}
public JLabel newBullet()
{
return bullet;
}
public double getSpeed()
{
return speed;
}
public double getDmg()
{
return dmg;
}
public double getDist()
{
return dist;
}
public String getImg()
{
return img;
}
public double getTraveledDist()
{
return traveledDist;
}
public void setTraveledDist(double nDist)
{
traveledDist = nDist;
}
}
private void fireBullet()
{
System.out.println("bullet");
double originX = lblCross.getX() - lblChar.getX();
double originY = lblCross.getY() - lblChar.getY();
double mouseX = MouseInfo.getPointerInfo().getLocation().getX();
double mouseY = MouseInfo.getPointerInfo().getLocation().getY();
double bulletVelocity = 1.0;
//mouseX/Y = current x/y location of the mouse
//originX/Y = x/y location of where the bullet is being shot from
double angle = Math.atan2(mouseX - originX, mouseY - originY);
double xVelocity = (bulletVelocity) * Math.cos(angle);
double yVelocity = (bulletVelocity) * Math.sin(angle);
Bullet tempBullet = new Bullet(((ProjectileWeapon) sWeapon).getProjectileSpeed(), sWeapon.getDamage(), 0, 0,
sWeapon.getRange() * 100, ("res/img/bullet.png"), xVelocity, yVelocity);
tempBullet.getEntity().setVisible(true);
room.add(tempBullet.getEntity());
room.repaint();
tempBullet.getEntity().setLocation(lblChar.getX(), lblChar.getY());
bullets.add(tempBullet);
}
private void updateBullet()
{
for (int i = 0; i < bullets.size(); i++)
{
bullets.get(i).getEntity().getY());
if (true)
{
System.out.println("updating" + bullets.get(i));
Bullet b = bullets.get(i);
b.getEntity().setLocation((int) (b.getEntity().getLocation().getX() + (b.getvX() * 10)),
(int) (b.getEntity().getLocation().getY() + (b.getvY() * 10)));
b.setTraveledDist(b.getTraveledDist() + 1);
room.repaint();
}
else
{
room.remove(bullets.get(i).getEntity());
bullets.remove(i);
room.repaint();
}
}
}
Your help is much appreciated.
Here's the code I ultimately used:
double theta = Math.atan2(destination.getY() - origin.getY(), destination.getX() -
origin.getX());
xVelocity = Math.cos(-theta);
yVelocity = -Math.sin(-theta);
Related
I asked this question on Math.se a few days ago, and got the following answer in pseudocode:
Function RandomCircleInside(centerX, centerY, radius):
Let newRadius = radius * Random()
Let radians = 2.0 * 3.14159265358979323846 * Random()
Let deviation = (radius - newRadius) * Sqrt(Random())
Let newX = centerX + deviation * Cos(radians)
Let newY = centerY + deviation * Sin(radians)
Return (newX, newY, newRadius)
End Function
I changed the pseudocode to Java and added my own changes to fit my needs. The new code looks like this:
Circle createNewCircle(int centerX, int centerY, int radius, int newR, Color newColor) {
int newRadius = radius * Random();
double radians = 2.0 * 3.141592653589793 * Random();
double deviation = (radius - newRadius) * Math.sqrt(Random());
System.out.println(radius + " - " + newRadius + " * sqrt(0 or 1) = " + (radius-newRadius) + " * (0 or 1) = " + deviation);
double newX = centerX + deviation * Math.cos(radians);
System.out.println(centerX + " + " + deviation + " * cos(" + radians + ") = " + (centerX + deviation) + " * " + Math.cos(radians));
double newY = centerY + deviation * Math.sin(radians);
int newCirX = (int) newX;
int newCirY = (int) newY;
Circle newCir = new Circle(newCirX, newCirY, newR*2, newR*2, newR, newColor, true);
return newCir;
}
The code itself is supposed to create a new Circle inside of a preexisting one. I created a circle class that looks like this:
import java.awt.Color;
import java.awt.Graphics;
public class Circle {
public int X, Y, Width, Height, radius;
public Color color;
public boolean toFill;
public Circle(int x, int y, int width, int height, int radius, Color color, boolean fill) {
X = x;
Y = y;
Width = width;
Height = height;
this.radius = radius;
this.color = color;
toFill = fill;
}
public void render(Graphics g) {
g.setColor(color);
for(int i=-5; i<5; i++) {
if(toFill) {
g.fillOval(X+i, Y+i, Width-i, Height-i);
} else {
g.drawOval(X+i, Y+i, Width-i, Height-i);
}
}
}
public boolean contains(Circle pBound) {
int pBoundCenterX = pBound.X+pBound.radius;
int cirCenterX = X+radius;
int diffBetweenCentersX = Math.abs(pBoundCenterX-cirCenterX);
int pBoundCenterY = pBound.Y+pBound.radius;
int cirCenterY = Y+radius;
int diffBetweenCentersY = Math.abs(pBoundCenterY-cirCenterY);
if(diffBetweenCentersX<= (pBound.radius+radius) && diffBetweenCentersX>=Math.abs(pBound.radius-radius)) { // X
if(diffBetweenCentersY>=Math.abs(pBound.radius-radius)) { // Y
return true;
}
}
return false;
}
public int getX() {
return X;
}
public int getWidth() {
return Width;
}
public int getRadius() {
return radius;
}
public void setWidth(int width) {
Width = width;
}
public int getHeight() {
return Height;
}
public void setHeight(int height) {
Height = height;
}
public void setX(int x) {
X = x;
}
public int getY() {
return Y;
}
public void setY(int y) {
Y = y;
}
}
My way of creating the new circle is this:
if(secInGame==timesForCircle[X] && !hasChanged) { // circle 2
Circle cir1 = cir;
cir = createNewCircle(cir1.X+(cir1.Width/2), cir1.Y+(cir1.Height/2), cir1.getRadius(), 135, Color.cyan);
hasChanged = true;
circleOn++;
circ++;
}
Where cir1 is the preexisting Circle and cir is the new circle.
Is there anything I didn't code correctly? I've tried a few different variations, but they all give the same result.
Before I implemented the pseudocode, my circles looked like this:
but now it looks like this:
All of my code can be found on github at: link
I think there are several issues in your code.
1. First of all it is not clear why your Circle has radius, Width and Height. For a circle all 3 things should be the same. Also your render in case toFill is true looks strange. Here is a simplified version (note: I didn't compile it so there might be some bugs):
public class Circle {
public int X, Y, radius;
public Color color;
public boolean toFill;
public Circle(int x, int y, int radius, Color color, boolean fill) {
X = x;
Y = y;
this.radius = radius;
this.color = color;
toFill = fill;
}
public void render(Graphics g) {
g.setColor(color);
final int r2 = 2*radius;
if(toFill) {
g.fillOval(X, Y, r2, r2);
}
else {
for(int i=-5; i<5; i++) {
g.drawOval(X+i, Y+i, r2-i, r2-i);
}
}
}
public boolean contains(Circle pBound) {
int pBoundCenterX = pBound.X+pBound.radius;
int cirCenterX = X+radius;
int diffBetweenCentersX = Math.abs(pBoundCenterX-cirCenterX);
int pBoundCenterY = pBound.Y+pBound.radius;
int cirCenterY = Y+radius;
int diffBetweenCentersY = Math.abs(pBoundCenterY-cirCenterY);
if(diffBetweenCentersX<= (pBound.radius+radius) && diffBetweenCentersX>=Math.abs(pBound.radius-radius)) { // X
if(diffBetweenCentersY>=Math.abs(pBound.radius-radius)) { // Y
return true;
}
}
return false;
}
public int getX() {
return X;
}
public int getRadius() {
return radius;
}
public void setX(int x) {
X = x;
}
public int getY() {
return Y;
}
public void setY(int y) {
Y = y;
}
}
I didn't check your code, but I'd consider as a good practice:
renaming x and y into leftX and topY to avoid confusion with centerX/centerY meaning. Or change meaning to more typical center one.
declaring all your fields as private (see encapsulation);
declaring all your fields as final and remove all the setXyz methods (see immutability)
2. I don't understand why your createNewCircle has newR parameter and at the same time you generate a random newRadius in the first line. One of these definitely should be removed. Given that the parameter is always a constant 135 I think it should be removed.
3. Now I believe the main bug in your translation is in the lines
int newCirX = (int) newX;
int newCirY = (int) newY;
It probably should be something like
int newCirX = (int) newX - newRadius;
int newCirY = (int) newY - newRadius;
It looks like you messed with center vs top-left. Actually I think the fact that you made such a bug is an argument that supports renaming x and y I suggested in item #1.
I'm trying to do my first methods.
I'm having trouble getting the perimeter to display the output as a String. I'm wondering why this is happening. I very well could have other problems inside of my code but the perimeter not outputting is what is holding me back right now.
Following is my code.
public class Polygon {
public Polygon() {
int numSides = 4;
double SideLength = 5.0;
double xCoord = 0.0;
double yCoord = 0.0;
double apothem = 5.0;
double perimeter = 20.0;
}
private int numSides = 2;
private double SideLength = 2;
private double xCoord;
private double yCoord;
private double apothem;
private double perimeter;
private double area;
public Polygon(int numsides, double sideLength, double xcoord, double ycoord, double Apothem, double Perimeter) {
SideLength = sideLength;
numSides = numsides;
xCoord = xcoord;
yCoord = ycoord;
apothem = Apothem;
perimeter = Perimeter;
}
public int getnumsides() {
return numSides;
}
public double getSideLength() {
return SideLength;
}
public double getxcoord() {
return xCoord;
}
public double getycoord() {
return yCoord;
}
public double getApothem() {
return apothem;
}
public double getPerimeter() {
return numSides * SideLength;
}
public void setsideLength(double ssideLength){
SideLength = ssideLength;
}
public void setnumsides(int snumsides){
numSides = snumsides;
}
public void setxcoord(double sxcoord){
xCoord = sxcoord;
}
public void setycoord(int sycoord){
yCoord = sycoord;
}
public void setApothem(int sApothem){
apothem = sApothem;
}
public void setPerimeter(int sPerimeter){
perimeter = sPerimeter;
}
public String toString() {
String str = numSides + " is the number of sides the polygon has and " + SideLength + " is how long the sides are. "+ xCoord + " is how long the x coordinate is and " + yCoord + " is how long the y coordinate is. " + apothem + " is the apothem of the polygon and " + perimeter + " is the perimeter of the polygon.";
return str;
}
public void getArea() {
area = .5 * apothem * perimeter;
}
}
You are again defining same field variables in Polygon() constructor which is not required because you have already defined them as private class members. This is the reason that some values are setting as default while printing toString() method.
Your Polygon() constructor should be look like this:
public Polygon() {
numSides = 4;
SideLength = 5.0;
xCoord = 0.0;
yCoord = 0.0;
apothem = 5.0;
perimeter = 20.0;
}
What do you mean by "perimeter not outputting"?
May be this is what you want to achieve?
public static void main(String[] args){
Polygon p = new Polygon();
double perimeter = p.getPerimeter();
System.out.println("Perimeter is " + perimeter);
}
I am trying to convert world coordinates to pixel coordinates. The problem is, some files (shapefiles) do not convert as it should. The lines are slanted or moved, they should look exactly as when I load the file for display.
The reason I am converting the lines is because it needs to display in Adobe Illustrator, and normal map coordinates are much to large to display properly.
Is there a better way to convert world coordinates to screen coordinates more reliably?
(the convertLines method is where all the conversion is happening)
ArrayList<FeatureLine> temp = new ArrayList();
public static void main(String[] args) throws Exception {
MCV_TestProgram test = new MCV_TestProgram();
}
public MCV_TestProgram() {
temp.add(new FeatureLine("2466308.97 709571.48, 2466306.03 709566.79", 0));
temp.add(new FeatureLine("2466800.14 710357.15, 2466308.97 709571.48", 1));
temp.add(new FeatureLine("2456506.25 707356.2, 2456487.75 707715.23, 2456450.68 707809.01", 2));
temp.add(new FeatureLine("2324352.2 669626.61, 2324365.6 669328.81, 2324146.77 669316.22, 2324165.41 669264.1, 2324174.26 669057.93, 2324192.39 668895.68, 2324211.04 668561.95, 2324219.11 668494.04, 2324230.7 668370.9, 2324247.66 668128.16, 2324260.89 667951.94, 2324268.86 667848.91, 2324278.83 667705.33, 2324289.97 667508.67", 3));
convertLines(temp);
}
// Converts map lines to fit in smaller window (mainly for Adobe Illustrator)
private ArrayList<FeatureLine> convertLines(ArrayList<FeatureLine> lines) {
ArrayList<FeatureLine> convertedCoords = new ArrayList();
try {
Rectangle imageBounds = new Rectangle(250, 200, 1000, 800);
CoordinateReferenceSystem crs = createCRS();
ReferencedEnvelope mapBounds = new ReferencedEnvelope(2104208.77, 2595754.33, 500627.08, 1286916.23, crs);
AffineTransform world2screen = createTransform(mapBounds, imageBounds);
for (FeatureLine coord : lines) {
Point2D screenCoordStart = world2screen.transform(coord.StartPoint, null);
Point2D screenCoordEnd = world2screen.transform(coord.EndPoint, null);
if (coord.StartPoint.x != 0.0) {
convertedCoords.add(new FeatureLine(screenCoordStart, screenCoordEnd));
}
}
} catch (FactoryException | MismatchedDimensionException ex) {
Logger.getLogger(MCV_TestProgram.class.getSimpleName()).log(Level.SEVERE, "Error occured while converting lines", ex);
}
return convertedCoords;
}
// Custom line class to store line data, StartPoint and Endpoint (coordinates)
// of one unbreaking line.
public class FeatureLine {
private Point2D.Double StartPoint = new Point2D.Double();
private Point2D.Double EndPoint = new Point2D.Double();
public FeatureLine(double x1, double y1, double x2, double y2) {
StartPoint.x = x1;
StartPoint.y = y1;
EndPoint.x = x2;
EndPoint.y = y2;
}
public FeatureLine(Point2D.Double start, Point2D.Double end) {
StartPoint = start;
EndPoint = end;
}
public FeatureLine(Point2D start, Point2D end) {
StartPoint = (Point2D.Double) start;
EndPoint = (Point2D.Double) end;
}
public FeatureLine(String parseString, int index) {
String latlon[];
String xy1[];
String xy2[];
double x1, y1;
double x2, y2;
try {
if (!parseString.equals("")) {
latlon = parseString.split(",");
xy1 = latlon[0].split(" ");
xy2 = latlon[1].replaceFirst(" ", "").split(" ");
x1 = Double.parseDouble(xy1[0]);
y1 = Double.parseDouble(xy1[1]);
x2 = Double.parseDouble(xy2[0]);
y2 = Double.parseDouble(xy2[1]);
StartPoint.x = x1;
StartPoint.y = y1;
EndPoint.x = x2;
EndPoint.y = y2;
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Error occured while creating line at: " + index + " ", ex);
}
}
public double getX(int index) {
if (index == 0) {
return StartPoint.x;
} else {
return EndPoint.x;
}
}
public double getY(int index) {
if (index == 0) {
return StartPoint.y;
} else {
return EndPoint.y;
}
}
public void setX(double x, int index) {
if (index == 0) {
StartPoint.x = x;
} else {
EndPoint.x = x;
}
}
public void setY(double y, int index) {
if (index == 0) {
StartPoint.y = y;
} else {
EndPoint.y = y;
}
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
return (builder.append(String.valueOf(StartPoint.x)).append(" ").append(String.valueOf(StartPoint.y)).append(", ")
.append(String.valueOf(EndPoint.x)).append(" ").append(String.valueOf(EndPoint.y))).toString();
}
}
/**
* Uses the window's aspect ratio to choose a scale factor for the map,
* and constructs an AffineTransform to scale the shapefile's contents.
*/
private AffineTransform createTransform(ReferencedEnvelope mapEnvelope, Rectangle imageBounds) {
double mapWidth = mapEnvelope.getWidth();
double mapHeight = mapEnvelope.getHeight();
double imageWidth = imageBounds.getWidth();
double imageHeight = imageBounds.getHeight();
double sx = imageWidth / mapWidth;
double sy = imageHeight / mapHeight;
double aspectRatio = mapWidth / mapHeight;
double scale = aspectRatio < 1 ? sy : sx;
AffineTransform m = new AffineTransform();
m.scale(scale, scale);
return m;
}
// Create CRS from custom data
private CoordinateReferenceSystem createCRS() throws FactoryException {
String wkt = "PROJCS[\"NAD_1983_Michigan_GeoRef_Feet_US\"," +
"GEOGCS[\"GCS_North_American_1983\"," +
"DATUM[\"D_North_American_1983\"," +
"SPHEROID[\"GRS_1980\", 6378137.0, 298.257222101]]," +
"PRIMEM[\"Greenwich\", 0.0]," +
"UNIT[\"degree\", 0.017453292519943295]," +
"AXIS[\"Longitude\", EAST]," +
"AXIS[\"Latitude\", NORTH]]," +
"PROJECTION[\"Hotine_Oblique_Mercator\"]," +
"PARAMETER[\"longitude_of_center\", -86.0]," +
"PARAMETER[\"latitude_of_center\", 45.30916666666666]," +
"PARAMETER[\"azimuth\", 337.25555555555593]," +
"PARAMETER[\"scale_factor\", 0.9996]," +
"PARAMETER[\"false_easting\", 8355401.583000001]," +
"PARAMETER[\"false_northing\", -14284780.538]," +
"PARAMETER[\"rectified_grid_angle\", 337.25555555555593]," +
"UNIT[\"foot_survey_us\", 0.3048006096012192]," +
"AXIS[\"X\", EAST]," +
"AXIS[\"Y\", NORTH]]";
CRSFactory crsFactory = ReferencingFactoryFinder.getCRSFactory(null);
CoordinateReferenceSystem crs = crsFactory.createFromWKT(wkt);
return crs;
}
//I'm trying to draw a new dot every 250 milliseconds but it only draws the dot a single time. I have tried fixing it many times, but it still will only paint a single dot, rather than one after 250 milliseconds. Is this a problem with the timer or the paint method? Here is the code:
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Window extends JPanel{
private int size;
private static double maxValue;
private double elevation;
private double vertV;
public double horizV;
public double gravity;
public double range;
public double time;
public double t = 0;
public Window(int s, double v, double e, double v2, double g,double h,double r,double t){
size = s;
maxValue = v;
elevation = e;
vertV = v2;
gravity = g;
horizV = h;
range = r;
time = t;
setPreferredSize(new Dimension(size, size));
}
public void paintComponent(Graphics g){
g.drawLine(size/25, 0,size/25, size);
g.drawLine(0, size - (size/25), size, size - (size/25));
double[] lines = getLine();
int x = size/5 + (size/25), y = size - (size/25);
int x2 = x;
for(int i = 0; i < 4; i++){
g.drawLine(x, y+5, x, y-5);
g.drawString(lines[i]+"",x-size/50,y+size/30);
x+=x2;
}
int yx = size/25, yy = size - (size/5 + (size/25));
int y2 = size/5 + (size/25);
for(int i=0;i<4;i++){
g.drawLine(yx-5, yy, yx+5, yy);
g.drawString(lines[i]+"",yx-size/25,yy+size/30);
yy -= y2;
}
drawDots(g);
}
//this is the place where i make the dots but it only makes one.
//used to be a for loop but i altered it to an if statement so i could paint one dot at a time
public void drawDots(Graphics g)
{
double ratio = (size-((size/25)*2))/maxValue;
double fx;
double xvalue;
// This for loop is where dots are drawn, each iteration draws one dot. It starts at zero, and counts up to the time variable t.
if(t<=time)
{
t+=0.025;
t = Math.round(t*1000.0)/1000.0;
fx = function(t);
xvalue = xfunction(t);
if(fx >= 0){
System.out.print("Time: " + t + " " + "Range: " + xvalue + " " + "Height: ");
System.out.println(fx);
g.drawLine((int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)),
(int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)));
}
}
}
//where i make the timer
//250 mill
public void dostuff()
{
int delay = 250;
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
repaint();
}
};
new Timer(delay, taskPerformer).start();
}
public double xfunction(double t){
double x = 0.0;
x = Math.round(horizV * t * 1000.0)/1000.0;
return x;
}
public double function(double t){
double fx = 0.0;
fx = Math.round((vertV*t + .5*(-(gravity))*(t*t) + elevation)*1000.0)/1000.0;
return fx;
}
private static double[] getLine(){
double increment = maxValue / 4;
double currentLine = 0;
double[] lines = new double[4];
for(int i = 0; i < 4; i++){
currentLine+=increment;
lines[i] = Math.round(currentLine * 10.0)/10.0;
}
return lines;
}
}
This is the original version of the code that displays the projectile's motion, but it does not wait 250 milliseconds between drawing each point:
import javax.swing.JPanel;
import java.awt.*;
public class Window extends JPanel{
private int size;
private static double maxValue;
private double elevation;
private double vertV;
public double horizV;
public double gravity;
public double range;
public double time;
public Window(int s, double v, double e, double v2, double g,double h,double r,double t){
size = s;
maxValue = v;
elevation = e;
vertV = v2;
gravity = g;
horizV = h;
range = r;
time = t;
setPreferredSize(new Dimension(size, size));
}
public void paintComponent(Graphics g){
g.drawLine(size/25, 0,size/25, size);
g.drawLine(0, size - (size/25), size, size - (size/25));
double[] lines = getLine();
int x = size/5 + (size/25), y = size - (size/25);
int x2 = x;
for(int i = 0; i < 4; i++){
g.drawLine(x, y+5, x, y-5);
g.drawString(lines[i]+"",x-size/50,y+size/30);
x+=x2;
}
int yx = size/25, yy = size - (size/5 + (size/25));
int y2 = size/5 + (size/25);
for(int i=0;i<4;i++){
g.drawLine(yx-5, yy, yx+5, yy);
g.drawString(lines[i]+"",yx-size/25,yy+size/30);
yy -= y2;
}
drawDots(g);
}
public void drawDots(Graphics g){
double ratio = (size-((size/25)*2))/maxValue;
double fx;
double xvalue;
// This for loop is where dots are drawn, each iteration draws one dot. It starts at zero, and counts up to the time variable t.
for(double t=0;t<=time; t+=0.025){
t = Math.round(t*1000.0)/1000.0;
fx = function(t);
xvalue = xfunction(t);
if(fx >= 0){
System.out.print("Time: " + t + " " + "Range: " + xvalue + " " + "Height: ");
System.out.println(fx);
g.drawLine((int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)),
(int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)));
}
}
}
public double xfunction(double t){
double x = 0.0;
x = Math.round(horizV * t * 1000.0)/1000.0;
return x;
}
public double function(double t){
double fx = 0.0;
fx = Math.round((vertV*t + .5*(-(gravity))*(t*t) + elevation)*1000.0)/1000.0;
return fx;
}
private static double[] getLine(){
double increment = maxValue / 4;
double currentLine = 0;
double[] lines = new double[4];
for(int i = 0; i < 4; i++){
currentLine+=increment;
lines[i] = Math.round(currentLine * 10.0)/10.0;
}
return lines;
}
}
I'm working on a lab for school and I have it almost completed, but there's one part that I can't get to work. The inheritance works except when I get to Cube. For some reason, it won't calculate the Area or Volume (it just comes up with 0). I'm thinking it's a problem with the way I have the inheritance from Square to Cube. Help would be awesome!
package InheritanceTest;
import javax.swing.JOptionPane;
public class InheritanceTest {
public static void main(String[] args) {
String input = "";
Point point = new Point();
input = getinput("Set variable X");
point.setx(input);
input = getinput("Set variable Y");
point.sety(input);
System.out.println("Point, x = " + point.getx() + " y = " + point.gety());
Square square = new Square();
input = getinput("Set variable Side Length");
square.setSideLength(input);
System.out.println("Square, x = " + point.getx() + " y = " + point.gety()
+ " Area = " + square.getAreaOfSquare() + " Perimeter = "
+ square.getPerimeterOfSquare());
Cube cube = new Cube();
input = getinput("Set variable depth");
cube.setDepth(input);
System.out.println("cube, x = " + point.getx() + " y = " + point.gety()
+ " Depth = " + cube.getDepth() + " Area = " + cube.getAreaOfCube()
+ " Volume = " + cube.getVolumeOfCube());
}
private static String getinput(String string) {
String x = JOptionPane.showInputDialog(string);
return x;
}
}
package InheritanceTest;
public class Cube extends Square {
private int depth;
Cube() {
super();
depth = 0;
}
Cube(int x, int y, int sideLength, int d) {
super(x, y, sideLength);
this.depth = d;
}
public int getAreaOfCube() {
return (6 * sideLength * sideLength);
}
public int getVolumeOfCube() {
return (sideLength * sideLength * sideLength);
}
public String getDepth() {
return Integer.toString(depth);
}
public void setDepth(String i) {
depth = Integer.parseInt(i);
}
}
package InheritanceTest;
public class Point {
private int x;
private int y;
Point() {
x = 0;
y = 0;
}
Point(int x, int y) {
this.x = x;
this.y = y;
}
public String getx() {
return Integer.toString(x);
}
public String gety() {
return Integer.toString(y);
}
public void setx(String input) {
x = Integer.parseInt(input);
}
public void sety(String input) {
y = Integer.parseInt(input);
}
}
package InheritanceTest;
public class Square extends Point {
protected int sideLength;
Square() {
super();
sideLength = 0;
}
Square(int x, int y, int l) {
super(x, y);
this.sideLength = l;
}
public int getAreaOfSquare() {
return sideLength * sideLength;
}
public int getPerimeterOfSquare() {
return sideLength + sideLength;
}
public String getSideLength() {
return Integer.toString(sideLength);
}
public void setSideLength(String input) {
sideLength = Integer.parseInt(input);
}
}
When you create cube (new Cube()) you aren't setting the side length (or x and y) for the Square Object it extends.
Cube(){
// This is the constructor called.
super();
depth = 0;
}
Cube(int x, int y, int sideLength, int d){
super(x, y, sideLength);
this.depth = d;
}
You probably want extract the x,y and length values into variables and use "new Cube(x, y, length, depth)"
Something like the following
String x = getinput("Set variable X");
String y = getinput("Set variable Y");
String sideLength = getinput("Set variable Side Length");
String depth getinput("Set variable depth");
Cube cube = new Cube(x, y, sideLength, depth);
Look at how you are defining getVolumeOfCube(). You are calculating volume with sideLength, but you never set sideLength to any non-zero value. Change sideLength to depth and you will get the value you are looking for.