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

2015/4/17

Help with writing a save file?

decadence18 decadence18

2015/4/17

#
I'm attempting to write a literal string to a file that can then be loaded. Here is my current code:
int x = 0;
    int y = 0;
    String actorStringRaw;
    String actorStringFinal;
    String stringToWrite;
    List actorList;
    public void writeFile()
    {
        FileWriter fw = null;

        for (int i=0; i<(getWidth()); i++)
        {
            if (getObjectsAt(x, y, null) != null)
            {
                try
                {
                    fw = new FileWriter("Save.txt");
                    List<String> actorList = (getObjects(null));
                    
                    for (int j=0; j<actorList.size(); j++)
                    {
                        actorStringRaw = actorList.get(j);
                        String[] actorStringArray = actorStringRaw.split("@");
                        actorStringFinal = actorStringArray[0];
                        stringToWrite = ("addObject(" + actorStringFinal + ", " + x + ", " + y + ");"); 
                        fw.write(stringToWrite + " ");
                    }
                }
                catch (Exception e)
                { 
                    e.printStackTrace();
                }
                finally
                {
                    if(fw != null)
                    {
                        try {
                            fw.close();
                        }
                        catch (Exception e)
                        {
                            e.printStackTrace();
                        }
                    }
                }
                x += 1;
            }
            else
            {
                x += 1;
            }
            if (x > getWidth())
            {
                x = 0;
                y += 1;
            }
        }
    }
Now, when I run this code, it basically crashes Greenfoot, and I have no idea why. It says "Actor cannot be written to java.lang.String". What am I doing wrong, and how can I possibly fix it?
danpost danpost

2015/4/17

#
You show the following for line 18 above:
List<String> actorList = (getObjects(null));
You are declaring a List object called 'actorList' that is to hold String objects. However, the list returned from 'getObjects(null)' is a List of Object actors -- not Object strings. In other words, the elements of the returned list cannot be cast to the type String; they can only be cast to the type Actor. This does not mean that you cannot execute the 'toString' method on the elements to acquire the String representation of the referenced actor. That is, to fix the issue you are talking about, you could change line 18 to:
List<Object> actorList = getObjects(null);
and then change line 22 to this:
actorStringRaw = actorList.get(j).toString();
BUT, there seems to be a larger issue which should be addressed, first and foremost. The 'for' loop starting at line 11 seems to be oddly placed. In fact, it appears to be an outright unnecessary over-complication. It looks like you are trying to check each location in the world individually for an object; then, each time you find an object, you write to the 'Save.txt' file every actor in the world; on top of that, if no actors are in the top row of pixels in your world (along the top edge), nothing will every be written because 'i' and 'x' will increase together until they equal the value returned by 'getWidth', when the loop will terminate. The condition on line 52 will never get a chance to be true. You will be a lot closer to what you are looking for if you remove lines 11 through 14 and lines 46 through 57.
decadence18 decadence18

2015/4/17

#
Okay, the new code semi works.. I'm using -
int[] y2;
    int[] x2;
    String actorString;
    String actorStringFinal;
    String stringToWrite;
    Object[] actorArray;
    List<Object> actorList;
    public void writeFile()
    {
        FileWriter fw = null;

        if ((!((getObjects(null)).isEmpty())) && (getObjects(null) != null))
        {
            try
            {
                fw = new FileWriter("Save.txt");
                actorList = getObjects(null);
                // Populate array
                actorArray = new Object[actorList.size()];
                for (int a=0; a<actorList.size(); a++)
                {
                    actorArray[a] = actorList.get(a);
                    
                    x2[a] = actorArray[a].getX();
                    y2[a] = actorArray[a].getY();
                }
                for (int b=0; b<actorArray.length; b++)
                {
                    actorArray[b] = actorArray[b].toString().split("@")[0];
                }
                for (int c=0; c<actorArray.length; c++)
                {
                    stringToWrite = ("addObject(new " + actorArray[c] + "(), " + x2 + ", " + y2 + ");"); 
                    fw.write(stringToWrite);
                }
            }
            catch (Exception e)
            { 
                e.printStackTrace();
            }
            finally
            {
                if(fw != null)
                {
                    try {
                        fw.close();
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
I have no idea how to get the X and Y values for each object, as (apparently) you cannot use the getX method on objects. (I apologize for the length of time in response; I couldn't get it to allow me to post replies until a little bit ago.)
Super_Hippo Super_Hippo

2015/4/17

#
You could change
Object[] actorArray;
to
Actor[] actorArray;
and change line 22 to
actorArray[a] = (Actor) actorList.get(a);
Then you would need another array to hold the string objects though (e.g. line 29 wouldn't work). Is there a reason why x2 and y2, the actorArray and actorList are created outside the method? In line 33 you should use x2 and y2. So this part could look like this I think:
                fw = new FileWriter("Save.txt");
                actorList = getObjects(null);
                actorArray = new Actor[actorList.size()];
                String[] stringArray = new String[actorList.size()];
                for (int a=0; a<actorList.size(); a++)
                {
                    actorArray[a] = (Actor) actorList.get(a);
                    stringArray[a] = actorArray[a].toString().split("@")[0];
                    stringToWrite = ("addObject(new " + stringArray[a] + "(), " + actorArray[a].getX() + ", " + actorArray[a].getY() + ");"); 
                    fw.write(stringToWrite);
                }
Didn't test it, but it should be closer. EDIT: Just removed the x and y arrays. If you need them, change it back.
decadence18 decadence18

2015/4/17

#
Several things are created outside the method because I'm planning on utilizing them in other places (for checks and such). I tried similar to what you were doing, but I realize now I had a few things defined wrong. Thank both of you for your help; after some tweaking it seems to work correctly now. EDIT: First, I love how as I was replying you were editing it. Second, both should work, but I'm going to stick to the first due to the aforementioned purpose.
danpost danpost

2015/4/17

#
Actually, I do not see the need for declaring any of the fields outside of where they are being used; or even for using them where you are using them. Any information retained can be easily re-attained.
public void writeFile()
{
    FileWriter fw = null;
    try
    {
        fw = new FileWriter("Save.txt");
        for (Object obj : getObjects(null))
        {
            Actor actor = (Actor) obj;
            fw.write("addObject(new "+actor.getClass().getName()+"(), "+actor.getX()+", "+actor.getY()+");");
        }
        fw.close();
    }
    catch (Exception e)
    { 
        e.printStackTrace();
    }
    finally
    {
        if (fw != null)
        {
            try
            {
                fw.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}
What kind of checks were you intending to perform using the information stored in those fields?
decadence18 decadence18

2015/4/18

#
I'm planning on having it write a second file ever few "acts", and then on startup calling both files and verifying integrity. Also, certain pieces in the game are not allowed to remain on a space for any sort of time, only pass over, so due to this I want to check and make sure that, whether intended or not, there are no pieces in that area when saving. There are other things I want to do as well, but I can't think of them all at the moment. I have a file of them somewhere.
You need to login to post a reply.