Приглашаем посетить
Ходасевич (hodasevich.lit-info.ru)

9.5 Handling multiple moving objects

Table of Contents

Previous Next

9.5 Handling multiple moving objects

9.5.1 Generating multiple flying objects

One of the efficient ways to create and control multiple objects is to use an array structure. By using one variable name, an array can store a number of different things. It also allows you to manipulate them in a consistent manner. This section is dedicated to multiple moving objects and to showing you how to use an array to generate and control them on a Web page. For example, if you have a butterfly image bfly01.gif, you can display it at the (90, 240) top left position with the following XHTML statement:



<img id="obj1" src="bfly01.gif" alt="pic" s
  style="position:absolute;top:90px;left:240px;width:32px;height:32px" />

If you have 5 red butterflies (bfly01.gif), 5 blue butterflies (bfly02.gif), and 10 different locations, then one practical way to display them all is to use the array structure. To construct this example, and to use it to build a more functional application for this section, we begin with a simple interface program. This XHTML interface is listed in ex09-11.htm.



Example: ex09-11.htm - Display Multiple Objects

 1: <?xml version="1.0" encoding="iso-88591"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title> Display Multiple Objects - ex0911.htm </title></head>
 6: <body style="background:#dddddd;font-family:arial;font-size:20pt;
 7:    color:#000088;font-weight:bold">
 8:
 9:  <div style="text-align:center">Generating Multiple Objects</div>
10:  <div id="buttLoc"></div>
11:  <script src="ex0911.js"></script>
12: </body>
13: </html>

Basically, this page contains three statements (lines 911): a display text, an empty division. and an included script file. In fact, it is possible to build an entire page with script. One of the great strengths of XHTML and many other markup languages is that the language itself can be generated by other programs or techniques without too much difficulty. The external file ex09-11.js contains a script to generate 10 butterflies at 10 different locations and to display them at the element position with id="buttLoc" (butterfly location). The script file at this moment is also simple and is listed as follows:



Example: ex09-11.js - The ECMAScript For ex09-11.htm

 1:
 2: llX = new Array(240,380,180,410,210,440,240,380,180,440)
 3: llY = new Array(90 ,140,140,110,110,140,140,90 ,90 ,90)
 4: llSt =""
 5:
 6: for (ii=0;ii<5;ii++)
 7: {
 8:   llSt = llSt + '<img id=\"obj'+ii+'\" src=\"bfly01.gif\" alt=\"pic\" '+
 9:          'style=\"position:absolute;top:'+llY[ii]+
10:          'px;left:'+llX[ii]+'px;width:32px;height:32px\" />'
11: }
12:
13: for (ii=5;ii<10;ii++)
14: {
15:   llSt = llSt + '<img id=\"obj'+ii+'\" src=\"bfly02.gif\" alt=\"pic\" '+
16:          'style=\"position:absolute;top:'+llY[ii]+
17:          'px;left:'+llX[ii]+'px;width:32px;height:32px\" />'
18: }
19:
20: document.getElementById("buttLoc").innerHTML=llSt
21:

Again, a string concatenation technique is used, taking advantage of the array structure. Variables llY (local location Y) and llX are two arrays to hold the top and left positions of the butterflies. The for-loop in lines 611 is basically used to generate the XHTML image element for the display. This for-loop generates five butterflies with different locations and another for-loop in lines 1318 generates another five blue butterflies. The statement in line 20 outputs the image string llSt (local location string) on the page at the location with id="buttLoc".

To appreciate more the combination of these techniques, let's consider adding some random flying motion to the butterflies. In order to have a realistic flying action and to keep the coding to a minimum, we add the following features:

  • Assign each butterfly a flying flag to determine whether the butterfly should fly.

  • To make a butterfly fly, we randomly change the top and left positions.

  • The flying direction should also be randomly changed.

To put these into action, ex09-11.js is extended to form a new example. The XHTML page for this example becomes:



