I am doing this project that simulates the solar system using java's stdDraw. I want to make the change where I can show the trace of the corn, because my ultimate goal is to make this corn fly in a heart shape and if I can draw out the trace of the corn I can present the heart. Right now I've been trying to do it, but it seems like the background image is blocking the trace. And if I comment out the background image, all of the planets will show their trace. I don't know what to do, help!!!
Here is the Object Class:
public class BodyExtreme{
public double xxPos;
public double yyPos;
public double xxVel;
public double yyVel;
public double mass;
public String imgFileName;
private static final double G = 6.67e-11;
public BodyExtreme(double xP, double yP, double xV, double yV, double m, String img){
xxPos = xP;
yyPos = yP;
xxVel = xV;
yyVel = yV;
mass = m;
imgFileName = img;
}
public BodyExtreme(BodyExtreme b){
xxPos = b.xxPos;
yyPos = b.yyPos;
xxVel = b.xxVel;
yyVel = b.yyVel;
mass = b.mass;
imgFileName = b.imgFileName;
}
public double calcDistance(BodyExtreme b) {
double dx = b.xxPos - this.xxPos;
double dy = b.yyPos - this.yyPos;
return Math.sqrt(dx * dx + dy * dy);
}
public double calcForceExertedBy(BodyExtreme b) {
if (this.calcDistance(b) == 0) {
return 0;
} else {
return (G * b.mass * this.mass)/(this.calcDistance(b) * this.calcDistance(b));
}
}
public double calcForceExertedByX(BodyExtreme b) {
return (this.calcForceExertedBy(b) * (b.xxPos - this.xxPos) / this.calcDistance(b));
}
public double calcForceExertedByY(BodyExtreme b) {
return (this.calcForceExertedBy(b) * (b.yyPos - this.yyPos) / this.calcDistance(b));
}
public double calcNetForceExertedByX(BodyExtreme[] b) {
int i = 0;
double sum = 0;
while (i < b.length) {
if (this.equals(b[i])) {
sum += 0;
i += 1;
} else {
sum = sum + this.calcForceExertedByX(b[i]);
i += 1;
}
} return sum;
}
public double calcNetForceExertedByY(BodyExtreme[] b) {
int i = 0;
double sum = 0;
while (i < b.length) {
if (this.equals(b[i])) {
sum += 0;
i += 1;
} else {
sum = sum + this.calcForceExertedByY(b[i]);
i += 1;
}
} return sum;
}
public void update(double dt, double fX, double fY) {
double ax = fX / this.mass;
double ay = fY / this.mass;
double vx = this.xxVel + dt * ax;
double vy = this.yyVel + dt * ay;
double px = this.xxPos + dt * vx;
double py = this.yyPos + dt * vy;
this.xxPos = px;
this.yyPos = py;
this.xxVel = vx;
this.yyVel = vy;
}
public void draw() {
StdDraw.picture(this.xxPos, this.yyPos, "images/" + this.imgFileName);
}
public void lonelyplanet_update1(){
this.xxPos = this.xxPos + 45000000;
this.yyPos = this.yyPos + 100000000;
this.draw();
}
}
Here is the Main method class:
import java.util.Scanner;
public class NBodyExtreme{
public static double readRadius(String name) {
In in = new In(name);
int NumPlanets = in.readInt();
double Size = in.readDouble();
return Size;
}
public static BodyExtreme[] readBodies(String name) {
In in = new In(name);
int NumPlanets = in.readInt();
double Size = in.readDouble();
BodyExtreme[] bodies = new BodyExtreme[NumPlanets];
int i = 0;
while (i < NumPlanets) {
bodies[i] = new BodyExtreme(in.readDouble(), in.readDouble(), in.readDouble(), in.readDouble(), in.readDouble(), in.readString());
i += 1;
}
return bodies;
}
public static void main(String[] args) {
double T = Double.parseDouble(args[0]); /** Stoping Time */
double dt = Double.parseDouble(args[1]); /** Time Step */
String filename = args[2];
BodyExtreme[] bodies = readBodies(filename); /** Array of Bodies */
double radius = readRadius(filename); /** Canvas Radius */
In in = new In(filename);
int NumPlanets = in.readInt(); /** Number of Planets */
String imageToDraw = "images/starfield.jpg"; /** Background */
StdDraw.enableDoubleBuffering();
StdDraw.setScale(-2*radius, 2*radius);
StdDraw.clear();
StdDraw.picture(0, 0, imageToDraw); /** Draw Initial Background */
StdDraw.show();
int k = 0;
while (k < NumPlanets-1) { /** Draw Planets */
bodies[k].draw();
k += 1;
}
StdDraw.enableDoubleBuffering();
double time = 0.0;
while (time < T) {
double[] xForces = new double[NumPlanets-1];
double[] yForces = new double[NumPlanets-1];
int i = 0;
while (i < NumPlanets-1) {
xForces[i] = bodies[i].calcNetForceExertedByX(bodies);
yForces[i] = bodies[i].calcNetForceExertedByY(bodies);
i += 1;
}
i = 0;
while (i < NumPlanets-1) {
bodies[i].update(dt, xForces[i], yForces[i]);
i += 1;
}
bodies[NumPlanets-1].lonelyplanet_update1();
bodies[NumPlanets-1].draw();
StdDraw.show();
StdDraw.picture(0, 0, imageToDraw);
int j = 0;
while (j < NumPlanets) {
bodies[j].draw();
j += 1;
}
StdDraw.show();
StdDraw.pause(10);
}
time += dt;
}
}
This is what happens when the trace of route is blocked with the background image:
This is what happens when the trace is not blocked, but I only want the corn's trace not to be blokcekd.
you have a flaw in your animation logic:
to animate your screen you have to
update the model (each element, eg. backgroud or bodY),
then draw each model by using StdDraw.picture(..) and
finally make that content visible (by using StdDraw.show();)
for each time step in your animation (while (time < T){..}) you have to do all three steps.
public static void main(String[] args) {
...
StdDraw.enableDoubleBuffering(); //it's enough to call this only once!
double time = 0.0;
while (time < T) {
//do all the update stuff first, as shown in your code above
//then draw ONCE the BackGround:
StdDraw.picture(0, 0, imageToDraw);
//then draw all the planets (yes, i missed one)
while (j < NumPlanets) {
bodies[j].draw();
j += 1;
}
//finally make all the previous drawing visible
StdDraw.show();
//wait a bit for the next animation step
StdDraw.pause(10);
time += dt;
}
}
Related
I have made a simple perceptron model with java. For visualization I use processing to see results.
Basically, the perceptron gives either negative or positive 1, depending on the location of the given position (float array with 2 values x and y). It is supposed to learn, if a given position is above or below a line.
My code worked fine with a formula of y=x, but has troubles when getting a formula like y=height-x
I tried tweaking the learningStrength, the number of dots it has to guess, changing the bias and line formula.
I can't figure out why it works with the formula y=x, but not with any other...
Class node (Perceptron):
public class Node {
float[] weights;
PApplet pApplet;
float trainingStrength = 0.01f;
public Node(int inputs, PApplet pApplet){
this.weights = new float[inputs + 1];
this.pApplet = pApplet;
for (int i = 0; i < inputs; i++){
this.weights[i] = pApplet.random(1);
}
}
private float activation(float sum){
return Math.signum(sum);
}
public float guess(float[] inputs){
float[] inputsB = addBias(inputs);
if (inputsB.length != weights.length){
return 0;
}
float sum = 0;
for (int i = 0; i < inputsB.length; i++){
sum += inputsB[i] * weights[i];
}
return activation(sum);
}
public void tweak(float[] inputs, int error){
float[] inputsB = addBias(inputs);
for(int i = 0; i < weights.length; i++){
weights[i] += error * inputsB[i] * trainingStrength;
}
}
public float guessY(int x){
float w0 = weights[0];
float w1 = weights[1];
float w2 = weights[2];
return -(w2/w1) - (w0/w1) * x;
}
private float[] addBias(float[] inputs){
float[] inputsB = new float[inputs.length + 1];
for (int i = 0; i < inputs.length; i++) {
inputsB[i] = inputs[i];
if (i + 1 >= inputs.length){
// bias = 1
inputsB[i + 1] = 1;
}
}
return inputsB;
}
}
Class Dot:
public class Dot {
PVector position;
PApplet pApplet;
int answer;
boolean correct;
public Dot(PVector position, PApplet pApplet){
this.position = position;
this.pApplet = pApplet;
}
public void setAnswer(int answer) {
this.answer = answer;
}
public int getAnswer() {
return answer;
}
public PVector getPosition() {
return position;
}
public void guessed(boolean correct) {
this.correct = correct;
}
public void show(){
pApplet.push();
if (!correct) {
pApplet.fill(255, 0, 0);
} else {
pApplet.fill(0,255,0);
}
pApplet.ellipse(position.x,position.y,20,20);
if (answer >= 0){
pApplet.fill(255);
} else {
pApplet.fill(0);
}
pApplet.ellipse(position.x,position.y,10,10);
pApplet.pop();
}
}
Main with processing sketch:
public class NeuralNetworkLibrary extends PApplet{
Node brain;
List<Dot> dots;
int nDots = 1000;
public void settings() {
size(1200,1200);
brain = new Node(2, this);
dots = new ArrayList<>();
for (int i = 0; i < nDots; i++){
dots.add(new Dot(new PVector(random(width), random(height)), this));
dots.get(i).setAnswer((int) Math.signum(formula((int) dots.get(i).getPosition().x) - dots.get(i).getPosition().y));
}
}
public void draw() {
frameRate(1);
background(120);
strokeWeight(1);
for (Dot dot : dots){
int guess = (int) brain.guess(new float[]{dot.getPosition().x,dot.getPosition().y});
int error = dot.getAnswer() - guess;
boolean correct = false;
if (error == 0){
correct = true;
} else {
brain.tweak(new float[]{dot.getPosition().x,dot.getPosition().y}, error);
}
dot.guessed(correct);
dot.show();
}
strokeWeight(5);
line(0, formula(0), width, formula(width));
line(0,brain.guessY(0),width,brain.guessY(width));
}
public int formula(int x){
return x + height / 2;
}
public static void main(String[] args) {
PApplet.main(NeuralNetworkLibrary.class);
}
}
I'm trying to figure out how to count the number of stars that were printed last time the print() method was used.
I'm confused on how to take the value of starsInLastPrint variable into the starsInLastPrint() method. My understanding is that this isn't possible. I assume there are plenty of things wrong with my current code that isn't helping. Below is my current state as I am stuck.
import java.util.Random;
public class NightSky {
private double density;
private int width;
private int height;
private int starsInLastPrint;
public NightSky(double density) {
width = 20;
height = 10;
this.density = density;
}
public NightSky(int width, int height) {
density = 0.1;
this.width = width;
this.height = height;
}
public NightSky(double density, int width, int height) {
this.density = density;
this.width = width;
this.height = height;
}
public void printLine() {
Random starPlacement = new Random();
String[] stars = new String[(this.width)];
for (int i = 0; i < this.width; i++) {
double random = starPlacement.nextDouble();
if (random <= this.density) {
stars[i] = "*";
this.starsInLastPrint++;
} else {
stars[i] = " ";
}
}
int j = 0;
while (j < stars.length) {
System.out.print(stars[j]);
j++;
}
System.out.println("");
}
public void print() {
NightSky nightSky = new NightSky(this.density, this.width, this.height);
this.starsInLastPrint = 0;
int i = 0;
while (i < this.height) {
nightSky.printLine();
i++;
}
}
public int starsInLastPrint() {
return this.starsInLastPrint;
}
}
You are on the right track. Though, you don't need to instantiate another NightSky object inside the print method. You can just do the following,
public void print() {
this.starsInLastPrint = 0;
int i=0;
while (i < this.height) {
printLine();
i++;
}
}
So, everytime you call print, it will update the stars count for that print method call. Here is the whole code,
import java.util.Random;
public class NightSky {
private double density;
private int width;
private int height;
private int starsInLastPrint;
public static void main(String[] args){
NightSky sky = new NightSky(5,5);
sky.print();
System.out.println(sky.starsInLastPrint());
sky.print();
System.out.println(sky.starsInLastPrint());
}
public NightSky(double density) {
width = 20;
height = 10;
this.density = density;
}
public NightSky(int width, int height) {
density = 0.1;
this.width = width;
this.height = height;
}
public NightSky(double density, int width, int height) {
this.density = density;
this.width = width;
this.height = height;
}
public void printLine() {
Random starPlacement = new Random();
String[] stars = new String[(this.width)];
for (int i = 0; i < this.width; i++) {
double random = starPlacement.nextDouble();
if (random <= this.density) {
stars[i] = "*";
this.starsInLastPrint++;
} else {
stars[i] = " ";
}
}
int j = 0;
while (j < stars.length) {
System.out.print(stars[j]);
j++;
}
System.out.println("");
}
public void print() {
this.starsInLastPrint = 0;
int i=0;
while (i < this.height) {
printLine();
i++;
}
}
public int starsInLastPrint() {
return this.starsInLastPrint;
}
}
Sample run of the above code:
* *
*
*
4
0
Hi I want to drawing image inside in Pane , when a bounds are heigh I want to cut image. This image consists of tile. One tile size is 256. Now my full image is bigger tham Pane. I don't know how I can cut image.
Hi I want to draw one large image, which consists of tiles. One tile has dimensions of 256x256. This image is in Pane. At this time, image dimensions are larger than the dimension Pane. I do not know how to do to draw only in Pane. Thanks for help
public class TestURLImage8 {
public static ArrayList<BusStop2> list = new ArrayList<>();
public static ArrayList<PositionTilesAndURLPaths> positionTilesAndURLPathsList = new ArrayList<>();
public static HashMap<String, Image> imgCache = new HashMap<>();
public static double lat;
public static double lon;
public static double deltaY;
public static double deltaX;
public static double positionX;
public static double positionY;
public static int[] imageCount = getCountImage();
public static int [] countImage = countImage();
public static int []x = new int [countImage[0]];
public static int []y = new int [countImage[1]];
private File file = new File("C:/Users/022/workspace22/EkranLCD/res/images/kropka.png");
private Image bus = new Image(file.toURI().toString());
static ArrayList<UtlToImageConverter> threadList = new ArrayList<>();
public TestURLImage8(Pane pane) {
}
/**
* Method use to get count of image what we need
* #return
*/
private static int[] getCountImage(){
int xImageCount = (int) Math.ceil(Main4.width/256);
int yImageCount = (int) Math.ceil(Main4.height/256);
return new int[] {xImageCount, yImageCount};
}
/**
* Method use to get count of tiles
* #return
*/
public static int[] countImage(){
int xImageCount = imageCount[0];
int yImageCount = imageCount[1];
if(xImageCount-1 %2 != 0){
xImageCount = xImageCount + 2;
}
if(yImageCount-1 %2 != 0){
yImageCount = yImageCount + 2;
}
return new int[] {xImageCount, yImageCount};
}
/**
* Method use to get tiles
* #param lat
* #param lon
* #return
*/
private static ArrayList<BusStop2> getTiles(double lat, double lon ){
int [] numberTile = getTileNumber(lat, lon, Config.mapZoom);
int a1 = 1;
int a2 = 1;
int a3 = 1;
int a4 = 1;
x[0] = numberTile[0];
y[0] = numberTile[1];
for (int i = 1; i<x.length; i++){
if(i%2==0){
x[i] = numberTile[0]+(a1);
a1++;
}
else{
x[i] = numberTile[0]-(a2);
a2++;
}
}
for (int i = 1; i<y.length; i++){
if(i%2==0){
y[i] = numberTile[1]+(a3);
a3++;
}
else{
y[i] = numberTile[1]-(a4);
a4++;
}
}
for(int i = 0 ; i<x.length ; i++){
for (int j = 0 ;j<y.length ; j++ ){
list.add(new BusStop2(x[i], y[j], x[0] - x[i], y[0]-y[j]));
}
}
return list;
}
/**
*
* #param list
* #return
*/
private static ArrayList<PositionTilesAndURLPaths> getImgPositionAndURLsPath(ArrayList<BusStop2> list){
for(BusStop2 bus : list){
positionTilesAndURLPathsList.add(new PositionTilesAndURLPaths(256*bus.getX(), 256*bus.getY(),
Config.mapPath + "/" + bus.getA() + "/" + bus.getB() + ".png"));
}
return positionTilesAndURLPathsList;
}
public static int [] getTileNumber(final double lat, final double lon, final int zoom) {
int xtile = (int)Math.floor( (lon + 180) / 360 * (1<<zoom) ) ;
int ytile = (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1<<zoom) ) ;
if (xtile < 0)
xtile=0;
if (xtile >= (1<<zoom))
xtile=((1<<zoom)-1);
if (ytile < 0)
ytile=0;
if (ytile >= (1<<zoom))
ytile=((1<<zoom)-1);
return new int[] {xtile, ytile};
}
static double tile2lon(int x, int z) {
return x / Math.pow(2.0, z) * 360.0 - 180;
}
static double tile2lat(int y, int z) {
double n = Math.PI - (2.0 * Math.PI * y) / Math.pow(2.0, z);
return Math.toDegrees(Math.atan(Math.sinh(n)));
}
public void start(Pane pane ,double lat, double lon) throws Exception {
int [] tiles= getTileNumber(lat, lon, Config.mapZoom);
Canvas canvas = new Canvas(Config.xSize, Config.ySize);
GraphicsContext gc = canvas.getGraphicsContext2D();
int [] aa =getTileNumber(lat,lon, Config.mapZoom);
getTiles(lat,lon);
getImgPositionAndURLsPath(list);
ExecutorService executor = Executors.newFixedThreadPool(10);
ArrayList<UtlToImageConverter2> threadList = new ArrayList<>();
for(PositionTilesAndURLPaths url : positionTilesAndURLPathsList){
threadList.add(new UtlToImageConverter2(url.getPath()));
}
try {
executor.invokeAll(threadList);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println(imgCache.size());
System.out.println( aa[0] + " " + aa[1] );
deltaX = tile2lon(tiles[0] + 1 , Config.mapZoom) - tile2lon(tiles[0], Config.mapZoom);
deltaY = tile2lat(tiles[1], Config.mapZoom) - tile2lat(tiles[1] + 1 , Config.mapZoom);
positionX = (lon - tile2lon(tiles[0], Config.mapZoom)) * Config.imgSize/deltaX;
positionY = (tile2lat(tiles[1], Config.mapZoom) - lat) * Config.imgSize/deltaY;
gc.drawImage(bus,847.0-100 ,621.0-100);
gc.strokeText("aalala", 847.0-10 ,621.0-10);
for(PositionTilesAndURLPaths pos : getImgPositionAndURLsPath(list)){
gc.drawImage(imgCache.get(pos.getPath()),Config.xSize/2-pos.getX()-Config.imgSize/2 ,(Config.ySize/2)- pos.getY()-Config.imgSize/2, Config.imgSize, Config.imgSize);
System.out.println(pos.getX() + " " + pos.getY());
}
gc.drawImage(bus,Config.xSize/2-Config.imgSize/2-Config.markWidth/2+positionX, Config.ySize/2+positionY-Config.imgSize/2-Config.markHeight/2, Config.markWidth, Config.markHeight);
pane.getChildren().add(canvas);
}
#SuppressWarnings("unused")
public static void clear(){
for(PositionTilesAndURLPaths url : positionTilesAndURLPathsList){
url = null;
}
positionTilesAndURLPathsList.clear();
threadList.clear();
for(UtlToImageConverter utl : threadList){
utl = null;
}
for(BusStop2 bus :list){
bus = null;
}
list.clear();
}
}
There are multiple options to display a part of a image in JavaFX:
When using a Canvas node, use the correct drawImage, i.e. the one that does not scale the image to the target rectangle. e.g.
Rectangle2D rectInSource = ...
Rectangle2D targetRect = ...
gc.drawImage(image,
rectInSource.getMinX(),
rectInSource.getMinY(),
rectInSource.getWidth(),
rectInSource.getHeight(),
targetRect.getMinX(),
targetRect.getMinY(),
targetRect.getWidth(),
targetRect.getHeight());
Alternatively you could also use a ImageView for displaying part of a Image by setting the viewport property accordingly:
ImageView imageView = new ImageView(image);
imageView.setViewport(rectInSource);
// ----------- Only required, if rescaling is desired -----------
imageView.setFitWidth(targetRect.getWidth());
imageView.setFitHeight(targetRect.getHeight());
// --------------------------------------------------------------
imageView.relocate(targetRect.getMinX(), targetRect.getMinY());
pane.getChildren().add(imageView);
rectInSource denotes the part of the image that should be displayed, targetRect the position where it should be drawn.
//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;
}
}
Hi all so I a tank war game thats ran over a network and is multiplayer, however whenever I fire a bullet it shows on my screen but not the other player's screen. Can you help, here's a snippet of code form where i think the problem is coming from:
class Tank implements Ball {
double locX, locY, radius, angle;
int self; // index of this tank in WarPanel.tanks
public boolean turnL, turnR, forth, back, fire;
boolean prevtL, prevtR, prevfo;
Color color;
Image image;
public static final double twoPi = Math.PI * 2.0;
public static final double turnRate = Math.PI / 8;
public static final double speed = 4.0;
public static final int RELOAD = 8; // delay between bullets
int count; // timer for reloading
public static final int MAXBULLETS = 7; // max simultaneous shots
Bullet bullets[] = new Bullet[MAXBULLETS];
AffineTransform saveAT; // place to hold current affine transform
public Tank(double x, double y, double a, int index, Image im){
locX = x;
locY = y;
angle = a;
self = index;
image = im;
radius = 22;
// create bullets for this tank
for (int i = 0; i < bullets.length; i++)
bullets[i] = new Bullet(self);
}
public double getX() { return locX; }
public double getY() { return locY; }
public double getRadius() { return radius; }
public boolean isAlive() { return true; }
void update(Boolean local) {
if (turnL)
turnLeft(turnRate);
if (turnR)
turnRight(turnRate);
if (forth){
moveForward();
// Check for rocks
if (WarPanel.hitAnItem(this, WarPanel.rocks) >= 0)
backUp();
}
if (local){
if (turnL != prevtL){
WarPanel.send("turnL "+turnL+" "+locX+" "+locY+" "+angle);
prevtL = turnL;
}
if (turnR != prevtR){
WarPanel.send("turnR "+turnR+" "+locX+" "+locY+" "+angle);
prevtR = turnR;
}
if (forth != prevfo){
WarPanel.send("forth "+forth+" "+locX+" "+locY+" "+angle);
prevfo = forth;
}
}
if (fire){
fireBullet();
}
// Update all of our bullets
for (Bullet b: bullets)
b.update();
}
public void processMove(String s){
// Update movement parameters based on s
Scanner sc = new Scanner(s);
// Get the flag change
String command = sc.next();
boolean value = sc.nextBoolean();
if (command.equals("turnL"))
turnL = value;
else if (command.equals("turnR"))
turnR = value;
else if (command.equals("forth"))
forth = value;
else
System.out.println("Unexpected move: "+command);
// then unpack position update
locX = sc.nextDouble();
locY = sc.nextDouble();
angle = sc.nextDouble();
}
void paint(Graphics g){
// Use the affine transform feature in Graphics2D
// to easily rotate the tank's image.
Graphics2D g2 = (Graphics2D)g;
saveAT = g2.getTransform();
g2.translate(locX, locY);
g2.rotate(angle);
g2.drawImage(image, (int)(-radius), (int)(-radius), null);
// Reset the transform (this is important)
g2.setTransform(saveAT);
// Then draw bullets
for (Bullet b: bullets)
b.paint(g2);
}
void fireBullet(){
// If it has been long enough since the last shot...
count--;
if (count > 0) return;
// ...and if all the bullets aren't currently in use...
int slot = getAvailableBullet();
if (slot < 0)
return;
// ...then launch a new bullet
bullets[slot].setLocation(locX, locY);
bullets[slot].setDirection(angle);
bullets[slot].reset();
// Reset the timer
count = RELOAD;
}
int getAvailableBullet(){
for (int i = 0; i < bullets.length; i++)
if (!bullets[i].isAlive())
return i;
return -1;
}
void turnRight(double a){
angle += a;
if (angle > twoPi)
angle -= twoPi;
}
void turnLeft(double a){
angle -= a;
if (angle < 0.0)
angle += twoPi;
}
void moveForward(){
locX += speed*Math.cos(angle);
locY += speed*Math.sin(angle);
}
void backUp(){
locX -= speed*Math.cos(angle);
locY -= speed*Math.sin(angle);
}
}