16 Replies Latest reply on Dec 17, 2008 11:04 PM by kglad

    Adventure game engine: a couple of issues

    ilttu
      I'm making an adventure game for a uni course and I'm having a few issues with building the interface:

      ---------------

      1. I'm not able to have multiple hotspots at the same time, because of a declaration conflict.

      I have a boolean variable in the root timeline, called onHotspot that is meant to track if the mouse is currently on any of the hotspots. Each hotspot movieClip has it's own hitTest (in onEnterFrame), which sets the onHotspot variable to True, when the mouse is over it. The problem is how and where to set the variable to False, whenever the mouse isn't on a hotspot.

      If I have the False set in each of the movieClips in an if-else statement (if onHotspot=true {do something}, else onHotspot=false), it naturally forces the variable to False, even if the mouse is on a hotspot. So, basically I need the onHotspot to be globally available to any interactions, but I'm having trouble controlling it, because there are multiple hotspots.

      What's the best way to change the onHotspot variable to False whenever the mouse is NOT on any of the hotspots?

      ---------------

      2. Is there any way of freezing all interactions within the flash movie except a specific one?

      I have an inventory box that appears on top of the game scene when the inventory button is pressed. I need all of the scene interactions to be unavailable while the inventory is visible. Currently, whenever the inventory is open, you can still control the character in the background and interact with the scene hotspots. I want it so that everything in the background becomes frozen and unusable when the inventory is open, and when the inventory is closed, everything returns to normal.

      How do I freeze the background while the inventory box is open?

      ---------------

      Thanks in advance :D! I'm really stumped with these two issues.
        • 1. Re: Adventure game engine: a couple of issues
          kglad Adobe Community Professional & MVP
          1. you should use a unique boolean for each hotspot.

          2. that depends on what listeners you have defined. if keyboard interaction is detected, you should remove the listener(s) when not needed. for mouse events, you can use a blocking movieclip that has a mouse handler attached which is disabled. that will prevent all underlying objects from responding to the mouse.
          • 2. Re: Adventure game engine: a couple of issues
            ilttu Level 1
            Thanks for replying :D!

            1. Isn't there any way to have a global parameter that is controlled by each of the hotspots? Thing is, there could be up to 20 different hotspots in one single room, and even up to 20 separate rooms. That means, in such a case, I'd have to have 400 conditionals to make something very simple work.

            The main interactions I want to utilize when the mouse is on a hotspot are:
            - a cursor change, from normal to an active red color
            - an object line text change, e.g. printing out "door" when the mouse is on the door hotspot, and clearing the object line text whenever it's not
            - appearance of a verbcoin UI that should come up when you click and hold the mouse whenever on a hotspot
            - "use", "talk" and "examine" custom interactions for each hotspot when the mouse is released on any of the specific U, T or E buttons on the verbcoin

            On top of being incredibly cumbersome to have everything defined in each of the hotspots, it still doesn't fix the "false" definition. Let's say I have two frames in the cursor movieClip: "default" and "active". If I determine the cursor to go to "active" from each of the hotspot, how do I change it back to "default" when the cursor is not on any of the hotspots? The only way I can think of making it work this way would be for the cursor itself to check every hotspot hitTest, but that would be madness with a potentially endless amount of hotspot boolean variables to condition through.

            Would it be possible to have a tracker in the root that defines onHotspot to False continuously, which would then be overridden by any one of the hotspots whenever the mouse is on one?

            2. No keyboard interactions are utilized in the interface, so I only need the mouse events to be unavailable. I have a fader movieClip that goes from 0 to 50 alpha upon opening the inventory, covering all of the background stuff. I've tried adding button interactions to it, to override all other interactions underneath, but it didn't work properly. It still recognized the stuff underneath. I'll have to retry this, because I think it might still work with some more effort.
            • 3. Re: Adventure game engine: a couple of issues
              kglad Adobe Community Professional & MVP
              1. if you have one parameter controlled by all the hotspots, the hotspots can't use a loop that executes without limit. you could use rollover and rollout handlers.

              2. you must have done something wrong.
              • 4. Re: Adventure game engine: a couple of issues
                ilttu Level 1
                Thanks again!

                I got issue 2 to work by adding a movieClip with button functionality under the inventory box. It now covers everything under it and disables the hotspots. I tried it earlier without avail, but this time I added a boolean var to determine whether the inventory is open or not, so currently character movement and the verbcoin are disabled whenever the inventory is open.

                Btw, is there a way to make something go grayscale with a movieClip set to a specific blend mode, as in drain the saturation from everything seen underneath it? In Photoshop, the blend mode would be called 'saturation' but I couldn't find a corresponding one in Flash. I'm thinking of maybe graying out the background, while the inventory box is open.

                As for issue 1, I solved it by having the variable defined by rollOvers and rollOuts in each hotspot, like you said. Works perfectly, and I can't believe I didn't get it any earlier :D. Thanks for that.

                There is one problem with it, though. If I click and hold the mouse on the hotspot and move away from the hotspot, then release, it never runs the rollOut script. Is there some logical reason why the rollOut wouldn't work, while the mouse is down? And how might I be able to remedy this?
                • 5. Re: Adventure game engine: a couple of issues
                  Level 7
                  ilttu,

                  > If I click and hold the mouse on the hotspot and move away
                  > from the hotspot, then release, it never runs the rollOut script.

                  Events, like computers in general, tend to be very, very picky.

                  > Is there some logical reason why the rollOut wouldn't work,
                  > while the mouse is down? And how might I be able to remedy
                  > this?

                  When you click, hold, and move out, you're actually triggering an
                  onDragOut event, rather than onRollOut. You can assign the same event
                  handler function to both of those events, and that may do it for you.


                  David Stiller
                  Adobe Community Expert
                  Dev blog, http://www.quip.net/blog/
                  "Luck is the residue of good design."


                  • 6. Re: Adventure game engine: a couple of issues
                    ilttu Level 1
                    Thanks a lot! That worked perfectly.

                    Any idea about the grayscaling thingy? Is it even possible to do dynamically in Flash?
                    • 7. Re: Adventure game engine: a couple of issues
                      kglad Adobe Community Professional & MVP
                      flash can manipulate saturation via the bitmapdata class. this will be too complicated for you and is not really needed.

                      you can achieve a suitable effect by creating either a black (or white, depending on the effect you want) movieclip to position under your inventory box and assign it an _alpha less than 100.

                      btw, if you assign the enabled property of this movieclip to false, the handcursor won't show and this movieclip will still prevent mouse interaction with the objects below it.
                      • 8. Re: Adventure game engine: a couple of issues
                        ilttu Level 1
                        I have it currently so that there's a black area underneath that's semi-transparent, and it works well enough right now. I was just curious if desaturation were possible in Flash. Using bitmapdata would exclude all dynamic stuff (animation, etc.) in the background from working, so that's not a viable option.

                        I'm using custom cursors, so I don't need to disable the default interaction cursor. There is one issue concerning mouse hiding, too: If I have mouse.hide() on the onLoad event of the cursor movieClip, the OS cursor becomes visible, and stays so, if I right-click for the flash menu. On the other hand, if I have mouse.hide() also in onEnterFrame, the OS cursor won't show in the flash menu.

                        How might I be able to hide the mouse again when the flash menu is closed?
                        • 10. Re: Adventure game engine: a couple of issues
                          ilttu Level 1
                          That worked great, thanks kglad!

                          Thanks to both of you. I'll return to this thread very soon as I encounter more issues :D. I have a few already, but they're more difficult to explain :).
                          • 11. Re: Adventure game engine: a couple of issues
                            kglad Adobe Community Professional & MVP
                            you're welcome.
                            • 12. Re: Adventure game engine: a couple of issues
                              ilttu Level 1
                              I've encountered another stumping issue:

                              ---------------

                              3. How can I have a function loop if it's called from a single non-looping event?

                              Basically what I have is a function that makes the player character walk to a coordinate, after which the scene changes (in traditional adventure game manner): moveToAndExit(). This function is called from a mouse onRelease event, so it's not looping. The problem is that for the character to move, I need the function to loop until the character reaches it's target after which the scene is changed. I've tried putting an onEnterFrame inside the function, but it screws up all later character movement, supposedly because it's left looping, and it uses global character attributes (such as targetX/targetY).

                              function moveToAndExit(char, targetX, targetY, run, changeFrom, changeTo) {
                              onEnterFrame = function () {
                              //move char with charMove function
                              _root.charMove(char, targetX, targetY, run)
                              //exit scene if movement has stopped
                              if (Math.round(char._x) == targetX && Math.round(char._y) == targetY) {
                              _root.changeScene(changeFrom, changeTo)
                              }
                              }
                              }

                              I'm not gonna post the charMove() or changeScene() functions, because they aren't that relevant. The important thing is that the charMove function is used for all character movement, and it gets screwed up after this function. I also have other functions that rely on this system, such as moveToAndSpeak(), etc.

                              Should I perhaps add some line into the if-statement, after the changeScene function is run, which would kill the function and end the looping? What would be the best way to do this?
                              • 13. Re: Adventure game engine: a couple of issues
                                kglad Adobe Community Professional & MVP
                                well, charMove is relevant and almost certainly the problem. instead of calling charMove() in that onEnterFrame, you should

                                1. be incrementing char's _x and _y properties.
                                2. using Math.abs(char._x-targetX)<somenumber && similarly for _y to
                                determine when to change scene AND
                                3. delete that onEnterFrame loop.
                                • 14. Adventure game engine: a couple of issues
                                  ilttu Level 1
                                  Seems I spoke too soon. The problems I was having with the movement wasn't due to the movetoAndExit() function, but rather a variable conflict in the charMove() function, like you said.

                                  Nevertheless, I got the function to stop looping with "delete this.onEnterFrame;", and the movement is now working almost without issues. And this leads me to issue 4:

                                  ---------------

                                  4. When using a extended move function (e.g. charMoveToAndExit()) that uses the charMove() function, the walkspeed is doubled for some reason.

                                  So, I have a charMove() function that's used by other functions to move characters around. Within this function is a run condition, which basically increases the walkspeed, whenever run is set to True. The charMove() function works perfectly by itself, but when I embed it into another function, the walkspeed is doubled.

                                  I've gone through it a few times and it's not becoming any clearer to me. The function is a bit of a mess right now, so I'll be especially grateful if anyone is willing to go through it.

                                  charMove():
                                  ---------------
                                  //function: any non-mouse character movement
                                  function charMove(char, targetX, targetY, run) {
                                  //determine the character attributes from the given values
                                  char.targetX = targetX
                                  char.targetY = targetY
                                  char.run = run

                                  //directional unit vectors
                                  char.i = char.targetX - char._x
                                  char.j = char.targetY - char._y
                                  //calculate distance and choose smaller value
                                  char.dist = Math.sqrt(char.i * char.i + (char.j/_root.axisRatio) * (char.j/_root.axisRatio))
                                  if (char.run == false) {
                                  char.diff = Math.min(char.dist, char.walkSpeed)
                                  } else if (char.run == true) {
                                  char.diff = Math.min(char.dist, char.runSpeed)
                                  }
                                  char.i /= char.dist
                                  char.j /= char.dist
                                  char.i *= char.diff
                                  char.j *= char.diff
                                  char._x += char.i
                                  char._y += char.j

                                  //directional idle
                                  if (Math.round(char._x) == char.targetX && Math.round(char._y) == char.targetY) {
                                  //movement has stopped
                                  char.walking = "no"
                                  char.run = false
                                  }
                                  }
                                  ---------------

                                  charMoveToAndExit():
                                  ---------------
                                  //function: move to given coordinates and exit scene
                                  function charMoveToAndExit(changeFrom, changeTo, sceneXFrom, sceneXTo, teleportX, teleportY, idleDirection, charFrom, targetXFrom, targetYFrom, runFrom, charTo, targetXTo, targetYTo, runTo) {
                                  onEnterFrame = function () {
                                  //move char with charMove function
                                  _root.charMove(charFrom, targetXFrom, targetYFrom, runFrom)
                                  //exit scene if movement has stopped
                                  if (Math.round(charFrom._x) == targetXFrom && Math.round(charFrom._y) == targetYFrom) {
                                  //change the scene
                                  _root.changeScene(changeFrom, changeTo, sceneXFrom, sceneXTo)
                                  //teleport char to given coordinates
                                  _root.charTeleport(charTo, teleportX, teleportY, idleDirection)
                                  delete this.onEnterFrame
                                  }
                                  }
                                  }
                                  ---------------

                                  charMoveToAndSpeak():
                                  ---------------
                                  //function: print spoken dialog lines for chars after moving to coordinates
                                  function charMoveToAndSpeak(char, targetX, targetY, run, idleDirection, charSpeech, spokenLine) {
                                  onEnterFrame = function () {
                                  //move char with charMove function
                                  _root.charMove(char, targetX, targetY, run)
                                  //print spoken line with charSpeak function if movement has stopped
                                  if (Math.round(char._x) == targetX && Math.round(char._y) == targetY) {
                                  //make char face given direction
                                  _root.charFace(char, idleDirection)
                                  //make char say given spoken line
                                  _root.charSpeak(charSpeech, spokenLine)
                                  delete this.onEnterFrame
                                  }
                                  }
                                  }
                                  ---------------

                                  EDIT:

                                  I took out all the useless rubbish from the charMove() function so that it's a little clearer. I also added another extended function (charMoveToAndSpeak()) that's a bit simpler, but still uses the same technique and has the same problem.

                                  Also, I've come to the conclusion that the run condition has no bearing on my problem. Even if I set the global runSpeed to the same as walkSpeed, or comment out the runSpeed variables from the function, the problem still persists. I'm now thinking that the issue is from the enterFrame in conjunction with the movement tweening code, distorting it somehow. There's also another distinction with the charMove() and charMoveToAndExit() functions: charMove can be interrupted by clicking to walk somewhere else, whereas charMoveToAndExit continues to move even though you click somewhere else.

                                  Oh, you can try it out here for yourself:

                                  http://users.evtek.fi/~ilarim/flash_...project_a.html

                                  charMove(): choose U on the wall hotspot
                                  charMoveToAndSpeak(): choose E on the wall hotspot
                                  charMoveToAndExit(): click on the exit
                                  running: double-click with the mouse
                                  • 15. Re: Adventure game engine: a couple of issues
                                    ilttu Level 1
                                    Scratch that :D. I got it sorted now.

                                    As I kinda thought, it was an issue with the enterFrames. The move code was present in the character movieClip enterFrame in addition to the move function inside another enterFrame within the extended function. The code was in the character movieClip, because it was checking for mouse-driven movement. So, basically both enterFrames were running at the same time, doubling the effects of the movement, making it go two times faster than it was supposed to go.
                                    • 16. Re: Adventure game engine: a couple of issues
                                      kglad Adobe Community Professional & MVP
                                      that would be a problem.