21 Replies Latest reply on Mar 26, 2010 9:30 AM by NOCK2k8

    Setting boundaries for a maze

    NOCK2k8

      Right guys.

       

      I have a sprite on top of a birds-eye-view of a 'maze' that I created in Photoshop.  I need to know how to constrain the sprite so that it can only walk on the 'grass' of the maze rather than over the 'bushes'.

       

      I hope that makes sense?

       

      I have searched for ages and cannot find anything on how I would do this.

       

      I'm guessing that I will have to work out coordinates to allow/deny the sprite to move over.  I have no problem with working them out, but how would I code it?

       

      I have had another idea which is coding it so that the sprite can only 'walk' on RGB(10,255,10) areas (i.e. the grass), but I don't know if there is any way of doing this in Director.

       

      Any help would be greatly appreciated.

       

      Many thanks in advance.

        • 1. Re: Setting boundaries for a maze
          Mike Blaustein Level 4

          The color approach would probably be the easiest.  You can find out the rgb value of any given pixel of an image using getPixel().  You would just have to calculate where the sprite would be if he were to travel to the new location.  Before moving him, check that color, and if it is the right one, allow the move to take place.  If it is a different color, then do not move... maybe make a sound or something to let the user know he is trying to go somewhere illegal.  Also, you could make a copy of the maze sprite which is just black and white.  Black where the player can go and white where the player can not go.  Set this sprite underneath the real maze graphic and use getPixel() on this sprite instead.  That way you are not bound by the color scheme of the real maze graphics.

          1 person found this helpful
          • 2. Re: Setting boundaries for a maze
            NOCK2k8 Level 1

            Thanks for your properly fast response.  I'm surprised that it is possible to do it by colour, and nice tip in regards to making a second maze.  Is there any chance that you could skeleton the code for me as I have no idea what I should write.

             

            I'm guessing I add it to the sprite's behavior, currently the code I have for this is this:

             

            -- properties used in this script:
            -- pSprite - the sprite reference
            -- pSpeed - the speed the sprite should move
            -- myLocH - the current horizontal position of the sprite
            -- myLocV - the current vertical position of the sprite
            property pSprite, pSpeed, myLocH, myLocV

             

            on beginSprite me
              -- initialise sprite properties
              pSprite = me.spriteNum
              -- controls the speed that the sprite moves at
              pSpeed = 10
            end

             

            on keyPress me, direction
              -- actions THIS sprite should take on key press
             
              -- store current location
              myLocH = sprite(pSprite).locH
              myLocV = sprite(pSprite).locV
             
              -- find which direction to move
              case direction of
                #left: goLeft
                #right: goRight
                #up: goUp
                #down: goDown
              end case
             
            end

             

            -- individual custom event handlers for movement
            on goLeft
              -- swap the sprite for one based on the
              -- left film loop cast member
              sprite(pSprite).member = member("left")
              -- move the sprite to the left
              sprite(pSprite).locH = myLocH - pSpeed
            end
            on goRight
              sprite(pSprite).member = member("right")
              sprite(pSprite).locH = myLocH + pSpeed
            end
            on goUp
              sprite(pSprite).member = member("up")
              sprite(pSprite).locV =  myLocV - pSpeed
            end
            on goDown
              sprite(pSprite).member = member("down")
              sprite(pSprite).locV =  myLocV + pSpeed
            end

             

            Thanks again for your help

            • 3. Re: Setting boundaries for a maze
              Mike Blaustein Level 4

              Basically, in each of the goLeft, goRight, etc handlers, you would do something like this:

               

              on goRight
                sprite(pSprite).member = member("right")

                newLocH = myLocH + pSpeed

               

                --find out if newLoc is a legal space

                iColor = getPixel(member("BWMAP"), newLocH, myLocV)

                if iColor=color(0,0,0) then

                  --black is legal so move it over
                  sprite(pSprite).locH = newLocH

                else

                  beep

                end if
              end

               

              This uses the MEMBER (named BWMAP)... not the sprite.  So you may need to offset the newLocH and myLocV properties in the getPixel statement if the maze sprite is not sitting at point(0,0) in the top left of the stage.

              • 4. Re: Setting boundaries for a maze
                James Newton, ACP Level 3

                Are you looking for something like this: http://nonlinear.openspark.com/tips/dragging/irregular/?

                1 person found this helpful
                • 5. Re: Setting boundaries for a maze
                  NOCK2k8 Level 1

                  That's brilliant, but for some reason I just keep getting beeping and the sprite refuses to move down.

                   

                  I'm quite new to thei Director-lark, so can I ask where you have used BWMAP, is that the name of the Cast Member from the library at the bottom of the screen, or is that something else?  Do I need to add newLocV and newLocH to the variables list at the top of the screen?

                   

                  My code currently looks like this:

                   

                  -- properties used in this script:
                  -- pSprite - the sprite reference
                  -- pSpeed - the speed the sprite should move
                  -- myLocH - the current horizontal position of the sprite
                  -- myLocV - the current vertical position of the sprite
                  property pSprite, pSpeed, myLocH, myLocV

                   

                  on beginSprite me
                    -- initialise sprite properties
                    pSprite = me.spriteNum
                    -- controls the speed that the sprite moves at
                    pSpeed = 10
                  end

                   

                  on keyPress me, direction
                    -- actions THIS sprite should take on key press
                   
                    -- store current location
                    myLocH = sprite(pSprite).locH
                    myLocV = sprite(pSprite).locV
                   
                    -- find which direction to move
                    case direction of
                      #left: goLeft
                      #right: goRight
                      #up: goUp
                      #down: goDown
                    end case
                   
                  end

                   

                  -- individual custom event handlers for movement
                  on goLeft
                    -- swap the sprite for one based on the
                    -- left film loop cast member
                    sprite(pSprite).member = member("left")
                    -- move the sprite to the left
                    sprite(pSprite).locH = myLocH - pSpeed
                  end
                  on goRight
                    sprite(pSprite).member = member("right")
                    sprite(pSprite).locH = myLocH + pSpeed
                  end
                  on goUp
                    sprite(pSprite).member = member("up")
                    sprite(pSprite).locV =  myLocV - pSpeed
                  end
                  on goDown
                    sprite(pSprite).member = member("down")
                    newLocV = myLocV + pSpeed
                   
                     --find out if newLoc is a legal space

                   

                    iColor = getPixel(member("Level_1_Maze"), newLocV, myLocH)

                   

                    if iColor=color(10,225,10) then

                   

                      --grass colour is legal so allow move
                      sprite(pSprite).locV = newLocV

                   

                    else

                   

                      beep

                   

                    end if
                  end

                   

                   
                  end

                   

                  Sorry if I sound dumb.  Thanks again for your help.

                  • 6. Re: Setting boundaries for a maze
                    NOCK2k8 Level 1

                    Erm, no.  Thanks for trying to help but my sprite is keyboard controlled.

                    • 7. Re: Setting boundaries for a maze
                      Mike Blaustein Level 4

                      In my example, BWMAP was the member name of the black and white version of the map.  The name that shows up in the cast window.  You do not need to add additional property declarations.  Those are just local variables, not properties.  You need to find out why it is not moving down, so put in a few "put" statements to find out what is going on

                       

                      if iColor=color(10,225,10) then
                          --grass colour is legal so allow move
                          sprite(pSprite).locV = newLocV
                      else
                          put iColor
                          beep

                      end if

                       

                       

                      Now it will show you what color is there in the message window when it beeps.  Your image may have an incorrect color (for example, it may be off a very little bit like color(10,255,9) due to compression of something.  Also, as I said, you will probably need to offset the getPixel coordinates to match your movie.  The member's (0,0) point is at the top left of the image.  The sprite's (0,0) point is wherever the sprite's top left corner is on the stage.  If your maze sprite is not at (0,0) of the stage, then you need to offset the getPixel.

                      • 8. Re: Setting boundaries for a maze
                        NOCK2k8 Level 1

                        Okay,

                         

                        I got the (10,225,10) value from Directors own color picker tool (so I'm thinking that it should be correct?)

                         

                        In the Message window after adding that "put" statement in I get:

                         

                        -16064246

                         

                        Which, to me means nothing whatsoever, I googled it but got nothing of any use.

                         

                        How do I offset the getPixel coordinates?

                         

                        Thanks again, your help really is very much appreciated.

                        • 9. Re: Setting boundaries for a maze
                          Mike Blaustein Level 4

                          Try using the newer syntax for getPixel (also, I noticed that the order for the V and H are reversed... I fixed that here:

                           

                          iColor = member("Level_1_Maze").getPixel( myLocH, newLocV)

                           

                          You would offset the newLocV and myLocH in that command by however many pixels the sprite is offset from the top left corner.  If the sprite's top left is at the stage's 10,200 point for example, you would do this:

                           

                          iColor = member("Level_1_Maze").getPixel( myLocH+10, newLocV+200)

                          • 10. Re: Setting boundaries for a maze
                            Chunick Level 3

                            This is probably exactly what the OP is looking for: http://collab.directorforum.com/Collision_Detection_Scripts_for_2D_Games

                             

                            A link to the source is at the bottom of the page. It was written by me, so if there are any questions then ask away.

                             

                            Oh, and no need to use getPixels... just a straight sprite intersects() comparison.

                            • 11. Re: Setting boundaries for a maze
                              NOCK2k8 Level 1

                              Thanks again for your help, but for some reason it still isn't working

                              • 12. Re: Setting boundaries for a maze
                                NOCK2k8 Level 1

                                Thank you Joshua, that is almost EXACTLY what I am trying to do.

                                 

                                However I have a few concerns:

                                1) I have no idea what this code does:

                                 

                                property spriteNum, sp, mem

                                 

                                on beginSprite me
                                  sp = sprite(me.spriteNum)
                                  mem = sp.member
                                  if mem.type = #bitmap then
                                    sp.ink = 8 --#matte
                                    if mem.depth = 32 then mem.alphaThreshold = 128
                                  end if
                                end

                                 

                                on collisionDetect me, playerSpriteNum
                                  if sprite(playerSpriteNum).intersects(sp) then
                                    put spriteNum
                                    return True
                                  end if
                                end

                                 

                                2)  I have a movie script man rather than a static circle, will that cause an issue?

                                 

                                and 3) My bushes are a dark green not black, how will I need to change the code to allow for this difference?

                                 

                                Thanks in advance.

                                • 13. Re: Setting boundaries for a maze
                                  Chunick Level 3

                                  NOCK2k8 wrote:

                                   

                                  Thank you Joshua, that is almost EXACTLY what I am trying to do.

                                   

                                  However I have a few concerns:

                                  1) I have no idea what this code does:

                                   

                                  property spriteNum, sp, mem

                                   

                                  on beginSprite me
                                    sp = sprite(me.spriteNum)
                                    mem = sp.member
                                    if mem.type = #bitmap then
                                      sp.ink = 8 --#matte
                                      if mem.depth = 32 then mem.alphaThreshold = 128
                                    end if
                                  end

                                   

                                  on collisionDetect me, playerSpriteNum
                                    if sprite(playerSpriteNum).intersects(sp) then
                                      put spriteNum
                                      return True
                                    end if
                                  end

                                   

                                  2)  I have a movie script man rather than a static circle, will that cause an issue?

                                   

                                  and 3) My bushes are a dark green not black, how will I need to change the code to allow for this difference?

                                   

                                  Thanks in advance.

                                  1. The code in the on beginSprite handler deals with setting up references to the sprite and member so they can be accessed throughout the behavior. As well, it sets sprite's ink attribute to matte if it's a bitmap image and the threshold to 128 if it's a 32-bit image (image with transparency). These settings are important for the sprite(x).intersects(sprite(y)) part of the code in the collisionDetect handler to work.

                                   

                                  Essentially, what's happening is that the code broadcasts the message every move from the player... like the player shouting out, "Did I bump into anything?" and the walls (in the case of the maze - one big, transparent image with black walls) shouting back "no, you did not!".

                                   

                                  2. The movie script man may cause problems... it all depends on how you have him set up, but it can be solved (which may mean a change in how you're currently doing things with your man, like making him a filmloop or animated gif, if you want to create a walking cycle).

                                   

                                  3. The type of image you are using doesn't matter. Take a look at the maze in photoshop and you will see what it consists of. Create a similar maze, but with bushes as walls and the path being the transparent part of the image and replace it in my exmaple. it should work fine. If you have troubles I can try posting another example for you to see these elements working together (ie. a moving character with walkcycle and a prettier maze with bushes). Let me know.

                                  • 14. Re: Setting boundaries for a maze
                                    NOCK2k8 Level 1

                                    I'm really not managing to get this to work.  I think it's because my man is a movie script.  I could change it for a .gif but I need to demonstrate the use of a movie script for my coursework, so I'd rather keep it as it is.

                                     

                                    I'm pretty sure that Mike's method was getting there, and that I was only missing something with it.  So I think I'm going to revert back to that way and tinker.  If you (or anyone else for that matter) has any suggestions for why it wasn't quite working before then please let me know.  In theory it looks right but it just isn't working for me for some reason.

                                    • 15. Re: Setting boundaries for a maze
                                      Chunick Level 3

                                      NOCK2k8 wrote:

                                       

                                      I'm really not managing to get this to work.  I think it's because my man is a movie script.  I could change it for a .gif but I need to demonstrate the use of a movie script for my coursework, so I'd rather keep it as it is.

                                       

                                      I'm pretty sure that Mike's method was getting there, and that I was only missing something with it.  So I think I'm going to revert back to that way and tinker.  If you (or anyone else for that matter) has any suggestions for why it wasn't quite working before then please let me know.  In theory it looks right but it just isn't working for me for some reason.

                                      A moviescript is better utilized for things like initializing progam settings/global variables/objects/etc... I wouldn't use it for creating the walk cycle of your character.

                                      • 16. Re: Setting boundaries for a maze
                                        NOCK2k8 Level 1

                                        I am still struggling with this.  I just don't get it.  Mike's method in theory is perfect, but all I get is a beep and my character not moving anywhere.  I bet there is a tiny little error  somewhere, something silly.  Code currently looks like this:

                                        -- properties used in this script:
                                        -- pSprite - the sprite reference
                                        -- pSpeed - the speed the sprite should move
                                        -- myLocH - the current horizontal position of the sprite
                                        -- myLocV - the current vertical position of the sprite
                                        property pSprite, pSpeed, myLocH, myLocV

                                         

                                        on beginSprite me
                                          -- initialise sprite properties
                                          pSprite = me.spriteNum
                                          -- controls the speed that the sprite moves at
                                          pSpeed = 10
                                        end

                                         

                                        on keyPress me, direction
                                          -- actions THIS sprite should take on key press
                                         
                                          -- store current location
                                          myLocH = sprite(pSprite).locH
                                          myLocV = sprite(pSprite).locV
                                         
                                          -- find which direction to move
                                          case direction of
                                            #left: goLeft
                                            #right: goRight
                                            #up: goUp
                                            #down: goDown
                                          end case
                                         
                                        end

                                         

                                        -- individual custom event handlers for movement
                                        on goLeft
                                          -- swap the sprite for one based on the
                                          -- left film loop cast member
                                          sprite(pSprite).member = member("left")
                                          -- move the sprite to the left
                                          sprite(pSprite).locH = myLocH - pSpeed
                                        end
                                        on goRight
                                          sprite(pSprite).member = member("right")
                                          sprite(pSprite).locH = myLocH + pSpeed
                                        end
                                        on goUp
                                          sprite(pSprite).member = member("up")
                                          sprite(pSprite).locV =  myLocV - pSpeed
                                        end
                                        on goDown

                                          sprite(pSprite).member = member("down")
                                          newLocV = myLocV + pSpeed
                                         
                                          --find out if newLoc is a legal space
                                         
                                          iColor = member("Level_1_Maze").getPixel(myLocH, newLocV)
                                         
                                          if iColor = color(10,225,10) then
                                           
                                            --grass colour is legal so allow move
                                            sprite(pSprite).locV = newLocV
                                           
                                          else
                                            put iColor
                                            beep
                                          end if
                                        end

                                         


                                        I'm wondering if it may be a good or bad idea to split the code so that I have one script that deals with the changing of image and another that deals with whether or not it can move?  I don't know what best practice is?

                                        • 17. Re: Setting boundaries for a maze
                                          Mike Blaustein Level 4

                                          When it beeps, what shows up in the message window?  It should show you the color that the block is where the character should move to.  It is beeping because it /thinks/ that it is trying to move to an illegal location.  You need to see where on the map the program thinks it is going.

                                           

                                          As a temporary test, you may want to make a test "map" that is a color gradient where every pixel is actually a different color.  That way, you can easily track where it is.  Make sure that your test map is the same size and location as your real one, and the coordinates and offsets should be the same.

                                          • 18. Re: Setting boundaries for a maze
                                            NOCK2k8 Level 1

                                            In the message window I get:

                                             

                                            -- -16064246

                                             

                                            Do you have any idea what that is supposed to mean? As I have no idea whatsoever. Starting to get really ticked off with this now.  I will try the offset thing that you mentioned before.  Do I get the numbers from the Sprite coordinates?

                                            • 19. Re: Setting boundaries for a maze
                                              NOCK2k8 Level 1

                                              I have just discovered that when my 'man' passes over the hedges and I hit down I get:

                                               

                                              -- -16754176

                                               

                                              in the message window.


                                              So Lingo is seeing the 'grass' as -- -16064246 (as I said before)

                                              and the 'hedges' as -- -16754176

                                               

                                              Can I use these message codes to my advantage somehow?

                                               

                                              By changing the color(10,255,10) part maybe?

                                              • 20. Re: Setting boundaries for a maze
                                                Mike Blaustein Level 4

                                                my bad... change the getPixel to this:

                                                 

                                                member("Level_1_Maze").image.getPixel(myLocH, newLocV)

                                                 

                                                You need to get the pixel value of the image of the member... not the member itself. Now it should put a normal color object in the message window for you to compare to.

                                                • 21. Re: Setting boundaries for a maze
                                                  NOCK2k8 Level 1

                                                  Thanks!  My problem is potentially solved.  Just need to sort up, left and right out in the same way now.

                                                   

                                                  You are a star! Thank you.  Question answered.