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

2017/11/7

getting variable form world to actor

NielsV5B NielsV5B

2017/11/7

#
I'm trying to make my actor called Enemy sequentially move to 3 points. The X and Y coordinates are specified in my World called MyWorld by means of a matrix. In the code of MyWorld I'm giving the public (int) variables ex1 (x-coordinate of enemy's target 1), ey2 (y-coordinate of enemy's target 1), ex2, ey2, ex3 and ey3. Then in the actor Enemy I've got the private (int) variables called pointx1, pointy2 etc. To set the pointx1 variables equal to the ex1 variables I've got the next code in the constructor of Enemy: if (getWorld() != null) { pointx1 = ((MyWorld) getWorld()).getEX1(); pointy1 = ((MyWorld) getWorld()).ey1; pointx2 = ((MyWorld) getWorld()).ex2; pointy2 = ((MyWorld) getWorld()).ey2; pointx3 = ((MyWorld) getWorld()).ex3; pointy3 = ((MyWorld) getWorld()).ey3; } After that, in the act of the Enemy, I'm using the turnTowards method to move the Enemy sequentially to between the 3 points. if (getX() == pointx1 && getY() == pointy1) { turnTowards(pointx2, pointy2); passed1 = true; } else if (getX() == pointx2 && getY() == pointy2) { if( passed1 == true ) { turnTowards(pointx3, pointy3); } else { turnTowards(pointx1, pointy1); } } else if (getX() == pointx3 && getY() == pointy3) { turnTowards(pointx2, pointy2); passed1 = false; } else { turnTowards(pointx1, pointy1); } But it doesn't work, the enemy keeps moving to the point while none of the points I placed are on that position. By the way: the order of the points I placed are like this: . point3 point 2 . point 1
danpost danpost

2017/11/7

#
Main issue is that you will never get the points coordinates from the world from the constructor that way. The constructor is executed before the actor can be placed into a world and 'getWorld' will always return a 'null' value there. You can make use of the 'addedToWorld' method to access the coordinate values. Something to be aware of is that if moving by one, the actor will move horizontally and/or diagonally while moving toward the current point and unless you continually use 'turnTowards' while moving toward it, you will usually miss it terribly (you will only reach the point only if it happens to be exactly on its line of movement which will be along an angle that is an exact multiple of 45 degrees). However, if it moves more than one cell at a time, you will come a lot closer; but, still not guaranteed to be exactly in line with the point. Also, now you could end up skipping over the point. Another issue is with your current code, the actor moves blindly -- not knowing which point it was pointed towards. First and foremost, it would be best to keep a reference to the point currently going towards using destination coordinates. Second, control the position and rotation of the actor more accurately. My QActor support class can help in this regard. It helps keep accurate track of the position and the rotation of the actor with good precision. It can be found in my Asteroids w/Improved QActor class scenario. You will still have to check if skipping over a point if moving faster than one.
NielsV5B NielsV5B

2017/11/8

#
Thanks for quick response. I've tried it, but it's still isn't working. This is my code now. I'm now testing by only letting it turn to point 1.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Enemy extends  Movers
{
    private boolean canSeePlayer;
    private int pointx1;
    private int pointy1;
    private int pointx2;
    private int pointy2;
    private int pointx3;
    private int pointy3;
    
    
    public Enemy()
    {
        canSeePlayer = false;
    }
    
    public void act() 
    {
        turnTowards(pointx1, pointy1);
        move(3);
    }
    
    protected void addedToWorld(World MyWorld)
    {
        pointx1 = ((MyWorld) getWorld()).ex1;
        pointy1 = ((MyWorld) getWorld()).ey1;
        pointx2 = ((MyWorld) getWorld()).ex2;
        pointy2 = ((MyWorld) getWorld()).ey2;
        pointx3 = ((MyWorld) getWorld()).ex3;
        pointy3 = ((MyWorld) getWorld()).ey3;
    }
}

It's still heading to point
danpost danpost

2017/11/8

#
Maybe there is a problem with the points in your MyWorld class. Show its code.
NielsV5B NielsV5B

2017/11/9

#
In the matrix, 6 = point 1, 7 = point 2 & 8 = point 3
private int[][] Level = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
        { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 4, 0, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
    };


    public MyWorld()
    {    
        super(20*20, 20*20, 1); 
        Generate();
    }

    private void Generate()
    {
        
        int px = tilesize/2;
        int py = tilesize/2;
        
        for (int i = 0; i < 20; i++)
        {
            for (int j = 0; j < 20; j++)
            {
                int id = Level[i][j];
                if (id == 1){
                    addObject(new Block(), px, py);
                }
                else if (id == 2){
                    addObject(new Door(), px, py);
                }
                else if (id == 3)
                {
                    addObject(new Man(), px, py);
                }
                else if (id == 4)
                {
                    addObject(new Key(), px, py);
                }
                else if (id == 5)
                {
                    addObject(new Enemy(), px, py);
                }
                else if (id == 6)
                {
                    ex1 = j;
                    ey1 = i;
                }
                else if (id == 7)
                {
                    ex2 = j;
                    ey2 = i;
                }
                else if (id == 8)
                {
                    ex3 = j;
                    ey3 = i;
                }
                px = px + tilesize;
            }
            px = tilesize/2;
            py = py + tilesize;
        }
        
    }
