home *** CD-ROM | disk | FTP | other *** search
/ ActiveX Programming Unleashed CD / AXU.iso / source / chap17 / cyberball.avr < prev    next >
Encoding:
Text File  |  1996-08-14  |  12.0 KB  |  294 lines

  1. // ActiveVRML 1.0 ASCII
  2. // CyberBall Sample Script
  3.  
  4. // First we create the arena, starting with the four corners
  5. corner = first (import ("cyl.wrl"));
  6. cornercolor = colorRgb (0.5, 0.5, 0.5);
  7. post = diffuseColor (cornercolor, 
  8.    transformGeometry (scale (0.5, 0.5, 0.5), corner));
  9. corners = transformGeometry (translate (-15,0.20,-20), post) union
  10.    transformGeometry (translate (-15, 0.20, 0), post) union
  11.    transformGeometry (translate (-15, 0.20, 20), post) union
  12.    transformGeometry (translate (15, 0.20, -20), post) union
  13.    transformGeometry (translate (15, 0.20, 0), post) union
  14.    transformGeometry (translate (15, 0.20, 20), post);
  15.  
  16. // Now the goals
  17. goal1 = diffuseColor (colorRgb (0.5, 0.5, 1.0), 
  18.    transformGeometry (scale (0.3, 0.5, 0.3), corner));
  19. goal2 = diffuseColor (colorRgb (1.0, 0.5, 0.5), 
  20.    transformGeometry (scale (0.3, 0.5, 0.3), corner));
  21. goals = transformGeometry (translate (-3, 0.20, -20), goal1) union
  22.    transformGeometry (translate (3.0, 0.20, -20.0), goal1) union
  23.    transformGeometry (translate (-3.0, 0.20, 20.0), goal2) union
  24.    transformGeometry (translate (3.0, 0.20, 20.0), goal2);
  25.  
  26. // Set up some side rails and end rails
  27. rail = first (import ("stick.wrl"));
  28. railcolor = colorRgb (0.5, 3.0, 0.5);
  29. siderail = diffuseColor (railcolor, transformGeometry (
  30.    rotate (yVector3, 1.57079) o scale (1.0, 0.3, 0.2), rail));
  31. sides = transformGeometry (translate(-15, 0, -10), siderail) union
  32.    transformGeometry (translate (15, 0, -10), siderail) union
  33.    transformGeometry (translate (-15, 0, 10), siderail) union
  34.    transformGeometry (translate (15, 0, 10), siderail);
  35. endrail = diffuseColor (railcolor, 
  36.    transformGeometry (scale (0.6, 0.3, 0.2), rail));
  37. ends = transformGeometry (translate (-9.0, 0, -20), endrail) union
  38.    transformGeometry (translate (9.0, 0, -20.0), endrail) union
  39.    transformGeometry (translate (-9.0, 0, 20.0), endrail) union
  40.    transformGeometry (translate (9.0, 0, 20.0), endrail);
  41. rails = sides union ends;
  42.  
  43. // Create some lights
  44. lights = lightColor (colorRgb (0.5, 0.5, 0.5), 
  45.    transformGeometry (rotate (xVector3, -0.1), directionalLight)
  46.    union
  47.    transformGeometry (rotate (xVector3, 3.24), directionalLight));
  48.  
  49. // Put it all together and define a background
  50. arena = corners union goals union rails union lights;
  51. backgnd = first (import ("backgnd.gif")); 
  52.  
  53. // Build a puck
  54. puck, pmin, pmax = import ("puck.wrl");
  55. puckradius = xComponent (smax) * 0.05;
  56. correctedpuck = transformGeometry (scale(0.05, 0.05, 0.05), puck);
  57. coloredpuck = diffuseColor (red, correctedpuck);
  58.  
  59. // Build a player 
  60. socket, smin, smax = import ("socket.wrl");
  61. playerradius = xComponent (smax) * 0.1;
  62. correctedsocket = transformGeometry (rotate (xVector3, 1.57079) o
  63.    scale(0.1, 0.1, 0.1), socket);
  64. coloredsocket = diffuseColor (blue, correctedsocket);
  65. ball = first (import ("ball.wrl"));
  66. correctedball = transformGeometry (translate (0, 0.6, 0) o
  67.    scale (1.3, 1.3, 1.3), ball);
  68. spinningball = transformGeometry (rotate (yVector3, time * 3),
  69.    correctedball);
  70. coloredball = diffuseColor (red, spinningball);
  71. player = coloredsocket union coloredball;
  72.  
  73. // Load some sounds
  74. winner = first (import ("winner.wav"));
  75. loser = first (import ("loser.wav"));
  76. wallhit = first (import ("wallhit.wav"));
  77. puckhit = first (import ("puckhit.wav"));
  78.  
  79. // Helper function to restrict value to a specified range
  80. clamp (val, min, max) = if (val < min) then min
  81.     else if (val > max) then max 
  82.     else val;
  83.  
  84. // User input events
  85. keyleft = keyState (vkLeft);
  86. keyright = keyState (vkRight);
  87. keyforward = keyState (vkUp);
  88. keyback = keyState (vkDown);
  89.  
  90. // Handle player motion
  91. playermover (pos0 : vector3, vel0 : vector3) =
  92.    let
  93.       rebound (pos : vector3, vel : vector3, snd) = 
  94.          let
  95.             // Dampen function slows player down over time
  96.             dampen (oldvel : vector3) = 
  97.                vector3Xyz (xComponent (oldvel) * 0.5 / time, 
  98.                   0, zComponent (oldvel) * 0.5 / time);
  99.  
  100.             // Calculate force(s) appied by user control
  101.             accelstrength = 5;
  102.             forwardaccel = 
  103.                if keyforward then 
  104.                   vector3Xyz (0, 0, -accelstrength)
  105.                else if keyback 
  106.                   then vector3Xyz (0, 0, accelstrength)
  107.                else zeroVector3;
  108.             sideaccel = 
  109.                if keyleft 
  110.                   then vector3Xyz (-accelstrength, 0, 0)
  111.                else if keyright 
  112.                   then vector3Xyz (accelstrength, 0, 0)
  113.                else zeroVector3;
  114.             pushvel = integral (forwardaccel + sideaccel);
  115.  
  116.             // Calculate new unclamped velocity
  117.             newvel = dampen (vel) + pushvel;
  118.             magnitude = length (newvel);
  119.  
  120.             // Clamp velocity
  121.             newmagnitude = clamp (magnitude, -4, 4);
  122.             velocity = normal (newvel) * newmagnitude;
  123.  
  124.             // Calculate new position
  125.             newpos = pos + integral (velocity);
  126.             xpos = (xComponent (newpos));
  127.             zpos = (zComponent (newpos));
  128.  
  129.             // Handle side wall collisions
  130.             sideextent = 15 - playerradius;
  131.             sidecollide = predicate ((xpos < -sideextent) or
  132.                (xpos > sideextent));
  133.             sidenewvel = vector3Xyz (xComponent (velocity) * -1, 
  134.                yComponent (velocity), zComponent (velocity));
  135.             sidenewpos = vector3Xyz (clamp (xComponent (newpos),
  136.                -sideextent, sideextent), 0, zComponent (newpos));
  137.  
  138.             // Handle end wall collisions
  139.             endextent = 20 - playerradius;
  140.             endcollide = predicate ((zpos < -endextent) or
  141.                (zpos > endextent));
  142.             endnewvel = vector3Xyz (xComponent(velocity), 
  143.                yComponent(velocity), zComponent(velocity) * -1);
  144.             endnewpos = vector3Xyz (xComponent (newpos), 0, 
  145.                clamp (zComponent(newpos), -endextent, endextent));
  146.  
  147.          in
  148.             (newpos, velocity, snd) until 
  149.                snapshot ((sidenewpos, sidenewvel, wallhit), 
  150.                   sidecollide) => rebound |           
  151.                snapshot ((endnewpos, endnewvel, wallhit), 
  152.                   endcollide) => rebound;           
  153.    in
  154.       rebound (pos0, vel0, silence);
  155.  
  156.  
  157. // Handle puck motion
  158. puckmover (pos0 : vector3, vel0, ppos0, pvel0, score0) =
  159.    let
  160.       rebound (pos : vector3, vel, ppos1, pvel1, snd, oldscore) = 
  161.          let
  162.             // Dampen function slows puck down over time
  163.             dampen (oldvel : vector3) = 
  164.                vector3Xyz (xComponent (oldvel) * 0.5 / time, 
  165.                   0, zComponent (oldvel) * 0.5 / time);
  166.             velocity = dampen (vel);
  167.  
  168.             // Calculate new position
  169.             newpos = pos + integral (velocity);
  170.             xpos = (xComponent (newpos));
  171.             zpos = (zComponent (newpos));
  172.  
  173.             // Handle side wall collisions
  174.             sideextent = 15 - puckradius;
  175.             sidecollide = predicate ((xpos < -sideextent) or
  176.                (xpos > sideextent));
  177.             sidenewvel = vector3Xyz (xComponent (velocity) * -1, 
  178.                0, zComponent (velocity));
  179.             sidenewpos = vector3Xyz (clamp (xComponent (newpos),
  180.                -sideextent, sideextent), 0, zComponent (newpos));
  181.  
  182.             // Handle end wall collisions
  183.             endextent = 20 - puckradius;
  184.             endcollide = predicate (((zpos < -endextent) or
  185.                (zpos > endextent)) and ((xpos<-3) or (xpos>3)));
  186.             endnewvel = vector3Xyz (xComponent(velocity), 
  187.                0, zComponent(velocity) * -1);
  188.             endnewpos = vector3Xyz (xComponent (newpos), 0, 
  189.                clamp (zComponent(newpos), -endextent, endextent));
  190.  
  191.             // Goal-keeping functions
  192.             EVENTSCORE = 200;
  193.             goalnewvel = zeroVector3;
  194.             goalnewpos = zeroVector3;
  195.             goodscore = oldscore + 1;
  196.             badscore = oldscore - 1;
  197.  
  198.             // Handle good goal collisions
  199.             goal1event = predicate ((zpos < -endextent) and
  200.                (xpos > -3) and (xpos < 3));
  201.             collide1data = snapshot (goodscore, goal1event);
  202.             goal1collide = exportEvent (collide1data, EVENTSCORE);
  203.  
  204.             // Handle bad goal collisions
  205.             goal2event = predicate ((zpos > endextent) and
  206.                (xpos > -3) and (xpos < 3));
  207.             collide2data = snapshot (badscore, goal2event);
  208.             goal2collide = exportEvent (collide2data, EVENTSCORE);
  209.  
  210.             // Determine player's position, velocity, and sound
  211.             (ppos, pvel, psound) = playermover (ppos1, pvel1);
  212.             mixsnd = snd mix psound;
  213.  
  214.             // Handle player collisions
  215.             relativevector = newpos - ppos;
  216.             playercollide = predicate (length (relativevector) < 
  217.                (playerradius + puckradius));
  218.             oldenergy = length (velocity);
  219.  
  220.             // Clamp velocity
  221.             newvel = relativevector * oldenergy + velocity + pvel;
  222.             magnitude = length (newvel);
  223.             newmagnitude = clamp (magnitude, -4, 4);
  224.             phitnewvel = normal (newvel) * newmagnitude;
  225.             phitnewpos = newpos + normal (phitnewvel) *
  226.                (playerradius + puckradius);
  227.  
  228.       in
  229.          (newpos, velocity, ppos, pvel, mixsnd, oldscore) until 
  230.             snapshot ((sidenewpos, sidenewvel,ppos, pvel, wallhit,
  231.                oldscore), sidecollide) => rebound |           
  232.             snapshot ((endnewpos, endnewvel,ppos, pvel, wallhit,
  233.                oldscore), endcollide) => rebound |           
  234.             snapshot ((goalnewpos,goalnewvel,ppos, pvel, winner,
  235.                goodscore), goal1collide) => rebound |           
  236.             snapshot ((goalnewpos,goalnewvel,ppos, pvel, loser,
  237.                badscore), goal2collide) => rebound |           
  238.             snapshot ((phitnewpos,phitnewvel,ppos, pvel, puckhit,
  239.                oldscore), playercollide) => rebound;           
  240.    in
  241.       rebound (pos0, vel0, ppos0, pvel0, silence, score0);
  242.  
  243. (puckpos, puckvelocity, playerpos, playervelocity, sounds, score)= 
  244.    puckmover (vector3Xyz (0, 0, -5), vector3Xyz (-2, 0, 0),
  245.       vector3Xyz (-10, 0, -6), vector3Xyz (-2, 0, 0), 0);
  246.  
  247. // Apply all positional changes to the player and the puck
  248. puckmotion = translate (puckpos) o rotate (yVector3, time * 2.9);
  249. activepuck = transformGeometry (puckmotion, coloredpuck);
  250. playermotion = translate (playerpos) o rotate (yVector3, time);
  251. activeplayer = transformGeometry (playermotion, player);
  252.  
  253. // HTML User Input Events
  254. EVENTSTART = 100;
  255. EVENTSTATIC = 101;
  256. EVENTORBITAL = 102;
  257. EVENTTRACKING = 103;
  258. extstartevent = importUnitEvent (EVENTSTART);
  259. extstaticevent = importUnitEvent (EVENTSTATIC);
  260. extorbitalevent = importUnitEvent (EVENTORBITAL);
  261. exttrackingevent = importUnitEvent (EVENTTRACKING);
  262.  
  263. // Define the linear tracking and the orbital cameras
  264. staticxform = rotate (xVector3, -0.25) o scale (1, 1, 0.3) o 
  265.    translate (0, 0.5, 200 + zComponent (playerpos));
  266. orbitxform = rotate (yVector3, time / 4) o 
  267.    rotate (xVector3, -0.25) o scale (1, 1, 0.3) o 
  268.    translate (0, 0.5, 200);
  269.  
  270. // Determine current camera transformation
  271. cameraxform (xform) = xform until
  272.    extstaticevent => cameraxform (staticxform) |
  273.    extorbitalevent => cameraxform (orbitxform);
  274. currentxform = cameraxform (staticxform);
  275. camera = transformCamera (currentxform, defaultCamera); 
  276.  
  277. // Use camera transformation to position headlight
  278. headlight = transformGeometry (currentxform, 
  279.    lightColor (colorRgb (0.5, 0.5, 0.5), directionalLight));
  280.  
  281. // Compute cropped area
  282. topright = point2Xy (xComponent (viewerUpperRight),
  283.    yComponent (viewerUpperRight));
  284. bottomleft = point2Xy (-xComponent (viewerUpperRight),
  285.    -yComponent (viewerUpperRight));
  286.  
  287. // Ouput everything
  288. totalsounds = sounds;
  289. totalobjects = arena union activepuck union activeplayer;
  290. totalimage = crop (bottomleft, topright,
  291.    renderedImage (totalobjects union headlight, camera));
  292. model = (totalimage over backgnd, totalsounds, totalsounds)
  293.    until extstartevent => model;
  294.