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

4
5
6
7
8
danpost danpost

2016/9/30

#
Parte wrote...
This is the player in my prepare
Player_Test1 player_test1 = new Player_Test1(movement_test21);
addObject(player_test1,100,100);
Remove 'Player_Test1' from the beginning of the first line.
Parte Parte

2016/9/30

#
danpost wrote...
Parte wrote...
This is the player in my prepare
Player_Test1 player_test1 = new Player_Test1(movement_test21);
addObject(player_test1,100,100);
Remove 'Player_Test1' from the beginning of the first line.
Thanks it is working now! However now that camera tracking has been implemented the game seems to lag (everything moves at a slower rate than what it was prior to camera tracking). I tried to increase the scenario speed to 100 though it seems as though it doesn't make much of a difference. How can I increase the speed at which the scenario runs to achieve the movement speed which I originally had without having to increase the move value (I would like to avoid increasing the move value because I find that bullets will teleport through walls, objects etc).
Parte Parte

2016/9/30

#
Also when the Player is removed from the world an error appears, how can I remove this error? Console error: java.lang.IllegalStateException: Actor not in world. An attempt was made to use the actor's location while it is not in the world. Either it has not yet been inserted, or it has been removed. at greenfoot.Actor.failIfNotInWorld(Actor.java:711) at greenfoot.Actor.getX(Actor.java:164) at Worldbackground.act(Worldbackground.java:39) at greenfoot.core.Simulation.actWorld(Simulation.java:610) at greenfoot.core.Simulation.runOneLoop(Simulation.java:545) at greenfoot.core.Simulation.runContent(Simulation.java:221) at greenfoot.core.Simulation.run(Simulation.java:211)
danpost danpost

2016/9/30

#
Keep in mind that increasing the scenario speed only decreases the delay between act methods. If your code takes longer to execute than the delay allows, then lag will occur. That is why you see no difference after increasing it to a certain speed. One thing you might be able to do is to not scroll the background image at all (just have the actors relocate for scrolling as the background is a flat color and really does not change). I think you can do this just by commenting out line 113 in the ImgScroll class (the 'scrollBackground();' line in the 'scroll(int, int)' method).
when the Player is removed from the world an error appears, how can I remove this error?
Place a condition on the 'scroller.scroll' command in your world act method:
if (player_test1.getWorld() != null)
Parte Parte

2016/9/30

#
danpost wrote...
Keep in mind that increasing the scenario speed only decreases the delay between act methods. If your code takes longer to execute than the delay allows, then lag will occur. That is why you see no difference after increasing it to a certain speed. One thing you might be able to do is to not scroll the background image at all (just have the actors relocate for scrolling as the background is a flat color and really does not change). I think you can do this just by commenting out line 103 in the ImgScroll class (the 'scrollBackground();' line in the 'scroll(int, int)' method).
when the Player is removed from the world an error appears, how can I remove this error?
Place a condition on the 'scroller.scroll' command in your world act method:
if (player_test1.getWorld() != null)
Thanks a lot! Works wonderfully (well almost).
danpost wrote...
Maybe they are automatically going back into the chase state upon clearing the 'pursued' field because the player is still in range. That will have to be checked into.
You say that my Enemy class could be going back into the chase state upon clearing the pursued field. I tried putting the block associated with the pursue method into an "if los.obstructedView" block and it worked, however now my Enemy class does not pursue the player when in range and has no obstructed line of sight. Is what I'm doing going down the right path to fix this issue and if so what could I add to make this work?
danpost danpost

2016/9/30

#
Parte wrote...
I tried putting the block associated with the pursue method into an "if los.obstructedView" block and it worked, however now my Enemy class does not pursue the player when in range and has no obstructed line of sight. Is what I'm doing going down the right path to fix this issue and if so what could I add to make this work?
I do not think so. You probably need a boolean field to track whether a chase attempt was made or not (something else to keep track of). It may be cleared upon being out of range again or after a specific number of act cycles (which again would be another timer field).
Parte Parte

2016/9/30

#
danpost wrote...
Parte wrote...
I tried putting the block associated with the pursue method into an "if los.obstructedView" block and it worked, however now my Enemy class does not pursue the player when in range and has no obstructed line of sight. Is what I'm doing going down the right path to fix this issue and if so what could I add to make this work?
I do not think so. You probably need a boolean field to track whether a chase attempt was made or not (something else to keep track of). It may be cleared upon being out of range again or after a specific number of act cycles (which again would be another timer field).
I'm not sure how I can do this, any applicable examples?
danpost danpost

2016/9/30

#
Parte wrote...
I'm not sure how I can do this, any applicable examples?
I would be similar to your 'turnPhase' and 'obstacleTimer' fields. The boolean field determines the on/off or ready/not ready state of the action and the timer field controls the length of time for the action.
Parte Parte

2016/9/30

#
danpost wrote...
Parte wrote...
I'm not sure how I can do this, any applicable examples?
I would be similar to your 'turnPhase' and 'obstacleTimer' fields. The boolean field determines the on/off or ready/not ready state of the action and the timer field controls the length of time for the action.
I didn't mean the fields themselves but how they would interact with each other in a method, what the method would contain, or is that also similar to how turnPhase and obstacleTimer fields are setup?
danpost danpost

