touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · chapter 7 basic graphics,...

14
Version 1.1 for TouchDevelop v2.8 Basic Graphics, Events and Global Data – 73 – Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are introduced and then combined with scripts when an action, such as turning the phone around, is performed. That topic leads very naturally to scripts which access the sensors built into a Windows phone. Providing code to be executed whenever an event is triggered then leads naturally into scripts which use global data items. 7.1 Graphics Facilities 7.2 Events and Sensors 7.3 Global Data Graphics Facilities The phone’s screen is composed of many dots which can be illuminated in different colors. All characters, all lines, all pictures seen on the screen are displayed as patterns of these dots where the phone’s software has selected the color and intensity for each dot. Graphics programming is, in effect, a matter of writing code to set the color and intensity of each dot in an area of the screen. Anyone who has had some previous experience with graphics programming can skip the follow- ing brief introduction to the subject. After that introduction, we will move on to the facilities for graphics pro- gramming provided in TouchDevelop. Computer Graphics Terminology Each dot on the screen is known as a PICTURE ELEMENT and that term is usually abbreviated to PIXEL or to PEL. We will use the term pixel. The TouchDevelop API for setting the pixel’s color and intensity uses a triple of three numbers. In most graphics software, these three numbers are one-byte integers in the range 0 to 255, and they specify the intensity of the red, green and blue components of the color separately. However TouchDevelop scales these numbers to be in the range 0.0 to 1.0.

Upload: others

Post on 23-Aug-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Version 1.1 for TouchDevelop v2.8 Basic Graphics, Events and Global Data

– 73 –

Chapter 7

BASIC Graphics, Events,

and Global Data In this chapter, the graphics features of TouchDevelop are introduced and then combined with scripts when an

action, such as turning the phone around, is performed. That topic leads very naturally to scripts which access

the sensors built into a Windows phone. Providing code to be executed whenever an event is triggered then

leads naturally into scripts which use global data items.

7.1 Graphics Facilities

7.2 Events and Sensors

7.3 Global Data

Graphics Facilities The phone’s screen is composed of many dots which can be illuminated in different colors. All characters, all

lines, all pictures seen on the screen are displayed as patterns of these dots where the phone’s software has

selected the color and intensity for each dot.

Graphics programming is, in effect, a matter of writing code to set the color and intensity of each dot in an area

of the screen. Anyone who has had some previous experience with graphics programming can skip the follow-

ing brief introduction to the subject. After that introduction, we will move on to the facilities for graphics pro-

gramming provided in TouchDevelop.

Computer Graphics Terminology

Each dot on the screen is known as a PICTURE ELEMENT and that term is usually abbreviated to PIXEL or to PEL.

We will use the term pixel. The TouchDevelop API for setting the pixel’s color and intensity uses a triple of three

numbers. In most graphics software, these three numbers are one-byte integers in the range 0 to 255, and they

specify the intensity of the red, green and blue components of the color separately. However TouchDevelop

scales these numbers to be in the range 0.0 to 1.0.

Page 2: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Basic Graphics, Events and Global Data Version 1.1 for TouchDevelop v2.8

– 74 –

The triple of three numbers is commonly called an RGB VALUE. A value of 0 means that the color component

has zero intensity and a value of 1.0 means maximum intensity. Some typical combinations of integers as RGB

values in TouchDevelop are:

(0.0, 0.0, 0.0) black (0.0, 1.0, 0.0) green

(1.0, 1.0, 1.0) white (0.0, 0.0, 1.0) blue

(0.5, 0.5, 0.5) gray (1.0, 1.0, 0.0) yellow

(1.0, 0,0, 0.0) red (1.0, 0.0, 1.0) purple

The pixels on the screen are arranged in a rectangular grid. Each pixel has a coordinate position in this grid giv-

en by an x value and a y value. The x values start at 0 and increase from left-to-right

across the screen; the y values start at 0 and increase from top to bottom down the

screen. (Note that y-axis values grow in the opposite direction to how you would normally

draw a graph.)

The size of the displayable area on the screen is exactly 480 pixels wide by 800 pixels high

for a Windows 7 phone. This means that the x and y coordinates can range from (0,0) in

the top-left corner to (479,799) in the bottom right corner, as shown on the right.

A Trivial Graphics Program

A short graphics program was used as an example in Chapter 2.

It begins by creating a new Picture value and assigning it to variable pic. It is an array of pixel values 480 wide

