Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6759ed6

Browse files
Merge pull request #82 from HarryDulaney/chapter-15-solutions
Chapter 15 solutions
2 parents 35e3750 + 3241184 commit 6759ed6

File tree

2 files changed

+247
-20
lines changed

2 files changed

+247
-20
lines changed

‎README.md

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,34 +43,37 @@ object-oriented, GUI programming, advanced GUI and Web programming using Java...
4343
____
4444

4545
<span id="contribute"><span/>
46+
4647
## How to Contribute
4748

4849
### _Coding Guidelines_
50+
4951
- #### Solution must use Java 8 SE, as this is the version used by the book.
50-
- #### Every solution should have a java file containing a public main method for testing it.
51-
- #### Naming convention is: ExerciseCC_EE.java where CC is the chapter number and EE is the exercise number.
52-
- #### The public Exercise class containing the main method must include a JavaDoc comment on the class with original exercise question.
53-
- #### Each solution should be its own self-contained program with minimal dependencies on other files. If you need multiple files please create a package for the exercise.
54-
- #### ch_XX/exercise22_07/Exercise22_07.java
55-
- #### This allows us to utilize the Exercise Checking Tool [Exercise Checking Tool](https://liveexample.pearsoncmg.com/CheckExercise/faces/CheckExercise.xhtml?chapter=1&programName=Exercise01_01) to verify solutions.
52+
- #### Every solution should have a java file containing a public main method for testing it.
53+
- #### Naming convention is: ExerciseCC_EE.java where CC is the chapter number and EE is the exercise number.
54+
- #### The public Exercise class containing the main method must include a JavaDoc comment on the class with original exercise question.
55+
- #### Each solution should be its own self-contained program with minimal dependencies on other files. If you need multiple files please create a package for the exercise.
56+
- #### ch_XX/exercise22_07/Exercise22_07.java
57+
- #### This allows us to utilize the Exercise Checking Tool [Exercise Checking Tool](https://liveexample.pearsoncmg.com/CheckExercise/faces/CheckExercise.xhtml?chapter=1&programName=Exercise01_01) to verify solutions.
5658
- ### Example exercise solution:
59+
5760
```java
5861
package ch_01;
62+
5963
/**
60-
* 1.1 (Display three messages) Write a program that displays Welcome to Java,
61-
* Welcome to Computer Science, and Programming is fun.
62-
*/
63-
public class Exercise01_01 {
64-
public static void main(String[] args) {
65-
System.out.println("Welcome to Java");
66-
System.out.println("Welcome to Computer Science");
67-
System.out.println("Programming is fun");
68-
}
64+
* 1.1 (Display three messages) Write a program that displays Welcome to Java,
65+
* Welcome to Computer Science, and Programming is fun.
66+
*/
67+
public class Exercise01_01 {
68+
public static void main(String[] args) {
69+
System.out.println("Welcome to Java");
70+
System.out.println("Welcome to Computer Science");
71+
System.out.println("Programming is fun");
72+
}
6973

7074
}
7175
```
7276

73-
7477
### <em id="prs">Pull requests:</em>
7578

7679
- _When to use Pull Requests_
@@ -156,10 +159,8 @@ Indicates 100% completion of all exercises for that chapter
156159
14</strong></a> - JavaFx Basics <img src="./resources/images/icons8-complete-26.png" alt="complete-check-img"/>
157160
</li><br>
158161
<li><a href="https://github.com/HarryDulaney/intro-to-java-programming/tree/master/ch_15"><strong>Chapter 15
159-
</strong></a> - Event-Driven Programming and Animations
160-
<h6>
161-
Exercises Needed: 33
162-
</h6>
162+
</strong></a> - Event-Driven Programming and Animations <img src="./resources/images/icons8-complete-26.png" alt="complete-check-img"/>
163+
163164
</li><br>
164165
<li><a href="https://github.com/HarryDulaney/intro-to-java-programming/tree/master/ch_16"><strong>Chapter
165166
16</strong></a> - JavaFx UI Controls and Multimedia