Example: ex09-12.htm - Handling Multiple Moving Objects

 1: <?xml version="1.0" encoding="iso-88591"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title> Handling Multiple Objects - ex0912.htm </title></head>
 6: <body style="background:#dddddd;font-family:arial;font-size:20pt;
 7:    color:#000088;font-weight:bold">
 8:
 9:  <div style="text-align:center">Generating Multiple Objects</div>
10:  <div id="buttLoc"></div>
11:    <script src="ex0911.js"></script>
12:    <script src="ex0912.js"></script>
13: </body>
14: </html>

In this example, the same script file ex09-11.js is used to generate the butterflies on the page. Another script file, ex09-12.js, is dedicated to generating the flying motions and is listed below.



Example: ex09-12.js - The ECMAScript For ex09-12.htm

 1:
 2: var flyFlag = new Array
 3: var maxHeight = 600
 4: var maxWidth = 600
 5:
 6: for(mm=0;mm<10;mm++)
 7: {
 8:   flyFlag[mm]=true
 9: }
10:
11: function moveFlyObj()
12: {
13:  for(ii=0;ii<10;ii++)
14:  {
15:   if (flyFlag[ii]==true)
16:   {
17:    objSt = "obj"+ii
18:    mObjStyle = document.getElementById(objSt).style
19:    mObjStyle.top=change_top(parseInt(mObjStyle.top))+"px"
20:    mObjStyle.left=change_left(parseInt(mObjStyle.left))+"px"
21:   }
22:  }
23:  setTimeout("moveFlyObj()",150)
24: }
25:
26:  function chgDir()
27:  {
28:    if (Math.random() < .5) return true
29:    return false
30:  }
31:
32:  var flyStep =15
33:
34:  function change_top(vTopPos)
35:  {
36:    chgTop = Math.floor(Math.random() * flyStep)
37:    if ((chgDir() || vTopPos >= maxHeight) && vTopPos > flyStep)
38:         vTopPos -= chgTop
39:    else vTopPos += chgTop
40:
41:    return vTopPos
42:  }
43:
44:  function change_left(vLeftPos)
45:  {
46:    chgLeft = Math.floor(Math.random() * 15)
47:    if ((chgDir() || vLeftPos >= maxWidth) && vLeftPos > flyStep)
48:         vLeftPos -= chgLeft
49:    else vLeftPos += chgLeft
50:
51:    return vLeftPos
52:  }
53:
54: moveFlyObj()
55:

Another array, flyFlag, is used to determine which butterfly should fly and which should not. The for-loop in lines 69 provides an initial flying condition for all butterflies. The variables maxHeight and maxWidth are used to restrict the flying boundary and to act as a rough guide for changing the flying direction of the butterflies.

The important function here is moveFlyObj() given in lines 1124. This function checks the flying condition of each butterfly and makes it fly. The first two lines of this function are to get the moving object style (mObjStyle). The object style statement in line 19



mObjStyle.top=change_top(parseInt(mObjStyle.top))+"px"

calls the change_top() function to change the top position of the moving object. This new value is assigned back to the object to deliver the movement. This is a compact statement and the "px" (pixel) at the end of the code is essential to comply with the W3C standard. This is important, especially if you want the program to work on NS6+. Inside the change_top() function, we have two random functions used to obtain the new position. The effect is similar to flying. The first random function Math.random() is to get the value for the random flying (line 36):



chgTop = Math.floor(Math.random() * flyStep)

A random number (between 0 and 1) times the flyStep yields the step the butterfly should fly upward. Together with a 50% chance for the random change of flying direction issued by chgDir() in line 37, the result is random flying in the up and down directions. The left position situation is similar to that of the top and is handled by the change_left() function. Finally, there are 10 butterflies flying together to give a more realistic picture. A screen shot of this page is shown in Fig. 9.24.

Figure 9.24. ex09-12.htm

graphics/09fig24.jpg


9.5.2 Catching flying objects with the mouse

In order to catch the butterflies with the mouse, you need to set up some event handlers to control the mouse movements and picking actions. As an alternative, a mouse click is shown here instead of the drag and drop technique as described in section 9.4.3. You need to set up the following operations:

  • When the mouse clicks on a butterfly, the butterfly stops flying and is locked.

  • While a butterfly is locked and mouse movement detected, the butterfly moves with the mouse.

  • Another mouse click releases and drops the butterfly.

