<> <> 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 ]; 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*( }; 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 }.