home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Libraries / Graphic Elements 2 / GETest / SynchGraphic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-23  |  7.8 KB  |  359 lines  |  [TEXT/MPS ]

  1. /*
  2.     SynchGraphic.c
  3.     
  4.     Graphics for Graphic Elements SynchTest
  5.     
  6.     1/29/94
  7.     
  8.     Al Evans
  9.     
  10. */
  11.  
  12. #include "SynchGraphic.h"
  13. #include "Motion.h"
  14.  
  15.  
  16. short    objUpdateIntrvl;
  17. short    objMoveDist;
  18. Boolean    objLinearMotion;
  19. Boolean objCollision;
  20. short    objSeparation;
  21. short    numObjs;
  22. Ptr        objMask;
  23.  
  24. short RangedRdm(short min, short max)
  25. {
  26.     short rdm;
  27.     
  28.     rdm = Random();
  29.     if (rdm < 0) 
  30.         rdm = -rdm;
  31.     rdm = rdm % (max - min);
  32.     rdm += min;
  33.     return rdm;
  34. }
  35.  
  36. GrafElPtr MakeAnObject(GEWorldPtr world, OSType id)
  37. {
  38.     GrafElPtr anObject;
  39.     
  40.     anObject = FindElementByID(world, id);
  41.     if (anObject == nil) {
  42.         anObject = NewAnimatedGraphic(world, id, testObjPlane, rTestObj, transparent, 0, 0, 2);
  43.         if (anObject == nil) return nil;
  44.     }
  45.     SetElementPlane(world, anObject->objectID, testObjPlane);
  46.     SetFrame(world, anObject->objectID, 1);
  47.     if (objLinearMotion) {
  48.         SetAutoChange(world, id, DoObjectLinear, nil, objUpdateIntrvl);
  49.         SetCollision(world, id, nil, 0);
  50.     }
  51.     else {
  52.         SetAutoChange(world, id, DoObjectRandom, nil, objUpdateIntrvl);
  53.     }
  54.     
  55.     return anObject;
  56. }
  57.  
  58. Boolean InitObjectGraphics(GEWorldPtr world)
  59. {
  60.     GrafElPtr        thisElement;
  61.     Rect            nullRect;
  62.     
  63.     objUpdateIntrvl = 33;
  64.     objMoveDist = 4;
  65.     objSeparation = 4;
  66.     objLinearMotion = true;
  67.     objCollision = false;
  68.     objMask = nil;
  69.     thisElement = MakeAnObject(world, firstObjID);
  70.     if (thisElement == nil) return false;
  71.     ShowElement(world, firstObjID, false);
  72. }
  73.  
  74. void HideObjects(GEWorldPtr world)
  75. {
  76.     GrafElPtr    thisObj;
  77.     OSType        objID = firstObjID;
  78.     
  79.     while (thisObj = FindElementByID(world, objID)){
  80.         ShowElement(world, objID, false);
  81.         objID++;
  82.     }
  83. }
  84.  
  85. short GetMoveDistance(void)
  86. {
  87.     return objMoveDist;
  88. }
  89.  
  90. Boolean MotionIsLinear(void)
  91. {
  92.     return objLinearMotion;
  93. }
  94.  
  95. void SetObjMotionLinear(Boolean linearMotion)
  96. {
  97.     objLinearMotion = linearMotion;
  98. }
  99.  
  100. Boolean ObjCollisionActive(void)
  101. {
  102.     return objCollision;
  103. }
  104.  
  105. void SetObjCollision(GEWorldPtr world, Boolean collide)
  106. {
  107.     OSType        objID = firstObjID;
  108.     GrafElPtr    anObject;
  109.  
  110.     if (objLinearMotion) return; //no collision possible
  111.     
  112.     objCollision = collide;
  113.     while (anObject = FindElementByID(world, objID)){
  114.         if (objCollision)
  115.             SetCollision(world, objID, DoObjectCollide, testObjPlane);
  116.         else
  117.             SetCollision(world, objID, nil, 0);
  118.         objID++;
  119.     }
  120. }
  121.  
  122. void SetMoveDistance(GEWorldPtr world, short newMove)
  123. {
  124.     OSType        objID = firstObjID;
  125.     GrafElPtr    anObject;
  126.     short        objMove;
  127.     
  128.     objMoveDist = newMove;
  129.     
  130.     while (anObject = FindElementByID(world, objID)){
  131.         if (objLinearMotion) {
  132.         objMove = (short) ((long) anObject->changeData);
  133.         if (objMove >= 0)
  134.             objMove = newMove;
  135.         else
  136.             objMove = -newMove;
  137.         anObject->changeData = (Ptr) ((long) objMove);
  138.         }
  139.         else {
  140.             anObject->changeData = (Ptr) ((long) RangedRdm(1, 2 * objMoveDist) << 16) + 
  141.                                             RangedRdm(1, 2 * objMoveDist);
  142.         }
  143.         objID++;
  144.     }
  145. }
  146.  
  147. short GetUpdateInterval(void)
  148. {
  149.     return objUpdateIntrvl;
  150. }
  151. void SetUpdateInterval(GEWorldPtr world, short newInterval)
  152. {
  153.     OSType        objID = firstObjID;
  154.     GrafElPtr    anObject;
  155.     
  156.     objUpdateIntrvl = newInterval;
  157.     while (anObject = FindElementByID(world, objID)){
  158.         anObject->changeIntrvl = newInterval;
  159.         objID++;
  160.     }
  161. }
  162.  
  163. short GetNumberOfObjects(void)
  164. {
  165.     return numObjs;
  166. }
  167.  
  168. void SetNumberOfObjects(GEWorldPtr world, short newNumber)
  169. {
  170.     OSType        objID = firstObjID;
  171.     GrafElPtr    anObject;
  172.     Rect        objRect;
  173.     short        objCount;
  174.     short        hOffset, vOffset;
  175.     
  176.     numObjs = newNumber;
  177.     HideObjects(world);
  178.     anObject = MakeAnObject(world, objID);
  179.     objRect = anObject->animationRect;
  180.     RectOffset(&objRect, -objRect.left + 4, -objRect.top + 16);
  181.     hOffset = RectWidth(&objRect) + ScaleToWorld(world, objSeparation);
  182.     vOffset = RectHeight(&objRect) + ScaleToWorld(world, objSeparation);
  183.     if (objLinearMotion) {
  184.         for (objCount = 0; objCount < newNumber; objCount++) {
  185.             anObject= MakeAnObject(world, objID);
  186.             if (anObject == nil) return;
  187.             ChangedRect(world, &anObject->animationRect);
  188.             anObject->animationRect = objRect;
  189.             ChangedRect(world, &anObject->animationRect);
  190.             anObject->changeData = (Ptr) ((long) objMoveDist);
  191.             ShowElement(world, anObject->objectID, true);
  192.             RectOffset(&objRect, hOffset, 0);
  193.             if (objRect.right > world->animationRect.right) 
  194.                 RectOffset(&objRect, -objRect.left + 4, vOffset);
  195.             objID++;
  196.         }
  197.     }
  198.     else {
  199.         for (objCount = 0; objCount < newNumber; objCount++) {
  200.             anObject= MakeAnObject(world, objID);
  201.             if (anObject == nil) return;
  202.             MoveElementTo(world, anObject->objectID, 
  203.                 RangedRdm(4, 512 - hOffset), 
  204.                 RangedRdm(16, 364 - vOffset));
  205.             anObject->changeData = (Ptr) ((long)  RangedRdm(1, 2 * objMoveDist) << 16) + 
  206.                             RangedRdm(1, 2 * objMoveDist);
  207.             ShowElement(world, anObject->objectID, true);
  208.             objID++;
  209.         }
  210.     }
  211.     
  212. }
  213.  
  214. short GetObjSeparation(void)
  215. {
  216.     return objSeparation;
  217. }
  218.  
  219. void SetObjSeparation(GEWorldPtr world, short newSeparation)
  220. {
  221. #pragma unused(world)
  222.     objSeparation = newSeparation;
  223. }
  224.  
  225.  
  226. pascal void DoObjectLinear(GEWorldPtr world, GrafElPtr obj)
  227. {
  228.     GEDirection    collisionDir;
  229.     short currXMove = (short) ((long) obj->changeData);
  230.     short currYMove = 0;
  231.     register Rect *objRect = &obj->animationRect;
  232.     
  233.     collisionDir = CheckLimits(objRect, &world->animationRect);
  234.     switch (collisionDir) {
  235.         case right:
  236.         case left:
  237.             obj->changeData = (Ptr) ((long) -currXMove);
  238.             currXMove = -currXMove;
  239.             currYMove = (objRect->bottom - objRect->top + objSeparation) >> 2;
  240.             if (collisionDir == right) {
  241.                 currXMove -= objRect->right - world->animationRect.right;
  242.                 SetElementPlane(world, obj->objectID, testObjPlane + 5);
  243.             }
  244.             else {
  245.                 currXMove += world->animationRect.left - objRect->left;
  246.                 SetElementPlane(world, obj->objectID, testObjPlane);
  247.             }
  248.             break;
  249.         case down:
  250.             PtrMoveElementTo(world, obj, 4, 16, true);
  251.             return;
  252.     }
  253.     PtrMoveElement(world, obj, currXMove, currYMove);        
  254. }
  255.  
  256. void BounceObj(GEDirection direction, short *xMove, short *yMove)
  257. {
  258.     switch (direction) {
  259.         case right:
  260.             if (*xMove > 0);
  261.                 *xMove = -*xMove;
  262.             break;
  263.         case left:
  264.             if (*xMove < 0);
  265.                 *xMove = -*xMove;
  266.             break;
  267.         case up:
  268.             if (*yMove < 0)
  269.                 *yMove = -*yMove;
  270.             break;
  271.         case down:
  272.             if (*yMove > 0)
  273.                 *yMove = -*yMove;
  274.             break;
  275.     }
  276. }
  277.  
  278. pascal void DoObjectRandom(GEWorldPtr world, GrafElPtr obj)
  279. {
  280.     GEDirection collisionDir;
  281.     register short *currXMove = (short *) &obj->changeData + 1;
  282.     register short *currYMove = (short *) &obj->changeData;
  283.     
  284.     collisionDir = CheckLimits(&obj->animationRect, &world->animationRect);
  285.     if (collisionDir != none)
  286.         BounceObj(collisionDir, currXMove, currYMove);
  287.     PtrMoveElement(world, obj, *currXMove, *currYMove);
  288.     
  289. }
  290.  
  291. pascal void DoObjectCollide(GEWorldPtr world, GrafElPtr obj, GEDirection dir, CollisionPhase phase, GrafElPtr objHit)
  292. {
  293.     register short *currXMove = (short *) &obj->changeData + 1;
  294.     register short *currYMove = (short *) &obj->changeData;
  295.     
  296.     if (objHit->objectID >= 'TST\0') {                //If we're colliding with another ball
  297.         switch (phase) {
  298.         
  299.             case collisionBegin:
  300.             SetFrame(world, obj->objectID, 2);
  301.             break;
  302.             
  303.             case collisionContinue:
  304.             switch (dir) {
  305.                 case left:
  306.                     if (*currXMove < 0)
  307.                         *currXMove = -*currXMove;
  308.                     break;
  309.                 case right:
  310.                     if (*currXMove > 0)
  311.                         *currXMove = -*currXMove;
  312.                     break;
  313.                 case up:
  314.                     if (*currYMove < 0)
  315.                         *currYMove = -*currYMove;
  316.                     break;
  317.                 case down:
  318.                     if (*currYMove > 0)
  319.                         *currYMove = -*currYMove;
  320.                     break;
  321.                 case upLeft:
  322.                     if (*currYMove < 0)
  323.                         *currYMove = -*currYMove;
  324.                     if (*currXMove < 0)
  325.                         *currXMove = -*currXMove;
  326.                     break;
  327.                 case upRight:
  328.                     if (*currYMove < 0)
  329.                         *currYMove = -*currYMove;
  330.                     if (*currXMove > 0)
  331.                         *currXMove = -*currXMove;
  332.                     break;
  333.                 case downLeft:
  334.                     if (*currYMove > 0)
  335.                         *currYMove = -*currYMove;
  336.                     if (*currXMove < 0)
  337.                         *currXMove = -*currXMove;
  338.                     break;
  339.                 
  340.                 case downRight:
  341.                     if (*currYMove > 0)
  342.                         *currYMove = -*currYMove;
  343.                     if (*currXMove > 0)
  344.                         *currXMove = -*currXMove;
  345.                     break;
  346.             }
  347.             break;
  348.             
  349.         case collisionEnd:
  350.             SetFrame(world, obj->objectID, 1);
  351.             break;
  352.         }
  353.     
  354.     
  355.     }
  356.  
  357.     
  358. }
  359.