I think I've found the problem, the ex and ey where set to i and j, but that should be px and py, is that right?
danpost danpost

2017/11/9

#
NielsV5B wrote...
In the matrix, 6 = point 1, 7 = point 2 & 8 = point 3
I could not find a '6' in the matrix; and there are two '7's.
I think I've found the problem, the ex and ey where set to i and j, but that should be px and py, is that right?
That would be correct.
NielsV5B NielsV5B

2017/11/10

#
I've changed the names of the coordinates: ET1x, ET1y, etc. in the World, which becomes T1x, T1y, etc. in the Enemy. But it's only got the x and y coordinates of point one (so T1x and T1y have got the right values). But all the others are 0, while they shouldn't be zero. Enemy code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Enemy extends Movers
{
    private int Health;
    private int speed;
    
    private int T1x;
    private int T1y;
    private int T2x;
    private int T2y;
    private int T3x;
    private int T3y;
    
    private int toWhere = 2;
    private int fromWhere = 1;
    
    public Enemy()
    {
        Health = 3;
        speed = 3;
    }
    
    protected void addedToWorld(World MyWorld)
    {
        T1x = ((MyWorld) getWorld()).ET1x;
        T1y = ((MyWorld) getWorld()).ET1y;
        T2x = ((MyWorld) getWorld()).ET2x;
        T2y = ((MyWorld) getWorld()).ET2y;
        T3x = ((MyWorld) getWorld()).ET3x;
        T3y = ((MyWorld) getWorld()).ET3y;
    }
    
    public void act() 
    {
        move(speed);
        setToWhere();
        keepTurning();
        getHit();
    }
    
    private void turns()
    {
        if (Greenfoot.getRandomNumber(100) < 15 )
        {
            turn(Greenfoot.getRandomNumber(60)-30);
        }
        if ( getOneIntersectingObject(Block.class) != null )
        {
            turn(180);
        }
    }
    
    private void getHit()
    {
        if ( isTouching(Bullet.class) )
        {
            Health--;
            removeTouching(Bullet.class);
        }
        if ( Health == 0 )
        {
            getWorld().removeObject(this);
        }
    }
    
    private void setToWhere()
    {
        if (getX() == T1x && getY() == T1y )
        {
            toWhere = 2;
            fromWhere = 1;
        }
        else if(getX() == T3x && getY() == T3y )
        {
            toWhere = 2;
            fromWhere = 3;
        }
        else if (getX() == T2x && getY() == T2y )
        {
            if ( fromWhere == 1 )
            {
                toWhere = 3;
            }
            else if ( fromWhere == 3 )
            {
                toWhere = 1;
            }
            fromWhere = 2;
        }
    }
    
    private void keepTurning()
    {
        if (toWhere == 1)  turnTowards(T1x, T1y); 
        else if (toWhere == 2)  turnTowards(T2x, T2y); 
        else if (toWhere == 3)  turnTowards(T3x, T3y); 
    }
}
Code MyWorld:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class MyWorld extends World
{
    public final int tilesize = 20;
    private int Xsize = 40;
    private int Ysize = 23;
    private boolean isDown = false;
    private int levelChanger = 2;
    
    public int ET1x; //Enemy Target One x-coordinate
    public int ET1y;
    public int ET2x;
    public int ET2y;
    public int ET3x;
    public int ET3y;
    
    /**
     * 1 = block (wall)
     * 2 = door
     * 3 = player
     * 4 = key
     * 5 = enemy
     * 6 = Enemy target 1
     *   7 = Enemy target 2
     *   8 = Enemy target 3
     */
    
    private int[][] Level = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 6, 0, 0, 5, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, },
        { 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
    };
        
        
    public MyWorld()
    {    
        super(40*20, 23*20, 1); 
        Generate();
    }

private void Generate()
    {
        int px = tilesize/2;
        int py = tilesize/2;
        
        for (int i = 0; i < Ysize; i++)
        {
            for (int j = 0; j < Xsize; j++)
            {
                int id = Level[i][j];
                if (id == 1){
                    addObject(new Block(), px, py);
                }
                else if (id == 2){
                    addObject(new Door(), px, py);
                }
                else if (id == 3)
                {
                    addObject(new Man(), px, py);
                }
                else if (id == 4)
                {
                    addObject(new Key(), px, py);
                }
                else if (id == 5)
                {
                    addObject(new Enemy(), px, py);
                }
                else if (id == 6)
                {
                    ET1x = px;
                    ET1y = py;
                }
                else if (id == 7)
                {
                    ET2x = px;
                    ET2y = py;
                }
                else if (id == 8)
                {
                    ET3x = px;
                    ET3y = py;
                }
                px = px + tilesize;
            }
            px = tilesize/2;
            py = py + tilesize;
        }
        
    }
danpost danpost

2017/11/10

#
As you iterate through the map, you are creating both the enemies and assigning the point coordinates. All points not gotten to before an enemy will show (0, 0) in the enemy for those points. Assign the point coordinates in the world before iterating over the map.
NielsV5B NielsV5B

2017/11/10

#
Thanks, that was indeed the problem.
You need to login to post a reply.