1+ class Ball {
2+
3+ float radius = 10 ;
4+ Body body;// the body representing the ball in the box2d world
5+ boolean isWhite = false ;
6+ boolean stopped = true ; // has the ball stopped or is it still moving
7+ Box2DProcessing world;
8+ boolean sunk = false ;// whether the ball is sunk or not
9+ color colour;// colour of the ball
10+
11+ // ------------------------------------------------------------------------------------------------------------------------------------------------------------------
12+ // constructor
13+ Ball (float x , float y , Box2DProcessing box2d , color col ) {
14+
15+ colour = col;
16+ world = box2d;
17+ Vec2 pos = new Vec2 (x, y);
18+
19+
20+ float r = world. scalarPixelsToWorld(radius);// convert the radius to world coordinates
21+
22+ // CREATE BODY DEFINITION
23+ BodyDef df = new BodyDef ();
24+ df. type = BodyType . DYNAMIC ;
25+ df. position. set(world. coordPixelsToWorld(pos. x, pos. y));
26+
27+ // APPPLY IT TO THE BODY
28+ body = world. createBody(df);
29+
30+
31+ // CREATE SHAPE AS CIRCLE
32+ CircleShape circle = new CircleShape ();
33+ circle. setRadius(r);
34+
35+ // CREATE FIXTURE
36+ FixtureDef fd = new FixtureDef ();
37+ fd. shape = circle;
38+ fd. density = 0.0000001 ;// very low density
39+ fd. friction = 0.001 ;// low friction
40+ fd. restitution = 0.8 ;// high bounciness
41+
42+ // FIX THE SHAPE TO THE BODY;
43+ body. createFixture(fd);
44+ }
45+ // ------------------------------------------------------------------------------------------------------------------------------------------------------------------
46+ void applyFriction () {// called every step to simulate friction between the table and ball
47+ Vec2 vel = body. getLinearVelocity();
48+ vel. mulLocal(0.98 );// slow by 2%
49+ if (vel. length() < 4 ) {// increase friction when slower
50+ vel. mulLocal(0.98 );
51+ }
52+ if (vel. length() < 0.1 ) {// stop the ball if the speed is slow enough because without this the speed will never reach 0
53+ vel. mulLocal(0 );
54+ }
55+ }
56+
57+ // ------------------------------------------------------------------------------------------------------------------------------------------------------------------
58+ // whether the ball is in a hole or not
59+ boolean isInHole () {
60+ if (sunk) {// if ball is already sunk then problem solved
61+ return true ;
62+ }
63+ Vec2 pos = world. getBodyPixelCoord(body);// get the position and if its within 15 of a holes center then it is sunk
64+ for (int i = 0 ; i < 6 ; i++ ) {
65+ if (dist (pos. x, pos. y, tables[0 ]. holes[i]. pos. x, tables[0 ]. holes[i]. pos. y) < 15 ) {
66+ Vec2 vel = body. getLinearVelocity();
67+ vel. mulLocal(0 );// set speed to 0
68+ sunk = true ;
69+ world. destroyBody(body);// remove ball from world
70+ return true ;
71+ }
72+ }
73+ return false ;
74+ }
75+
76+ // ------------------------------------------------------------------------------------------------------------------------------------------------------------------
77+ boolean isStopped () {// is the ball stopped
78+
79+ if (body. getLinearVelocity(). length() == 0 ) {
80+ return true ;
81+ } else {
82+ return false ;
83+ }
84+ }
85+ // ------------------------------------------------------------------------------------------------------------------------------------------------------------------
86+ void update () {// update ball (kind of useless but I though I would do more than just apply friction each update)
87+ applyFriction();
88+ }
89+ // ------------------------------------------------------------------------------------------------------------------------------------------------------------------
90+ // draw a circle representing the ball
91+ void show () {
92+ if (! sunk) {// if sunk then dont bother showing it
93+ Vec2 pos = world. getBodyPixelCoord(body); // get position
94+
95+ pushMatrix ();
96+ translate (pos. x, pos. y);
97+ if (isWhite) {// choose colour
98+ fill (255 );
99+ } else {
100+ fill (colour);
101+ }
102+ noStroke ();
103+ ellipse (0 , 0 , 2 * radius, 2 * radius);// draw ball
104+ popMatrix ();
105+ }
106+ }
107+ // ------------------------------------------------------------------------------------------------------------------------------------------------------------------
108+ // simulates a shot
109+ void applyForce (Vec2 force ) {
110+ Vec2 scaledForce = new Vec2 (force. x, force. y);
111+ scaledForce. mulLocal(500000 );
112+ body. applyForce(scaledForce, body. getWorldCenter());// apply force on ball
113+ }
114+
115+ // ---------------------------------------------------------------------------------------------------------------------------------------------------------------
116+ // creates and returns a clone of this ball object in the parameter world
117+ Ball clone (Box2DProcessing World ) {
118+
119+ Vec2 pos = World . getBodyPixelCoord(body);// get pixel coord
120+ Ball clone = new Ball (pos. x, pos. y, World , colour);
121+
122+ clone. isWhite = isWhite;
123+ clone. sunk = sunk;
124+ if (sunk) {// if the ball is sunk then remove the body from the world
125+ World . destroyBody(clone. body);
126+ }
127+ return clone;
128+ }
129+ }
0 commit comments