Move object in a circle from random location - java

This is about the third time I've asked a question like this. I've already read all the similar questions and the previous help was useful but this time I want to add a new feature to this app. I have an app that makes a ball move in a circle.
Now I want to place the ball at a random location on the screen and then move in a circle. I think I've got the logic mostly correct but the ball jumps around erratically - no matter how much I play with the math. Code is below.
Does anyone know what I'm doing wrong?
public class DrawingTheBall extends View {
Bitmap bball;
int randX, randY;
double theta;
public DrawingTheBall(Context context) {
super(context);
// TODO Auto-generated constructor stub
bball = BitmapFactory.decodeResource(getResources(), R.drawable.blueball);
randX = 1 + (int)(Math.random()*500);
randY = 1 + (int)(Math.random()*500);
theta = 45;
}
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Rect ourRect = new Rect();
ourRect.set(0, 0, canvas.getWidth(), canvas.getHeight()/2);
float a = 50;
float b = 50;
float r = 50;
int x = 0;
int y = 0;
theta = theta + Math.toRadians(2);
Paint blue = new Paint();
blue.setColor(Color.BLUE);
blue.setStyle(Paint.Style.FILL);
canvas.drawRect(ourRect, blue);
if(x < canvas.getWidth()){
x = randX + (int) (a +r*Math.cos(theta));
}else{
x = 0;
}
if(y < canvas.getHeight()){
y = randY + (int) (b +r*Math.sin(theta));
}else{
y = 0;
}
Paint p = new Paint();
canvas.drawBitmap(bball, x, y, p);
invalidate();
}
}

Do you really mean to generate new random values for randX and randY on every pass trough onDraw()? If I understand you right, this bit should be moved in to the constructor:
int randX = 1 + (int)(Math.random()*500);
int randY = 1 + (int)(Math.random()*500);
edit: Also, remove the "int"s as so:
randX = 1 + (int)(Math.random()*500);
randY = 1 + (int)(Math.random()*500);
This way will assign values to your class-level variables instead of creating local variables (which never get read). If that doesn't make sense, here's a clearer explanation:
class foo {
int x = 1; // this is a class-level variable
public foo() {
bar1();
System.out.println(x); // result: 1
bar2();
System.out.println(x); // result: 2
}
public void bar1() {
int x = 2; // This instantiated a new
// local variable "x", it did not
// affect the global variable "x"
}
public void bar2() {
x = 2; // This changed the class var
}
}

Related

Anything declared in a method of Java is local (except in some special cases), is that right?

