This site requires JavaScript, please enable it in your browser!
Greenfoot back
Frost.D
Frost.D wrote ...

2016/11/3

Need Help With My Pong Inspired Game

Frost.D Frost.D

2016/11/3

#
So I recently started an endeavor to recreate pong with my own little twists. So I added three internal walls that are their own actors, one moves up the other two down and they hit the walls and come back the other way. I have created goals. A top barrier wall, lower barrier wall, and goal barriers(4 of them, each is the same actor), and two paddles. My issue is with the ball. The ball bounces off the walls and paddles relatively good, however, it gets stuck, gets launched out of the world, or rotates in the same spot for awhile then launches out again. Here is the code I am using for the ball and its interactions with other objects outside of the goals.
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
public void ballHitSomething()
    {
        if(isAtEdge())
        {
            turn(Greenfoot.getRandomNumber(541)+getRotation());
        }
        if (isTouching(LeftPaddle.class))
        {
             
            turn(Greenfoot.getRandomNumber(541)-getRotation());
        }
        if (isTouching(RightPaddle.class))
        {
            turn(Greenfoot.getRandomNumber(541)-getRotation());
        }
        if (isTouching(TopWall.class))
        {
           turn(Greenfoot.getRandomNumber(361)-getRotation());
        }
        if (isTouching(BottomWall.class))
        {
            turn(Greenfoot.getRandomNumber(361)+getRotation());
        }
        if (isTouching(WallMiddle.class))
        {
             
            turn(Greenfoot.getRandomNumber(541)+getRotation());
        }
        if (isTouching(WallRight.class))
        {
            
            turn(Greenfoot.getRandomNumber(541)+getRotation());
        }
        if (isTouching(WallLeft.class))
        {
             
            turn(Greenfoot.getRandomNumber(541)+getRotation());
        }
        if (isTouching(GoalBarrier.class))
        {
            turn(Greenfoot.getRandomNumber(541)+getRotation());
        }
    }
Frost.D Frost.D

2016/11/3

#
Any suggestions on different code to make it so the ball doesn't freak out or better code for interactions to make it appear to bounce off the paddles and walls?
danpost danpost

2016/11/3

#
Frost.D wrote...
Any suggestions on different code to make it so the ball doesn't freak out or better code for interactions to make it appear to bounce off the paddles and walls?
You will need to show all codes for the ball that relate to movement as well as turning (and showing the declaration lines for related fields as well). The freaking out is due to movement that does not cause separation between the actors.
Frost.D Frost.D

2016/11/3

#
1
2
3
4
5
6
public void act()
    {
        move(6);
        hitEdge();
        ballHitSomething();
    }
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
public void hitEdge()
    {
        if (isTouching(RightGoal.class))
        {
            setLocation(426,225);
            //int rand = Greenfoot.getRandomNumber(2);
             
            World myWorld = getWorld();
            Background background = (Background)myWorld;
            RightCounter counter = background.getCounter();
            //LeftCounter leftCounter = background.getLeftCounter();
            counter.addRightScore();
            //leftCounter.addLeftScore();
            setRotation(180);
             
        }
        if (isTouching(LeftGoal.class))
        {
            setLocation(426,225);
            //int rand = Greenfoot.getRandomNumber(2);
             
            World myWorld = getWorld();
            Background background = (Background)myWorld;
            //RightCounter counter = background.getCounter();
            LeftCounter leftCounter = background.getLeftCounter();
            //counter.addRightScore();
            leftCounter.addLeftScore();
             
             
           setRotation(0);
             
        }
    }
Super_Hippo Super_Hippo

2016/11/3

#
To make the ball bounce off the obstacles, you could move x and y separately and check which movement caused the intersection. So for example if the x movement caused the intersection (= wall left or right), the rotation would be set like this:
1
setRotation(-getRotation());
and for y it is this:
1
setRotation(180-getRotation());
Frost.D Frost.D

2016/11/3

#
Super_Hippo wrote...
To make the ball bounce off the obstacles, you could move x and y separately and check which movement caused the intersection. So for example if the x movement caused the intersection (= wall left or right), the rotation would be set like this:
Could you explain how I could move the x and y separately? How do I check for this intersection?
danpost danpost

2016/11/3

#
If you split the movement into horizontal and vertical distances and then moved each way separately, checking for edge and objects individually for each direction, it would be a simple task to change the direction along the respective axis. The basic parts would be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// splitting the move from 'move(dist)' to 'setLocation(getX()+dx, getY()+dy)'
int dist = 6;
int dx = (int)((double)dist*Math.cos(Math.PI*getRotation()/180));
int dy = (int)((double)dist*Math.sin(Math.PI*getRotation()/180));
 
// moving horizontally
setLocation(getX()+dx, getY());
/** edge and object/goal collision checking */
 
// if edge or non-goal object collision
dx = -dx;
setLocation(getX()+dx, getY()); // move back off object
 
