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

2016/5/19

I need help with getting one object following another object

Bat8 Bat8

2016/5/19

#
Hi! I've got the following problem with coding an enemie in my Greenfoot game. The enemie is supposed to follow the player. I tried this code to make it possible: Player class:
Player player = ((MyWorld)getWorld()).player;
        
turnTowards(player.getX(), player.getY());
move(1);
MyWord class:
other code

public Player player;

public MyWorld()
    {   
        super(1200, 900, 1); 
       
        player = new Player();

        other code

        addObject(player, 110, 100);

        other code

     }
The "other code" does not influence this code in any way. When I compile this, the enemie is following the player, but not as I want it. I already created the same game with a drag and drop "coding" program called Scratch. There I just chose the "Turn Towards" code and the "Move" code to make the enemie follow the player. Let me show you the difference in the behavior of the enemie between the Scratch and the Greenfoot version: Scratch version: or http://www.mediafire.com/view/crps5dysp7fmxss/Scratch.gif Greenfoot version: or http://www.mediafire.com/view/tggz4cd14x8n32t/Greenfoot.gif I hope the difference between those two is visible. I'd like the enemie to follow the player as it does in the Scratch version. How do I have to change the code for that? Thank you for your answers!
valdes valdes

2016/5/19

#
after the move(1) line put setRotation(0);
danpost danpost

2016/5/20

#
Greenfoot tracks player location coordinates as integer values. This means that when you move one pixel, you will move either horizontally or vertically. No other angles can be achieved by moving only one pixel unless you apply more precise coordinate tracking fields. You can do this yourself or have the class subclass one that can achieve this for you (like the SmoothMover class or my QActor class). You can look at either of them (or both) to see how to accomplish this.
Bat8 Bat8

2016/5/21

#
danpost wrote...
Greenfoot tracks player location coordinates as integer values. This means that when you move one pixel, you will move either horizontally or vertically. No other angles can be achieved by moving only one pixel unless you apply more precise coordinate tracking fields. You can do this yourself or have the class subclass one that can achieve this for you (like the SmoothMover class or my QActor class). You can look at either of them (or both) to see how to accomplish this.
Thank you for your answer! As you suggested, I checked out the SmoothMover class and the QActor class. But I'm new to Greenfoot and coding and I didn't completely understand them. So, I created my own way to make the actors follow each other, using this code in my "Enemie" class.
    int a;
    int b;
    int gradient;
    int xValue;
    int yValue;
    long EnemieMoved;
    boolean UpdateEnemieMoved = true;

public void act() 
    {
        Player player = ((MyWorld)getWor()).player;

                a = Math.abs(player.getX() - getX());
                b = Math.abs(player.getY() - getY());
                xValue = getX();
                yValue = getY();
               
                if (a > b && b != 0)
                {
                    gradient = a / b;
                    
                    if (getY() > player.getY())
                    {
                        setLocation(getX(), getY()-1);
                    }
                    if (getY() < player.getY())
                    {
                        setLocation(getX(), getY()+1);
                    }
                    
                    if (getX() > player.getX())
                    {
                        while (getX() > (xValue -gradient))
                        {
                            if(UpdateEnemieMoved ==true)
                            {
                                EnemieMoved = player.Moved; 
                                UpdateEnemieMoved = false;
                            }
                            
                            if (player.Moved > EnemieMoved)
                            {
                                move(-1);
                                UpdateEnemieMoved = true;
                            }
                                
                        }
                    }
                    if (getX() < player.getX())
                    {
                        while (getX() < (xValue + gradient))
                        {
                            if (UpdateEnemieMoved == true)
                            {
                                EnemieMoved = player.Moved; 
                                UpdateEnemieMoved = false;
                            }
                            
                            if (player.Moved > EnemieMoved)
                            {    
                                move(1);
                                UpdateEnemieMoved = true;
                            }
                        }
                    }
                }
                
                else if (b > a && a != 0)
                {
                    gradient = b / a;
                    
                    if (getX() > player.getX())
                    {
                        move(-1);
                    }
                    if (getX() < player.getX())
                    {
                        move(1);
                    }
                    
                    if (getY() > player.getY())
                    {
                        while (getY() > yValue - gradient)
                        {
                            
                            if (UpdateEnemieMoved == true)
                            {
                                EnemieMoved = player.Moved; 
                                UpdateEnemieMoved = false;
                            }
                            
                            if (player.Moved > EnemieMoved)
                            {        
                                setLocation(getX(), getY()-1);
                                UpdateEnemieMoved = true;
                            }
                        }
                    }
                    if (getY() < player.getY())
                    {
                        while (getY() < yValue + gradient)
                        {
                            if (UpdateEnemieMoved == true)
                            {
                                EnemieMoved = player.Moved; 
                                UpdateEnemieMoved = false;
                            }
                            
                            if (player.Moved > EnemieMoved)
                            {            
                                setLocation(getX(), getY()+1);
                                UpdateEnemieMoved = true;
                            }
                        }
                    }
                }
                
                else if (a == b)
                {
                    if (getX() < player.getX())
                    {
                        move(1);
                    }
                    if (getX() > player.getX())
                    {
                        move(-1);
                    }
                    
                    if (getY() < player.getY())
                    {
                        setLocation(getX(), getY()+1);
                    }
                    if (getY() > player.getY())
                    {
                        setLocation(getX(), getY()-1);
                    }
                }
                
                else if (a == 0)
                {
                    if (getY() < player.getY())
                    {
                        setLocation(getX(), getY()+1);
                    }
                    if (getY() > player.getY())
                    {
                        setLocation(getX(), getY()-1);
                    }
                }
                
                else if (b == 0)
                {
                    if (getX() < player.getX())
                    {
                        move(1);
                    }
                    if (getX() > player.getX())
                    {
                        move(-1);
                    }
                }
The variable "Moved" in the player class is always increased by one at the end of the code of that class. At first, the while-loops only contained setLocation(getX(), getY()-1); , setLocation(getX(), getY()+1); , move(1); or move(-1);. The problem was that, of course, if the value of the gradient variable became too heigh, the enemie moved way too fast. I tried to fix that by creating the variable "Moved" in the player class and using the code I posted. The enemie should only be allowed to move again if the player code had been run once so the enemie would not be faster than the player. However, when I use this code, the game just starts too lag extremely so you can't play it. Do you know a different way to slow the enemie down?
danpost danpost

2016/5/21

#
Bat8 wrote...
Do you know a different way to slow the enemie down?
You could have the class extend my QActor class which allows a factor of 100x fine tuning to the movement and rotation of actors. Check my support classes collection for it (it is in the Asteroids w/Improved QActor class scenario). Then, your original code would have 1/100th the original speed. You can now increase 'move(1)' to 'move(50)' to produce half the original speed or adjust it to your liking from there.
You need to login to post a reply.