public class Triangle {
double area;
int height;
int length;
public static void main(String [] args) {
int x = 0;
Triangle [ ] ta = new Triangle[4];
while ( x < 4 ) {
ta[x] = new Triangle();
ta[x].height = (x + 1) * 2;
ta[x].length = x + 4;
ta[x].setArea();
System.out.print("triangle "+x+", area");
System.out.println(" = " + ta[x].area);
x = x + 1;
}
int y = x;
x = 27;
Triangle t5 = ta[2];
ta[2].area = 343;
System.out.print("y = " + y);
System.out.println(", t5 area = "+ t5.area);
}
void setArea() {
ta[x].area = (height * length) / 2;
}
}
$javac Triangle.java
Triangle.java:25: error: cannot find symbol
ta[x].area = (height * length) / 2;
^
symbol: variable ta
location: class Triangle
Triangle.java:25: error: cannot find symbol
ta[x].area = (height * length) / 2;
^
symbol: variable x
location: class Triangle
2 errors
Of course I soon find that I need to take "ta[x]." thing off the setArea method, that's clear, but now I'm wondering why I cannot put a previously-declared Triangle array before that area function.
Is it because within the method, all things are local and you can't use variables which aren't declared in that method even if you've already declared them in other parts of code? Thank you guys.
x ta are local variable their scope are limited their respective function outside the scope you can not reference it.
Just pass the reference.
public class Triangle {
double area;
int height;
int length;
public static void main(String [] args) {
int x = 0;
Triangle [ ] ta = new Triangle[4];
while ( x < 4 ) {
ta[x] = new Triangle();
ta[x].height = (x + 1) * 2;
ta[x].length = x + 4;
ta[x].setArea(ta[x]);
System.out.print("triangle "+x+", area");
System.out.println(" = " + ta[x].area);
x = x + 1;
}
int y = x;
x = 27;
Triangle t5 = ta[2];
ta[2].area = 343;
System.out.print("y = " + y);
System.out.println(", t5 area = "+ t5.area);
}
void setArea(Triangle t) {
t.area = (height * length) / 2;
}
}
ta,x variable scope limited to Main() funtion
The question you have asked is related to the concept of scope of a variable in java.
Any variable declared inside {}, can be accessible inside those{} only. Outside the {},variables are not accessible.
In your code area is instance variable of class Triangle having length and height as instance variables.
So to calculate area you can directly use length and height. like
area=length*height
To calculate the area of perticular object call it through that object or you can pass triangle object as mentioned in previous post posted by user207421
You have couple of the problems in the snippet. Let me show you:
It's better to use immutable objects whenever it's possible. Imagine if someone will use your Triangle and forget to invoke setArea();
One of OOP's principles is encapsulation, so you should avoid access to the class's variables directly (only with getters);
In general, you should store minimum information. E.g. setArea() should be moved directly to the Triangle class. Moreover, it's pretty simple to calculate and it's better to do it
And finally look at division operation; before doing / you have to cast the result to the double. If you do (int + int) / int - the result will always be an integer.
Please check my solution:
// class is final (this is not mandatory)
public final class Triangle {
// variables are final (in general this is good approach)
// variables are private (access only via getters)
private final int width;
private final int height;
public Triangle(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
// 2.0 is very important, here we cast (width * height) to double before division
public double getArea() {
return (width * height) / 2.0;
}
}
public class Main {
public static void main(String... args) {
Triangle[] triangles = createTriangles(4);
print(triangles);
}
private static Triangle[] createTriangles(int total) {
Triangle[] triangles = new Triangle[total];
// for loops letters like i,j,k are more common (x is mostly to 2D)
for (int i = 0; i < triangles.length; i++) {
int width = i + 4;
int height = (i + 1) * 2;
triangles[i] = new Triangle(width, height);
}
return triangles;
}
private static void print(Triangle... triangles) {
if (triangles != null)
for (int i = 0; i < triangles.length; i++)
System.out.format(Locale.ENGLISH, "triangle %d, area = %.2f",
i, triangles[i].getArea());
}
}
The setArea() mehtod is part of the class triangle,so there is no issue in calculating area of a trisngle.
public class Triangle {
double area;
int height;
int length;
public double setArea(){
return area=(length*height)/2;
}
public static void main(String[] args) {
int x=0;
Triangle [ ] ta = new Triangle[4];
while ( x < 4 ) {
ta[x] = new Triangle();
ta[x].height = (x + 1) * 2;
ta[x].length = x + 4;
ta[x].setArea();
System.out.print("triangle "+x+", area");
System.out.println(" = " + ta[x].area);
x = x + 1;
}
int y = x;
x = 27;
Triangle t5 = ta[2];
ta[2].area = 343;
System.out.print("y = " + y);
System.out.println(", t5 area = "+ t5.area);
}
}

Android Canvas.How to calculate difference between centres in loop?

I new android. Trying to implement bouncing ball each other. Like this
My BouncingBallView class look like:
private ArrayList<Ball> balls;
public BouncingBallView(Context context) {
super(context);
this.balls = new ArrayList<>();
for(int i=0; i<2; i++)
this.balls.add(addBall());
}
public Ball addBall(){
Ball ball;
// Init the ball at a random location (inside the box) and moveAngle
Random rand = new Random();
int radius = 60;
int x = rand.nextInt(500 - radius * 2 - 20) + radius + 10;
int y = rand.nextInt(800- radius * 2 - 20) + radius + 10;
int speed = 10;
int angleInDegree = rand.nextInt(360);
ball = new Ball(x, y, radius, speed, angleInDegree);
return ball;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(int i=0; i < balls.size(); i++)
balls.get(i).draw(canvas);
for(int i=0; i < balls.size(); i++){
balls.get(i).intersect(canvas);
// Update the ball's state with proper collision response if collided.
balls.get(i).update();
}
for(int i=0; i<balls.size(); i++){
balls.get(i).collide(balls);
}
invalidate();
}
And class Ball has method collide();
public void collide(ArrayList<Ball> balls){
//Log.d("TEst", "LOG");
// Calculate difference between centres
float distX = balls.get(0).getBallX() - balls.get(1).getBallX();
float distY = balls.get(0).getBallY() - balls.get(1).getBallY();
// Get distance with Pythagora
double dist = Math.sqrt((distX * distX) + (distY * distY));
float r = ballRadius + ballRadius;
if ((float) dist <= r) {
Log.d("Collide", "Detected");
this.ballSpeedX = -this.ballSpeedX;
this.ballSpeedY = -this.ballSpeedY++;
}
/*for(int i=0; i < balls.size(); i++) {
for(int j=1; j<balls.size(); j++) {
// Calculate difference between centres
float distX = balls.get(i).getBallX() - balls.get(j).getBallX();
float distY = balls.get(i).getBallY() - balls.get(j).getBallY();
// Get distance with Pythagora
double dist = Math.sqrt((distX * distX) + (distY * distY));
*//*double distance = Math.sqrt(((balls.get(0).getBallX() - balls.get(1).getBallX()) * (balls.get(0).getBallX() - balls.get(1).getBallX())) + ((balls.get(0).getBallY()
- balls.get(1).getBallY()) * (balls.get(0).getBallY() - balls.get(1).getBallY())));*//*
float r = ballRadius + ballRadius;
if ((float) dist <= r) {
Log.d("Collide", "Detected");
this.ballSpeedX = -this.ballSpeedX;
this.ballSpeedY = -this.ballSpeedY++;
}
}
}*/
}
Here, I'm using Pythagoras' theorem, a^2 + b^2 = c^2, to figure out the distance between the two circles' centers. How to calculate if ball count > 2. I try to in loop but it works very bad(frozen ball).
Full code you can find github
Now work like in this video my bouncing ball video
Thx for help ;)
P.s Sorry so poor English.
You can have a counter for balls in each stage, when a ball is destroyed(if you destroy them) you can change the count and you can check (the counter) in the collide method.
But i don't thing that you need to check this condition, if a collision happens then OK else nothing should happen to this method.

