I am trying to make a game in Win forms using VB from scratch which i know is a bad idea but i like the challenge. Therefore i have been testing movement systems so i can choose my favourite , however i have ran into an issue as trying to move with a picture box as when i press the movement key the picture box just starts erasing the image in the direction i wanted to move until it disappears.
I am using
Public Class Form1
Dim RightM As Boolean
Dim LeftM As Boolean
Dim UpM As Boolean
Dim DownM As Boolean
Sub Movement()
Do While UpM = True
PictureBox1.Top += -5
Threading.Thread.Sleep(20)
Loop
Do While LeftM = True
PictureBox1.Left += -5
Threading.Thread.Sleep(20)
Loop
Do While DownM = True
PictureBox1.Top += 5
Threading.Thread.Sleep(20)
Loop
Do While RightM = True
PictureBox1.Left += 5
Threading.Thread.Sleep(20)
Loop
Do While (UpM = True) And (RightM = True)
PictureBox1.Top += -5
PictureBox1.Left += 5
Threading.Thread.Sleep(20)
Loop
Do While (UpM = True) And (LeftM = True)
PictureBox1.Top += -5
PictureBox1.Left += -5
Threading.Thread.Sleep(20)
Loop
Do While (DownM = True) And (RightM = True)
PictureBox1.Top += 5
PictureBox1.Left += 5
Threading.Thread.Sleep(20)
Loop
Do While (DownM = True) And (LeftM = True)
PictureBox1.Top += 5
PictureBox1.Left += -5
Loop
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.A Then
LeftM = True
Movement()
ElseIf e.KeyCode = Keys.D Then
RightM = True
Movement()
ElseIf e.KeyCode = Keys.W Then
UpM = True
Movement()
ElseIf e.KeyCode = Keys.S Then
DownM = True
Movement()
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If e.KeyCode = Keys.A Then
LeftM = False
Movement()
ElseIf e.KeyCode = Keys.D Then
RightM = False
Movement()
ElseIf e.KeyCode = Keys.W Then
UpM = False
Movement()
ElseIf e.KeyCode = Keys.S Then
DownM = False
Movement()
End If
End Sub
End Class
The question took me back to the Z80 days, I got a little nostalgic so decided to post a simplified answer.
'Position of PictureBox
Private Plocation As Point
'PictureBox Movement Boundries
Private XL As Integer 'X - Left
Private XR As Integer 'X - Right
Private YT As Integer 'Y - Top
Private YB As Integer 'Y - Bottom
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
'Set Boundries
XL = 0
XR = Me.ClientSize.Width - PictureBox1.Width
YT = 0
YB = Me.ClientSize.Height - PictureBox1.Height
'Position PictureBox roughly in the centre of the Form
Plocation = New Point((Me.ClientSize.Width / 2) - (PictureBox1.Width / 2), (Me.ClientSize.Height / 2) - (PictureBox1.Height / 2))
PictureBox1.Location = Plocation
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
'Change X,Y depending on KeyPress
If e.KeyCode = Keys.A Then Plocation.X -= 5
If e.KeyCode = Keys.D Then Plocation.X += 5
If e.KeyCode = Keys.W Then Plocation.Y -= 5
If e.KeyCode = Keys.S Then Plocation.Y += 5
'Check for X,Y boundries
If Plocation.X < XL Then Plocation.X = XL
If Plocation.X > XR Then Plocation.X = XR
If Plocation.Y < YT Then Plocation.Y = YT
If Plocation.Y > YB Then Plocation.Y = YB
'Update Position
PictureBox1.Location = Plocation
End Sub
I'm intentionally checking all key presses one after another, helps with diagonal movements. It's a little choppy and basic but may give you some ideas. Happy programming...
Related
I'm very, VERY, new to coding and started a class in Visual Studio and the language Visual Basic in a .NET windows form app. So on that note, please cut me some slack.
I am trying to make a little game where you can move your character and shoot a monster or two in only 4 directions (left, right, up, left). Well, the problem is that my bullets move when I try to move my character with the WASD keys. This is most likely because I have set my WASD keys to both movements for the movement of the character, and the direction in which the bullets (PictureBox) shoots. I've tried making boolean switches, but me being new to coding seems to have caused some trouble figuring it out. I'll drop what I have so far:
Public Class Form1
Dim Health As Integer = 7
Dim UUp As Boolean = True
Dim UDown As Boolean = True
Dim ULeft As Boolean = True
Dim URight As Boolean = True
Dim EUp As Boolean = True
Dim EDown As Boolean = True
Dim ELeft As Boolean = True
Dim ERight As Boolean = True
Dim Bullets(-1) As Bullet
Dim intCount As Integer
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
'movement of character player controls
If (e.KeyCode = Keys.W And UUp = True) Then
pbIssac.Top -= 5
ElseIf (e.KeyCode = Keys.A And ULeft = True) Then
pbIssac.Left -= 5
ElseIf (e.KeyCode = Keys.D And URight = True) Then
pbIssac.Left += 5
ElseIf (e.KeyCode = Keys.S And UDown = True) Then
pbIssac.Top += 5
ElseIf (e.KeyCode = Keys.Escape) Then
End
End If
'creation of bullet? code from internet!
Select Case e.KeyCode
Case Keys.Space
ReDim Preserve Bullets(intCount)
Dim bullet1 As New Bullets
Controls.Add(bullet1)
Bullets(intCount) = bullet1
intCount += 1
tmrShoot.Enabled = True
End Select
'direction character is facing determines direction of bullet
If (e.KeyCode = Keys.A) Then
My.Settings.Keypressed = 1
My.Settings.Save()
ElseIf (e.KeyCode = Keys.D) Then
My.Settings.Keypressed = 2
My.Settings.Save()
ElseIf (e.KeyCode = Keys.W) Then
My.Settings.Keypressed = 3
My.Settings.Save()
ElseIf (e.KeyCode = Keys.S) Then
My.Settings.Keypressed = 4
My.Settings.Save()
End If
Bullet Class (From the internet!)
Public Class Bullet
Inherits PictureBox
Public Sub New()
With Me
.Size = New Size(10, 30)
.Location = Form1.pbIssac.Location
.BackgroundImageLayout = ImageLayout.Stretch
.BackgroundImage = My.Resources.green
End With
End Sub
Public Sub Shoot()
If (My.Settings.Keypressed = 1) Then
Me.Left -= 3
My.Settings.Save()
ElseIf (My.Settings.Keypressed = 2) Then
Me.Left += 3
My.Settings.Save()
ElseIf (My.Settings.Keypressed = 3) Then
Me.Top -= 3
My.Settings.Save()
ElseIf (My.Settings.Keypressed = 4) Then
Me.Top += 4
My.Settings.Save()
End If
End Sub
End Class
This is the sort of thing that I would do in that situation:
Public Class Form1
Private characterPosition As Point
'Set a default direction for the character.
Private characterDirection As Direction = Direction.Up
Private ReadOnly bullets As New List(Of Bullet)
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
Select Case e.KeyCode
Case Keys.W
characterDirection = Direction.Up
'Move character up.
Case Keys.S
characterDirection = Direction.Down
'Move character down.
Case Keys.A
characterDirection = Direction.Left
'Move character left.
Case Keys.D
characterDirection = Direction.Right
'Move character right.
Case Keys.Space
bullets.Add(New Bullet(characterPosition, characterDirection))
End Select
End Sub
End Class
Public Enum Direction
Up
Down
Left
Right
End Enum
Public Class Bullet
Private direction As Direction
Public Sub New(location As Point, direction As Direction)
'...
Me.direction = direction
End Sub
Public Sub Move()
Select Case direction
Case Direction.Up
'Move bullet up.
Case Direction.Down
'Move bullet down.
Case Direction.Left
'Move bullet left.
Case Direction.Right
'Move bullet right.
End Select
End Sub
End Class
Note that each bullet remembers its own direction so you just tell it to move and it moves.
I need to stagger each body parts release so that they dont just overlap like they do currently.
Is there a way to stagger the running of this code?
Public Class Form1
Public xx As New List(Of Integer)
Public yy As New List(Of Integer)
Public up As Boolean = True
Public down As Boolean = False
Public lefty As Boolean = False
Public righty As Boolean = False
Public sizey As Integer = -1
Public tik As Integer = 0
Public neww As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
newpart()
newpart()
newpart()
End Sub
Public Sub square(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
e.Graphics.Clear(Color.Black)
For a = 0 To sizey
e.Graphics.FillRectangle(Brushes.Aqua, xx(a), yy(a), 20, 20)
Next
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Right Then
righty = True
lefty = False
up = False
down = False
ElseIf e.KeyCode = Keys.Left Then
righty = False
lefty = True
up = False
down = False
ElseIf e.KeyCode = Keys.Up Then
righty = False
lefty = False
up = True
down = False
ElseIf e.KeyCode = Keys.Down Then
righty = False
lefty = False
up = False
down = True
End If
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e _
As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
square(sender, e)
End Sub
Private Sub clock_Tick(sender As Object, e As EventArgs) Handles head.Tick
If up = True Then
yy(0) = yy(0) - 20
ElseIf down = True Then
yy(0) = yy(0) + 20
ElseIf lefty = True Then
xx(0) = xx(0) - 20
ElseIf righty = True Then
xx(0) = xx(0) + 20
End If
Me.Refresh()
For b = 0 To sizey - 1
If yy(b) - yy(b + 1) = 0 Then
xx(b + 1) = xx(b + 1) + (xx(b) - xx(b + 1))
ElseIf xx(b) - xx(b + 1) = 0 Then
yy(b + 1) = yy(b + 1) + (yy(b) - yy(b + 1))
If neww = True Then
neww = False
Exit For
End If
End If
Next
End Sub
Sub newpart()
xx.Add(100)
yy.Add(100)
sizey = sizey + 1
neww = True
Return
End Sub
End Class
Its mainly the bit in the clock tick as in I need it to wait another tick before running the for loop again. This edited version works but really poorly as the third body part jumps to the first occasionally then just stays still.
You over-complicated that for loop there.
Just make tail catch up before you move head. It can be done in single tick.
Public Class Form1
Public p As New List(Of Point)
Public direction As eDircetion = eDircetion.Up
Public Enum eDircetion
Up
Down
Left
Right
End Enum
Public sizey As Integer = -1
Public tik As Integer = 0
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
newpart()
newpart()
newpart()
head.Interval = 500
head.Start()
End Sub
Public Sub square(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
e.Graphics.Clear(Color.Black)
For a = 0 To sizey
e.Graphics.FillRectangle(Brushes.Aqua, p(a).X, p(a).Y, 20, 20)
Next
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.D Then
direction = eDircetion.Right
ElseIf e.KeyCode = Keys.A Then
direction = eDircetion.Left
ElseIf e.KeyCode = Keys.W Then
direction = eDircetion.Up
ElseIf e.KeyCode = Keys.S Then
direction = eDircetion.Down
End If
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e _
As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
square(sender, e)
End Sub
Private Sub clock_Tick(sender As Object, e As EventArgs) Handles head.Tick
'THIS!
For i = p.Count - 1 To 1 Step -1
p(i) = p(i - 1)
Next
Select Case direction
Case eDircetion.Up
p(0) -= New Size(0, 20)
Case eDircetion.Down
p(0) += New Size(0, 20)
Case eDircetion.Left
p(0) -= New Size(20, 0)
Case eDircetion.Right
p(0) += New Size(20, 0)
Case Else : Throw New Exception("Something went wrong")
End Select
'Me.Refresh()
me.Invalidate() 'This is faster.
Me.Update()
'For b = 0 To sizey - 1
' If p(b).Y - p(b + 1).Y = 0 Then
' p(b + 1).X = p(b + 1).X + (p(b).X - p(b + 1).X)
' ElseIf xx(b) - xx(b + 1) = 0 Then
' yy(b + 1) = yy(b + 1) + (yy(b) - yy(b + 1))
' If neww = True Then
' neww = False
' Exit For
' End If
' End If
'Next
End Sub
Sub newpart()
p.Add(New Point(100, 100))
sizey = sizey + 1
Return
End Sub
End Class
I made some minor changes:
-Use enum instead of 4 booleans, makes cleaner code
-Do not use Me.Refresh, it's slow and does things you do not need here
-It's better to use not two integer lists, but one point list
Hope it helps.
Hi i have make small program when you hold Shift+Control and after you drag the mouse draw nice Rectangle when release the keys finish
this working very well in windows and some game also when it's full screen :) !
2 Problem i try to solve it
1) some game take the mouse and lock in center the problem it's you cant move the mouse where you like always it's in center
i try in time to use
Me.Cursor = New Cursor(Cursor.Current.Handle)
Cursor.Position = New Point(Control.MousePosition.X, Control.MousePosition.Y)
2) some game ignore the keys control+shift i try to put something like
control+shift+A for example but this don't work
GetKeyPress(Keys.ShiftKey) AndAlso GetKeyPress(Keys.ControlKey) AndAlso GetKeyPress(Keys.A)
the only i see to work its the HotKey but i want get stage when Up Down and i don't know how
<Runtime.InteropServices.DllImport("User32.dll")>
Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr,
ByVal id As Integer, ByVal fsModifiers As Integer,
ByVal vk As Integer) As Integer
End Function
here full code copy paste and run it , to make your test
Dim timerUpdate As New Timer
Private Const KEY_DOWN As Integer = &H8000
Private Declare Function GetKeyPress Lib "user32" Alias "GetAsyncKeyState" (ByVal key As Integer) As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'form Setting transparent and hide
Me.TransparencyKey = Color.Black
Me.BackColor = Color.Black
Me.FormBorderStyle = FormBorderStyle.None
Me.Opacity = 0.0
Me.TopMost = True
'Timer
timerUpdate.Interval = 1
timerUpdate.Enabled = True
AddHandler timerUpdate.Tick, AddressOf timerUpdate_Tick
End Sub
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
'paint rectangle to border red
Dim size = 2
Dim RedPen As New Pen(Color.Red, size)
Dim rect As New Rectangle(size, size, Me.ClientSize.Width - size * 2, Me.ClientSize.Height - size * 2)
e.Graphics.DrawRectangle(RedPen, rect)
End Sub
Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles MyBase.Resize
'Refresh for drawing update
Me.Refresh()
End Sub
Private Sub timerUpdate_Tick(sender As Object, e As EventArgs)
Dim key_shift As Integer = GetKeyPress(Keys.ShiftKey) AndAlso GetKeyPress(Keys.ControlKey)
Static key_shift_down As Boolean = False
Static mousePosKeep As New Point()
Static mousePosLast As New Point()
If GetKeyPress(Keys.ShiftKey) AndAlso GetKeyPress(Keys.ControlKey) = KEY_DOWN Then
If (Not key_shift_down) Then
'keep mouse position
mousePosKeep.X = Control.MousePosition.X
mousePosKeep.Y = Control.MousePosition.Y
'Move Form to mouse
Me.Left = mousePosKeep.X
Me.Top = mousePosKeep.Y
'Set Key Shift To True
key_shift_down = True
'Make Form Vissible
Me.Opacity = 1.0
'this help the form to show in game when it's full screen
'If call again make top the form And you can see it !!! :)
Me.TopMost = True
Console.WriteLine("key Shift+Controls Press Down")
End If
'Draw rectangle on mouse move
'Move Size Form Left , Width
If (Control.MousePosition.X - mousePosKeep.X) > -1 Then
Me.Left = mousePosKeep.X
Me.Width = (Control.MousePosition.X - mousePosKeep.X)
Else
Me.Left = Control.MousePosition.X
Me.Width = (mousePosKeep.X - Control.MousePosition.X)
End If
'Move Size Form Top , Height
If (Control.MousePosition.Y - mousePosKeep.Y) > -1 Then
Me.Top = mousePosKeep.Y
Me.Height = Control.MousePosition.Y - mousePosKeep.Y
Else
Me.Top = Control.MousePosition.Y
Me.Height = mousePosKeep.Y - Control.MousePosition.Y
End If
Console.WriteLine("Key Shift+Controls is Down")
Else
If key_shift_down = True Then
'hide form finish when shift up
Me.Opacity = 0.0
'nake shift to false
key_shift_down = False
'Do your stuff when finish
'
'
Console.WriteLine("Key Shift+Controls Press Up")
End If
'Draw Small Point To see where is the mouse when mouse is move
If (mousePosLast.X <> Control.MousePosition.X And mousePosLast.Y <> Control.MousePosition.Y) Then
mousePosLast.X = Control.MousePosition.X
mousePosLast.Y = Control.MousePosition.Y
Me.Width = 5
Me.Height = 5
Me.Opacity = 1.0
Me.TopMost = True
Me.Left = Control.MousePosition.X
Me.Top = Control.MousePosition.Y
Me.Cursor = Cursors.Cross
Console.WriteLine("Key Shift+Controls Up")
Else
Me.Opacity = 0.0
End If
End If
End Sub
thank you
So I am making a basic pinball game using vb.net and am having an issue with the collisions that once the ball slows down a certain amount it glitches inside and then through the walls.
I am using a picturebox for the walls and the ball and am using the intersectwith(picturebox command to detect collision.
any help on how to fix this would be appreciated. Thanks
Bellow is most of the code: (pctball is the ball)
Private Sub Screen_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DoubleBuffered = True
dX = 6 ' Pixels per timer tick
dY = 6
Timer1.Enabled = True
'array for colliding scores
For Each obj In Me.Controls
If TypeOf obj Is PictureBox AndAlso obj.tag = "Disc" Then
DiscArray(i) = obj
i += 1
End If
Next
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If GameActive = True Then
Labelx.Text = PctBall.Left
Labely.Text = PctBall.Top
PctBall.Left = PctBall.Left + dX
PctBall.Top = PctBall.Top + dY
' check for ball hitting edges, reverse direction if so
If PctBall.Left < 10 Or PctBall.Left > MyBase.Width - PctBall.Width Then
dX = -dX
End If
If PctBall.Top < 10 Then
dY = -dY
End If
If LeftFlipper = True Then
FlipperDefaultL.Visible = False
FlipperUpL.Visible = True
Else
FlipperDefaultL.Visible = True
FlipperUpL.Visible = False
End If
If RightFlipper = True Then
FlipperDefaultR.Visible = False
FlipperUpR.Visible = True
Else
FlipperDefaultR.Visible = True
FlipperUpR.Visible = False
End If
GravityFunction()
ReboundAngle()
' If ball goes outside bottom
If PctBall.Bottom > MyBase.Height Then
GameActive = False
Game_Over()
End If
End If
End Sub
Private Sub Keys_Down(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
Select Case e.KeyValue
Case Keys.Space
GameActive = True
Case Keys.D
LeftFlipper = True
Case Keys.K
RightFlipper = True
End Select
End Sub
Private Sub Keys_Up(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
Select Case e.KeyValue
'Case Keys.Space
' GameActive = False
Case Keys.D
LeftFlipper = False
Case Keys.K
RightFlipper = False
End Select
End Sub
Private Sub GravityFunction()
' gravity
gravity = CollisionCount
dY += gravity
PctBall.Top += dY
End Sub
Private Function CheckCollision()
For Each PictureBox In Me.Controls
If PictureBox IsNot PctBall AndAlso PictureBox.visible = True AndAlso PctBall.Bounds.IntersectsWith(PictureBox.Bounds) Then
collision = True
CollisionCount += 0.1
For discCount = 0 To DiscArray.Length - 1
If PictureBox IsNot PctBall AndAlso PctBall.Bounds.IntersectsWith(DiscArray(discCount).Bounds) Then
score = score + 1
ScoreBoard.scorelabel.Text = "Score: " & score
End If
Next
Exit For 'Exit when at least one collision found
Else : collision = False
End If
Next
If Collision = True Then
Coll.Text = "True"
Else
Coll.Text = "False"
End If
Return collision
End Function
Private Function ReboundAngle()
If CheckCollision() Then
dX = -dX
dY = -dY
End If
End Function
I am trying to detect the left and right mouse movements for a control - like you can use delta for up/down movement. Can anyone help with this? Thanks.
If e.x > 0 Then 'moved right
msgbox("Moved right!")
else 'moved left
msgbox("Moved left!")
End If
Private oldXY As Point = Point.Empty
Private Sub Form1_MouseMove(sender As Object,
e As MouseEventArgs) Handles Me.MouseMove
If e.X < oldXY.X Then
' ....
ElseIf e.X > oldXY.X Then
' ...
End If
oldXY.X = e.X
oldXY.Y = e.Y
End Sub
You will likely want to add a test for Point.Empty so that you dont misreport the first mousemove. Or try to initialize it to Cursor.Position to start with
I'm using Timer , and I get a good result
Dim lx As Integer = 0 ' last x position
Dim ly As Integer = 0 ' last y position
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim x As Integer = MousePosition.X
Dim y As Integer = MousePosition.Y
Dim s As String = ""
If x > lx Then
s &= "Right,"
ElseIf x < lx Then
s &= "Left,"
ElseIf x = lx Then
s &= "No Change,"
End If
If y > ly Then
s &= "Down"
ElseIf y < ly Then
s &= "Top"
ElseIf y = ly Then
s &= "No Change"
End If
lx = x
ly = y
Label1.Text = s
End Sub
Private firstTime As Boolean = False
Private oldX As Integer
Private Sub Button1_MouseEnter(sender As System.Object, e As System.EventArgs) Handles Button1.MouseEnter
firstTime = True
End Sub
Private Sub Button1_MouseMove(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseMove
If firstTime = True Then
firstTime = False
Else
If e.X > oldX Then
'moves right
ElseIf e.X < oldX Then
'moves left
End If
End If
oldX = e.X
End Sub