-1

I am programming Atari Breakout in VB.NET, and I need to program my ball to detect collisions with the paddle, blocks, and the edges of the gameboard. I have written out a small piece of code, but I am unsure of what to do next. Essentially, when the ball touches either the blocks, the paddle, or the edges of the game board, it needs to bounce off of it and move in a different direction. For the moment I am only focusing on the vertical movement of the ball, so the ball will move down, but then must move upwards when it hits the paddle.

The way I am moving the picturebox I am using as the ball is by setting up a timer, and every time the timer ticks, the ball will move at a certain pace. To achieve this, I use the following piece of code:

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Ball.Top += 10
End Sub

This piece of code can be adjusted to get the ball to move different directions. So for example, I can change the plus to a minus to get the ball to move upwards, and I can also use Ball.Left to control sideways movement. I can even combine the two together to get diagonal movement. I can also edit the speed at which the ball moves. Right now it is on 10, which is more than fast enough for the game I am making.

What I want to do is program the ball so that, when it is touching another object (in this case, a picturebox, which I am using as my paddle), the direction of travel is reversed, so it will move upwards instead of downwards. I tried to do this in the code written below, however this does not work as the ball simply stops when it gets close to the paddle, and won't move until I move the paddle, only for it to keep moving downwards.

Here is the code I have written:

Private Sub Ball_Move(sender As Object, e As EventArgs) Handles Ball.Move    
    If Ball.Bounds.IntersectsWith(Platform.Bounds) Then        
        Ball.Top -= 10    
    End If
End Sub

UPDATE:

I thought I'd quickly edit this just so I can show what I'm trying to do more clearly, as my code goes over the character limit for comments.

First of all, I'd like to thank @jmcilhinney for sharing the code. When I tried to use it in my program however, it didn't work properly. I tried to place it within the subroutine I am using for the movement of the ball (posted in my initial question, uses a timer to allow the ball to move). The main issue is that, when the program is run, the ball goes straight past my paddle, which is a green PictureBox at the location of 318, 397. Another issue is that, when I added the code to my program, it showed a lot of errors. Some of which I was able to amend using the quick actions menu, but some I was not able to amend. I've tried to move the code to different parts of the same subroutine to no avail. Here is the subroutine with the collision code in it that is giving me the errors:

 Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    'Direction of movement. +1 is down and -1 is up.

    Private direction As Integer = &B1
Private Sub MoveControl(ctrl As Control)
    Dim direction As Integer = Nothing
    'Move the control is the current direction.
    ctrl.Top += direction * 10

    'If the control has reached the top or the bottom of the form...
    If ctrl.Top <= 0 OrElse ctrl.Bottom >= ClientSize.Height Then
        '...reverse the direction.
        direction *= -1
    End If
End Sub
    Ball.Top += 10
End Sub
End Class

Some sections of the code look different to the code that was posted in @jmcilhinney's answer, but that is because I had to use the quick actions and refactorings menu to change some parts of the code so as to not give me any errors. I may have done something wrong here, because the code just doesn't seem to be working for me.

These are the errors I have with this code: Line 1 has error code BC30026, Line 4 has error code BC30247, Line 5 has error code BC30289, Line 15 has error code BC30188, Line 16 has error code BC30429.

UPDATE 2: I've managed to figure out something that has reduced the number of errors present in my program. What I've done is moved the piece of code calling the Timer subroutine to be after the 'Private direction As Integer' line. My code has gone from having five errors down to just two. Here is the code with the change I have made:

    'This part of the code uses a timer to allow to the ball to move. It moves in a certain direction at a certain speed with every tick.'
    Private increment As Integer = 10

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Private Sub MoveControl(ctrl As Control)
        ctrl.Top += increment

        If ctrl.Top <= 0 OrElse ctrl.Bottom >= ClientSize.Height Then
            increment *= -1
        End If
    End Sub
End Class

My first error is present on line 3 (Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick). Here, I am getting error BC30026 'End Sub expected', and the other error I am getting is on line 4 (Private Sub MoveControl (ctrl as Control)). Here, I am getting error BC30289 'Statement cannot appear within a method body. End of method assumed.' However, when I tried to move that particular piece of code outside of the method, I got error BC30026 'End Sub expected.' I am so confused on what to do next. I am still relatively new to VB and I haven't tried something like this before, so this is probably why I am doing everything so wrong. Thanks to jmcilhinney for all the help so far, including providing me with code. I appreciate it a lot!

I should also mention that the code I used here is the second piece of code jmcilhinney posted, rather than the first one. That's why it is slightly different.

