RobotArenaImpl.mesa
Eric Nickell, July 11, 1985 11:22:06 pm PDT
DIRECTORY
RobotArena,
Atom USING [MakeAtom],
Imager,  --USING Lots of stuff!
ImagerBackdoor USING [GetBounds],
ImagerColor USING [ColorFromAtom],
ImagerPath USING [ArcTo, MoveTo],
ImagerPixelMaps USING [PixelMap],
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
xScale, yScale: REAL;
IF whatChanged#$MoveRobots THEN {
Make the whole arena gray to start
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] ~ {
Set the position of the specified robot within the arena...
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] ~ {
Change the picture of the specified robot
};
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
}.