2016/9/30

#
Parte wrote...
I didn't mean the fields themselves but how they would interact with each other in a method, what the method would contain, or is that also similar to how turnPhase and obstacleTimer fields are setup?
It really depends on what you are going to use as a terminator for the "cool down" period (the time between stopping chase and resuming possible chase after an obstruction caused the lack of a chase). If you are going to have the enemy wait until out of range of the player and go into random mode before any attempt at a new chase, then only a boolean field would be needed. If you are going to use some time delay, then a timer field shoul be implemented (like the 'obtacleTimer' field).
Parte Parte

2016/9/30

#
danpost wrote...
Parte wrote...
I didn't mean the fields themselves but how they would interact with each other in a method, what the method would contain, or is that also similar to how turnPhase and obstacleTimer fields are setup?
It really depends on what you are going to use as a terminator for the "cool down" period (the time between stopping chase and resuming possible chase after an obstruction caused the lack of a chase). If you are going to have the enemy wait until out of range of the player and go into random mode before any attempt at a new chase, then only a boolean field would be needed. If you are going to use some time delay, then a timer field shoul be implemented (like the 'obtacleTimer' field).
I don't see how a timer is going to fix the issue of the Enemy pursuing the player when there is an obstruction (note this only occurs with 2 or more Enemy objects in the world and when the player is in range but with a wall class obstructing los). So I think a boolean field for los obstruction would be best at this point because the Enemy can already detect when the player is in range but for some unknown reason decides to ignore the wall (though from testing and observations I agree with what you said about how the Enemy class is actually switching from randomMovement to pursue constantly when there are 2 or more Enemy classes that have the player in range while having a wall class in los). How would I implement this boolean field into my Enemy class?
danpost danpost

2016/9/30

#
Declare the field at the top of the code block. Set it to true when in-range los-obstructed random movement mode ends. Check its value when determining the current action(s) to take and set it to false when it is true and out-of-range. Now, this will allow random movement even when los is not obstructed even when in-range. This may not be what you might want. Maybe just going random until out-of-range (which continues random) or until los is unobstructed (which would start a pursuit) is the best course of action. It would be the simplest -- if in-range and los-unobstructed, pursue; else, random movement (regardless); no need for the 'obtructedTimer' field, either.
Parte Parte

2016/9/30

#
danpost wrote...
Declare the field at the top of the code block. Set it to true when in-range los-obstructed random movement mode ends. Check its value when determining the current action(s) to take and set it to false when it is true and out-of-range. Now, this will allow random movement even when los is not obstructed even when in-range. This may not be what you might want. Maybe just going random until out-of-range (which continues random) or until los is unobstructed (which would start a pursuit) is the best course of action. It would be the simplest -- if in-range and los-unobstructed, pursue; else, random movement (regardless); no need for the 'obtructedTimer' field, either.
I tried the "simplest" and it didn't work
public class Enemy_Test2 extends Animal
{
    //instance fields
    /**
     * Assigns SimpleTimer the variable of timer to this class.
     */
    private SimpleTimer timer = new SimpleTimer();
    /**
     * turnPhase is assigned to hold a boolean value
     */
    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;
    
    private boolean rangeOccur;
    
    public void act()
    {
        if (getObjectsInRange(650, Player_Test1.class).isEmpty() && los.obstructedView(this, pursued, Walls.class))
        {
            pursue();
        }   
        else
        {
            randomMovement();
        }
    }
    
    /**
     * 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);
        }
       
    }
    
    /**
     * This method will execute the shootBullet method every 360 milliseconds that elapse and will play the sound "Pistol Shot.mp3" every time this happens.
     */
    public void shoot()
    {     
        if (timer.millisElapsed() >= 360)
        {
            shootBullet();
            timer.mark();
            Greenfoot.playSound("Pistol Shot.mp3");
        }
    }
     
    /**
     * Method summary: This method spawns an Enemy_Bullet_Test1 class on this classes coordinates that is in the world and will rotate the Enemy_Bullet_Test1 class towards Player_Test1's coordinates.
     */
    public void shootBullet()
    {
        Enemy_Bullet_Test1 enemy_bullet = new Enemy_Bullet_Test1();
        enemy_bullet.setRotation(getRotation());
        getWorld().addObject(enemy_bullet, getX(), getY());
    }
}
When I go behind an obstruction it just comes up with an error. Console error: java.lang.NullPointerException at LineOfSight.obstructedView(LineOfSight.java:24) at LineOfSight.obstructedView(LineOfSight.java:38) at Enemy_Test2.act(Enemy_Test2.java:41) at greenfoot.core.Simulation.actActor(Simulation.java:604) at greenfoot.core.Simulation.runOneLoop(Simulation.java:562) at greenfoot.core.Simulation.runContent(Simulation.java:221) at greenfoot.core.Simulation.run(Simulation.java:211)
danpost danpost

2016/9/30

#
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();
    }
}
Facet Facet

2016/9/30

#
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
There are more replies on the next page.
4
5
6
7
8