‎ch_15/Exercise15_33.java

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
package ch_15;
2+
3+
import javafx.animation.PathTransition;
4+
import javafx.application.Application;
5+
import javafx.collections.ObservableList;
6+
import javafx.geometry.Point2D;
7+
import javafx.scene.Scene;
8+
import javafx.scene.layout.Pane;
9+
import javafx.scene.paint.Color;
10+
import javafx.scene.shape.Circle;
11+
import javafx.scene.shape.Line;
12+
import javafx.scene.shape.Polyline;
13+
import javafx.stage.Stage;
14+
import javafx.util.Duration;
15+
16+
import java.util.ArrayList;
17+
import java.util.List;
18+
19+
/**
20+
* ***15.33 (Game: bean-machine animation) Write a program that animates the bean
21+
* machine introduced in Programming Exercise 7.21. The animation terminates
22+
* after ten balls are dropped, as shown in Figure 15.36b and c.
23+
*/
24+
public class Exercise15_33 extends Application {
25+
26+
@Override
27+
public void start(Stage primaryStage) {
28+
double WIDTH = 400;
29+
double HEIGHT = 400;
30+
BeanMachinePane pane = new BeanMachinePane(WIDTH, HEIGHT, 8);
31+
Scene scene = new Scene(pane, WIDTH, HEIGHT);
32+
primaryStage.setScene(scene);
33+
primaryStage.setResizable(false);
34+
primaryStage.setTitle(getClass().getName());
35+
primaryStage.show();
36+
playAnimation(pane);
37+
}
38+
39+
static void playAnimation(BeanMachinePane pane) {
40+
/* Drop 10 balls */
41+
for (int i = 0; i < 10; i++) {
42+
pane.dropBall();
43+
}
44+
}
45+
46+
static class BeanMachinePane extends Pane {
47+
private final int numberOfPins;
48+
private final int numberOfSlots;
49+
50+
double ballRadius;
51+
52+
Line[] outlineShape;
53+
Line outlineShapeBaseLine;
54+
Line[] slotVerticalLines;
55+
Circle[] pins;
56+
57+
List<Circle> droppedBalls = new ArrayList<>();
58+
59+
double spaceBallDropDelaySeconds = 0.5;
60+
61+
public BeanMachinePane(double width, double height, int numberOfSlots) {
62+
setWidth(width);
63+
setHeight(height);
64+
this.numberOfSlots = numberOfSlots;
65+
this.numberOfPins = getNumberOfPins(numberOfSlots);
66+
buildStaticShapes();
67+
getChildren().add(outlineShapeBaseLine);
68+
getChildren().addAll(outlineShape);
69+
getChildren().addAll(slotVerticalLines);
70+
getChildren().addAll(pins);
71+
}
72+
73+
public void dropBall() {
74+
ballDropAnimation();
75+
}
76+
77+
private void ballDropAnimation() {
78+
/* Draw ball in the center flask shape opening */
79+
double flaskOpeningCenterX = getDropStartPtX();
80+
/* Draw ball just ABOVE flask shape opening */
81+
ballRadius = pins[0].getRadius();
82+
Circle ball = new Circle(flaskOpeningCenterX,
83+
outlineShape[5].getEndY() - ballRadius - 20,
84+
ballRadius,
85+
Color.RED);
86+
Polyline polyline = createRandomPath(ball);
87+
PathTransition path = new PathTransition(Duration.seconds(4), polyline, ball);
88+
path.setDelay(Duration.seconds(spaceBallDropDelaySeconds));
89+
spaceBallDropDelaySeconds += 1.5;
90+
getChildren().addAll(polyline);
91+
getChildren().addAll(ball);
92+
droppedBalls.add(ball);
93+
path.play();
94+
}
95+
96+
private double getDropStartPtX() {
97+
return outlineShapeBaseLine.getStartX()
98+
+ (outlineShapeBaseLine.getEndX()
99+
- outlineShapeBaseLine.getStartX()) / 2;
100+
}
101+
102+
103+
private Line getBaseLineShape(double paneWidth, double paneHeight) {
104+
/* Horizontal line at the bottom of the machine (Y value does not change) */
105+
double baseLineYValue = paneHeight * 0.8;
106+
double baseLineStartXValue = paneWidth * 0.2;
107+
double baseLineEndXValue = paneWidth * 0.8;
108+
return new Line(baseLineStartXValue, baseLineYValue, baseLineEndXValue, baseLineYValue);
109+
110+
}
111+
112+
113+
/**
114+
* @param slots the number of slots in the bean machine
115+
* @return the number of pins in the bean machine
116+
*/
117+
int getNumberOfPins(int slots) {
118+
int numPins = 0;
119+
do {
120+
slots--;
121+
numPins += slots;
122+
} while (slots > 1);
123+
124+
return numPins;
125+
}
126+
127+
private void buildStaticShapes() {
128+
double paneWidth = getWidth();
129+
double paneHeight = getHeight();
130+
outlineShapeBaseLine = getBaseLineShape(paneWidth, paneHeight);
131+
double distance = (outlineShapeBaseLine.getEndX() - outlineShapeBaseLine.getStartX()) / numberOfSlots;
132+
pins = new Circle[numberOfPins];
133+
int index = 0;
134+
for (int i = 1; i < numberOfSlots; i++) {
135+
double x = outlineShapeBaseLine.getStartX() + (i * distance * 0.50) + distance / 2;
136+
double y = outlineShapeBaseLine.getStartY() - (distance * i) - distance / 2;
137+
for (int j = 0; j < numberOfSlots - i; j++) {
138+
pins[index++] = new Circle(x, y, paneWidth * 0.012, Color.BLUE);
139+
x += distance;
140+
}
141+
}
142+
143+
distance = distance + (distance / 2) - pins[0].getRadius();
144+
slotVerticalLines = new Line[numberOfSlots - 1];
145+
for (int i = 0; i < numberOfSlots - 1; i++) {
146+
double x1 = pins[i].getCenterX() + pins[i].getRadius() * Math.sin(Math.PI);
147+
double y1 = pins[i].getCenterY() - pins[i].getRadius() * Math.cos(Math.PI);
148+
slotVerticalLines[i] = new Line(x1, y1, x1, y1 + distance);
149+
150+
}
151+
152+
outlineShape = new Line[6];
153+
outlineShape[0] = new Line(
154+
outlineShapeBaseLine.getEndX(), outlineShapeBaseLine.getEndY(),
155+
outlineShapeBaseLine.getEndX(), outlineShapeBaseLine.getEndY() - distance);
156+
outlineShape[1] = new Line(
157+
outlineShapeBaseLine.getStartX(), outlineShapeBaseLine.getStartY(),
158+
outlineShapeBaseLine.getStartX(), outlineShapeBaseLine.getStartY() - distance);
159+
160+
for (int i = 2; i < 4; i++) {
161+
double x = pins[pins.length - i].getCenterX();
162+
double y = pins[pins.length - i].getCenterY() - distance;
163+
outlineShape[i] =
164+
new Line(x, y, outlineShape[i - 2].getEndX(), outlineShape[i - 2].getEndY());
165+
}
166+
167+
for (int i = 4; i < outlineShape.length; i++) {
168+
outlineShape[i] =
169+
new Line(
170+
outlineShape[i - 2].getStartX(),
171+
outlineShape[i - 2].getStartY(),
172+
outlineShape[i - 2].getStartX(),
173+
outlineShape[i - 2].getStartY() - (distance * 0.6)
174+
);
175+
}
176+
}
177+
178+
private Polyline createRandomPath(Circle ball) {
179+
Polyline polyLine = new Polyline();
180+
polyLine.setFill(Color.TRANSPARENT);
181+
polyLine.setStroke(Color.TRANSPARENT);
182+
ObservableList<Double> pathPoints = polyLine.getPoints();
183+
Point2D startPoint = new Point2D(ball.getCenterX(), ball.getCenterY());
184+
double nextX = startPoint.getX(); // Set current X to ball's center X starting position
185+
double nextY = startPoint.getY(); // Set current Y to ball's center Y starting position
186+
pathPoints.addAll(nextX, nextY);
187+
188+
while (nextY < outlineShapeBaseLine.getStartY() - ball.getRadius()) {
189+
nextY += 1; // Move ball down on Y axis to simulate falling
190+
/* Re-calculate random path until it does not pass through a static shape */
191+
nextX = getRandomX(nextX);
192+
while (collideWithPins(nextX, nextY) || collideWithOutline(nextX, nextY)) {
193+
nextX = getRandomX(nextX);
194+
}
195+
pathPoints.addAll(nextX, nextY);
196+
}
197+
198+
return polyLine;
199+
}
200+
201+
private boolean collideWithOutline(double nextX, double nextY) {
202+
return false;
203+
}
204+
205+
private boolean collideWithPins(double nextX, double nextY) {
206+
for (Circle pin : pins) {
207+
if (pin.contains(nextX, nextY + ballRadius)) {
208+
return true;
209+
}
210+
}
211+
return false;
212+
}
213+
214+
private double getRandomX(double currentX) {
215+
double random = Math.random();
216+
if (random < 0.5) {
217+
currentX -= 1;
218+
} else {
219+
currentX += 1;
220+
}
221+
return currentX;
222+
}
223+
224+
225+
}
226+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /