Figure 6.10 overrides class View
’s onSizeChanged method, which is called whenever the View
’s size changes, including when the View
is first added to the View
hierarchy as the layout is inflated. This app always displays in portrait mode, so onSizeChanged
is called only once when the activity’s onCreate
method inflates the GUI. The method receives the View
’s new width and height and its old width and height—when this method is called the first time, the old width and height are 0. The calculations performed here scale the game’s on-screen elements based on the device’s pixel width and height. We arrived at our scaling factors via trial and error, choosing values that made the game elements look nice on the screen. Lines 170–175 configure the Paint
objects that are used to specify drawing characteristics for the game’s elements. After the calculations, line 177 calls method newGame
(Fig. 6.11).
132 // called by surfaceChanged when the size of the SurfaceView changes,
133 // such as when it's first added to the View hierarchy
134 @Override
135 protected void onSizeChanged(int w, int h, int oldw, int oldh)
136 {
137 super.onSizeChanged(w, h, oldw, oldh);
138
139 screenWidth = w; // store CannonView's width
140 screenHeight = h; // store CannonView's height
141 cannonBaseRadius = h / 18; // cannon base radius 1/18 screen height
142 cannonLength = w / 8; // cannon length 1/8 screen width
143
144 cannonballRadius = w / 36; // cannonball radius 1/36 screen width
145 cannonballSpeed = w * 3 / 2; // cannonball speed multiplier
146
147 lineWidth = w / 24; // target and blocker 1/24 screen width
148
149 // configure instance variables related to the blocker
150 blockerDistance = w * 5 / 8; // blocker 5/8 screen width from left
151 blockerBeginning = h / 8; // distance from top 1/8 screen height
152 blockerEnd = h * 3 / 8 ; // distance from top 3/8 screen height
153 initialBlockerVelocity = h / 2; // initial blocker speed multiplier
154 blocker.start = new Point(blockerDistance, blockerBeginning);
155 blocker.end = new Point(blockerDistance, blockerEnd);
156
157 // configure instance variables related to the target
158 targetDistance = w * 7 / 8; // target 7/8 screen width from left
159 targetBeginning = h / 8 ; // distance from top 1/8 screen height
160 targetEnd = h * 7 / 8; // distance from top 7/8 screen height
161 pieceLength = (targetEnd - targetBeginning) / TARGET_PIECES;
162 initialTargetVelocity = -h / 4; // initial target speed multiplier
163 target.start = new Point(targetDistance, targetBeginning);
164 target.end = new Point(targetDistance, targetEnd);
165
166 // endpoint of the cannon's barrel initially points horizontally
167 barrelEnd = new Point(cannonLength, h / 2);
168
169 // configure Paint objects for drawing game elements
170 textPaint.setTextSize(w / 20); // text size 1/20 of screen width
171 textPaint.setAntiAlias(true); // smoothes the text
172 cannonPaint.setStrokeWidth(lineWidth * 1.5f); // set line thickness
173 blockerPaint.setStrokeWidth(lineWidth); // set line thickness
174 targetPaint.setStrokeWidth(lineWidth); // set line thickness
175 backgroundPaint.setColor(Color.WHITE); // set background color
176
177 newGame(); // set up and start a new game
178 } // end method onSizeChanged
179