View Single Post
Super Moderator
Status: Offline
Posts: 250
Join Date: Dec 2012
Location: Frosno, Ca
Default 08-09-2015, 03:50 PM

Originally Posted by shaolinkidd View Post
Lol! Here is the code. I should have been more specific. I'm sure I have some fluff in the code so don't be shy about pointing it out.

Alice Ring Catcher

There are a couple of problems here that cause confusion. The first is a property of an object or variable called its scope. The scope of a variable defines when the program can ‘see’ or act on it. For instance in the world’s properties you have an object variable called ‘ringCatcher’ because this is declared in the world properties section it is available for use in any method or function. Conversily, if you look at the variable ringNumber defined in the 3D Text object, it will not be visible unless either it is being used in a method belonging to the 3D Text object where it was declared as is the case in 3D Text.ringsMade() or it is explicitly (fully) identified by the object that owns it. In the world (or some other object’s function or method) you would have to use 3D Text.ringNumber to get or change its value.
Side Note:
In object programming it is usually considered bad from to directly change another object’s variables. This is why get() and set() methods are provided by objects for values the object’s user is allowed to see or change. The get() and set() methods also allow the object’s designer to do any internal ‘house keeping’ that may need to be done due to the change of a variables value.
So what about my movie you may be asking, after reading the above, eating a handful of advil and taking a nap. Well, the ringSet defined in ‘My first method’ is only visible within that method, just as the rings variable is only defined within the ‘ringsMovement’ method. There are two ways to consolidate these. The first step in either way is to move the list to the worlds properties section. This means declaring a new list variable in the world property panel and populating it with the torus objects. Now you can either drag the new list directly into your method/function or you can declare an object list parameter and pass the whole list in to a method or function.

Another problem area is your ‘index’ variable. There are two problems with index. The first is that by specifying a value between 0 and 3 you are saying that you want to generate any number from 0 up to but not including 3! Not ever generating the largest number is true in most random number generators. So if you every want to see a 3 you will have to change the maximum to 4. The other problem is that the random number generator is returning fractional values between your min and max. I think Alice converts these to integers (whole numbers) when used as an index but I am not sure and it is not a good idea to leave details like this up to Alice, or any other programming environment. Depending on whether and how the random number is rounded off, the results can be unpredictable. (see the attached movie.)
To get around this problem, go to the random instruction and set the IntegerOnly parameter to true. So that your instruction reads:
index = random min=0, max=4, IntegerOnly=true

Now for the main event:
Look at your movie and try to picture what Alice is going to do.
At the start:
previous is set to previous
index is set to a random number between 0 and 2.99999…
next is set to next
The previous and next statements do nothing as the values are defined to be 3 and 0 in the method’s variable section and setting a variable to itself does not change its value.
The index however is set to some value between 0 and 2.9999… and we are hoping that it will take on the value of 0, 1, 2 or 3 (which as described above, it will not do.) But if index = 0 then it will be the same as previous, and if it equals 3 it will be the same as next. And in these cases only two of the rings will be affected.
But wait, there is an easier way. If you look at the bottom of the authoring window there are a couple of statements that start with “For all” these statements are the reason you want to use lists to start with. You can make a method for each torus that will move it around however you want and then use ‘For all together’ to make every element in the list call your method at the same time.

In any event you now have your rings dropping. And that is all that will happen until the do together block finishes. You can move the cone because it’s movement is controlled by the mouse and has nothing to do with the movie’s methods but it will not effect anything until the ‘do together’ terminates.
It is at that time and only at that time that the position of you rings will be evaluated. At that exact time if a ring is within 1 meter of the cone (or its dummy object), you will update success, otherwise you will update fail. And then you will restart. What is happening has nothing to do with the rings and the cone during the fall and everything to do with where the rings are relative to the dummy object when they are all finished falling.

The easiest way to correct this is to use an event. If you create a ‘when the world starts’ event and then right click on it, you can change it to a ‘while the world is running event’
Now you can make a new method out of the bottom half of your ‘my first method’ where you are checking to see if you caught a ring and resetting the game (maybe call it caught) and place it in this event.
There is no need for a loop as whenever the caught method finishes, it will automagically begin again as long as the movie is running.

I hope all this helps you with your project.

Attached Files
File Type: a2w Random.a2w (202.2 KB, 20 views)

Mark Henwood
Reply With Quote