Simulating swimming objects (like fish) in a circular pond (in Java)

public class Pond {
public static void allcreationco(){
for (int i = 0; i < 100; i++){
int radius = 100;
int x = (int) (Math.random() * 2 * radius - radius);
int ylim = (int) Math.sqrt(radius * radius - x * x);
int y = (int) (Math.random() * 2 * ylim - ylim);
Fish.xfishc.add((int) x);
Fish.yfishc.add((int) y);
}
allcreationdir();
}
public static void allcreationdir(){
for (int i = 0; i < Fish.xfishc.size(); i++){
double radius = Math.random()*1;
double angle = Math.random()*2*Math.PI;
double x = Math.cos(angle)*radius + 0;
if (x > 0){
Fish.xfishcb1.add(true);
}
else {
Fish.xfishcb1.add(false);
}
}
for (int i = 0; i < Fish.yfishc.size(); i++){
double radius = Math.random()*1;
double angle = Math.random()*2*Math.PI;
double x = Math.cos(angle)*radius + 0;
if (x > 0){
Fish.yfishcb1.add(true);
}
else {
Fish.yfishcb1.add(false);
}
}
Hi, my objective is to create a simulation (no visual drawing needed, just something to easily print info about) of a circular pond with fish randomly swimming in it. The code above is a way of initiating 100 hypothetical fish into Arraylists in the form of x and y coordinates based on a hypothetical circle with a radius of 100 (there's gotta be a better way to do this). I would like to have each of the 100 fish be able to swim in random directions and change to new random directions every time they reach the end of the pond. Maybe I'd like them to reproduce after a certain time, or include another fish that moves in straight lines and can eat another fish.
public class Salmon extends Fish {
public static int salmonre = 0;
public static void salmonmove(){
for (int i = 0; i < xfishc.size(); i++){
if (xfishcb1.get(i) == true){
int d = xfishc.get(i);
int e = d + 1;
xfishc.set(i , e);
}
else{
int d = xfishc.get(i);
int e = d - 1;
xfishc.set(i , e);
}
}
for (int i = 0; i < yfishc.size(); i++){
if (yfishcb1.get(i) == true){
int d = yfishc.get(i);
int e = d + 1;
yfishc.set(i , e);
}
else{
int d = yfishc.get(i);
int e = d - 1;
yfishc.set(i , e);
}
}
salmonre++;
}
}
I also used Boolean arraylists to randomly determine what directions the fish are supposed move in. Please be gentle with me in your rhetoric because I'm well aware that my approaches are ridiculous. I know it's best to use trigonometry when simulating objects and their behaviors in a circle, but for some reason, I'm not able to wrap my head around this when looking on the internet (I keep finding things more complicated that involve visual illustrations). Could you "please" give me comprehensive answers with ideas? I'm frustrated.
I wasn't entirely able to figure out how you wanted your Fish class to work based on your code, but some tips:
In Object Oriented programming, you do not want to have a class Fish that has static methods for updating two lists containing X and Y coordinates for all the fish.
Instead, you want an object of class Fish to represent everything about a single fish. You can then have a list of Fish objects.
A pair of booleans is really too coarse for directions. Use a double instead, one for each fish (stored in the Fish instance).
To implement the direction changing behavior, just check whether the next move would move the fish out of the water, and if so, pick a different direction.
Here's a simple, self contained example of the above for two Fish. They start out together and in the same direction, but diverge when they hit the edge and swim in different, random directions:
class Fish {
private double x, y;
private double angle, speed;
public Fish() {
x = y = angle = 0;
speed = 5;
}
void move() {
// If we swim at this angle, this is where we'll end up
double newX = x + Math.cos(angle) * speed;
double newY = y + Math.sin(angle) * speed;
if (isInPond(newX, newY)) {
// That's still in the pond, go there
x = newX;
y = newY;
} else {
// That's outside the pond, change direction
angle = Math.random() * 2 * Math.PI;
}
}
public String toString() {
return String.format(
"Position: %.0f,%.0f. Angle: %.0f degrees.",
x, y, angle * 180/Math.PI);
}
// Check whether some coordinates are within a circular pond with radius 100
static boolean isInPond(double x, double y) {
return Math.sqrt(x*x+y*y) < 100;
}
public static void main(String[] args) throws Exception {
Fish nemo = new Fish();
Fish marlin = new Fish();
while(true) {
nemo.move();
marlin.move();
System.out.println("Nemo: " + nemo);
System.out.println("Marlin: " + marlin);
Thread.sleep(500);
}
}
}

Detect Collision of multiple BufferedImages Java

I am making a 2d rpg game in java and I have run into a problem. I can make the player move around the stage and I have rocks, trees, walls, etc. on the stage as well. I don't know how to detect the collision and make it to where the player can't move through the object. The code that reads map file and draws image on the canvas is as follows:
public void loadLevel(BufferedImage levelImage){
tiles = new int[levelImage.getWidth()][levelImage.getHeight()];
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
Color c = new Color(levelImage.getRGB(x, y));
String h = String.format("%02x%02x%02x", c.getRed(),c.getGreen(),c.getBlue());
switch(h){
case "00ff00"://GRASS Tile - 1
tiles[x][y] = 1;
break;
case "808080"://Stone -2
tiles[x][y] = 2;
break;
case "894627"://Dirt -3
tiles[x][y] = 3;
break;
case "404040"://Rock on Grass -4
tiles[x][y] = 4;
break;
case "00b700"://Tree -5
tiles[x][y] = 5;
break;
case"000000"://Wall -6
tiles[x][y] = 6;
break;
case "cccccc"://Rock on stone -7
tiles[x][y] = 7;
break;
default:
tiles[x][y] = 1;
System.out.println(h);
break;
}
}
}
}
And the player class is as follows:
public class Player {
private int x,y;
public int locx,locy;
private Rectangle playerR;
private ImageManager im;
public boolean up =false,dn = false,lt=false,rt=false,moving = false,canMove = true;
private final int SPEED =2;
public Player(int x, int y, ImageManager im){
this.x = x;
this.y = y;
this.im = im;
locx = x;
locy = y;
playerR = new Rectangle(x,y,16,16);
}
public void tick(){
if (up) {
if(canMove){
y -= SPEED;
locx = x;
locy = y;
playerR.setLocation(locx, locy);
moving = true;
}
else{
y += 1;
canMove=true;
}
}
if (dn) {
y +=SPEED;
locx = x;
locy = y;
moving = true;
}
}
if (lt) {
x -= SPEED;
locx = x;
locy = y;
moving = true;
}
if (rt) {
x+=SPEED;
locx = x;
locy = y;
moving = true;
}
}
if(moving){
System.out.println("PLAYER\tX:"+locx+" Y:"+locy);
moving = false;
}
}
public void render(Graphics g){
g.drawImage(im.player, x, y, Game.TILESIZE*Game.SCALE, Game.TILESIZE*Game.SCALE, null);
}
}
I don't really know how to do collision, but i googled it and people said to make a rectangle for the player and all the objects that the player should collide with, and every time the player moves, move the player's rectangle. Is this the right way to do this?
EDIT EDIT EDIT EDIT
code for when collision is true:
if (rt) {
x+=SPEED;
locx = x;
locy = y;
playerR.setLocation(locx, locy);
for(int i = 0;i<Level.collisions.size();i++){
if(intersects(playerR,Level.collisions.get(i))==true){
x-=SPEED;
locx = x;
playerR.setLocation(locx, locy);
}
}
moving = true;
}
And the intersects method is as follows:
private boolean intersects(Rectangle r1, Rectangle r2){
return r1.intersects(r2);
}
I'm going to focus on your tick method since that is where most of this logic is going. There are a couple changes here. Most notably, we only move the rectangle before checking for collisions. Then loop through all the collideable objects in your level. Once one is found, we reset our x and y and break out of the loop (no sense in looking at any of the other objects since we already found the one we collided with). Then we update our player position. By doing it this way, I centralized the code so it is not being repeated. If you ever see yourself repeating code, there is a pretty good chance that it can be pulled out to a common place, or to a method.
public void tick() {
if (up) {
y -= SPEED;
} else if (dn) {
y += SPEED;
} else if (lt) {
x -= SPEED;
} else if (rt) {
x += SPEED;
}
playerR.setLocation(x, y);
for (Rectangle collideable : Level.collisions) {
if (intersects(playerR, collideable)) {
x = locx;
y = locy;
playerR.setLocation(x, y);
break;
}
}
locx = x;
locy = y;
}
There are different ways to do that. As you talk about a "rpg" i think your view is Isometric (45° top down).
I would do the collision detection in pure 90° top down, as it is easier and, imho, more realistic.
We have 2 possibilities:
Move your Player to the next position. If there is a collision, reset his position.
Calculate the next position, if there would be a collision don't move.
If you want to have a "gliding" collision response, you have to check in which axis the collision will happen, and stop / reset movement for this axis only.
To have a more efficient collision detection only check near objects, which will possibly collide.
Do this by comparing a squared "dangerRadius" with the squared distance between your player and the object:
if ((player.x - object.x)² + (player.y - object.y)² <= dangerRadius²)
// Check for intersection
This will sort out most of the objects by using a simple calculation of:
2 subtractions
1 addition
3 multiplications (the ²)
1 compare (<=)
In your game you should sepparate the logic and the view. So basicly you don't detect, if the two images overlapp, but you check, if the objects in your logic overlap. Then you draw the images on the right position.
Hope this helps.
EDIT: Important: If you update your character, depending on the time between the last and this frame (1/FPS) you have to limit the max timestep. Why? Because if for some reason (maybe slow device?) the FPS are really low, it is possible, that the character moves verry far between 2 frames and for that he could go through an object in 1 frame.
Also if you simply reset the movement on collision or just don't move the distance between you and the object could be big for low FPS. For normal FPS and not to high movementspeed this won't happen/ be noticeable.
I personally am fairly new to Java, though I have worked with C# in the past. I am making a similar game, and for collision detection I just check the locations of the player and objects:
if (z.gettileX() == p.gettileX()){
if (z.gettileY() == p.gettileY()){
System.out.println("Collision!");
}
}
If the player (p) has equal X coordinates and Y coordinates to z(the bad guy), it will send this message and confirm that the two have, in fact, collided. If you can make it inherent in the actual class behind z to check if the coordinates a equal, you can create an unlimited number of in-game objects that detect collision and react in the same way, i.e. walls.
This is probably what your looking for. I've made this class spicificly for collision of multiple objects and for individual side collisions.
abstract class Entity {
private Line2D topLine;
private Line2D bottomLine;
private Line2D leftLine;
private Line2D rightLine;
private Rectangle rectangle;
private Entity entity;
protected boolean top;
protected boolean bottom;
protected boolean left;
protected boolean right;
protected int x;
protected int y;
protected int width;
protected int height;
public Entity(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
updateLinesAndRects();
}
public void updateLinesAndRects() {
topLine = new Line(x + 1, y, width - 2, 0);
bottomLine = new Line(x + 1, y + height, width - 2, height);
leftLine = new Line(x, y + 1, 0, height - 2);
rightLine = new Line(x + width, y + 1, 0, height - 2);
rectangle = new Rectangle(x, y, width, height)
}
public void setCollision(Entity entity) {
this.entity = entity;
top = isColliding(new Line2D[]{topLine, bottomLine, leftLine, rightLine});
bottom = isColliding(new Line2D[]{bottomLine, topLine, leftLine, rightLine});
left = isColliding(new Line2D[]{leftLine, topLine, bottomLine, rightLine});
right = isColliding(new Line2D[]{rightLine, topLine, bottomLine, leftLine});
}
public void updateBounds() {
if(top) y = entity.y + entity.height;
if(bottom) y = entity.y - height;
if(left) x = entity.x + entity.width;
if(right) x = entity.x - width;
}
public boolean isColliding() {
return rectangle.intersects(entity.rect);
}
private boolean isLinesColliding(Line2D[] lines) {
Rectangle rect = entity.getRectangle();
return lines[0].intersects(rect) && !lines[1].intersects(rect) && !lines[2].intersects(rect) && !lines[3].intersects(rect);
}
private Line2D line(float x, float y, float width, float height) {
return new Line2D(new Point2D.Float(x, y), new Point2D.Float(x + width, x + height));
}
public Rectangle getRectangle() {
return rectangle;
}
}
Example:
class Player extends Entity{
Entity[] entities;
public Player(int x, int y, int width, int height) {
super(x, y, width, height);
}
public void update() {
updateLinesAndRects();
for(Entity entity : entities) {
setCollision(entity);
if(top) system.out.println("player is colliding from the top!");
if(isColliding()) system.out.println("player is colliding!");
updateBounds(); // updates the collision bounds for the player from the entities when colliding.
}
}
public void setEntities(Entity[] entities) {
this.entities = entities;
}
}