We will use some of the previous coding. First, the interface page of this example is



Example: ex09-13.htm - Catching The Flying Butterflies

 1: <?xml version="1.0" encoding="iso-88591"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title>Catching The Flying Butterflies - ex0913.htm</title></head>
 6: <body style="background:#eeeeee;font-family:arial;font-size:20pt;
 7:    color:#000088;font-weight:bold">
 8: <div style="position:absolute;top:20px;left:180px">
 9:       Catching Some Flying Butterflies</div>
10: <div id="buttLoc"></div>
11: <div id="infoLoc"></div>
12: <div id="boxLoc"></div>
13:   <script src="ex09-13a.js"></script>
14:   <script src="ex09-13b.js"></script>
15: </body>
16: </html>

This page is similar to that of ex09-12.htm but with more fields. The statement in line 10 concerns the location of the butterflies. The information on how to play will be displayed at the location specified in line 11. In order to collect the captured butterflies, we have some boxes displayed at the location given in line 12. These features are generated by the external file ex09-13a.js.



Example: ex09-13a.js - The ECMAScript For ex09-13.htm

 1:
 2: llX = new Array(340,480,280,510,310,540,340,480,280,540)
 3: llY = new Array(90 ,140,140,110,110,140,140,90 ,90 ,90)
 4: llSt =""
 5:
 6: for (ii=0;ii<5;ii++)
 7: {
 8:   llSt = llSt + '<img id=\"obj'+ii+'\" src=\"bfly01.gif\" alt=\"pic\" '+
 9:     'style=\"position:absolute;top:'+llY[ii]+'px;left:'+llX[ii]+
10:     'px;width:32px;height:32px;z-index:2\" onclick=\"mClick('+ii+')\" />'
11: }
12:
13: for (ii=5;ii<10;ii++)
14: {
15:   llSt = llSt + '<img id=\"obj'+ii+'\" src=\"bfly02.gif\" alt=\"pic\" '+
16:    'style=\"position:absolute;top:'+llY[ii]+'px;left:'+llX[ii]+
17:    'px;width:32px;height:32px;z-index:2\" onclick=\"mClick('+ii+')\" />'
18: }
19:
20: infoSt =""
21: infoSt = infoSt + '<table style=\"font-family:arial;font-size:16pt;'+
22:    'color:#888888;position:absolute;top:100px;left:210px;z-index:1\">'+
23:    '<tr><td>*******************************</td></tr> '+
24:    '<tr><td>Click One Butterfly To Catch</td></tr> '+
25:    '<tr><td>Move Mouse To Move </td></tr> '+
26:    '<tr><td>(Don\'t Hold Down Mouse Button While Moving)</td></tr> '+
27:    '<tr><td>One More Mouse Click To Release</td></tr> '+
28:    '<tr><td>*******************************</td></tr></table> '
29:
30: boxSt=""
31: boxSt = boxSt +
32:  '<img id=\"red_buf\" src=\"close_box.gif\" alt=\"pic\" style=\"'+
33:    'position:absolute;left:200px;top:290px;height:130px;width:120px;'+
34:    'background: #bbbbbb;z-index: 0\" /> '+
35:  '<div id=\"FirstPar\" style=\"position:absolute;left:200px;top:430px; '+
36:    'height:60px;width:110px;font-size:14pt;color:#aa0000;z-index:3\"> '+
37:    'Red Butt. Box</div> '+
38:  '<img id=\"red_buf\" src=\"close_box.gif\" alt=\"pic\" style=\"'+
39:    'position:absolute;left:400px;top:290px;height:130px;width:120px;'+
40:    'background: #bbbbbb;z-index: 0\" /> '+
41:  '<div id=\"FirstPar\" style=\"position:absolute;left:400px;top:430px; '+
42:    'height:60px;width:110px;font-size:14pt;color:#0000aa;z-index:3\"> '+
43:    'Blue Butt. Box</div> '
44:
45: document.getElementById("buttLoc").innerHTML=llSt
46: document.getElementById("infoLoc").innerHTML=infoSt
47: document.getElementById("boxLoc").innerHTML=boxSt
48:

One way to catch the butterflies is to set up event handlers on each of the butterfly objects. The for-loop in lines 611 is designed just for that. For example, when the loop variable ii=0, the for-loop in lines 611 turns out to be



<img id="obj0" src="bfly01.gif" alt="pic"
   style="position:absolute;top:90px;left:340px;
   width:32px;height:32px;z-index:2" onclick="mClick(0)" />

The z-index value is used so that the butterfly is captured at a suitable level. The onclick handler will trigger and handle all moving activities. All 10 butterflies are concatenated into one string and output to the screen by executing the statement in line 45.

The information on how to play is given in an XHTML table string as defined in lines 2028 and output to the screen by the statement in line 46. Two simple boxes are also displayed at the location with id="boxLoc".

The external file ex09-13b.js contains all the actions and is a continuation of ex09-12.js. Program file ex09-12.js is used to generate the random flying motion of the objects. You require all the codes to make the butterflies fly. Therefore, the line number and listing of ex09-13b.js below continue from the line number in ex09-12.js.



Example: ex09-13b.js - The ECMAScript For ex09-13.htm

56: var IE = document.all?true:false
57: var dragging =0
58: var selectId
59: function mClick(objV)
60: {
61:   flyFlag[objV]=false
62:   selectId = objV
63:   if (dragging ==0) dragging =1
64:   else dragging =0
65: }
66:
67: function mMove()
68: {
69:   if (dragging ==1)
70: {
71:   if (IE)
72:   {
73:     llxPos = event.clientX
74:     llyPos = event.clientY
75:    } else {
76:     llxPos = e.pageX
77:     llyPos = e.pageY
78:    }
79:    lObj = "obj"+selectId
80:
81:    objW = parseInt(document.getElementById(lObj).style.width)
82:    objH = parseInt(document.getElementById(lObj).style.height)
83:    document.getElementById(lObj).style.left = llxPos - objW/2 +"px"
84:    document.getElementById(lObj).style.top = llyPos - objH/2 +"px"
85:   }
86:
87:   return false
88: }
89:
90: document.onmousemove = mMove
91:

Once a butterfly is clicked by a mouse, the variable objV of the function mClick(objV) carries the id of the butterfly. This identity sets the flyFlag condition to false and stops the butterfly from flying. Next, the global variable selectId for dragging is updated so that the system knows that a butterfly is selected and ready for moving along with the mouse.

As the usual step to trap the mouse movement, an onmousemove event in line 90 is set and redirects the event to the function mMove(). This function gets the position of the mouse and moves the selected butterfly to the mouse location. A screen shot of this example is shown in Fig. 9.25. To add more functionality and to demonstrate how to control multiple moving objects, we consider adding more buttons to control the flying butterflies in the next example so that it will act more like a game.

Figure 9.25. ex09-13.htm

graphics/09fig25.jpg


9.5.3 A game to catch the butterflies

Based on the previous example, seven buttons are added to perform some basic operations. The interface part of this new example is ex09-14.htm shown below.



Example: ex09-14.htm - Catching The Flying Butterflies II

 1: <?xml version="1.0" encoding="iso-88591"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title> Catching The Butterflies II - ex0914.htm</title></head>
 6: <body style="background:#eeeeee;font-family:arial;font-size:20pt;
 7:    color:#000088;font-weight:bold">
 8: <div style="position:absolute;top:20px;left:180px">
 9:       Catching Some Flying Butterflies (II)</div>
10: <div id="buttLoc"></div> <div id="infoLoc"></div>
11: <div id="boxLoc"></div>
12: <div id="buttonLoc"></div>
13:   <script src="ex09-14a.js"></script>
14:   <script src="ex09-14b.js"></script>
15: </body>
16: </html>

In this example, we will add more buttons and some boxes to the original features. This means that all the coding of ex09-13a.js is required. A copy of ex09-13a.js is made and called ex09-14a.js. More buttons and box codes are added at the end of this new file. Only the new code and the continuation line number are provided in the following listing:



Example: ex09-14a.js - The ECMAScript For ex09-14.htm

49: var buttonSt=""
50: var butMsg = new Array("Stop Flying","Continue Flying","Catch All Red",
51:      "Catch All Blue","Red Butt. Fly","Blue Butt. Fly","Reset Butt. Pos.")
52: var but_id=new Array("but_0","but_1","but_2","but_3",
53:                      "but_4","but_5","but_6")
54: for (ii=0;ii<7;ii++)
55: {
56:  buttonSt = buttonSt +
57:  '<input type=\"button\" id=\"but_'+ii+'\" ' +
58:  ' Style=\"position:absolute;width:180px;height:35px;'+
59:  'top:'+(100+ii*50)+'px;left:40px;font-weight:bold;'+
60:  'font-family:arial;font-size:16pt;background:#ddddff; color:#0000ff\" '+
61:  'onmouseover=\"this.style.color=\'#ff0000\'\" '+
62:  'onmouseout=\"this.style.color=\'#0000ff\'\" '+
63:  'onclick=\"button_'+ii+'()\" value=\"'+butMsg[ii]+'\" />'
64: }
65: document.getElementById("buttonLoc").innerHTML = buttonSt
66:

In this program fragment, a string technique is used to generate seven buttons with identities and their corresponding functions. The buttons and their functions are summarized in Table 9.4.

Table 9.4. Button identities and functions for ex09-14.htm

Button message

Button identity

Calling function

Description

Stop Flying

but_0

Button_0()

Stop all butterflies flying

Continue Flying

but_1

Button_1()

Make all butterflies fly

Catch All Red

but_2

Button_2()

Catch all red butterflies in a location

Catch All Blue

but_3

Button_3()

Catch all blue butterflies in a location

Red Butt. Fly

but_4

Button_4()

Make all red butterflies fly

Blue Butt. Fly

but_5

Button_5()

Make all blue butterflies fly

Reset Butt. Pos.

but_6

Button_6()

Reset butterfly positions


If you analyze the for-loop in lines 5464 and evaluate the output, you will find for example that the first button is



<input type="button" id="but_0"
   style="position:absolute;width:180px;height:35px;
       top:100px;left:40px;font-weight:bold;color:#0000ff;
       font-family:arial;font-size:16pt;background:#ddddff"
   onmouseover="this.style.color='#ff0000'"
   onmouseout="this.style.color='#0000ff'"
onclick="button_0()" value="Stop Flying " />

Note that two event handlers named onmouseover and onmouseout are used in the code fragment. When the mouse moves inside the button, the color of the button changes to red, signalling selection of the button. You create seven buttons in this manner and output them in line 65.

The external file ex09-14b.js is responsible for all the actions. Since we need all the functions from ex09-13b.js, file ex09-14b.js is a continuation of the example ex09-13b.js. Again, only the new code is listed. The first part is listed below.



Example: ex09-14b.js - The ECMAScript For ex09-14.htm (Part One)

92: function butDisable(butV) //Disable a mouse button
93: {
94:   for (jj=0;jj<7;jj++)
95:   {
96:     document.getElementById(but_id[jj]).disabled=0
97:     document.getElementById(but_id[jj]).style.color="blue"
98:   }
99:   document.getElementById(but_id[butV]).style.color="#aaaaaa"
100:   document.getElementById(but_id[butV]).disabled=1
101:
102: }
103:
104: function button_0() //Button - Stop Flying
105: {
106:   for(ii=0;ii<10;ii++) {
107:     flyFlag[ii]=false
108:     butDisable(0)
109:   }
110: }
111:
112: function button_1() //Button - Continue Flying
113: {
114:   for(ii=0;ii<10;ii++) {
115:     flyFlag[ii]=true
116:     butDisable(1)
117:   }
118: }
119:

Once a button is pressed and the corresponding function is called, you want to disable that button to signal that it has been used and should not be pressed again. The first function of this listing is to disable a button. The for-loop in lines 9498 is to initialize all buttons as active and to restore the color to blue. Then the statements in lines 99100 are used to change the color of the used button to gray and to disable it.