and 300 wide. The width is the maximum which can be displayed on a Windows phone. The height of 300 is

much less than the maximum 800 allowed for the phone. The pixels are initialized to be white. The second

statement draws a solid rectangle in the Picture array. The top left corner of the rectangle is at (10,10) – i.e. 10

pixels in from the left and 10 pixels down from the top. The width of the rectangle is 200 pixels and its height is

100 pixels. The fifth argument of 0 means that we do not want to rotate the rectangle before drawing it onto

the picture object. (To be more precise, it is rotated by 0 degrees.) The last parameter specified the color to use

for the rectangle. The colors→red value is equivalent to using (1.0,0.0,0.0) as the RGB value for the pixels, and

is much more readable.

Figure 7.1: Trivial graphics script

Page 3: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Version 1.1 for TouchDevelop v2.8 Basic Graphics, Events and Global Data

– 75 –

The third statement draws a solid ellipse inside the Picture array. One has to imagine that the ellipse fits inside

a rectangle whose top left corner is at the coordinates (270,190). The width and height of that ellipse are set to

be 200 and 100 respectively. Again, we rotate that containing rectangle by 0 degrees. The color for the ellipse is

chosen to be blue.

The fourth statement draws the four sides of a rectangle at approximately the extreme edges of the Picture

array. The thickness of the lines used for the four sides has been set at 3 pixels. The color of the lines is whatever

has been chosen in the phone’s settings as the accent color; for the screen shot shown below, that accent color

is magenta.

The fifth statement draws a line from the bottom left corner up towards the top right corner, and the thickness

of the line is chosen to be 3 pixels wide.

Finally the last statement sends the picture to be displayed on the wall. A screen shot of our program’s output

appears in Figure 7.2.

More details about Pictures

Any photograph held on the phone or downloadable from the web is held as a Picture value too. This means

that you can write scripts which transform the photograph or overwrite them in some way. Anything is possible

given enough effort spent developing a script.

Just to introduce you to the possibilities, Figure 7.3 shows a script which first prompts the user to enter a string

(to use as the value of the parameter msg), then asks the user to select a photograph from amongst those on

the phone, overprints a text message diagonally across the picture from the bottom left to the top right and

finally displays the picture.

Figure 7.2: Output from trivial graphics script

Page 4: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Basic Graphics, Events and Global Data Version 1.1 for TouchDevelop v2.8

– 76 –

The script has to make some calculations to determine a suitable size for the characters in the message being

displayed and what angle to draw the text at, if we want that text to be along the diagonal (/sdcn). The charac-

ter size calculation is very approximate (as not all characters are the same width) and the formula used here was

found by trial and error.

The angle of the diagonal is found by computing the arctangent of height/width for the image. The math

function atan2 provided in the TouchDevelop API performs that calculation but returns the result in radians.

The angle argument to the draw text method requires the angle in degrees however, so a call to the rad to

deg conversion function is needed too. Finally a minus sign is needed in front because we are drawing the text

in a direction which ascends from left to right which corresponds to an anticlockwise rotation, whereas the draw

text method normally performs a clockwise rotation on the text. A sample output from this script is shown in

Figure 7.4.

Note that the photograph selected for display in Figure 7.4 is too large to fit on the screen. Its width is 800 pixels

yet the screen itself is only 480 pixels wide. The post to wall method scaled the image by a factor of 480/800

in both dimensions so that it would fit without having to scroll the image from side to side.

Figure 7.4: Output from the Overprint Photograph Script

Figure 7.3: Script to Overprint a Photograph

Page 5: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Version 1.1 for TouchDevelop v2.8 Basic Graphics, Events and Global Data

– 77 –

Table 7.1 provides a description of most of the methods available for the Picture datatype.

Table 7.1: Useful Picture Methods

Method Description

Operations on the Image as a Whole

height: Number Returns the picture height in pixels

width: Number Returns the picture width in pixels

invert: Picture Inverts the R,G,B color components of every pixel

clear(col:Color): Nothing Sets all pixels to color col

clone: Picture Returns a duplicate of the picture

post to wall: Nothing Displays the picture on the screen, resizing it if necessary to fit

within the maximum width of 480 pixels and a maximum height

of 800 pixels.

crop(x:Number, y:Number, w:Number,

h:Number): Nothing

Crops the picture to have width w and height h, selecting a sub-

image whose top left corner is at position x,y

blend(other:Picture, x:Number,

y:Number, angle:Number,

alpha:Number): Nothing

