Section 5

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.

     | offset |
     offset := self offsetWithinGridForm + 1.
     ^offset extent: CellRenderer cellExtent - 2

| 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].

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.
                 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.

Index Page Next Page

Copyright © 2007, 2008, 2009, 2010 Stephan B Wessels