Our next step is to work in the LaserGameForms class. Modify the #arrowFormFromPointsArray class method to use the new trimming rectangle code.
arrowFormFromPointsArray: pts
"LaserGameForms initializeCachedForms"
| form fillForm index startPoint nextIndex endPoint line offset |
offset := 2@2.
form := Form extent: 330@330 depth: 1.
form fillColor: Color white.
fillForm := Form extent: 1@1 depth: 1.
fillForm fillColor: Color black.
index := 1.
[index <= pts size] whileTrue: [
startPoint := pts at: index.
nextIndex := index = pts size
ifTrue: [1]
ifFalse: [index + 1].
endPoint := pts at: nextIndex.
startPoint := startPoint + offset.
endPoint := endPoint + offset.
line := Line from: startPoint to: endPoint withForm: fillForm.
line displayOn: form.
index := index + 1].
form floodFill: Color black at: 1@1.
form reverse.
^form copy: (form tightRectangleAroundColor: Color black)
You need to execute "LaserGameForms initializeCachedForms" so that these forms are all re-calculated. Next we are going to perform a slight refactoring in the CellRenderer class. Add the following instance method.
backgroundRectangle
| offset |
offset := self offsetWithinGridForm + 1.
^offset extent: CellRenderer cellExtent - 2
fillBackground
| backgroundRect |
backgroundRect := self backgroundRectangle.
self targetForm fill: backgroundRect fillColor: LaserGameColors gameBoardBackgroundColor.
We're also going to do some refactoring in the MirrorCellRenderer class. Add the following instance method.
hintArrowColorFor: regionClass offset: offsetWithinCell
| permissionToActOnCell arrowColor |
permissionToActOnCell := regionClass
canActOnCellAtPoint: offsetWithinCell
cell: self cell
withinGrid: self grid.
arrowColor := permissionToActOnCell
ifTrue: [LaserGameColors allowActionArrowColor]
ifFalse: [LaserGameColors denyActionArrowColor].
^arrowColor
Modify this method.
showPositionHintFromWithinBoardOffset: aPoint
| cellPosn offsetWithinCell regionClass arrowAndOffset |
cellPosn := self offsetWithinGridForm.
offsetWithinCell := aPoint - cellPosn.
regionClass := CellClickRegion clickRegionForPoint: offsetWithinCell.
arrowAndOffset := regionClass scaledHintArrowAndOffsetFromWithinCell: offsetWithinCell.
arrowAndOffset isNil
ifTrue: [self currentHand showTemporaryCursor: nil]
ifFalse: [
| arrowColor arrow offset |
arrowColor := self hintArrowColorFor: regionClass offset: offsetWithinCell.
arrow := arrowAndOffset value.
offset := arrowAndOffset key.
offset := self offsetWithinGridForm + offset.
arrow
displayOn: self targetForm
at: offset
clippingBox: self backgroundRectangle
rule: Form oldPaint
fillColor: arrowColor.
self currentHand
showTemporaryCursor: LaserGameForms crossHair
hotSpotOffset: (LaserGameForms crossHair extent // 2)]
Our last change is on the CellClickRegionInside class. Modify the #scaledHintArrowAndOffsetFromWithinCell: class method to calculate a proper offset for our arrow form now that we have a better sized and centered form.
scaledHintArrowAndOffsetFromWithinCell: aPoint
| pushRegion arrow tinyArrow offset |
pushRegion := self pushRegionForPoint: aPoint.
arrow := pushRegion arrowForm.
tinyArrow := arrow scaledToSize: CellRenderer cellExtent - 2.
offset := (CellRenderer cellExtent - tinyArrow extent) // 2.
^offset->tinyArrow