sam-hobbs
  • 19
  • 7
  • 1
    You need to provide a clear problem statement. What you have is too vague/broad. – jmcilhinney Jun 09 '21 at 10:27
  • 2
    I can find [at least](https://stackoverflow.com/questions/345838/ball-to-ball-collision-detection-and-handling?rq=1) three [relevant](https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection?rq=1) questions [in the 'related'](https://stackoverflow.com/questions/1073336/circle-line-segment-collision-detection-algorithm?rq=1) section alone. Search before you ask. – RobIII Jun 09 '21 at 10:28
  • @jmcilhinney the problem I have is how to make a picturebox bounce off of another picturebox. – sam-hobbs Jun 09 '21 at 10:29
  • 1
    You shouldn't be using pictureboxes in the first place but that's another problem. Your problem statement is (still) to vague. See [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) – RobIII Jun 09 '21 at 10:30
  • 1
    Firstly, you don't provide your problem statement in comments. You provide a FULL and CLEAR explanation in the question, which means editing it if you have to. Secondly, that's not a clear problem statement anyway. It needs to ne a programming problem. `PictureBoxes` don't bounce so that's not a problem. If what you actually want is to reverse the direction of movement of a control when some condition is true then that's what you should say, but that would require you to show us how you're moving it in any direction in the first place. BE SPECIFIC. – jmcilhinney Jun 09 '21 at 10:42
  • @jmcilhinney I have edited it to include how I move the ball and what I am trying to get my program to do. Hopefully it looks better now and is clearer. – sam-hobbs Jun 09 '21 at 11:00
  • 1
    First you need some variable(s) to store movement direction. Then you need alter those variables after bounce. Then... - you already understood, yes? :) – Arvo Jun 09 '21 at 11:41
  • I have included some updates to my post that shows how I implemented @jmcilhinney's code into my program and the errors I am receiving. I'd appreciate if someone could please advise me on how to fix these errors because I have no idea what to do. – sam-hobbs Jun 23 '21 at 08:50
  • Well, you made a right mess of that. Firstly, you provided a bunch of error codes, which is a decent start, but no error messages. We shouldn't have to search online to find out what those codes mean when you already know. As for the code, it makes no sense. You've one one method inside another. What would possibly give you the impression that that would be a good idea, or possible? I provided you with a method that moves a control. If you want to move a control every time a `Timer` `Ticks`, call that method from the `Tick` event handler. Not sure how that wasn't obvious. – jmcilhinney Jun 23 '21 at 12:33
  • Also, why do you have two different `direction` variables and neither of them are set to the values that I specifically stated in the comment that you quoted? – jmcilhinney Jun 23 '21 at 12:34
  • Because I got an error saying that 'Private is not valid on a local variable declaration' on the line containing the 'Private direction as Integer' code, and the only refactoring were to either convert the value to hex or to binary. I have no idea what I'm doing wrong. I'm placing the code within the Timer subroutine (Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick), and I'm getting a bunch of errors. This is the first time I've ever tried to code something that reverses the direction of travel of an object when it touches something, and I'm getting it wrong. – sam-hobbs Jun 25 '21 at 09:59
  • UPDATE: I've managed to figure SOMETHING out. What I have done is moved the Timer subroutine to after the 'Private increment As Integer' section. However, I still have 2 errors: On the 2nd line I have error BC30026 'End Sub expected', and on line 3 I have error BC30289 'Statement cannot appear within a method body. End of statement assumed.' I'll make an update to my post to show what I've changed. I'm sorry that I keep bugging you, but I'm just really stuck on this one step. – sam-hobbs Jun 25 '21 at 10:19

1 Answers1

1

If you want to move the control by 10 pixels each time but you want the direction to change then the easiest option is to simply have a multiplier of +/- 1 that you flip the sign of each time the appropriate condition is True. Here's a simple example that will move the specified control up and down the form between the top and the bottom:

'Direction of movement. +1 is down and -1 is up.
Private direction As Integer = 1

Private Sub MoveControl(ctrl As Control)
    'Move the control is the current direction.
    ctrl.Top += direction * 10

    'If the control has reached the top or the bottom of the form...
    If ctrl.Top <= 0 OrElse ctrl.Bottom >= ClientSize.Height Then
        '...reverse the direction.
        direction *= -1
    End If
End Sub

EDIT:

I guess you could just store the increment in the field and change the sign of that. I was thinking to keep the direction and the increment separate but there's probably no need for that:

Private increment As Integer = 10

Private Sub MoveControl(ctrl As Control)
    ctrl.Top += increment

    If ctrl.Top <= 0 OrElse ctrl.Bottom >= ClientSize.Height Then
        increment *= -1
    End If
End Sub
jmcilhinney
  • 50,448
  • 5
  • 26
  • 46
  • I tried the bottom piece of code, however I am getting some errors. I got error code BC30734 on line 4, and it said that 'ctrtl' was already a parameter of that method. I also got error code BC30205 on line 4 as well, saying that the end of the statement was expected. Is there a way to fix either of these? – sam-hobbs Jun 10 '21 at 13:58
  • Sorry, those `Dim` keywords shouldn't have been there. That's what I get for writing code directly instead of in VS and copy/pasting. – jmcilhinney Jun 10 '21 at 14:19
  • I tried both of the pieces of code after the Dim keywords had been removed. Unfortunately, neither piece of code worked. The program ran fine and the code executed, but the ball simply went straight past the platform without anything happening, whereas it should've touched the paddle and then gone in the opposite direction. – sam-hobbs Jun 16 '21 at 10:52
  • I know for a fact that the code I provided works. I have tested it with a `Button` calling the `MoveControl` method in the`Tick` event handler of a `Timer`. It demonstrates a principle and it does it successfully. If you tried to write code that uses the same principle in a specific scenario and it didn't work then you did it wrong. If you don't show us what you did then we can't tell you what you did wrong. In my code, I change the direction from down to up when the `Bottom` of the control reaches a threshold. In your case, that threshold would be the top of your paddle, whatever that is. – jmcilhinney Jun 16 '21 at 11:10
  • I made a post here yesterday explaining how I implemented the code into my program and what errors showed up, along with what the code actually did when the program was executed. – sam-hobbs Jun 17 '21 at 12:59