Overwrites this picture with picture, other, putting its top left

corner at position x,y and rotating about that corner by angle

degrees in a clockwise direction; alpha is used as the transpar-

ency of all pixels in the other picture.

resize(w:Number, h:Number): Nothing Scales the picture to have width w and height h

Shape Drawing Methods

draw ellipse(x:Number, y:Number,

w:Number, h:Number, angle:Number,

c:Color, th:Number): Nothing

Draws the largest ellipse which fits inside a rectangle with width

w and height h; the top left corner of the rectangle is at position

x,y; the rectangle is rotated about the top left corner by angle

degrees in a clockwise direction; the line has a thickness of th

pixels and is drawn in color c.

draw line(x1:Number, y1:Number,

x2:Number, y2:Number, c:Color,

th:Number): Nothing

Draws a line from position x1,y1 to position x2,y2; the line has

thickness of th pixels and is drawn in color c.

draw rect(x:Number, y:Number,

w:Number, h:Number, angle:Number,

c:Color, th:Number): Nothing

Draws a rectangle whose top left corner is at position x,y; it has

width w and height h; the rectangle is rotated about the top left

corner by angle degrees in a clockwise direction; the line has a

thickness of th pixels and is drawn in color c.

draw text(x:Number, y:Number,

txt:String, fs:Number,

angle:Number, c:Color): Nothing

Draws text as pixels in color c on the picture; the top left of the

first character is at position x,y; the size used for the characters

is fs; the text is rotated by angle degrees about the x,y posi-

tion.

Page 6: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Basic Graphics, Events and Global Data Version 1.1 for TouchDevelop v2.8

– 78 –

fill ellipse(x:Number, y:Number,

w:Number, h:Number, angle:Number,

c:Color): Number

Like draw ellipse except that the ellipse is drawn as a solid ob-

ject (not as a line surrounding an elliptically shaped area)

fill rect(x:Number, y:Number,

w:Number, h:Number, angle:Number,

c:Color): Nothing

Like draw rect except that the rectangle is drawn as a solid ob-

ject (not as four lines surrounding a rectangular area)

Access to Pixels

pixel(x:Number, y:Number): Color Returns the color of the pixel at position x,y

set pixel(x:Number, y:Number,

c:Color): Nothing

Sets the pixel at position x,y to have color c

Working with Pixels

As explained earlier, each pixel has a color and an intensity determined by a triple of three numbers, the RGB

values. There is an additional number attached to each pixel which comes into play if we want to superimpose

one picture on top of another. This additional integer is known as the ALPHA value and controls the degree of

transparency of the pixel.

Suppose that we want to overlay part of picture A with picture B. Should the pixels from Picture B replace the

pixels of A? This is usually known as knockout overprinting. It means that you cannot see through the pixels

from picture B and see any remnants of picture A in the overlaid area. However, perhaps the colors of the B

picture pixels should be blended with the pixels of the A picture so that you can see both the A and B images

combined? The alpha values associated with the B pixels determine their degrees of transparency. If alpha is 1.0,

the pixel is fully opaque and the B pixel will knockout (replace) the A pixel. If alpha is 0.0, the pixel is fully trans-

parent and no trace of picture B will be seen when overlaid on picture A. Intermediate values for alpha result in

partial transparency for the B picture.

Given a picture referenced by variable pic, the pixel at coordinates x,y can be retrieved by a statement like the

following.

var col := pic→pixel(x,y)

The value so obtained has the datatype Color. That value can be decomposed into its A (alpha), R, G and B

components with statements like these:

var red component := col→R

var green component := col→G

var blue component := col→B

var alpha component := col→A

We can change these color components in any way we like, as long as the values stay in the 0.0 to 1.0 range,

and then recombine them to create a new color which can be stored back into the picture as a changed pixel

value. For example, the following code inverts the color intensities, giving an effect similar to creating a color

negative image:

Page 7: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Version 1.1 for TouchDevelop v2.8 Basic Graphics, Events and Global Data

– 79 –

red component := 1.0 - red component

green component := 1.0 - green component

blue component := 1.0 - blue component

col := colors→from argb(alpha component, red component, green component, blue component)

pic→set pixel(x, y, col)

However that particular sequence of statements would rarely be needed because the Picture datatype has an

invert method which performs exactly that operation to every pixel in the image.

Many of the methods used for working with colors and individual pixels are listed below in Table 7.2. They are

accessed from the service named colors. For example,

var y := colors→yellow

