Mscape Help


More complex variable assignments

<<< previous section: Setting properties and variables


The examples of property and variable assignment in the previous section had one notable limitation: they didn't allow you to manipulate the existing value of a property or variable. What if you want to decrease an audio track volume by ten each time a region is entered? What if you didn't know the coordinates you wanted to move a region to, only by how far you wanted to shift it? What if you wanted to change the filename of your log to ensure previous log files weren't overwritten? As it happens you've already seen how to achieve this.

Operators

When you logged the x coordinate in the previous section you used the + operator to display the value of x alongside a text label:

Logger.Log("x coordinate: " + x);

This approach can also be used with variables and properties. We'll start by duplicating the result of the above code using a text variable 'myText'. In the GPS OnLocation event type the following two lines:

myText.Value = "x coordinate: " + x;
Logger.Log(myText.Value);

When you run the tester and click on the map you'll get the same result as before - a log message with a label and the value of the current x coordinate. The important thing to realise here is that we have combined the label and coordinate into a single variable: 'myText' and the variable is updated each time the event is triggered.

Looking at this example you might see that we've actually broken the rule about always assigning properties or parameters of the same type. It's time to explain why this works. One important feature of Text variables is that they can be forgiving when you try and assign non-text values to them using an operator. As long as one part of the operation is text, the other part will automatically be converted to text. So in this example the value of x is converted from a number to text. Since all we're doing with the number is displaying it in the log that's not too much of a problem.

Operators and Numbers

When working with numbers the effect of operators changes and the number of operators available increases substantially. In this case the good old plus sign + has the expected result. In the Mediascape OnLoaded event type the following:

myNumber.Value = 6 + 2;
Logger.Log("result: " + myNumber.Value);

In this case what gets stored in the number variable and displayed by the Logger is the result of the sum of 6+2. i.e. 8. It shouldn't come as too much of a surprise that all the basic arithmetic operators are available, and have the expected result, as shown in the following example:

myNumber.Value = 6 + 2;
Logger.Log("6+2: " + myNumber.Value);
myNumber.Value = 6 - 2;
Logger.Log("6-2: " + myNumber.Value);
myNumber.Value = 6 * 2;
Logger.Log("6*2: " + myNumber.Value);
myNumber.Value = 6 / 2;
Logger.Log("6/2: " + myNumber.Value);

Note that each assignment sets a new value for 'myNumber' ignoring the previous value. Effectively we're using the logger as a calculator; and we're not limited to calculations with just two numbers: we can add, multiply, subtract or divide as many numbers as we like. Try the following:

myNumber.Value = 6+2*4-2/2;
Logger.Log("result: " + myNumber.Value);

What do you get as the result in the tester? Now try it on a calculator. Do you get the same result? The answer is almost certainly 'no'. This example isn't designed to put you off calculations with multiple values, it just highlights a potential problem with these types of calculations: the result will depend on the order in which the operations are carried out. A calculator takes the result of an operation and applies the next operation to the result; so:

6+2 = 8
8*4 = 32
32-2 = 30 
30/2 = 15

Programming languages deal with these calculations a little differently. There is a set order of precedence for operations, with multiplication and division coming first, then adding and subtraction. So:

2*4 = 8
2/2 = 1
6+8-1 = 13

Another way of writing this is:

6 + (2*4) - (2/2) = 13

Brackets (or 'parentheses') can be used when you want the next operation to be carried out on the result of the calculation inside the brackets. So to get the same result as a calculator in the tester you would need to do the following:

myNumber.Value = (((6+2)*4)-2)/2;
Logger.Log("result: " + myNumber.Value);

Basically when in doubt about operator precedence, or if you're getting an unexpected result, it's a good idea to use parentheses. Just remember that for every opening bracket you'll need a closing bracket.

Operators and Number variables

