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

2015/1/16

Offset Movement

Mrinal Mrinal

2015/1/16

#
Hi! I have this project where the main character has to go through a maze. The maze contains movable walls. For example, if there is a movable wall to the right of the hero and when I press right arrow button, I want the hero to move the wall as long as the right arrow key is being pressed. Similarly, if there's a movable wall below the hero and when I press down arrow key, the hero should move the wall downwards. and so on..... I know it has something to do with offsets but I couldn't make head or tail of it. Please help ASAP Thanks! :)
danpost danpost

2015/1/16

#
You could check out the movement for the woman in my Pushy Woman scenario.
Mrinal Mrinal

2015/1/17

#
I checked it out. And I'm getting nowhere with it. Perhaps you might wanna explain it to me in detail! :/
danpost danpost

2015/1/17

#
Post the code you do not understand and I will explain. Use the 'code' link below the reply box to insert code into your posts.
Mrinal Mrinal

2015/1/17

#
this
 private boolean canMove(int dx, int dy)
    {
        if (getX()+dx < 0 || getY()+dy < 0 || getY()+dy > 18) return false;  
        Actor actor = (Actor)getOneObjectAtOffset(dx, dy, null); 
        if (actor == null ||
        actor instanceof Gate ||
        (actor instanceof Ball && ((Ball)actor).canMove(dx, dy)) ||
        actor instanceof Goal)
        { // can move
            setLocation(getX()+dx, getY()+dy);
           
            if (actor instanceof Ball)
            {
                Maze.scoreCounter.add(-5);
                pushCount++;
            }
            moveTimer = 12; // reset delay counter
            // determine if end of level reached
            if (getX() == 19)
            {
                Maze.totalCounter.add(-Maze.levelScore[Maze.levelCounter.getValue()-1]); 
                int score = 200*Maze.levelCounter.getValue()-pushCount*5; 
                if (Maze.levelScore[Maze.levelCounter.getValue()-1] > score)
                    score = Maze.levelScore[Maze.levelCounter.getValue()-1]; 
                Maze.levelScore[Maze.levelCounter.getValue()-1] = score; 
                Maze.totalCounter.add(score); // add best level score to total score
                Maze.levelCounter.add(1); // increment level counter
               
                if (Maze.levelCounter.getValue() > 5 || Maze.fiveCompleted) Greenfoot.setWorld(new Menu());
                else Greenfoot.setWorld(new Maze());
            }
            return true;
        }
        return false;
    }
The first part of it has the ball moving code. Explain that ^
Mrinal Mrinal

2015/1/17

#
And this
public boolean canMove(int dx, int dy)
    {
        Actor actor = getOneObjectAtOffset(dx, dy, null); 
        if ((actor == null) ||
            (actor instanceof Goal) ||
            (actor instanceof Gate && ((Gate)actor).canMove(dx, dy)) ||
            (actor instanceof Ball && ((Ball)actor).canMove(dx, dy)))
        { 
            setLocation(getX()+dx, getY()+dy);
            return true;
        }
        return false; 
    }
is in the Ball class. How do you exactly get it to move?
danpost danpost

2015/1/17

#
I will presume that it is the moving that has you confused. First, let me explain the thought process that went behind the coding. When the woman 'pushes' on a ball, the force is transferred to the ball; the ball then may transfer the force to another ball or a gate, and so on until a wall is encountered or no additional objects are pushed. The last object must be found to be able to move before the woman is allowed to move. So, my coding was based basically as that would go. In your 35 line code post, which I believe is the 'canMove' method of the Player class: Line 3: ensures the player is not moving out of world bounds (world edge check); I probably did not need to check the top and bottom edges as they are lined with wall objects as obstacles; Line 4: gets a reference to the object at the location the player is attempting to move to (or 'null', if no actor is there); Line5: ensures the player can indeed move; any of the conditions can be true and include the following: - the location moving to is empty ('actor == null' -- line 5); (if this first condition is not true then there must be an actor at the location for the following conditions to check on) - a Gate object is at the location moving to ('actor instanceof Gate' -- line 6); - a Ball object is at the location AND the ball can move ('actor instanceof Ball && ((Ball)actor).canMove(dx, dy)' -- line 7); (when the ball is checked for being able to move and is found to be able to, it is moved even before the player moves; also, the ball returns a boolean value to indicate whether it moved or not) - the Goal object is at the location ('actor instanceof Goal' -- line 8); Line 10 moves the player if any of the conditions passed. Line 12 then checks to see if a ball was pushed on the move and if so lines 14 and 15 adjust the push count and score fields. We touched on what the Ball class 'canMove' method does above when finding a ball at the location the player was attempting to move to. Again, the method returns a boolean value to inform the object pushing on it whether it moved or not. Line 3 gets a reference to any object that may be at the location pushed toward. And here we go again, the conditions of which any can be true that will allow the ball to move are: - the location is empty ('actor == null' -- line 4); - the location is where the Goal is ('actor instanceof Goal' -- line 5); - a gate is at the location AND the gate can move ('actor instanceof Gate && ((Gate)actor).canMove(dx, dy)' -- line 6); - another ball is at the location AND that ball can move ('actor instanceof Ball && ((Ball)actor).canMove(dx, dy)' -- line 7); If found to be able to move, it is moved (line 9) and the calling method is informed of move (line 10); otherwise, the calling method is informed that the ball did not move (line 12). Hope this makes sense.
Mrinal Mrinal

2015/1/18

#
Made a little change in code and put it in. Works... Thanks a lot! :)
You need to login to post a reply.