-
Notifications
You must be signed in to change notification settings - Fork 0
/
Ball.java
149 lines (126 loc) · 5.84 KB
/
Ball.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
/**
* Defines the ball object and its movement in response to
* interactions with the other game elements.
*
* @author bcanada
* @version 2014.11.10
*/
public class Ball extends SmoothMover
{
/* FIELDS */
private Game playField; // this is the local reference to the game object
private double directionX; // -1 for left, +1 for right
private double directionY; // -1 for up, +1 for down
private double speed;
// constants
private final int PLAYER_ONE = 1;
private final int PLAYER_TWO = 2;
/* CONSTRUCTORS */
public Ball()
{
super( new Vector( -45 + Greenfoot.getRandomNumber( 90 ), 3.0 ));
if ( Greenfoot.getRandomNumber( 2 ) == 0 )
{
getMovement().revertHorizontal();
}
} // end Ball constructor
/* METHODS */
/**
* Act - do whatever the Ball wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
// need to explicitly cast as the World subclass (i.e., Game)
playField = (Game)getWorld();
// behavior depends on the game status
if ( playField.getGameStatus() == Status.NOT_PLAYING )
{
// don't do anything
}
else if ( playField.getGameStatus() == Status.PLAYING )
{
move();
/*
* Check for intersection with the player's paddle
*/
Paddle possiblePaddle = (Paddle)( getOneObjectAtOffset(-4,0,Paddle.class) );
if ( possiblePaddle != null )
{
// Display debug message
System.out.printf("Ball has intersected with %s\n",possiblePaddle.toString());
// compute return angle and increase speed by 10%
// TODO: Since this code is duplicated elsewhere, I probably
// should move it into a separate method in this class
double hitLocation = (this.getExactY()-4.0) - (possiblePaddle.getExactY()-32.0);
int returnAngle = (int)( 315.0 + (90.0/64.0)*hitLocation );
getMovement().setDirection( returnAngle );
getMovement().scale( 1.1 );
playField.playHighBlip();
} // end if
/*
* Check for intersection with the CPU paddle
*/
CPUPaddle possibleCPUPaddle = (CPUPaddle)( getOneObjectAtOffset(+4,0,CPUPaddle.class) );
if ( possibleCPUPaddle != null )
{
// Display debug message
System.out.printf("Ball has intersected with %s\n",possibleCPUPaddle.toString());
// compute return angle and increase speed by 10%
// TODO: Since this code is duplicated elsewhere, I probably
// should move it into a separate method in this class
double hitLocation = (this.getExactY()-4.0) - (possibleCPUPaddle.getExactY()-32.0);
int returnAngle = (int)( 225.0 - (90.0/64.0)*hitLocation );
getMovement().setDirection( returnAngle );
getMovement().scale( 1.1 );
playField.playHighBlip();
} // end if
/*
* If the ball hits the boundary, simply have it reflect off the
* surface in the opposite Y direction
*/
Boundary possibleTopBoundary = (Boundary)( getOneObjectAtOffset(0,-4,Boundary.class) );
Boundary possibleBottomBoundary = (Boundary)( getOneObjectAtOffset(0,4,Boundary.class) );
if ( possibleTopBoundary != null || possibleBottomBoundary != null )
{
getMovement().revertVertical();
playField.playLowBlip();
} // end if
// check if the ball has passed the player's paddle
if ( getExactX() <= 0 )
{
playField.updateScore( PLAYER_TWO );
// TODO: Since this code is duplicated elsewhere, I probably
// should move it into a separate method in this class
setLocation( playField.GAME_WIDTH / 2, playField.GAME_HEIGHT / 2 );
getMovement().setNeutral();
getMovement().add( new Vector( -45 + Greenfoot.getRandomNumber( 90 ), 3.0 ) );
if ( Greenfoot.getRandomNumber( 2 ) == 0 )
{
getMovement().revertHorizontal();
} // end inner if
playField.playLongBeep();
} // end outer if
// check if the ball has passed the CPU's paddle
if ( getExactX() >= playField.GAME_WIDTH )
{
playField.updateScore( PLAYER_ONE );
// TODO: Since this code is duplicated elsewhere, I probably
// should move it into a separate method in this class
setLocation( playField.GAME_WIDTH / 2, playField.GAME_HEIGHT / 2 );
getMovement().setNeutral();
getMovement().add( new Vector( -45 + Greenfoot.getRandomNumber( 90 ), 3.0 ) );
if ( Greenfoot.getRandomNumber( 2 ) == 0 )
{
getMovement().revertHorizontal();
} // end inner if
playField.playLongBeep();
} // end outer if
}
else if ( playField.getGameStatus() == Status.GAME_OVER )
{
playField.removeObject( this );
} // end multiway if/else
} // end method act
} // end class Ball