// moving vertically
setLocation(getX(), getY()+dy);
/** edge and object collision */
// if edge or object collision
dy = -dy;
setLocation(getX(), getY()+dy); // move back off object
 
// new angle for any non-goal collision
setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
With this set-up, you could probably just use:
1
if ( ! getIntersectingObjects(null).isEmpty())
for the initial check for all types of intersecting objects. Along the x-axis , if this is true, then check specifically for LeftGoal and RightGoal objects.
Frost.D Frost.D

2016/11/4

#
From what you gave me I was able to do this with my moving of the ball. However, it seems to only want to go to one corner and not bounce unless I have a setRotation outside of the ifs but then it never moves and bounces back and forth along the same path.
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
public void act()
    {
        //move(6);
        hitEdge();
        //ballHitSomething();
         
        // splitting the move from 'move(dist)' to 'setLocation(getX()+dx, getY()+dy)'
       int dist = 6;
       int dx = (int)((double)dist*Math.cos(Math.PI*getRotation()/180));
       int dy = (int)((double)dist*Math.sin(Math.PI*getRotation()/180));
        
       // moving horizontally
       setLocation(getX()+dx, getY());
       /** edge and object/goal collision checking */
  
       // if edge or non-goal object collision
       if(isTouching(TopWall.class))
       {
        dx = -dx;
        setLocation(getX()+dx, getY()); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(BottomWall.class))
       {
        dx = -dx;
        setLocation(getX()+dx, getY()); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(WallLeft.class))
       {
        dx = -dx;
        setLocation(getX()+dx, getY()); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(WallMiddle.class))
       {
        dx = -dx;
        setLocation(getX()+dx, getY()); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(WallRight.class))
       {
        dx = -dx;
        setLocation(getX()+dx, getY()); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(GoalBarrier.class))
       {
        dx = -dx;
        setLocation(getX()+dx, getY()); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(LeftPaddle.class))
       {
        dx = -dx;
        setLocation(getX()+dx, getY()); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(RightPaddle.class))
       {
        dx = -dx;
        setLocation(getX()+dx, getY()); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
        
       //dx = -dx;
       //setLocation(getX()+dx, getY()); // move back off object
  
       // moving vertically
       setLocation(getX(), getY()+dy);
       /** edge and object collision */
       // if edge or object collision
       if(isTouching(TopWall.class))
       {
        dy = -dy;
        setLocation(getX(), getY()+dy); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
        if(isTouching(BottomWall.class))
       {
        dy = -dy;
        setLocation(getX(), getY()+dy); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(WallLeft.class))
       {
        dy = -dy;
        setLocation(getX(), getY()+dy); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(WallMiddle.class))
       {
        dy = -dy;
        setLocation(getX(), getY()+dy); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(WallRight.class))
       {
        dy = -dy;
        setLocation(getX(), getY()+dy); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(GoalBarrier.class))
       {
        dy = -dy;
        setLocation(getX(), getY()+dy); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(LeftPaddle.class))
       {
        dy = -dy;
        setLocation(getX(), getY()+dy); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       if(isTouching(RightPaddle.class))
       {
        dy = -dy;
        setLocation(getX(), getY()+dy); // move back off object
        setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
       }
       //dy = -dy;
       //setLocation(getX(), getY()+dy); // move back off object
  
       // new angle for any non-goal collision
       //setRotation((int)(Math.atan2(dx, dy)*180/Math.PI));
 
    }
danpost danpost

2016/11/4

#
I was thinking of something more along these lines (this is not equivalent to your new code as you have made some major changes):
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
public void move(int dist)
{
    boolean scored = false;
    int x = Math.cos(getRotation()*Math.PI/180);
    int y = Math.sin(getRotation()*Math.PI/180);
    setLocation(getX()+x, getY());
    if (!getIntersectingObjects(null).isEmpty() || getX() < getImage().getWidth()/2 || getX() > getWorld().getWidth()-getImage().getWidth()/2)
    {
        if (isTouching(LeftGoal.class))
        {
            ((Background)getWorld()).getLeftCounter().addLeftScore();
            scored = true;
            setRotation(0);  
        }
        else if (isTouching(RightGoal.class))
        {
            ((Background)getWorld()).getCounter().addRightScore();
            scored = true;
            setRotation(180);  
        }
        setLocation(getX()-x, getY());
        x = -x;
    }
    setLocation(getX(), getY()+y);
    if (!getIntersectingObjects(null).isEmpty() || getY() < getImage().getHeight()/2 || getY() > getWorld().getHeight()-getImage().getHeight()/2)
    {
        setLocation(getX(), getY()-y);
        y = -y;
    }
    if ( ! scored )
    {
        setRotation((int)(Math.atan2(x, y)*180/Math.PI));
    }
}
Your act method should then be able to just use:
1
move(6);
for moving, turning, collision and edge checks, plus goal checks. (this code was not tested)
You need to login to post a reply.