Hello I have an app where there are circles floating around. At the moment the don't float around, which is the problem. I want them to slowly move around in random directions. How can I do this?
Here is my circle class:
public class data {
public int x,y, size,id;
public data(int x,int y){
this.x = x;
this.y = y;
size = new Random().nextInt(50);
id = new Random().nextInt(10);
}
public void tick(){
}
public void render(Graphics g){
g.setColor(new Color(38,127,0));
g.fillOval(x, y, size, size);
g.setColor(Color.black);
g.drawOval(x, y, size, size);
}
}
You can have a very random movement by adding a random value to x and to y every tick:
private Random random = new Random();
public void tick() {
x = x + random.nextFloat();
y = y + random.nextFloat();
}
This will result in a very fuzzy motion.
Another option is to have 2 variables: motionX and motionY. Those get added to x and y every tick, after which you add random values to motionX and motionY:
private Random random = new Random();
private float xMotion = 0f, yMotion = 0f;
private float factor = 0.5f; //just a value to reduce speed
private void tick() {
x = x + xMotion;
y = y + yMotion;
xMotion = xMotion + random.nextFloat() * factor;
yMotion = yMotion + random.nextFloat() * factor;
}
First of all, I think you messed up which one you should random, you random selected a size and the id(what is this for anyways?), not the x,y value. Also, I don't know why, but it seems that the render program must be called paint.
Related
Hi I just started taking a Java course so this is probably a very stupid question but hopefully someone is willing to help! I'm having issues understanding how to implement a random color generating code into this recursive squares code. (We're using the Princeton course Std library )I've been trying to add certain ones such as:
public Color randomColor()
{
Random random=new Random();
int red=random.nextInt(256);
int green=random.nextInt(256);
int blue=random.nextInt(256);
return new Color(red, green, blue);
}
but I don't know how to call it in my code below to change it from Stdlib's light gray to random colours.
public class Exercise5 {
public static void drawSquare(double x, double y, double size) {
StdDraw.setPenColor(StdDraw.LIGHT_GRAY);
StdDraw.filledSquare(x, y, size/2);
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.square(x, y, size/2);
}
public static void draw(int n, double x, double y, double size) {
if (n == 0) return;
drawSquare(x, y, size);
double ratio = 2.2;
draw(n-1, x - size/2, y - size/2, size/ratio); // lower left
draw(n-1, x - size/2, y + size/2, size/ratio); // upper left
draw(n-1, x + size/2, y - size/2, size/ratio); // lower right
draw(n-1, x + size/2, y + size/2, size/ratio); // upper right
}
public static void main(String[] args) {
//int n = Integer.parseInt(args[0]);
int n = 6;
double x = 0.5, y = 0.5; // center of square
double size = 0.5; // side length of square
draw(n, x, y, size);
}
}
If anyone could point me in the right direction I would really appreciate it! Thank you :)
Since your other methods are static, you'll need to make your randomColor() method static as well.
Then you can use StdDraw.setPenColor(randomColor()); to set a random pen color, or if you want to be more explicit:
Color rand = randomColor();
StdDraw.setPenColor(rand);
Here is the Planet class:
public class Planet extends CelestialBody {
private static Random r = new Random();
private static Star star;
public Planet(Star star, int orbitRadius, int x, int y){
name = "PLACEHOLDER";
radius = Tools.intBetween(Settings.MAX_PLANET_SIZE, Settings.MIN_PLANET_SIZE);
color = Tools.rObjFromArray(Settings.PLANET_COLORS);
this.star = star;
this.orbitRadius = orbitRadius;
this.x = x; this.y = y;
}
public static Planet createNewPlanet(Star star, int orbitRadius){
int px = (int) (star.x + orbitRadius * Math.cos(Math.toRadians(r.nextInt(360))));
int py = (int) (star.y + orbitRadius * Math.sin(Math.toRadians(r.nextInt(360))));
return new Planet(star, orbitRadius, px, py);
}
public void render(Graphics g){
//Draw orbit
g.setColor(Color.white);
g.drawOval(star.x - orbitRadius, star.y - orbitRadius, orbitRadius * 2, orbitRadius * 2);
//Draw planet
g.setColor(color);
g.fillOval(x - radius, y - radius, radius * 2, radius * 2);
}
}
orbitRadius = distance from planet to star (random);
radius = planet's radius (random)
Ask in the comments if you need any more code, and I know this is a noob question, but I just can't figure out why the orbits dont line up with the planets. Thanks.
The problem is in the following two lines:
int px = (int) (star.x + orbitRadius * Math.cos(Math.toRadians(r.nextInt(360))));
int py = (int) (star.y + orbitRadius * Math.sin(Math.toRadians(r.nextInt(360))));
Because you call r.nextInt(360) two separate times, you get a different random number each time.
The consequence is that the x and y coordinates are for different angles, I think it's clear why this would be a problem.
The solution is very simple: call r.nextInt once and save the result:
double randomAngle = Math.toRadians(r.nextInt(360));
int px = (int) (star.x + orbitRadius * Math.cos(randomAngle));
int py = (int) (star.y + orbitRadius * Math.sin(randomAngle));
I think this should solve the problem.
Say I had a 2d side view type game. In this game I have sprites and other objects. The sprite jumps when you click spacebar. The jumping and other things are affected by gravity. I'd have a Gravity class that requires the parameters of an x & y coordinate of the object it's affecting. When its constructed from the Sprite class, I'd give it the x and y of the sprites location as parameters. Then, the gravity class does the necessary math and now has a modified x & y coordinate. How can I update the old x & y in the Sprite class (which is the invoking class) to the new coordinate pair calculated by Gravity (the object which needs to modify the variables in Sprite)?
Extra info:
The x & y variables can't be static. This is all on one thread currently(with the exception of the graphics thread that draws). I could make more threads if needed. I have a swing Timer in the gravity class that starts when the object is created, and is used to calculate the coordinate as an effect of time, velocity, acceleration, etc.
Gravity Class Code:
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class Gravity implements ActionListener {
final double gravAccel = -32.174;
double velocity; // in FPS
double angle; // in degrees
double x; // centralized location of object in feet
double y; // centralized location in feet
double time = 0;
Timer timer;
boolean fired = true;
Point start;
public Gravity(double x, double y, double velocity, double angle, Point start) {
this.x = x;
this.y = y;
this.velocity = velocity;
this.angle = angle;
this.start = start;
initTimer();
}
void initTimer() {
timer = new Timer(10, this);
timer.start();
}
public void fire(double velocity, double angle) {
//timer.start();
x = (velocity * Math.cos(Math.toRadians(angle))) * time + start.getX();
y = 0.5 * gravAccel * Math.pow(time, 2) + (velocity * Math.sin(Math.toRadians(angle))) * time + start.getY();
System.out.println("Time:" + time + " " + x + "," + y);
}
#Override
public void actionPerformed(ActionEvent e) {
time = time + 0.01;
if (fired == true) {
fire(velocity, angle);
}
}
}
Sprite:
public class Sprite {
double x = 10; //how can I modify these from gravity
double y = 10;
Sprite() {
new Gravity(x, y, 100, 45, new Point(0,0));
}
}
Keep a reference to the Sprite in Gravity:
private Sprite;
public Gravity(double x, double y, double velocity, double angle, Point start, Sprite sprite) {
this.sprite = sprite;
...
}
and just pass this from Sprite when you create it:
Sprite() {
new Gravity(x, y, 100, 45, new Point(0,0), this);
}
You could just make x and y public:
public double x = 10;
public double y = 10;
And then access them directly from the sprite class.
I am currently developing a "chaos game" for android. For those that don't know what it is: you pick some random numbers, and according to a given set of rules a dot is drawn somewhere on a canvas; after many iterations you get a shape, always the same.
In this case, it is a fern.
here is my code:
MainActivity.java
public class MainActivity extends Activity {
DrawView drawView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
drawView = new DrawView(this);
setContentView(drawView);
}
}
DrawView.java
public class DrawView extends View{
int viewWidth;
int viewHeight;
int iterations = 10000; // how many dots
int myColor;
Paint paint = new Paint();
Random rand = new Random();
public DrawView(Context context) {
super(context);
myColor = context.getResources().getColor(com.*****.******.*****.R.color.ferncolor); //Green
paint.setColor(myColor);
paint.setAntiAlias(true);
}
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
super.onSizeChanged(xNew, yNew, xOld, yOld);
viewWidth = xNew;
viewHeight = yNew;
}
#Override
public void onDraw(Canvas canvas) {
Double x = rand.nextDouble();
Double y = rand.nextDouble();
Double random;
for(int i = 0; i < iterations; i++){
random = rand.nextDouble();
if(random < 0.01){
x = 0.0;
y *= 0.16;
}
else if(random < 0.86){
x = (0.85 * x) + (0.04 * y);
y = (-0.04 * x) + (0.85 * y) + 1.6;
}
else if(random < 0.93){
x = (0.2 * x) - (0.26 * y);
y = (0.23 * x) + (0.22 * y) + 1.6;
}
else{
x = (-0.15 * x) + (0.28 * y);
y = (0.26 * x) + (0.24 * y) + 0.44;
}
Double posx = viewWidth/2.0 + x*viewWidth/7.5;
Double posy = y*viewHeight/10.2;
canvas.drawCircle(posx.floatValue(), posy.floatValue(), (float) 0.5, paint); //drawing dot at (posx,posy), size 0.5, with custom paint
}
}
}
My problem is that you have to wait for all the point to be drawn before you can see the view. That often leads to several awkward seconds blankness. What I would like is a "refresh" after every iteration (or every x iterations, depending on how much iterations I have).
I think that could be achieved via threading but I have no idea on how to achieve that.
Any ideas?
Thank you!
You can force a view to redraw by calling its invalidate() method. So you can try putting that at the end of your for loop.
More information here.
Also, invalidating too often could cause a performace slowdown, so if you want to draw 10000 dots, you could probably call invalidate only on every 500th iteration or something...
I want an circular movement of an image in JAVA, i thought I have the solution but it doesn't work and i'm a bit clueless now.
For calculating the points it needs to go im using pythagoras to calculate the height (point B).
if it does one round im satisfied but more rounds would be cool.
The image size is around 500 x 300 pixels.
Here's my code :
package vogel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
public class Vogel extends Component {
private int x;
private int r;
private int b;
BufferedImage img;
public vogel() {
try {
img = ImageIO.read(new File("F:/JAVA/workspace/School/src/vogel/vogel.png"));
} catch (IOException e) {
}
r = 60;
x = 10;
}
#Override
public void paint(Graphics g) {
for(int i = -x; i <= x; i++) {
b = (int)Math.sqrt(r^2 - i^2);
g.drawImage(img, x, b, this);
}
}
public static void main(String[] args) {
JFrame f = new JFrame("Vogel");
f.setSize(1000,1000);
f.add(new Vogel());
f.setVisible(true);
for (int number = 1; number <= 1500000; number++) {
f.repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {}
}
}
}
Using your loop in the paint(Graphics) method, it draws 21 birds with one repaint.
You should do it with an angle stored in an object variable and use the Math.sin() and Math.cos() function calculate the x and y position. The angle should be increased with every repaint().
To add:
// To control the radius of moving
private final double MAX_X = 200;
private final double MAX_Y = 200;
private double angle = 0;
#Override
public void paint(Graphics g) {
// increase angle (should be a double value)
angle += 0.1;
// rotate around P(0/0), assuming that 0° is vector (1/0)
int x = (int) (Math.cos(angle) * MAX_X);
int y = (int) (Math.sin(angle) * MAX_Y);
// move P to center of JFrame (width and height = 1000)
x += 500;
y += 500;
// image is 500x300, calc upper left corner
x -= 250;
y -= 150;
// draw
g.drawImage(img, x, y, null);
}
To remove:
private double x, b, r;
So this is the code, try it.
Addition to Sibbo's code to convert angle to rads
private double angle = 0.1;
#Override
public void paint(Graphics g) {
// increase angle (should be a double value
double random = angle * 2.0 * Math.PI/360.0; //this will convert it to rads
// rotate around P(0/0)
int x = (int) (Math.cos(random) * MAX_X);
int y = (int) (Math.sin(random) * MAX_Y);
// move P to center of JFrame (width and height = 1000)
x += 500;
y += 500;
// image is 500x300, calc upper left corner
x -= 250;
y -= 150;
angle++
// draw
g.drawImage(img, x, y, null);
}