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

2016/9/18

Random timed movement, ranged player detection and camera tracking

5
6
7
8
danpost danpost

2016/9/30

#
Facet wrote...
This means you're removing the player before thing like the movement code have stopped being executed, try moving the remove player line down the class
No. The reason the error occurred is because 'pursued' was not being assigned any object within the code -- its value remains 'null' (no object referenced).
Parte Parte

2016/10/1

#
danpost wrote...
Parte wrote...
I tried the "simplest" and it didn't work
You tried to simplify it too much. You should only need these fields:
private SimpleTimer timer = new SimpleTimer();
private Actor pursued;
private int bulletTimer;
and the act method should be more like this:
public void act()
{
    if (!getObjectsInRange(650, Player_Test1.class).isEmpty())
    {
        if (pursued == null)
        {
            pursued = getObjectsInRange(650, Player_Test1.class).get(0);
        }
        if (!los.obstructedView(this, pursued, Walls.class))
        {
            pursue();
        }
        else
        {
            randomMovement();
        }
    }
    else
    {
        pursued = null;
        randomMovement();
    }
}
The Enemy class objects still pursue the player when there are more than 2 in the world when having the player in range while having los obstructed.
danpost danpost

2016/10/1

#
Parte wrote...
The Enemy class objects still pursue the player when there are more than 2 in the world when having the player in range while having los obstructed.
Well, that cannot come from the code given. The only way an enemy will "pursue' with the most recent code is when the player is in range and no obstructions are present. Also, each enemy will act on their own; one cannot influence any of the others.
Parte Parte

2016/10/1

#
danpost wrote...
Parte wrote...
The Enemy class objects still pursue the player when there are more than 2 in the world when having the player in range while having los obstructed.
Well, that cannot come from the code given. The only way an enemy will "pursue' with the most recent code is when the player is in range and no obstructions are present. Also, each enemy will act on their own; one cannot influence any of the others.
Then why is it that the Enemy_Test3 class does not pursue the player when obstructed and in range when there is only one in the world, however when there are 2 or more in range and that are obstructed they will switch between pursue and randomMovement.
public class Enemy_Test3 extends Animal
{
    //instance fields
    /**
     * Assigns SimpleTimer method to the variable of timer to this class.
     */
    private SimpleTimer timer = new SimpleTimer();
    /**
     * turnPhase is assigned to hold a boolean value (true or false).
     */
    private boolean turnPhase;
    /**
     * phasteTimer is assigned to hold a numerical value of -1
     */
    private int phaseTimer = -1;
    /**
     * Actor is assigned to be the variable pursued
     */
    private Actor pursued;
    /**
     * obstacleTimer is assigned to hold a numerical value
     */
    private int obstacleTimer;
    /**
     * bulletTimer is assigned to hold a numerical value
     */
    private int bulletTimer;
    
    /**
     * Method summary: This act method detects whether the Player_Test1 class is within 800 pixel range and whether it has any Wall classes obstructing its line of sight (meaning it will check whether there is a Wall class between the Player and this class by drawing up an invisible line that links between the two which checks for any Wall classes intersecting that line).
     * 
     * If Player_Test1 class is outside 650 pixel range or has a Wall class intersecting the line of sight to this class, Enemy_Test3 class will execute method randomMovement.
     * If Player_Test1 class is within 650 pixel range and has no Wall classes intersecting the line of sight to this class Enemy_Test3 class will execute method pursue.
     */
    public void act() 
    {
        
        if (pursued != null && pursued.getWorld() == null)
        {
            pursued = null;
        }
        
        if (pursued == null)
        {
            if (getObjectsInRange(650, Player_Test1.class).isEmpty())
            {
                randomMovement();
                return;
            }
            else
            {
                pursued = (Actor)getObjectsInRange(650, Player_Test1.class).get(0);
            }
           
        }
        
        if (pursued != null)
        {
            if (obstacleTimer == 0)
            {   
                if (los.obstructedView(this, pursued))
                {
                    obstacleTimer = 100;
                }
            
                else
                {
                    pursue(); 
                    return;
                }
            }   
        }
        
        if (obstacleTimer > 0)
        {
            if (--obstacleTimer == 0)
            {
                if (los.obstructedView(this, pursued))
                {   
                    pursued = null;
                }
            }
            else
            {
                if (los.obstructedView(this, pursued, Walls.class))
                {
                    randomMovement();
                    return;
                }
                else
                {
                    obstacleTimer= 0;
                    pursue(); 
                    return;
                }
            }
        }
            else
            {
                pursue(); 
            }
    
        }  
    
    

    
    /**
     * Method summary: This method makes this class move forward at a randomly selected distance then to stop for a randomly selected amount of time only then to instantly turn a random amount of degrees to then stop for a randomly selected amount of time to only move foward again a randomly selected distance (loop). This method also able to detect when this class is in contact with a wall, if this class is in contact with a wall the class will turn away from the wall.
     */
    public void randomMovement()
    {
        // control code (when out of range of or path obstructed toward player)
        int sign = (int)Math.signum(phaseTimer); // '1' means moving or turning and '-1' means stopped after moving or turning
        phaseTimer -= sign; // step toward zero
        if (phaseTimer == 0)
        {
            if (sign == -1)
            {
                if (turnPhase) phaseTimer = 50+Greenfoot.getRandomNumber(400);
                else phaseTimer = 1;
                turnPhase = !turnPhase;
            }
            else
            {
                if (turnPhase) phaseTimer = -(50+Greenfoot.getRandomNumber(400));
                else phaseTimer = -(50+Greenfoot.getRandomNumber(30));
            }
        }
             
        if (sign > 0)
        {
            if (turnPhase) turn(Greenfoot.getRandomNumber(360)); else move(1);
        }

        if (atWorldEdge() || isTouching(Walls.class) || isTouching(BulletPassableWalls.class))
        {
            turn(160+Greenfoot.getRandomNumber(180)-90);
            
        }
         
        
    }
    