declares variable y to have the type Color and initializes it to the yellow color.

Page 8: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Basic Graphics, Events and Global Data Version 1.1 for TouchDevelop v2.8

– 80 –

Table 7.2: Methods provided by the colors Service

Method Description

Composing and Decomposing Color Values

from argb(alpha:Number, r:Number,

g:Number, b:Number): Color

Constructs a color from the alpha and RGB values, which must

all be in the range 0.0 to 1.0

from rgb(r:Number, g:Number,

b:Number): Color

Constructs a color from the RGB values provided; the alpha

component is set to 1.0 (totally opaque)

Access to the Phone’s Theme Colors

accent: Color

background: Color

foreground: Color

chrome: Color

subtle: Color

Returns the accent, background, foreground, chrome and subtle

(light gray) colors selected for the phone’s theme in its Settings

menu

Standard Colors

black: Color

blue: Color

brown: Color

cyan: Color

dark gray: Color

gray: Color

green: Color

light gray: Color

magenta: Color

orange: Color

purple: Color

red: Color

white: Color

yellow: Color

Obtain standard colors by their usual names.

Obtaining Special Colors

random: Color Returns a random (opaque) color

linear gradient(c1:Color, c2:Color,

alpha:Number): Color

Computes a color in between c1 and c2 where c2 overlays c1

with the specified alpha factor for transparency.

Events and Sensors The Windows phone contains a number of sensors, such as an accelerometer, which can trigger events that get

passed on to the TouchDevelop script. In addition, a script which implements an interactive game needs to re-

spond when the user taps certain items on the screen, and those taps can also trigger events.

Page 9: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Version 1.1 for TouchDevelop v2.8 Basic Graphics, Events and Global Data

– 81 –

The various kinds of events recognized by TouchDevelop are listed in Table 7.3. Sensors are covered in some

more detail in Chapter 8 as well as more examples which use events. The events grouped in the ‘Game Playing’

category will be covered only in Chapter 9.

Table 7.3: Events in TouchDevelop Scripts

Event Description

Phone Movement Events

Shake Triggered when the phone is shaken

phone face up Triggered when the phone is turned so that it is face up

phone face down Triggered when the phone is turned so that it is face down

phone portrait Triggered when the phone is turned so the screen in portrait mode (such as

when the phone is vertical)

phone landscape left Triggered when the phone is turned so that its left side is facing down

phone landscape right Triggered when the phone is turned so that its right side is facing down

Media Events

active song changed

The names of these events describe the events camera button pressed

camera button half pressed

camera button released Wall Events

tap wall XX(item: XX)

XX represents any of the TouchDevelop datatypes, such as String or Loca-

tion or Number Map, etc. The event is triggered when a user taps a dis-

play of a value of type XX on the wall (i.e. the screen). The value is passed as

a parameter to the event.

empty space on wall Triggered more space is available on the wall. Typically this happens when

the user scrolled to the bottom of the wall.

Game Playing Events

gameloop An event which is triggered by a timer approximately every 50ms

player state changed

tap board: b(x,y) Triggered when a global data item named b with type Board is tapped; x

and y are the coordinates of the tap.

swipe: board: b(x, y, dx, dy) Similar to tap board, except that it is triggered by a swiping action starting at

position x,y and with a distance vector dx,dy

tap sprite in s(sprite, index,

x, y)

Sprites will be covered in Chapter 9. (They are graphics objects which can

move around on the screen.)

swipe sprite in s(sprite, in-

dex, x, y, delta x, delta y)

drag sprite in s(sprite, in-

dex, x, y, delta x, delta y)

Page 10: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Basic Graphics, Events and Global Data Version 1.1 for TouchDevelop v2.8

– 82 –

Example Event Handling Script: Phone Orientation

A script can optionally include code which is executed whenever a particular kind of event happens. As a simple

example, let us construct a script which displays the words ‘Portrait’ and ‘Landscape’ in large letters on the

screen according to the phone’s current orientation.

To reuse some of the graphics code covered earlier in this chapter, we will create Picture values and write text

with suitable orientations for display into the pictures and display the pictures in the event code.

The code for the main action and all three events is shown in Figure 7.5. As you can see, the main action has

got absolutely nothing to do. Even though control returns from the main action, the script stays active waiting

for events. The only way to stop this script is to tap the phone back button (or to tap the Windows button to exit

from TouchDevelop completely).

Figure 7.5: Code for the Orientation Event Script