When the Stop Flying button is pressed, the function button_0() is activated. This function sets the flying condition of all butterflies to false and disables this button. The Continue Flying button activates the button_1() function to make all butterflies fly.

The second part of the program is listed below.



Listing: Continuation Of The ECMAScript ex09-14b.js (Part Two)

120: fixX1 = new Array(280,220,250,280,220,420,450,480,420,480)
121: fixY1 = new Array(320,370,340,370,320,370,340,370,320,320)
122:
123: function button_2() //Button - Catch All Red (Butterflies)
124: {
125:  for(jj=0;jj<5;jj++) {
126:      flyFlag[jj] = false
127:      mObj = "obj"+jj
128:      mObj = document.getElementById(mObj).style
129:      mObj.top = fixY1[jj] +"px"
130:      mObj.left = fixX1[jj]+"px"
131:  }
132:    butDisable(2)
133: }
134:
135: function button_3() //Button - Catch All Blue (Butterflies)
136: {
137:  for(jj=5;jj<10;jj++) {
138:      flyFlag[jj] = false
139:      mObj = "obj"+jj
140:      mObj = document.getElementById(mObj).style
141:       mObj.top = fixY1[jj]+"px"
142:      mObj.left = fixX1[jj]+"px"
143:  }
144:  butDisable(3)
145: }
146:

Variables fixX1 and fixY1 store some predetermined positions for the captured butterflies. If the Catch All Red button is pressed, the function button_2() stops all red butterflies (obj0 through obj4) and puts them into the first five defined locations. Similarly the function button_3() catches all blue butterflies and puts them into the last five predefined locations.

The last three button functions and the final part of this program are listed as follows:



Listing: Continuation Of The ECMAScript ex09-14b.js (Part Three)

147:
148: function button_4()                  //Button  Red Butt. Fly
149: {
150:    for(jj=0;jj<5;jj++) flyFlag[jj] = true
151:    butDisable(4)
152: }
153:
154: function button_5()                  //Button  Blue Butt. Fly
155: {
156:  for(jj=5;jj<10;jj++) flyFlag[jj] = true
157:  butDisable(5)
158: }
159:
160: function button_6()                  //Button  Reset Butt. Pos.
161: {
162:  var YY
163:  for(jj=0;jj<5;jj++) {
164:    flyFlag[jj] = false
165:    lObj = "obj"+jj
166:    mObj = document.getElementById(lObj).style
167:    if (jj%2 ==1) YY = 110
168:    else YY = 70
169:    mObj.top= YY+"px"
170:    mObj.left= 330+jj*50 +"px"
171:  }
172:  for(ii=0;ii<5;ii++) {
173:    jj = ii+5
174:    flyFlag[jj] = false
175:    lObj = "obj"+jj
176:    mObj = document.getElementById(lObj).style
177:    if (jj%2 ==1) YY = 110
178:    else YY = 70
179:    mObj.top= YY +"px"
180:    mObj.left= 330+ii*50 +"px"
181:  }
182:  butDisable(6)
183: }
184:

The Red Butt. Fly and Blue Butt. Fly buttons activate the functions button_4() and button_5(). The basic idea is to change the flying flag, flyFlag, of the individual butterfly so that you can stop or activate them as desired. The last button is to reset the butterfly positions. When this button is pressed, the function button_6() arranges all butterflies into two rows. The initial arrangement is that the red ones are on the upper row and the blue ones on the lower. The conditional statement in lines 167168 is used to swap the top positions of red and blue so that we have different colors. A similar conditional statement also applied to the lower row of the blue butterflies is illustrated in lines 177178. This is also a demonstration of the swapping object technique often used on the Web. Now, we have a working example to catch the butterflies.

Some screen shots are shown in Figs 9.26 and 9.27.

Figure 9.26. Catch All Red

graphics/09fig26.jpg


Figure 9.27. Reset Butt. Pos.

graphics/09fig27.jpg


    Table of Contents

    Previous Next