    /**
     * Method summary: This method will get the coordinates of the pursued (Player_Test1.class) and will continuously turn towards those coordinates and move foward at a move speed of 2 and will execute the shoot method. This method also able to detect when this class is in contact with a wall, if this class is in contact with a wall the class will turn away from the wall.
     */
    public void pursue()
    {
        int x = getX(), y = getY();
        turnTowards(pursued.getX(), pursued.getY());
        move(1);
        shoot();
        
        if (atWorldEdge() || isTouching(Walls.class))
        {
            turn(160+Greenfoot.getRandomNumber(180)-90);
        }
         
        if (isTouching(Walls.class) || isTouching(BulletPassableWalls.class))
        {
            setLocation(x, y);
        }
       
    }
Super_Hippo Super_Hippo

2016/10/1

#
Well, I don't know what is wrong there, but I found something out. From the uploaded version right now, if you let the left enemy act once, it notices that the LOS is obstructed. If you let the next middle one act once then, it will shoot although there is the wall. If you let the middle one act first and then the other one, both will not shoot. With the code you just added, it seems to be similar (a bit different because the player isn't in range at the beginning). If you are adding the following line in the LOS class right before it compares the value to 2 and returns true/false...
System.out.println(getIntersectingObjects(null).size());
...then it prints out what it found. First thing I noticed it that you have a Movement_Test2 class which is always at the same position as the player, so actually the number of intersections should be compared to 3. But this doesn't solve the issue either. Well, it sometimes even prints '1'. I checked which object was detected and it was the wall. Not the enemy itself and not the player (and not the small movement point). The line itself is correct though (I made the image visible to check it). Sometimes it is finding all the 4 objects that it should, but sometimes not. I have no idea why though.
danpost danpost

2016/10/1

#
You know, I did not take into account the Movement_Test2 class. My question is this -- why is the movement for the player in a different Actor subclass? or, why is not the movement code for the player in the class of the player? Having two Actor subclasses here really does not make any sense. You gain nothing by doing this.
Parte Parte

2016/10/2

#
danpost wrote...
You know, I did not take into account the Movement_Test2 class. My question is this -- why is the movement for the player in a different Actor subclass? or, why is not the movement code for the player in the class of the player? Having two Actor subclasses here really does not make any sense. You gain nothing by doing this.
I have added a Movement_Test2 class because if the code for the movement (moving up,down,left,right) are in the same class as the Player class which contains the mouse movement; the player will merge with the walls when up against the walls as the player turns, to avoid this I split the movement of the player into a separate class.
danpost danpost

2016/10/2

#
Parte wrote...
I have added a Movement_Test2 class because if the code for the movement (moving up,down,left,right) are in the same class as the Player class which contains the mouse movement; the player will merge with the walls when up against the walls as the player turns, to avoid this I split the movement of the player into a separate class.
There would be no difference had you placed the movement code in the act method of the class of the player. You can still be moving, or adjusting the location of the player, on similar conditions. That is, I realize that the image sizes may be different and that you may not be able to just copy/paste the code back into the class of the player. Maybe, instead of 'isTouching', you can use 'getObjectsInRange' in the class of the player.
Parte Parte

2016/10/2

#
danpost wrote...
Parte wrote...
I have added a Movement_Test2 class because if the code for the movement (moving up,down,left,right) are in the same class as the Player class which contains the mouse movement; the player will merge with the walls when up against the walls as the player turns, to avoid this I split the movement of the player into a separate class.
There would be no difference had you placed the movement code in the act method of the class of the player. You can still be moving, or adjusting the location of the player, on similar conditions. That is, I realize that the image sizes may be different and that you may not be able to just copy/paste the code back into the class of the player. Maybe, instead of 'isTouching', you can use 'getObjectsInRange' in the class of the player.
I guess I could however I was originally planning on having the movement_test2 class to be animated legs (however I am short on time and that is not of high priority). Though I wanted the player to be able to merge with the walls partially anyway, unless that was somehow able to fix the issue of the Enemy class being able to pursue the player when there is more than one of them in the world which have the player in range and have their los obstructed, I think I may stick to what I have for now so in future I may implement my idea of animated legs.
You need to login to post a reply.
5
6
7
8