DIRECTORY RobotArena, Atom USING [MakeAtom], Imager, --USING Lots of stuff! ImagerBackdoor USING [GetBounds], ImagerColor USING [ColorFromAtom], ImagerPath USING [ArcTo, MoveTo], RealFns USING [Cos, Sin], Rope USING [ROPE], ViewerClasses USING [InitProc, PaintProc, Viewer, ViewerClass, ViewerClassRec], ViewerOps USING [RegisterViewerClass]; RobotArenaImpl: CEDAR PROGRAM IMPORTS Atom, Imager, ImagerBackdoor, ImagerColor, ImagerPath, RealFns, ViewerOps EXPORTS RobotArena ~ { OPEN RobotArena, V: ViewerClasses; rR: INT ~ 1; --Robot radius ArenaData: TYPE = REF ArenaDataRec; ArenaDataRec: TYPE = RECORD [ robot: ARRAY RobotIndex OF RobotImage ]; p: REAL ~ 3.14159265; robotColor: ARRAY RobotIndex OF Imager.ConstantColor; ArenaPaint: PRIVATE V.PaintProc ~ { bounds: Imager.Rectangle ~ ImagerBackdoor.GetBounds[context]; scale: REAL ~ MIN[bounds.w/(arenaWidth+10.0), bounds.h/(arenaHeight+10.0)]; arena: Arena ~ self; arenaData: ArenaData _ NARROW[self.data]; --Implementation data IF whatChanged#$MoveRobots THEN { Imager.SetGray[context, .5]; Imager.MaskRectangle[context, bounds]; }; Imager.TranslateT[context, [bounds.x, bounds.y]]; Imager.ScaleT[context, scale]; Imager.TranslateT[context, [5.0, 5.0]]; Imager.SetColor[context, Imager.white]; Imager.MaskRectangleI[context, 0, 0, arenaWidth, arenaHeight]; FOR i: RobotIndex IN RobotIndex DO --Things which can scar the wall OPEN R: arenaData.robot[i]; IF R.hit THEN { a: INT _ rR+1; Imager.SetColor[context, Imager.black]; Imager.MaskStrokeTrajectory[context, ImagerPath.MoveTo[[R.x-a, R.y-a]].ArcTo[[R.x+a, R.y-a], [R.x+a, R.y+a]].ArcTo[[R.x-a, R.y+a], [R.x-a, R.y-a]]]; }; IF R.fire THEN { Imager.SetColor[context, robotColor[i]]; Imager.MaskVector[context, [R.x, R.y], [R.x+150*RealFns.Cos[R.fireAngle*(p/128)], R.y+150*RealFns.Sin[R.fireAngle*(p/128)]]]; }; ENDLOOP; Imager.ClipRectangleI[context, 0, 0, arenaWidth, arenaHeight]; FOR i: RobotIndex IN RobotIndex DO --Things which can't scar the wall OPEN R: arenaData.robot[i]; Imager.SetColor[context, robotColor[i]]; Imager.MaskRectangle[context, [R.x-rR, R.y-rR, 2*rR, 2*rR]]; ENDLOOP; }; ArenaInit: PRIVATE V.InitProc ~ { arenaData: ArenaData _ NEW[ArenaDataRec]; self.data _ arenaData; }; SetRobot: PUBLIC PROC [self: V.Viewer, i: RobotIndex, image: RobotImage] ~ { arenaData: ArenaData _ NARROW[self.data]; --Implementation data arenaData.robot[i] _ image; }; GetRobot: PUBLIC PROC [self: V.Viewer, i: RobotIndex] RETURNS [image: RobotImage] ~ { arenaData: ArenaData _ NARROW[self.data]; --Implementation data image _ arenaData.robot[i]; }; SetRobotLocation: PUBLIC PROC [self: Arena, num: RobotIndex, x, y: REAL] ~ { arenaData: ArenaData ~ NARROW[self.data]; --Implementation data arenaData.robot[num].x _ x; --Set the coordinates... arenaData.robot[num].y _ y; }; SetRobotPicture: PUBLIC PROC [self: Arena, num: RobotIndex, picture: RobotPic] ~ { }; SetRobotColor: PUBLIC PROC [index: RobotIndex, color: Rope.ROPE] ~ { robotColor[index] _ ImagerColor.ColorFromAtom[Atom.MakeAtom[color]]; }; arenaClass: V.ViewerClass _ NEW[V.ViewerClassRec _ [ init: ArenaInit, paint: ArenaPaint, icon: tool ]]; ViewerOps.RegisterViewerClass[$Arena, arenaClass]; -- plug in to Viewers }.  RobotArenaImpl.mesa Eric Nickell, July 11, 1985 11:22:06 pm PDT ImagerPixelMaps USING [PixelMap], xScale, yScale: REAL; Make the whole arena gray to start Set the position of the specified robot within the arena... Change the picture of the specified robot ΚΧ– "Mesa" style˜šœΟc™J™+—J˜šΟk ˜ Jšœ ˜ Icodešœžœ ˜Jšœ ˜Kšœžœ ˜!Kšœ žœ˜"Kšœ žœ˜!Jšœžœ ™!Kšœžœ ˜Kšœžœžœ˜Jšœžœ<˜OJšœ žœ˜&J˜—šœžœž˜JšžœJ˜QJšžœ ˜J˜Jšžœ žœ˜"—J˜Kšœžœ˜J˜Jšœ žœžœ˜#šœžœžœ˜Jšœžœ žœ ˜%J˜J˜—šΟgœžœ˜J˜—Jšœ žœ žœ˜5šΟn œžœ˜#J˜=Jšœžœžœ:˜KJ˜Jšœžœ˜@Jšœžœ™J™šžœžœ˜!K™"J˜J˜&Kšœ˜—J™J˜J˜1J˜J˜'Jšœ'˜'Jšœ>˜>J˜šžœžœ žœ ˜DJšžœ˜šžœžœ˜Kšœžœ˜Kšœ'˜'Kšœ”˜”Kšœ˜—šžœžœ˜Jšœ(˜(KšœIŸœ)Ÿœ ˜}Kšœ˜—Jšžœ˜—K˜>šžœžœ žœ"˜FJšžœ˜Jšœ(˜(Jšœ<˜