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

2014/3/9

Need help using vector

1
2
karolis karolis

2014/3/9

#
I have the SmoothMover and vector classes and the class i am working on extending on SmoothMover. This is the code im using to add the vector:
addForce(new Vector(60, 0.5));
I am trying to add a vector initially and when a key is pressed but neither seems to make it move, what am i missing?
danpost danpost

2014/3/9

#
I an not certain, but you probably need something like a 'super.act();' call in your act method so the SmoothMover class can create the movement for the current state (field values -- such as vector, speed, etc).
karolis karolis

2014/3/9

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

import java.util.List;
import java.util.ArrayList;


public class spaceship extends SmoothMover
{
    public static int direction;

    public spaceship()
    {
        addForce(new Vector(60, 0.5));
    }
    
    /**
     * Act - do whatever the spaceship wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */

    public void act() 
    {
        super.act();
        
        keys();
    }
    
    public void keys()
    {
        direction = getRotation();
        if (Greenfoot.isKeyDown("up")  || (Greenfoot.isKeyDown("w")) )
        {
            this.addForce (new Vector(getRotation(), 0.5));
        }
        if (Greenfoot.isKeyDown("left") || (Greenfoot.isKeyDown("a")) )
        {
            setRotation(getRotation() - 3);
        }
        if (Greenfoot.isKeyDown("right") || (Greenfoot.isKeyDown("d")) )
        {
            setRotation(getRotation() + 3);
        }
    }
}
this is what i currently have if it helps, this is my first python project, so yeah.. I couldnt find the source code for SmoothMover or Vector classes so i used the one from someone elses project which worked, might that be the problem? SmoothMover verion 2.1 Vector version 2.0
danpost danpost

2014/3/9

#
ok, I had to look at the SmoothMover class. There is no act method in it, so remove the 'super.act();'. You need to add either a 'move' or a 'setLocation' command somewhere to create the movement (either in the act method or in the keys method)
danpost danpost

2014/3/9

#
You should be able to use the menubar with 'Edit>Import class...' and it should be one of the options to import into your project.
karolis karolis

2014/3/9

#
Yes! Thank you very much! but now ive updated smoothmover to 3.0 and it says 'cannot find symbol - method addForce(Vector) does it matter much if i had the outdated version?
danpost danpost

2014/3/9

#
Maybe that method is something that was added to the class by the person you originally got the SmoothMover class from. Do you still have a Vector class? What is its code?
karolis karolis

2014/3/9

#
Yes, the SmoothMover does have the addForce code The vector code:
import greenfoot.Greenfoot;

/**
 * A 2D vector.
 * 
 * @author Poul Henriksen
 * @author Michael Kolling
 * 
 * @version 2.0
 */
public final class Vector
{
    double dx;
    double dy;
    int direction;
    double length;
    
    /**
     * Create a new, neutral vector.
     */
    public Vector()
    {
    }

    /**
     * Create a vector with given direction and length. The direction should be in
     * the range [0..359], where 0 is EAST, and degrees increase clockwise.
     */
    public Vector(int direction, double length)
    {
        this.length = length;
        this.direction = direction;
        updateCartesian();
    }

    /**
     * Create a vector by specifying the x and y offsets from start to end points.
     */
    public Vector(double dx, double dy)
    {
        this.dx = dx;
        this.dy = dy;
        updatePolar();
    }

    /**
     * Set the direction of this vector, leaving the length intact.
     */
    public void setDirection(int direction) 
    {
        this.direction = direction;
        updateCartesian();
    }
   
    /**
     * Add another vector to this vector.
     */
    public void add(Vector other) 
    {
        dx += other.dx;
        dy += other.dy;
        updatePolar();
    }
    
    /**
     * Set the length of this vector, leaving the direction intact.
     */
    public void setLength(double length) 
    {
        this.length = length;
        updateCartesian();
    }
    
    /**
     * Scale this vector up (factor > 1) or down (factor < 1). The direction
     * remains unchanged.
     */
    public void scale(double factor) 
    {
        length = length * factor;
        updateCartesian();
    }
    
    /**
     * Set this vector to the neutral vector (length 0).
     */
    public void setNeutral() {
        dx = 0.0;
        dy = 0.0;
        length = 0.0;
        direction = 0;
    }
    
    /**
     * Revert to horizontal component of this movement vector.
     */
    public void revertHorizontal() {
        dx = -dx;
        updatePolar();
    }
    
    /**
     * Revert to vertical component of this movement vector.
     */
    public void revertVertical() {
        dy = -dy;
        updatePolar();
    }
    
    /**
     * Return the x offset of this vector (start to end point).
     */
    public double getX() {
        return dx;
    }
     
    /**
     * Return the y offset of this vector (start to end point).
     */
    public double getY() {
        return  dy;
    }
    
    /**
     * Return the direction of this vector (in degrees). 0 is EAST.
     */
    public int getDirection() {
        return direction;
    }
    
    /**
     * Return the length of this vector.
     */
    public double getLength() {
        return length;
    }

    /**
     * Update the direction and length fom the current dx, dy.
     */
    private void updatePolar() 
    {
        this.direction = (int) Math.toDegrees(Math.atan2(dy, dx));
        this.length = Math.sqrt(dx*dx+dy*dy);
    }   
    