Trouble making object move in a circle

I'm new to animation in android. I'm working with a tutorial I have found on youtube. The app draws a picture of a ball on a canvas and then moves diagonally. I'd like to make the ball move in a circle. I've found some information about the basic math of circular motion but I'm having trouble implementing it. Could someone look at my code and tell me what I'm doing wrong. Thanks.
Here is my code:
public class DrawingTheBall extends View {
Bitmap bball;
int x,y;
public DrawingTheBall(Context context) {
super(context);
// TODO Auto-generated constructor stub
bball = BitmapFactory.decodeResource(getResources(), R.drawable.blueball);
x = 0;
y = 0;
}
#Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Rect ourRect = new Rect();
ourRect.set(0, 0, canvas.getWidth(), canvas.getHeight()/2);
float a = 10;
float b = 10;
float r = 20;
double theta = 0;
theta = Math.toRadians(45);
Paint blue = new Paint();
blue.setColor(Color.BLUE);
blue.setStyle(Paint.Style.FILL);
canvas.drawRect(ourRect, blue);
if(x < canvas.getWidth()){
//x += 10;
x = (int) (a +r*Math.cos(theta));
}else{
x = 0;
}
if(y < canvas.getHeight()){
//y += 10;
y = (int) (b +r*Math.sin(theta));
}else{
y = 0;
}
Paint p = new Paint();
canvas.drawBitmap(bball, x, y, p);
invalidate();
}
}
Basically you need to use the Sine and Cosine trigonometric functions, which given the angle will give you the ratios of the corresponding x, and y coordinates on your screen.
something along:
double x = a + r * sin(angle);
double y = b + r * cos(angle);
should work.
where:
r - is the radius of the circle
(a,b) - is the center of the circle
angle - is the desired angle
Of course you need to increment the angle, in order for your object to move.
Mathematically a point on the circle is defined by an angle theta and a distance from the center radius. In your code the angle is a constant 100 so it never moves on the circle. What you want to do is increase the angle in your update.
theta = theta + Math.toRadians(10);
x = a + r*Math.cos(theta);
y = b + r*Math.sin(theta);
This will let you move on a circle that centers on (a,b) with radius r, 10 degrees at a time.
To your comment, add theta as a field and don't set it to 45 inside onDraw, if you want to start at 45 degrees you can initialize it to 45 inside your constructor.
int x,y;
to
int x,y, theta;
To your comment
int x,y, theta;
public DrawingTheBall(Context context) {
super(context);
bball = BitmapFactory.decodeResource(getResources(), R.drawable.blueball);
x = 0;
y = 0;
theta = 45;
}
And
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Rect ourRect = new Rect();
ourRect.set(0, 0, canvas.getWidth(), canvas.getHeight()/2);
float a = 10;
float b = 10;
float r = 20;
// double theta = 0; //You are using a local variable that shadows the field, it starts at 0 everytime
// theta = Math.toRadians(45); //You are setting it to 45 degrees everytime, instead:
theta = theta + Math.toRadians(10); //Increase of 10 degrees
Paint blue = new Paint();
blue.setColor(Color.BLUE);
blue.setStyle(Paint.Style.FILL);
canvas.drawRect(ourRect, blue);
if(x < canvas.getWidth()){
//x += 10;
x = (int) (a +r*Math.cos(theta));
}else{
x = 0;
}
if(y < canvas.getHeight()){
//y += 10;
y = (int) (b +r*Math.sin(theta));
}else{
y = 0;
}
Paint p = new Paint();
canvas.drawBitmap(bball, x, y, p);
invalidate();
}
Take a look at this post from another SO ticket, seems very similar.
Android - Moving an object in circle

Categories