This site requires JavaScript, please enable it in your browser!
Greenfoot back
Solringolt
Solringolt wrote ...

2013/6/2

Turn one object around another

Solringolt Solringolt

2013/6/2

#
I would like to make a "guard" that turn around my hero but I'm having some issues. For now I have this code:
public void act() 
    {
        moveAroundHero();
        checkKey();
    }   
    public void moveAroundHero()
    {
        PlayUniverse playUniverse = (PlayUniverse)getWorld();    
        Hero player = playUniverse.getplayer();
        if (player.getY() < getY() && player.getX() < getX())setLocation(getX()+3, getY()-3);
        
        if (player.getY() >= getY() && player.getX() < getX())setLocation(getX()-3, getY()-3);
        
        if (player.getY() >= getY() && player.getX() >= getX())setLocation(getX()-3, getY()+3);
        
        if (player.getY() <= getY() && player.getX() >= getX())setLocation(getX()+3, getY()+3);
    }
    public void checkKey()
    {
        if (Greenfoot.isKeyDown("right"))
        {
            move(5);
        }
        if (Greenfoot.isKeyDown("left"))
        {
            move(-5);
        }
        if (Greenfoot.isKeyDown("up"))
        {
            setLocation(getX(), getY() - 5);
        }
        if (Greenfoot.isKeyDown("down"))
        {
            setLocation(getX(), getY() + 5);
        }
    }
I wanted to make him follow the hero and then add the "turning around" effect but like that I have 2 problems: - as soon as I hit an edge of the world the distance between guard-hero is altered. - it doesn't "turn" around my actor properly How can I fix that or do that?
Gevater_Tod4711 Gevater_Tod4711

2013/6/2

#
To make your actor turn arround a point you can use this methods:
    /**
     * Rotates an Actor arround a given point.
     * 
     * @param rotationPoint
     *      The point arround which the Actor is rotated.
     * 
     * @param rotatedActor
     *      The Actor that is rotated arround a point.
     * 
     * @param angle
     *      The absolute angle the actor should be rotated.
     *      With 0 as a rotation to the right hand side and going on clockwise.
     * 
     * @throws
     *      NullPointerException is thrown if rotatedActor or rotationPoint is null.
     */
    public void rotateArroundPoint(Point rotationPoint, Actor rotatedActor, double angle) throws NullPointerException {
        double distance = getPointsDistance(rotationPoint, new Point(rotatedActor.getX(), rotatedActor.getY()));
        double[] newCoordinates = move(rotationPoint.getX(), rotationPoint.getY(), angle, (int) distance);
        rotatedActor.setRotation((int) angle);
        rotatedActor.setLocation((int) newCoordinates[0], (int) newCoordinates[1]);
    }


    /**
     * The position of an Actor that is moved the given distance into the given direction.
     * 
     * @param currentX
     *      The current x coordinate of the actor.
     * 
     * @param currentY
     *      The current y coordinate of the actor.
     * 
     * @param angle
     *      The angle to which the actor should be moved.
     * 
     * @param distance
     *      The distance the actor should be moved.
     * 
     * @return 
     *      Returns the new coordinates of the actor as a double array.
     */
    public double[] move(double currentX, double currentY, double angle, double distance) {
        double[] coordinates = new double[2];
        angle = Math.toRadians(angle);
        coordinates[0] = currentX + Math.cos(angle) * distance;
        coordinates[1] = currentY + Math.sin(angle) * distance;
        return coordinates;
    }


    /**
     * Calculates the distance between two Points.
     * 
     * @param p1
     *      The first Point.
     * 
     * @param p2
     *      The second Point.
     *      
     * @return
     *      Returns the distance between the two Points as a double value.
     */
    public double getPointsDistance(Point p1, Point p2) throws NullPointerException {
        return Math.hypot(p1.getX() - p2.getX(), p1.getY() - p2.getY());
    }
I'm not shure if they'll work when the actor touches the edge of the world. You'll have to try.
Solringolt Solringolt

2013/6/2

#
I just use rotateArroundPoint() in the actor who has an object turning around? I got an error for Point, Point is not an actor.
Gevater_Tod4711 Gevater_Tod4711

2013/6/2

#
Point is a class in java.awt you find the API here. To create a point of an actors location you can use new Point(actor.getX(), actor.getY()). Like in the discription the point (rotationPoint) is the point the actor turns arround and the actor is the actor that is moved and angle is the absolute angle the object turns.
Solringolt Solringolt

2013/6/2

#
Maybe I don't understand how this method works but with that:
public void act() 
    {
        PlayUniverse playUniverse = (PlayUniverse)getWorld();    
        Hero player = playUniverse.getplayer();
        
        rotateArroundPoint(new Point(player.getX(),player.getY()), this,360);
        

    }   
Everything compils but the object doesn't turn around it just slowly goes to the point...
danpost danpost

2013/6/2

#
Or, you could simply use this method
// instance fields
private int distance;
private int centerX, centerY;

public void orbit()
{
    setLocation(centerX, centerY);
    setRotation(getRotation()+1);
    move(distance);
}
That is the basics to have one object orbit a point. If you also need control over the rotation of the orbiting object, then:
// instance fields
private int distance;
private int centerX, centerY;
private int angle;

public void orbit()
{
    setLocation(centerX, centerY);
    setRotation(angle+1);
    angle = getRotation();
    move(distance);
    // change rotation as needed here
}
Using this avoid all the messy Maths involved and is quite simple.
Solringolt Solringolt

2013/6/3

#
Thx! This works perfectly, I just have the problem when I touch the edges, could I make it disappear until it goes "out of the edge" ?
danpost danpost

2013/6/3

#
You can 'unbound' your world so that actors can go beyond the world edges. In your world class 'super' call, add a Boolean parameter set to false. super( int, int, int, false );
Solringolt Solringolt

2013/6/3

#
Ho my god! Thank you! Didn't know I could do that! Many of my problems just got solved! Haha thx!
You need to login to post a reply.