    /**
     * Update dx and dy from the current direction and length.
     */
    private void updateCartesian() 
    {
        dx = length * Math.cos(Math.toRadians(direction));
        dy = length * Math.sin(Math.toRadians(direction));   
    }
    
    /**
     * Return a copy of this vector.
     */
    public Vector copy() 
    {
        Vector copy = new Vector();
        copy.dx = dx;
        copy.dy = dy;
        copy.direction = direction;
        copy.length = length;
        return copy;
    }    
}
danpost danpost

2014/3/9

#
I have version 3.0 of the SmoothMover class and it does not contain an 'addVector' method. Please show the code for the 'addVector' method you have.
karolis karolis

2014/3/9

#
There is no 'addVector' string inside the SmoothMover class, but if you meant this?
    /**
     * Increase the speed with the given vector.
     */
    public void addForce(Vector force) 
    {
        movement.add(force);
    }
karolis karolis

2014/3/9

#
also, is there a way to return the current velocity to use it for comparisons?
danpost danpost

2014/3/9

#
And this 'addForce' method is in your 'SmoothMover' 3.0 version? I wonder why it is not in mine. You may have to post that class, as I do not even see a 'movement' field anywhere. There should be some 'get' methods to return values like the velocity in the class.
karolis karolis

2014/3/9

#
it is the SmoothMover 2.1 version that i found on someone elses project
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)

/**
 * A variation of an actor that maintains precise location (using doubles for the co-ordinates
 * instead of ints). It also maintains a current movement in form of a movement vector.
 * 
 * This is a variation of the SmoothMover class presented ealier in the book (version 2.0).
 * This version implements wrap-around movement: when the actor moves out of the world at one
 * side, it enters it again at the opposite edge.
 * 
 * @author Poul Henriksen
 * @author Michael Kolling
 * 
 * @version 2.1
 */
public abstract class SmoothMover extends Actor
{
    public Vector movement;
    private double exactX;
    private double exactY;
    
    public SmoothMover()
    {
        this(new Vector());
    }
    
    /**
     * Create new thing initialised with given speed.
     */
    public SmoothMover(Vector movement)
    {
        this.movement = movement;
    }
    
    /**
     * Move in the current movement direction. Wrap around to the opposite edge of the
     * screen if moving out of the world.
     */
    public void move() 
    {
        exactX = exactX + movement.getX();
        exactY = exactY + movement.getY();
        if(exactX >= getWorld().getWidth()) {
            exactX = 0;
        }
        if(exactX < 0) {
            exactX = getWorld().getWidth() - 1;
        }
        if(exactY >= getWorld().getHeight()) {
            exactY = 0;
        }
        if(exactY < 0) {
            exactY = getWorld().getHeight() - 1;
        }
        super.setLocation((int) exactX, (int) exactY);
    }
    
    /**
     * Set the location from exact coordinates.
     */
    public void setLocation(double x, double y) 
    {
        exactX = x;
        exactY = y;
        super.setLocation((int) x, (int) y);
    }
    
    /**
     * Set the location from int coordinates.
     */
    public void setLocation(int x, int y) 
    {
        exactX = x;
        exactY = y;
        super.setLocation(x, y);
    }

    /**
     * Return the exact x-coordinate (as a double).
     */
    public double getExactX() 
    {
        return exactX;
    }

    /**
     * Return the exact y-coordinate (as a double).
     */
    public double getExactY() 
    {
        return exactY;
    }

    /**
     * Increase the speed with the given vector.
     */
    public void addForce(Vector force) 
    {
        movement.add(force);
    }
    
    /**
     * Accelerate the speed of this mover by the given factor. (Factors < 1 will
     * decelerate.)
     */
    public void accelerate(double factor)
    {
        movement.scale(factor);
        if (movement.getLength() < 0.15) {
            movement.setNeutral();
        }
    }
    
    /**
     * Return the speed of this actor.
     */
    public double getSpeed()
    {
        return movement.getLength();
    }
    
    /**
     * Stop movement of this actor.
     */
    public void stop()
    {
        movement.setNeutral();
    }
    
    /**
     * Return the current speed.
     */
    public Vector getMovement() 
    {
        return movement;
    }
    
    public static double calculateDirection(double x, double y)
    {
        return Math.toDegrees(Math.atan2(y, x));
    }

    public static double calculateMagnitude(double x, double y)
    {
        //return Math.sqrt(x * x + y * y);
        return Math.hypot(x, y);
    }

    public static double calculateX(double dir, double speed)
    {
        return Math.cos(Math.toRadians(dir)) * speed;
    }

    public static double calculateY(double dir, double speed)
    {
        return Math.sin(Math.toRadians(dir)) * speed;
    }
}
karolis karolis

2014/3/9

#
so i used this code for my comparison
getMovement()
but i am comparing it to an integer value using the '<' operand, which are not compatible, how may i resolve this?
danpost danpost

2014/3/9

#
I think you should stick with this 2.1 version for now. The 3.0 version has no references to Vector objects at all. I believe you can just use 'getSpeed()' for the current velocity.
There are more replies on the next page.
1
2