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

2013/12/11

Make an actor follow a line

1
2
SanderDub SanderDub

2013/12/16

#
So right now I have done a lot of reading up on assigning states to the spawned lines. When a boat is created by the boatspawner class, it will be assigned an ID (first boat is ID 0, second is 1 etc.) This works great. I then adjusted the placeGround() method I wrote so that the path that is created when dragging your mouse from a specific boat creates a path with the same ID. So if there's 5 boats in play with IDs from 0-4, and you drag a line from the third boat, it will create a path with ID 2. The last thing I have to do is make the actors with a given ID only move towards & remove the same ID path. However this is where I struggle. I can't seem to find a way to make the boat with a given ID face towards the path with a same ID. Somehow doing something like this won't work :
Actor closestpath = getOneObjectAtOffset(0,0,PathRed.class)

if(closestpath.getID()==boatID)
{
move etc...
remove path and face next one...
}
Keep in mind that this is just some stupid code that only is here to show how I am currently going at detecting the ID. I know that the getOneObjectAtOffset doesn't work for detecting close nodes etc, it really only is here to let u know how I'm trying to write it atm. However, this won't work. I am probably going at it the wrong way, but basically what i want it to do is find the closest path actor, check if it's the same ID as the boat and then move towards it, else do nothing.
danpost danpost

2013/12/16

#
First off, the method 'getID' is in the PathRed class (not the Actor class) and cannot be accessed via an Actor object that is not cast as type PathRed. Line 1 should read:
PathRed closestpath = (PathRed)getOneObjectAtOffset(0, 0, PathRed.class);
Line 6 should have your actor face the current path object before moving the actor and removing the path. This will avoid finding two paths per act method and possibly prevent lag. You may also want to sub-number the paths to indicate the order in which they should be encountered. That way, if the line of path objects loops upon itself, the proper path will be taken.
SanderDub SanderDub

2013/12/16

#
Thank, that clears up a lot! About the sub-numbering, do you mean assigning a seperate ID for the path? So if a path is created has pathID 3 I assign the first path spawned with this ID a 0, second a 1 etc... in a loop? So they ahve both the path ID and a seperate unique ID within this path? Also I was wondering if you could place the paths spawned in a seperate array. This way I don't have to add more ID methods but can still give them a seperate unique ID within this array (seeing arrays automatically assign them an index value).. How would I put the actors created in an array? I know that once they're in an array I can just make the boat actor turn towards the first value, move and remove in one act(), then make it go after the next path in the array in the next act scene and repeat.
danpost danpost

2013/12/16

#
SanderDub wrote...
About the sub-numbering, do you mean assigning a seperate ID for the path? So if a path is created has pathID 3 I assign the first path spawned with this ID a 0, second a 1 etc... in a loop? So they ahve both the path ID and a seperate unique ID within this path?
That was precisely what I was saying. As far as an array, let me check into that. I know you can do that, however, there may be a 'cheat' to doing this that would make things a whole lot easier. I will take me a little time to double-check to see if it will work. I will explain then, if it works.
danpost danpost

2013/12/16

#
Ok. Seems like it works. The World holds an array of objects added to it already. You can retrieve a list of any class of objects in the world with 'getWorld().getObjects(ClassName.class)'. It just so happens that the list returned is given in the precise order that the actors were added into the world. That means you can use the following for moving:
if (!getWorld().getObjects(PathRed.class).isEmpty())
{
    Actor path = (Actor)getWorld().getObjects(PathRed.class).get(0);
    setLocation(path.getX(), path.getY());
    getWorld().removeObject(path);
}
danpost danpost

2013/12/16

#
I find even with this method of movement that some lagging will occur (it would be worse if you created your own array on top of the one that the World already contains). I still think that creating lines instead of points would be the way to go to reduce lagging. The same method could be used with lines as well.
SanderDub SanderDub

2013/12/16

#
Alright. I am really uncertain as to how to make the lines thing work though. Could you show me what methods to use? Perhaps an example mini scenario? I would definitely consider throwing away my entire pathing system if you say that its better like that, just need to know how :) thanks a lot again Dan, you've been a great help!
danpost danpost

2013/12/16

#
I will upload what I have right now (using point objects). It will take me a little time to modify it for lines; but, when I have accomplished it, I will update the scenario. EDIT: The scenario is here.
SanderDub SanderDub

2013/12/16

#
Wow. That is just completely insane and exactly what I meant to create when I started this project. Do you mind me implementing this code in my project? Dan you're the best :D
SanderDub SanderDub

2013/12/16

#
Also, how do I actually make them look like ships instead of blocks? Is there a way to somehow give them an image without messing up the way the boats chase their line? And would it be possible to add rotation? Seeing it's following a set line and doesn't really go from 1 point on the line to the next, how would I turn it around when there's nothing solid I can make it turnTowards to? Was able to add basic rotation. will smooth it out now.
danpost danpost

2013/12/16

#
I updated the scenario by adding a switch to change from 'point' following to 'line' following. I kept both methods totally separate by using different worlds and different actor objects (World: Harbor uses Actors: Ship and Path; and World: Port uses Actors: Boat and Line). The Actor: Switch is used in both only to go from one world to the other and back. You can import image files into your 'images' folder of your scenario and 'set' the image of any subclass of Actor you have to that image. Right click on your class icon (on the right side in the boxes) and select 'Set image...'; the 'Import from file...' button will browse to copy an external image into the folder.
You need to login to post a reply.
1
2