I'm making a game. Essentially there is a boat on the sea and it goes places. Yadeeyadeeya. You get it.
I'm using KeyDown to get the picturebox to move around, but I don't know how to keep the boat within the boundaries of the form. So if it hits the side of the form, I want it to just stop.
You can simply just get the location of the picturebox and the size of the container and write an if statement. Add the size of the picturebox with the location to get the right or bottom location of the picture box for when you are trying to move right or down. The left and top, just check that it is greater than or equal to 0.
So here's a Boolean method to check if it is within bounds. example:
'the futurePosition is the location where the obj would be if it was to move
'the objMoving would be the size of your picturebox in this case
'you may want to use ClientSize for the container
Private Function moveIsInBounds(ByVal futurePosition As Point, ByVal objMoving As Size, ByVal container As Size) As Boolean
Dim xInBounds As Boolean = (futurePosition.x >= 0) AndAlso (futurePosition.x + objMoving.Width <= container.Width)
Dim yInBounds As Boolean = (futurePosition.y >= 0) AndAlso (futurePosition.y + objMoving.Height <= container.Height)
If xInBounds AndAlso yInBounds Then
Return True
Else
Return False
End If
End Function
Call that method somewhere like in your if statement to decide whether or not you want to move the obj. Instead of using Me.Size to get the size of the form you can use ClientSize. Since if your form has a border you are going to need an offset, but ClientSize will get just the size of the space you have to work with.
I have another question. I want to have another picturebox move up and down (enemy ship on patrol) and change direction when it hits the form boundaries (top and bottom of forum).
I'm currently trying to get it to work using a timer and a case/If statement. But I was also trying to do something with a Do Loop While, but I can't seem to figure it out.
Can you elaborate what your having trouble with exactly?
It sounds like you got the idea... so just write a method that moves the picturebox on every tick event.. if it is in bounds move it, if it is at one of the sides reverse direction..
Private Sub tmrBad1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrBad1.Tick
If (Me.picBad1.Top - 10) < 0 Then
picBad1.Top += 10
ElseIf (Me.picBad1.Top - 10) > 0 Then
picBad1.Top -= 10
End If
End Sub
Well I was doing some more research, and I found out *possibly* a better way to keep it in bounds, so I'm trying it on these "sprites".
So I want this enemy ship to bounce back and forth from the top of the form to the bottom. I put it on a timer so that the PictureBox moves upwards at an interval. When it hits the top, it goes down , but then the first part of the If statement draws it back upward once it gets too far away from the top of the form.
It's kind of "caught" up against the top of the form, going down one, and then up one, and then down one, and then up one....because of the If statement.
So I thought I would do a Loop While somehow....
VB.NET:
Private Sub tmrBad1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrBad1.Tick
If (Me.picBad1.Top - 10) Then
Do
Me.picBad1.Top -= 10
Loop While (Me.picBad1.Top - 10) > 0
Else
Do
Me.picBad1.Top += 10
Loop While (Me.picBad1.Top + Me.picBad1.Height + 10) < Me.ClientRectangle.Bottom
End If
End Sub
But this doesn't work either. I was never too good with Do Loops.
Do you (or anyone else) have a recommendation on how to do this? It's kind of like playing pong I guess...but endlessly.
Private Sub tmrBad1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrBad1.Tick
If (Me.picBad1.Top - 10) < 0 Then
picBad1.Top += 10
ElseIf (Me.picBad1.Top - 10) > 0 Then
picBad1.Top -= 10
End If
End Sub
.. bounce back and forth from the top of the form to the bottom. I put it on a timer so that the PictureBox moves upwards at an interval. When it hits the top, it goes down...
It's kind of "caught" up against the top of the form, going down one, and then up one, and then down one, and then up one....because of the If statement.
To make your tick method work, i think the easiest thing to do is to make a boolean that is of class-level scope. Store the direction it is moving in that boolean. So heres a simple example to make your method work.
Private moveUp As Boolean = True
Private moveSpeed As Integer = 5
Private Sub tmrBad1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrBad1.Tick
If moveUp Then
If (Me.picBad1.Top - moveSpeed) > 0 Then
Me.picBad1.Top -= moveSpeed
Else
moveUp = False
End If
Else
If (Me.picBad1.Top + Me.PictureBox1.Height + moveSpeed) < Me.ClientRectangle.Bottom Then
Me.picBad1.Top += moveSpeed
Else
moveUp = True
End If
End If
End Sub
the loop method you tried:
So I thought I would do a Loop While somehow....
VB.NET:
Private Sub tmrBad1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrBad1.Tick
If (Me.picBad1.Top - 10) Then
Do
Me.picBad1.Top -= 10
Loop While (Me.picBad1.Top - 10) > 0
Else
Do
Me.picBad1.Top += 10
Loop While (Me.picBad1.Top + Me.picBad1.Height + 10) < Me.ClientRectangle.Bottom
End If
End Sub
This has the same kinda logic error, also the first if statement does not return a (true or false - you forgot to compare the result with 0 or whatever), if you use a boolean like the above e.g. it should work. However, note that if you are using a loop you will lose your control over the speed of it moving up/down. Although you can add a timer or some kind of thread sleep/wait, that should be down outside of the tick event if you wanted to use a loop. The timer is already looping in a way since that tick event will be called ever 0.001 second or whatever interval you set, until you stop the timer. This way to change the speed of the movement you can just change the timer interval and/or the amount it moves each time.
i recommend that you use some kind of timer to control the speed, there is no need for a loop like that inside of the tick event.
Do you (or anyone else) have a recommendation on how to do this? It's kind of like playing pong I guess...but endlessly.
I think the way you are doing it with the timer is fine, i think it should be sufficient. If you can explain a bit more on the functionality or gameplay of this maybe someone or i can make a better recommendation? I'm not sure what topics you are familiar with in programming either, so a bit of
So think of a guard on patrol. Its going from the top to bottom and keeps on doing that. Here's a new idea that uses two timers....
I think this would be the best option, but once the picturebox hits the top of the form, it stops there and doesn't switch over to the other timer and go down. So it just goes up and stops. I've asked some of my friends who code, and we thought this would work well, but it doesn't.
Any ideas? Tmr1 is enabled on default. Tmr2 is disabled. However, it still doesn't work if I turn one on or the other etc.
VB.NET:
Private Sub tmrBad1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrBad1.Tick
Dim blnTop As Boolean
If blnTop = True Then
tmrBad2.Start()
tmrBad1.Stop()
End If
If Me.picBad1.Location.Y < 0 Then
blnTop = True
Else
Me.picBad1.Top -= 10
End If
End Sub
Private Sub tmrBad2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrBad2.Tick
Dim blnBottom As Boolean
If blnBottom = True Then
tmrBad1.Stop()
tmrBad2.Start()
End If
If Me.picBad1.Location.Y < 480 Then
blnBottom = True
Else
Me.picBad1.Top += 10
End If
End Sub
Looking at your code from a glance, it seems like the issue is probably your boolean. It appears that the boolean you declared is only visible in that method, the scope of the variable is just inside the method it is declared. Once that method finish executing and the tick event fires again blnTop is recreated and you are not really storing the value anywhere.
Try declaring your boolean's in the class level, and also you may want to check that the location is <= 0, since it could be equal to 0 if the picture started at 0,0
Working Sample using two timers, Moves image up and down continously
Here's a quick example using two timers but without a boolean. It doesn't necessary need a boolean, just an if statement is enough.
Here's a quick explanation about the logic behind it. You have two timers. Lets call them TimerDown and TimerUp, makes more sense. Timer up will check to see that if the image is moved, will it exceed the height of the form? if it does then don't move it and turn the timer off. Then start the TimerDown.
TimerDown does the exact opposite. If you wanted to, like i suggested, using one timer and one boolean is probably a better idea, this way you do not have redundant/similar code with slight differences, but it depends on your situation and how you want to write it.
Here's a sample (tested working code):
Public Class Form1
Inherits System.Windows.Forms.Form
Private imgBall As New Bitmap(50, 50)
Private rateOfMovement As Integer = 10
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim g As Graphics = Graphics.FromImage(imgBall)
g.FillEllipse(Brushes.Aqua, New Rectangle(0, 0, 25, 25))
g.Dispose()
g = Nothing
picBall.Image = imgBall
timerUp.Start()
End Sub
'this moves pic up
Private Sub timerUp_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerUp.Tick
If (Me.picBall.Location.Y - rateOfMovement) < 0 Then
timerDown.Start()
timerUp.Stop()
Else
Me.picBall.Top -= rateOfMovement
End If
End Sub
'moves pic down
Private Sub timerDown_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerDown.Tick
If (Me.picBall.Location.Y + rateOfMovement + Me.picBall.Height) > ClientSize.Height Then
timerUp.Start()
timerDown.Stop()
Else
Me.picBall.Top += rateOfMovement
End If
End Sub
#Region "GUI Related"
Private components As System.ComponentModel.IContainer
Friend WithEvents picBall As System.Windows.Forms.PictureBox
Friend WithEvents timerUp As System.Windows.Forms.Timer
Friend WithEvents timerDown As System.Windows.Forms.Timer
Sub New()
InitializeComponent()
End Sub
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Me.picBall = New System.Windows.Forms.PictureBox()
Me.timerUp = New System.Windows.Forms.Timer(Me.components)
Me.timerDown = New System.Windows.Forms.Timer(Me.components)
CType(Me.picBall, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
Me.picBall.Image = Nothing
Me.picBall.Location = New System.Drawing.Point(0, 0)
Me.picBall.Size = New System.Drawing.Size(33, 33)
Me.picBall.TabIndex = 0
Me.picBall.TabStop = False
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(278, 194)
Me.Controls.Add(Me.picBall)
CType(Me.picBall, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
#End Region
End Class
You probably have other code then? If you need help with that, please post what is relevant. The example i posted above is a working example. I just updated it with the GUI, this way you can copy and paste into a vb file and run the form.
I'm doing a simple animation using an array of pictures. It works fine, but I'm going to need to be able to play this on computers that are not mine, and do not have my files (pictures) on them.
I've been trying a lot of things, but it seems that there's no easy way around it. I've tried resources, putting the pictures in different folders etc....but if I send it to my friend and he tries opening the .exe, when this animation tries to initiate, the program breaks because the files cannot be found.
I'm doing a simple animation using an array of pictures. It works fine, but I'm going to need to be able to play this on computers that are not mine, and do not have my files (pictures) on them.
Please see the documentation MSDN has about using resources. If you are using them correctly they should be in the exe. See the links at the bottom of the page too.
MSDN has detailed instructions on how to add/remove and use them, i do not know what version you have but on the top of the page you can change the version so you get instructions that match yours.
I use 2010, for the most part i think its the same in 2008. Go to properties by right clicking on your solution in the 'Solution Explorer' or double clicking on 'My Project'. Then go to the resources tab. Import the resource images by clicking on 'Add Resource' > 'Add Exisiting File...' > select the files you want to add.
Then in your code when using the resources, use the My.Resources.RESOURCENAMEHERE to access it.
ex. (using images i added to my project)
Dim imgs() As Image = {My.Resources.clickherebutton, My.Resources.clickherebutton_MD}
When you compile the files, and go to your release/debug bin, those exe's should have the resources in them.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.