Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

share|improve this question
    
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. –  Matariki Jul 11 '12 at 19:24
    
In my other code, I used PassEventsDown->False. Would that be acceptable with nested EventHandlers? –  VF1 Jul 11 '12 at 19:33
add comment

1 Answer 1

up vote 7 down vote accepted

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})]
share|improve this answer
    
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? –  VF1 Jul 11 '12 at 19:24
    
@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 –  Rojo Jul 11 '12 at 19:27
    
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? –  VF1 Jul 11 '12 at 19:31
    
@Vlad I am not sure what you mean, if you can find a minimal example of what confuses you post it –  Rojo Jul 11 '12 at 19:35
    
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. –  VF1 Jul 11 '12 at 20:00
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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