Two of the screen displays produced by this script as the phone is rotated are shown below in Figure 7.6.

Page 11: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Version 1.1 for TouchDevelop v2.8 Basic Graphics, Events and Global Data

– 83 –

Figure 7.6: Some Output Displayed by the Orientation Script

Global Data Sometimes an event in a script needs to save information which is used later by an action or by another invoca-

tion of an event (perhaps the same event, perhaps a different event). Where can such information be saved?

The only reasonable answer is to use a GLOBAL DATA VARIABLE. We have already seen some example pro-

grams which use global data items. Let us look at one more.

Example Script: A Pedometer

If you carry your Windows phone with you when jogging or walking briskly, the phone’s sensors should trigger a

SHAKE event each time you take one step. We can therefore write a simple script which records how many

steps you take, incrementing a counter each time the shake event occurs. With a little more coding, we can

compute the number of steps per minute. By using access to the phone’s GPS location, we can also compute

your average speed. However that programming feature does not need to use any event code, so we will omit

that feature in this version of the program.

When we begin creating the Pedometer script, TouchDevelop provides a default action named main and that

is all. No events and no global data items exist for the script. We could tap the plus button to the right of the

data icon to create a global data item for the number of steps taken, but let’s do it another way. We can use the

promote to global data item form of refactoring explained in Chapter 6.

The first thing we do in creating the script is to edit the code for the main action. We add the statement

var steps := 0

Page 12: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Basic Graphics, Events and Global Data Version 1.1 for TouchDevelop v2.8

– 84 –

where we have declared and initialized steps as a local variable. Now, by selecting this declaration line for edit-

ing and selecting the left-hand side variable, we can promote it to a global data item named ◳steps.

Similarly, we should declare

var start time := time→now

and then promote the start time local variable to be the global data item ◳start time. We need to remem-

ber the time at which the script was started so that we can determine the elapsed time, needed for computing

the number of steps per minute.

The code for the Pedometer program is shown in Figure 7.6. The local variable elapsed is the time since the

script was started, measured in seconds. It is probably unnecessary to check that elapsed has a non-zero value,

but it is good programming practice to avoid division by zero. To compute the walking or jogging rate as the

number of steps per minute, we need to multiply the steps per second by 60. Otherwise, the script should be

easy to follow.

Figure 7.6: The Pedometer Script

Output from the script while it is running looks similar to that shown below.

This does not look very professional! Accuracy to 15 decimal places is just a bit excessive. Fortunately it takes

only one extra line of code to reduce the number of digits after to the decimal point to a more reasonable

number. Let’s pick one digit. If we insert either this line of code:

rate := math→round(10*rate)/10

Page 13: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Version 1.1 for TouchDevelop v2.8 Basic Graphics, Events and Global Data

– 85 –

or this line of code

rate := math→round with precision(rate,1)

after the line declaring and initializing the local variable rate, we will get just one digit to the right of the deci-

mal point. The output produced by the program now looks like this:

Now, why did we have to initialize ◳steps to zero in the main action? Why did it not just start with the value 0

when we begin running the script? This is explained in the next subsection.

Persistence of Global Data Values

The very first time you use a script after it has been installed, the global data items will have initial values which

are 0 for Number values, false for Boolean values, an empty string for String values, and date / time combi-

nation from long ago for DateTime values. For all other datatypes, the global data item has the special INVA-

LID value.

It may be necessary for the script to check and initialize global data variables to take account of first time use of

a script. The is invalid method is useful for checking the data items which start off with an invalid value.

When the script is run a second time or a third time or …, the global data items still have the same values as

they had at the end of the previous run. In the terminology of programming languages, we say that the values

of the global data items PERSIST from one run to the next on your phone. Persistence is a highly useful feature

because it allows your scripts to accumulate information over many runs. (In a misuse of the English language,

programmers often say that a variable “is persisted” if it retains its value from one run to the next .)

If you do not want to reuse a value from the previous run of the script, as is the case with the Pedometer exam-

ple, the script should re-initialize the global data items in whichever of its actions will be invoked when the script

is started. (This is likely to be every action which is not flagged as private.)

Page 14: touchdevelop chapter 7cdn.touchdevelop.com/c03/mvxh-bookchapter7.pdf · Chapter 7 BASIC Graphics, Events, and Global Data In this chapter, the graphics features of TouchDevelop are

Basic Graphics, Events and Global Data Version 1.1 for TouchDevelop v2.8

– 86 –