4
$\begingroup$

I've been having some difficulty with the aforementioned use of these three functions/options and would greatly appreciate some help.

I know that they're is probably an easy way of making a disk move across a square, but, as you may be able to guess, this is an abstraction of my real problem and thus I have to work with an object-oriented system (i.e., currying).

Let's say I wanted to make a disk move from the bottom left of a square to the top right, with enter as my play/pause control:

My code:

makeobject[name_String] := object[name]

(* Default values for position and velocity *)  
object[name_]["pos"] = {0, 0};  
object[name_]["vel"] = {.05, .05};

(* Return a graphic method *)  
(this : object[name_])["pic"] := {EdgeForm[Pink], Blue,  
Disk[this["pos"], .2]}

(* update *)  
tick[obj_] := ((obj["pos"] = obj["pos"] + obj["vel"] (.1)); obj)

(* Dynamic pictures *)
DynamicModule[{play = False, myobj = makeobject["myobj"]},
    EventHandler[
        Dynamic[
            EventHandler[
                If[play,
                    myobj = tick[myobj];
                    Graphics[{Black, Rectangle[{0, 0}, {50, 50}], myobj["pic"]}, 
                        PlotRange -> {{0, 1}, {0, 1}}],
                    Graphics[{Black, Rectangle[{0, 0}, {50, 50}], myobj["pic"]}, 
                        PlotRange -> {{0, 1}, {0, 1}}]
                  ],
                {"ReturnKeyDown" :> (play = False)}],
           UpdateInterval -> .01],
       {"ReturnKeyDown" :> (play = True)}
   ],
   Initialization :> ( myobj["pos"] = {0, 0})
]  

The site's not letting me put up any pictures of what's happening, but when I evaluate, you get an image of black rectangle with the quarter circle at the bottom. Pressing enter makes the disk move up and right.

But, while it's updating, if I press enter, nothing happens, and the disk keeps moving. This means that it's still calling tick[myobj] and therefore the "ReturnKeyDown":>(play=False) never worked.

Thanks in advance for any help.

Sorry if I am missing any kind of information, this is my first question. Please let me know if so.

MMA 8.0.1.0 for students
OS Windows 7 64-bit

$\endgroup$
2
  • $\begingroup$ You cannot have two Eventhandlers interlocked and reacting to the same event with opposite effect play = False and play = True. What play will be will depend on what Eventhandler get executed last. See Rojo's answer below on how to code this. $\endgroup$
    – Matariki
    Jul 11, 2012 at 19:24
  • $\begingroup$ In my other code, I used PassEventsDown->False. Would that be acceptable with nested EventHandlers? $\endgroup$
    – VF1
    Jul 11, 2012 at 19:33

1 Answer 1

7
$\begingroup$

I haven't looked in depth to see what's wrong in your code yet, but making the enter key toggle play works

makeobject[name_String] := object[name]

(* Default values for position and velocity *)  
object[name_]["pos"] = {0, 0};  
object[name_]["vel"] = {.05, .05};


(*Return a graphic method*)
(this : object[name_])["pic"] := {EdgeForm[Pink], Blue, 
  Disk[this["pos"], .2]}

(*update*)
tick[obj_] := ((obj["pos"] = obj["pos"] + obj["vel"] (.1)); obj)

(*Dynamic pictures*)
DynamicModule[{play = False, myobj = makeobject["myobj"]}, 
 EventHandler[Dynamic[If[play, myobj = tick[myobj];
    Graphics[{Black, Rectangle[{0, 0}, {50, 50}], myobj["pic"]}, 
     PlotRange -> {{0, 1}, {0, 1}}], 
     Graphics[{Black, Rectangle[{0, 0}, {50, 50}], myobj["pic"]}, 
      PlotRange -> {{0, 1}, {0, 1}}]], 
   UpdateInterval -> .01], {"ReturnKeyDown" :> (play = ! play)}], 
 Initialization :> (myobj["pos"] = {0, 0})]
$\endgroup$
7
  • $\begingroup$ Also, why was the Refresh necessary? You're directly changing myobj's value, so it would give you the most up-to-date image anyway, right? $\endgroup$
    – VF1
    Jul 11, 2012 at 19:24
  • $\begingroup$ @Vlad, it is not necessary, it's a leftover from something I tested and I didn't realise it was there. I'll edit it out $\endgroup$
    – Rojo
    Jul 11, 2012 at 19:27
  • $\begingroup$ I just deleted my comment regarding the PassEventsDown thing because I just realized what was going on - I had a Checkbox[Dynamic[play]] on top of the actual image. Try doing that and it gets confused. I just removed it and everything works fine. Thanks. (But seriously, why does Column[{Checkbox[Dynamic[play]], EventHandler[(*...*)]}] fail? $\endgroup$
    – VF1
    Jul 11, 2012 at 19:31
  • $\begingroup$ @Vlad I am not sure what you mean, if you can find a minimal example of what confuses you post it $\endgroup$
    – Rojo
    Jul 11, 2012 at 19:35
  • $\begingroup$ It's no big deal. I'll try to figure it out on my own. Thanks for the answer. I can't upvote yet, though (not enough rep)! Also, do you mind letting me know why I have to keep on clicking on the image for EventHandler to recognize my keystrokes? It keeps on "de-selecting" itself. $\endgroup$
    – VF1
    Jul 11, 2012 at 20:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.