In practice you're unlikely to be carrying out calculations with arbitrary numbers, you'll want to work with existing variables, properties and parameters. This is simply a matter of referencing a number variable, property or parameter in your calculation. For example:

// using the x parameter in the OnLocationChange event:
myNumber.Value = x + 10;
// using the radius of a CircleRegion:
myNumber = myCircleRegion.Radius - 10;
// using another number variable:
myNumber = playerScore.Value / 10;
// using two existing number variables:
myNumber = playerScore.Value * playerLevel.Value;

In the last example above you'll see that a calculation can be made up solely of number variables, properties or in fact parameters.

Division by zero

It's worth adding a warning at this point about one particular calculation you should avoid at all costs. Try adding the following to the Mediascape OnLoaded event:

myNumber.Value = 1/0;
Logger.Log("one divided by zero = " + myNumber.Value);

You should see the following error message:

zero-divide.gif

Whilst some mathematicians may be happy with the idea of dividing by zero and giving the answer as 'infinity', computers don't like it one bit; to the point that programming languages will usually report division by zero as an error. So, if you ever need to divide a number by the value of a variable, you should ensure that the variable is not zero or your mscape will crash.

Recursion

Finally let's answer the questions we posed at the beginning. How do we manipulate the existing value of a variable, property or parameter so that we can, for example decrease the volume of an audio clip, or change the position of a region? Look at the following code:

Logger.Log("value before: " + myNumber.Value);
myNumber.Value = myNumber.Value + 1;
Logger.Log("value after: " + myNumber.Value);

At first glance this doesn't look like it should work. How can something be equal to itself plus one? What you have to remember is that the equals sign is an assignment operator and does not represent equality. We're not saying that myNumber.Value is equal to myNumber.Value plus one; we're saying we want to set its value to be equal to itself plus one. This little trick is known as recursion and is incredibly useful. To test it let's use a button input. Select the OnCenter event of the Buttons object and add the following code:

myNumber.Value = myNumber.Value + 1;
Logger.Log("result: " + myNumber.Value);

Run the tester and click the center button in the Buttons panel on the right. Keep clicking and see what happens. Each time you click it the value of myNumber is increased by one. Now try replacing the operation with each of the following, testing each one in turn:

myNumber.Value = myNumber.Value - 1;
myNumber.Value = myNumber.Value * 2;
myNumber.Value = myNumber.Value / 2;
myNumber.Value = myNumber.Value + myNumber.Value;

You'll see that each time you click the button the operation is applied to the current value of myNumber. These recursive operations are important enough to have their own assignment operators. Instead of an equals sign and repeating the variable reference you use the type of operation (plus, minus, multiplication, division) followed by an equals sign, followed by the value you want to apply. So:

myNumber.Value = myNumber.Value + 1;
// can be written as:
myNumber.Value += 1;

myNumber.Value = myNumber.Value - 1;
// can be written as:
myNumber.Value -= 1;

myNumber.Value = myNumber.Value * 2;
// can be written as:
myNumber.Value *= 2;

myNumber.Value = myNumber.Value / 2;
// can be written as:
myNumber.Value /= 2;

myNumber.Value = myNumber.Value + myNumber.Value;
// can be written as:
myNumber.Value += myNumber.Value;
// Note that this is equivalent to:
myNumber.Value *= 2;

Adding and subtracting 1 to the value of a number is used so often in programming that there are separate shortcuts for this also:

// To add one to the value:
myNumber.Value ++;
// To subtract one from the value:
myNumber.Value --;

This technique is incredibly powerful and has a range of applications. In your mscape you might use it to add to a player's score, or even to move the position of a region. For example try adding the following to the Button OnRight event:

region01.X +=10;

This article will be added to in the future. In the meantime you may want to look at some of the other programming articles.

Ready to
get started?

Download Mscape Suite Version 2.6 | 11 MB

Download Mscape Experimental

Experimental Beta Version 2.6 | 11 MB

Ask the Mscape Community

Forums