Snake Game... Adding snake body function malfunctioning - vb.net

I am writing a snake game in visual studio in visual basic.
The playing field is a 2D Array of PictureBoxes. My Snake is a 1D array as type Point. The snake array is called 'Snake'.
When the form loads, Snake(0) is set as New Point(1, 1). I have created a sub routine that moves the snake depending on the arrow key the user presses. This is under a timer. Snake(0) (The snake head) is set to equal Snake(0) + direction (direction is a variable altered by the arrow key that the user presses, eg. when up is pressed direction is set to x: 0 and y: -1)
When snake(0) hits a piece of food, the amount of elements in the snake array is set to the length of the array. EG(If snake(0) = foodPosition Then ReDim Preserve snake(snake.Length) End If)
I have created a loop, also under the timer, to make the body of the snake follow the head (eg. snake(2) = snake(1) and snake(1) = snake(0) but can't get it to work)
Code:
Public Class frmPlayfield
'Food Creating and Grow Snake Variables
Dim randF As New Random
Dim foodPointX As Integer = randF.Next(0, 32)
Dim foodPointY As Integer = randF.Next(0, 32)
'Play Field Variables
Dim playMaxWidth As Integer = 32
Dim playMaxHeight As Integer = 32
Dim boxSize As Integer = 16 'Size of PictureBox
Dim boxArray(,) As PictureBox 'PictureBox Array
'Snake Stuff Variable
Dim snake(1) As Point 'Snake array
Dim direction As New Point(1, 0) 'Direction for snake movement
Private Sub frmPlayfield_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ReDim boxArray(playMaxWidth, playMaxHeight)
For x As Integer = 0 To playMaxWidth
For y As Integer = 0 To playMaxHeight
boxArray(x, y) = New PictureBox
boxArray(x, y).Width = boxSize
boxArray(x, y).Height = boxSize
boxArray(x, y).Top = y * boxSize
boxArray(x, y).Left = x * boxSize
boxArray(x, y).Visible = True
boxArray(x, y).BackColor = Color.White
boxArray(x, y).BorderStyle = BorderStyle.FixedSingle
Me.Controls.Add(boxArray(x, y))
Next
Next
Me.ClientSize = New Size((playMaxWidth + 1) * boxSize, (playMaxHeight + 1) * boxSize)
snake(0) = New Point(1, 1) 'Creates snake head
boxArray(foodPointX, foodPointY).BackColor = Color.Red
End Sub
Private Function createBox(x As Integer, y As Integer, bSize As Integer) As PictureBox
Dim tempBox As New PictureBox
tempBox.Width = bSize
tempBox.Height = bSize
tempBox.Top = y * bSize
tempBox.Left = x * bSize
tempBox.Visible = True
tempBox.BackColor = Color.White
tempBox.BorderStyle = BorderStyle.FixedSingle
Me.Controls.Add(tempBox)
Return tempBox
End Function
Private Sub Food()
If snake(0).X = foodPointX And snake(0).Y = foodPointY Then
ReDim Preserve snake(snake.Length) 'Increases the amount of elements in the snake array.
For j As Integer = 0 To 0
foodPointX = randF.Next(0, 32)
foodPointY = randF.Next(0, 32)
boxArray(foodPointX, foodPointY).BackColor = Color.Red
Next
End If
For h As Integer = snake.Length - 1 To snake.GetUpperBound(0)
snake(h) = snake(snake.Length - 2)
Next
End Sub
Private Sub CheckBoundsAndMovement()
For i As Integer = 0 To snake.GetUpperBound(0)
boxArray(snake(i).X, snake(i).Y).BackColor = Color.White 'Loop to change the whole snake black
Next
snake(1) = snake(0)
snake(0) = snake(0) + direction
If snake(0).X > playMaxWidth Then
snake(0).X -= (playMaxWidth + 1)
End If
If snake(0).X < 0 Then
snake(0).X += (playMaxWidth + 1)
End If 'Four If statements to check if the snake has gone outside the play area.
If snake(0).Y > playMaxWidth Then
snake(0).Y -= (playMaxWidth + 1)
End If
If snake(0).Y < 0 Then
snake(0).Y += (playMaxWidth + 1)
End If
For k As Integer = 0 To snake.GetUpperBound(0)
boxArray(snake(k).X, snake(k).Y).BackColor = Color.Black 'Loop to make the whole snake black
Next
End Sub
Private Sub timGameTick_Tick(sender As Object, e As EventArgs) Handles timGameTick.Tick
Food()
CheckBoundsAndMovement()
End Sub
Private Sub frmPlayfield_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown 'Subroutine for direction
Select Case (e.KeyCode)
Case Keys.Up
direction = New Point(0, -1)
Case Keys.Down
direction = New Point(0, 1)
Case Keys.Left
direction = New Point(-1, 0)
Case Keys.Right
direction = New Point(1, 0)
End Select
End Sub
End Class
This works fine after I eat the first piece of food. The snake of length 2 is increased to length 3. But when I eat another piece of food the end of the snake is left behind at the spot where the food was eaten.

Ok - It looks like I found the problems -
First off - you defined the snake array as Dim snake (1) As Point this created the array with two elements instead of 1
Next, in your Food sub, the loop to roll the pixels back along the snake should be done every time the snake moves, not just when food is eaten. So I moved it into the CheckBoundsAndMovement sub to replace line 4 of that sub which only copied the location of the head to the next point back rather than the whole snake. But of course trying to execute the loop when the length of the snake was only one pixel would result in an out of range exception on the array, so added an If statement to only execute the loop if the length of snake is more than 1.
Also the direction of the loop in your code was in increasing order. To do it properly it should be in decreasing order. This way, the loop overwrites the point representing the end of the tail with the next point forward and so on. Finally, the new location for the head is entered into snake(0)
So - here it is -
Public Class frmPlayfield
'Food Creating and Grow Snake Variables
Dim randF As New Random
Dim foodPointX As Integer = randF.Next(0, 32)
Dim foodPointY As Integer = randF.Next(0, 32)
'Play Field Variables
Dim playMaxWidth As Integer = 32
Dim playMaxHeight As Integer = 32
Dim boxSize As Integer = 16 'Size of PictureBox
Dim boxArray(,) As PictureBox 'PictureBox Array
'Snake Stuff Variable
Dim snake(0) As Point 'Snake array
Dim direction As New Point(1, 0) 'Direction for snake movement
Private Sub frmPlayfield_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ReDim boxArray(playMaxWidth, playMaxHeight)
For x As Integer = 0 To playMaxWidth
For y As Integer = 0 To playMaxHeight
boxArray(x, y) = New PictureBox
boxArray(x, y).Width = boxSize
boxArray(x, y).Height = boxSize
boxArray(x, y).Top = y * boxSize
boxArray(x, y).Left = x * boxSize
boxArray(x, y).Visible = True
boxArray(x, y).BackColor = Color.White
boxArray(x, y).BorderStyle = BorderStyle.FixedSingle
Me.Controls.Add(boxArray(x, y))
Next
Next
Me.ClientSize = New Size((playMaxWidth + 1) * boxSize, (playMaxHeight + 1) * boxSize)
snake(0) = New Point(1, 1) 'Creates snake head
boxArray(foodPointX, foodPointY).BackColor = Color.Red
End Sub
Private Function createBox(x As Integer, y As Integer, bSize As Integer) As PictureBox
Dim tempBox As New PictureBox
tempBox.Width = bSize
tempBox.Height = bSize
tempBox.Top = y * bSize
tempBox.Left = x * bSize
tempBox.Visible = True
tempBox.BackColor = Color.White
tempBox.BorderStyle = BorderStyle.FixedSingle
Me.Controls.Add(tempBox)
Return tempBox
End Function
Private Sub Food()
If snake(0).X = foodPointX And snake(0).Y = foodPointY Then
ReDim Preserve snake(snake.Length)
foodPointX = randF.Next(0, 32)
foodPointY = randF.Next(0, 32)
boxArray(foodPointX, foodPointY).BackColor = Color.Red
End If
End Sub
Private Sub CheckBoundsAndMovement()
For i As Integer = 0 To snake.GetUpperBound(0)
boxArray(snake(i).X, snake(i).Y).BackColor = Color.White 'Loop to change the whole snake white
boxArray(snake(i).X, snake(i).Y).Update()
Next
If snake.Length > 1 Then
For i As Integer = snake.GetUpperBound(0) To 1 Step -1
snake(i) = snake(i - 1)
Next
End If
snake(0) = snake(0) + direction
If snake(0).X > playMaxWidth Then
snake(0).X -= (playMaxWidth + 1)
End If
If snake(0).X < 0 Then
snake(0).X += (playMaxWidth + 1)
End If 'Four If statements to check if the snake has gone outside the play area.
If snake(0).Y > playMaxWidth Then
snake(0).Y -= (playMaxWidth + 1)
End If
If snake(0).Y < 0 Then
snake(0).Y += (playMaxWidth + 1)
End If
For k As Integer = 0 To snake.GetUpperBound(0)
boxArray(snake(k).X, snake(k).Y).BackColor = Color.Black 'Loop to make the whole snake black
Next
End Sub
Private Sub timGameTick_Tick(sender As Object, e As EventArgs) Handles timGameTick.Tick
Food()
CheckBoundsAndMovement()
End Sub
Private Sub frmPlayfield_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown 'Subroutine for direction
Select Case (e.KeyCode)
Case Keys.Up
direction = New Point(0, -1)
Case Keys.Down
direction = New Point(0, 1)
Case Keys.Left
direction = New Point(-1, 0)
Case Keys.Right
direction = New Point(1, 0)
End Select
End Sub
End Class

Related

What has to be done to show a marquee output with a scroll menu?

Today i continue my work, Building a menu with a vb.net console application. I found more samples to build with Windows forms. Still i try to get Basic Knowledge with the console surface.I was not able to put the following marquee text in a scroll menu, the second Code past the marquee text.
Module Module1
Dim aTimer As New System.Timers.Timer
Const marqueeText As String = "The quick brown fox... "
Dim sb As New System.Text.StringBuilder
Dim direction As Boolean = False
Sub Main()
aTimer.AutoReset = True
aTimer.Interval = 100 '1/10 second
AddHandler aTimer.Elapsed, AddressOf tick
aTimer.Start()
Console.ReadKey()
End Sub
Private Sub tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
Console.Clear()
If sb.Length = 0 Then sb.Append(marqueeText)
If direction Then
sb.Insert(0, sb(sb.Length - 1))
sb.Remove(sb.Length - 1, 1)
Else
sb.Append(sb(0))
sb.Remove(0, 1)
End If
Console.CursorLeft = 10 'no visible change
Console.CursorTop = 10 'visible change
Console.Write("{0}{1}", vbCr, sb.ToString)
End Sub
End Module
The marquee text Output from above is not easy to manage with the console.cursorleft command. I have no clue how to move it to the right or to put the marquee Output in the following Code, a scroll menu, on the third line.
Module Module1
Dim MenuList As New List(Of String)
Sub PrintMenu(highlight As Integer, left As Integer, top As Integer)
Dim Nickvektor() As Integer = {1, 2, 3, 4, 5}
For I = 0 To MenuList.Count - 1
Console.CursorLeft = left
Console.CursorTop = top + I
If I = highlight Then
Console.Write("{0}", "[" & Nickvektor(I) & "]")
Else
Console.Write(MenuList(I))
End If
Next
End Sub
Sub Main()
Console.CursorVisible = False
Dim x As Integer = 0
Dim Nickvektor() As String = {" "}
For counter As Integer = 0 To 0
Do
For Each s In Nickvektor
MenuList.Add(s)
Next
x += 1
Loop Until x = 5
Next
Console.SetCursorPosition(10, 16)
Console.Write("[ ]")
Dim CurrentItem As Integer = 0
Dim CurrentKey As ConsoleKey
While CurrentKey <> ConsoleKey.Enter
PrintMenu(CurrentItem, 10, 10)
CurrentKey = Console.ReadKey(True).Key
Select Case CurrentKey
Case ConsoleKey.DownArrow
CurrentItem += 1
Case ConsoleKey.UpArrow
CurrentItem -= 1
End Select
CurrentItem = (CurrentItem + MenuList.Count) Mod MenuList.Count
End While
End Sub
End Module
The menu Frame for the above Code can be used with the up and down arrows on the Keyboard.
Maybe it is to much work but i have no clue how to continue.
The first Solution for the marquee Output is an easy change of the original code. The wrap, vbCr, was the main Problem to move the text output toward the right edge oft he screen. The following code can be used to change the cursorTop Positon and also the cursorLeft Position of the Text.
Console.CursorVisible = False
Console.CursorLeft = 30
Console.CursorTop = 10
Console.Write("{0}", sb.ToString)
The heavy part are the Menu code Lines. To answer my own question some additional help was necessary.
I posted my question on the MS developer Network written in german language. With the following link it can be viewed.
For the case the link should be broken or other cases i post the code on this site.
Module Module1
Dim MenuList As New List(Of String)
Dim aTimer As New System.Timers.Timer
Const marqueeText As String = "The quick brown fox... "
Dim sb As New System.Text.StringBuilder
Dim direction As Boolean = False
Sub PrintMenu(highlight As Integer, left As Integer, top As Integer)
Dim Nickvektor() As Integer = {1, 2, 3, 4, 5}
For I = 0 To MenuList.Count - 1
Console.CursorLeft = left
Console.CursorTop = top + I
If I = highlight Then
Console.Write("{0}", "[" & Nickvektor(I) & "]")
Else
Console.Write(MenuList(I))
End If
Next
End Sub
Sub Main()
Console.CursorVisible = False
aTimer.AutoReset = True
aTimer.Interval = 100 '1/10 second
AddHandler aTimer.Elapsed, AddressOf tick
Dim x As Integer = 0
Dim Nickvektor() As String = {" "}
For counter As Integer = 0 To 0
Do
For Each s In Nickvektor
MenuList.Add(s)
Next
x += 1
Loop Until x = 5
Next
Console.SetCursorPosition(10, 16)
Console.Write("[ ]")
Dim CurrentItem As Integer = 0
Dim CurrentKey As ConsoleKey
While CurrentKey <> ConsoleKey.Enter
If CurrentItem = 2 Then ' Zero can be used to show the marquee output prompt
aTimer.Start() ' With a change to two or four the timer can be stoped:
'Else
'If aTimer.Enabled Then
' aTimer.Stop()
'End If
End If
PrintMenu(CurrentItem, 10, 10)
CurrentKey = Console.ReadKey(True).Key
Select Case CurrentKey
Case ConsoleKey.DownArrow
CurrentItem += 1
Case ConsoleKey.UpArrow
CurrentItem -= 1
End Select
CurrentItem = (CurrentItem + MenuList.Count) Mod MenuList.Count
End While
End Sub
Private Sub tick(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
If sb.Length = 0 Then sb.Append(marqueeText)
If direction Then
sb.Insert(0, sb(sb.Length - 1))
sb.Remove(sb.Length - 1, 1)
Else
sb.Append(sb(0))
sb.Remove(0, 1)
End If
Console.CursorVisible = False
Console.CursorLeft = 20
Console.CursorTop = 12 ' For the first Element CursorTop=10, fort he third 12
Console.Write("{0}", sb.ToString)
End Sub
End Module
To learn an other language like English i have to search a lot. Visual Basic Code is mostly written with English key words for the commands. I think it is easier to look up the maintainable changes for your self. To search is not every day funny.

Drawing an array of PictureBoxes in vb.net

I'm trying to draw an array of PictureBoxes, for testing I use the same picture for each picturebox.
But instead of showing the picture, it shows the color blue.
I would show you a picture, but I dont have 10 reputation..
Dim teren(120) As PictureBox
Dim x_locatie As Integer = 1, y_locatie As Integer = 0
For i = 0 To 10
x_locatie = 210
For j = 0 To 12
teren(i * j) = New PictureBox()
teren(i * j).Size = New Size(61, 61)
teren(i * j).Name = "x" + i.ToString + "y" + j.ToString
teren(i * j).Location = New Point(x_locatie, y_locatie)
Dim locatie As String = folder + "\harta\test.png"
teren(i * j).ImageLocation = locatie
teren(i * j).Show()
Next
y_locatie += 61
Next
I also tried another method , but same result.
Sub PictureBox1_Paint(sender1 As Object, er As PaintEventArgs)
If myImage IsNot Nothing Then
Dim r As New Rectangle(x, y, xlatime, ylungime)
er.Graphics.DrawImage(myImage, r)
End If
End Sub
Sub deseneaza(ByVal poza As String, ByRef x_perm As Integer, ByRef y_perm As Integer, ByRef lungime As Integer, ByRef latime As Integer)
myImage = Image.FromFile(poza)
x = x_perm
y = y_perm
xlatime = latime
ylungime = lungime
Refresh()
End Sub
'this part of code is in body of another function
Dim x_locatie As Integer = 1, y_locatie As Integer = 0
For i = 0 To 10
x_locatie = 210
For j = 0 To 12
Dim locatie As String = folder + "\harta\test.png"
deseneaza(locatie, x_locatie, y_locatie, 61, 61)
Next
y_locatie += 61
Next
I saw in other threads that their problem solution was something like that Dim teren() As PictureBox {teren1, teren2 , ... , teren n} But the problem in my case is that I need 120 PictureBoxes, and I think that it must be a way to do this without writing 120 pictureboxes.
Please try this...it will generate 16 picture box, size 20x20, in a row. I put it under "FormLoading" event.
Dim Shapes(16) As PictureBox
For i = 1 To 16
Shapes(i) = New PictureBox
With Shapes(i)
.BackColor = SystemColors.Control 'Color.Green
.BackgroundImage = New Bitmap(My.Resources.led_blk)
.BackgroundImageLayout = ImageLayout.Zoom
.Size = New Size(20, 20)
.Visible = True
.Location = New Point( 23 * i, 50)
End With
Me.Controls.Add(Shapes(i))
Next
I think GDI+ will be the way to go. I think you need a custom class that has a rectangle structure as a member with other properties that help you with further logic with the character intersecting with them. Paint should be done in the Paint event of the surface control you are using - PictureBox has the best rendering - IMO.
Public Class Tile
Public Property Bounds As New Rectangle
Public Property IsImpassable As Boolean
'others you think of
End Class
Dim iTop = 325
Dim pBox(48) As PictureBox
Dim pinColor = Color.SkyBlue
Dim leftStart = 50
For j = 0 To 3
For i = 0 To 11
pBox(i) = New PictureBox
'pBox(i).Image = Image.FromFile("\NoTest.bmp")
pBox(i).Visible = True
pBox(i).BackColor = pinColor
pBox(i).Top = iTop + (j * 40)
pBox(i).Width = 20
pBox(i).Height = 20
pBox(i).Left = leftStart + (35 * i)
If i > 9 Then
pBox(i).Left = leftStart + (35 * i) + 15
pBox(i).Width = 25
End If
pBox(i).BringToFront()
pBox(i).SizeMode = PictureBoxSizeMode.StretchImage
Controls.Add(pBox(i))
Next
Next

Convert 1DPointArray into 2DPointArray

I started a new project which loads and saves tilesets in style of ini-datas.
The problem is now, that it loads the tiles into a 1d- list, which got copied sorted into a 1d-array.
Now I am trying to convert this sorted 1d-array into a 2d-array.
My try:
LoadedTiles.Sort(Function(p1, p2) (p1.Position.X.CompareTo(p2.Position.X)))
LoadedTiles.Sort(Function(p1, p2) (p1.Position.Y.CompareTo(p2.Position.Y)))
Dim currentArray(AmountTiles) As Tile
currentArray = LoadedTiles.ToArray
Dim lengthX, lengthY As Integer
Dim yAxis As Integer = currentArray(0).Position.Y
For Each p In currentArray
If Not p.Position.Y = yAxis Then
lengthX = (p.Position.X / p.Size.Width)
lengthY = (currentArray(currentArray.Length - 1).Position.Y / p.Size.Width)
Else
lengthX = (currentArray(currentArray.Length - 1).Position.X / p.Size.Width)
lengthY = 0
End If
Next
MapTiles = New Tile(lengthX, lengthY) {}
Dim ii As Integer
For x = 0 To lengthX
For y = 0 To lengthY
MapTiles(x, y) = currentArray(ii)
If Not ii >= currentArray.Length - 1 Then
ii += 1
End If
Next
Next
This gives a wrong output.
See picture below:
http://www.directupload.net/file/d/3690/pz8x98jr_png.htm
Is it possible to do it right?
Thanks alot!
The k-th element in a 1D array can correspond to row i=k/N and column j=k%N where N is the number of columns. The reverse is k=i*N+j
Ok guys, I got it ( =
Public Class Form1
Dim List As New List(Of Point)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
List.Add(New Point(180, 360))
List.Add(New Point(180, 180))
List.Add(New Point(180, 540))
'Convert 1d to 2d
Dim count As Point = countXYAxis(List, 180)
MsgBox(count.ToString)
Dim p(count.X - 1, List.Count - 1) As Point
MsgBox(p.Length)
Dim rofl As Integer
For i = 0 To p.GetUpperBound(0)
For j = 0 To p.GetUpperBound(1)
p(i, j) = List(rofl)
If Not rofl >= List.Count - 1 Then
rofl += 1
End If
Next
Next
For Each t In p
MsgBox(t.ToString)
Next
End Sub
Private Function countXYAxis(ByVal pt As List(Of Point), ByVal size As Integer) As Point
Dim bufferY As New List(Of Integer)
Dim cP As New Point
For Each pts In pt
If Not bufferY.Contains(pts.Y) Then
bufferY.Add(pts.Y)
End If
Next
For i = 0 To pt.Count - 1
If pt(i).Y = bufferY(0) Then
Else
cP = New Point(pt(i).X / size, bufferY.Count)
End If
Next
Return cP
End Function
End Class

how to using e.HasMorePages With For Each

i me using e.HasMorePages with code
For x As Integer = RowNo To dgv.Rows.Count - 1
Dim mypen As New Pen(Color.Black, 6)
e.Graphics.DrawString(dgv.Rows(x - 1).Cells(0).Value.ToString(), f, Brushes.Black, 645, yElementy)
If RowNo Mod 6 = 0 Then
RowNo += 1
e.HasMorePages = True
Exit For
End If
RowNo += 1
Next
how to using e.HasMorePages With code
For Each myRow In dtn.Rows
ListView1.Items.Add(n + ListView1.Items.Count + 1)
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myRow.Item(13).ToString())
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myRow.Item(5).ToString())
ListView1.Items(ListView1.Items.Count - 1).SubItems.Add(myRow.Item(14).ToString())
'i want to add here
Next
Typical layout: count variable(class level) for remembering what position we are at in the items printing. I like a List(Of String) for looping and printing. Inside the printPage event you need to have a variable for what row(y axis) your printing the records to and increment it with each iteration. Since it's graphics based you can also use a Rectangle structure and print contents to it using a StringFormat object for text wrapping and layout.
Print Document
Example off the top of my head - not tested.
Public Class Form1 ' your form name here
Private count As Integer
Private row As Integer
Private Sub print_Page(...) Handles ...
row = 100 'starting point from the top
Using p As New Pen(Brushes.Bisque) 'self disposing graphics object
'we use the variable here to know where we are if we have to go to next page
Dim rowCount = dg.Rows.Count - 1
For i As Integer = count To rowCount
e.Graphics.DrawString({value},p, Font, x, y)
row += 16 'basically the font height and some space in-between
If row = e.MarginBounds.Bottom - 20 Then
e.HasMorePages = True
If i <> rowCount Then 'are we on the last row?
count = i ' remember where we left off
Exit Sub ' cause this event will fire again and we need to start over
End If
End If
Next
End Using
End Sub
'...
End Class
Public Class frmTestHasMorePages
Dim Font12 As Font = New Drawing.Font("Arial", 12, FontStyle.Regular)
Dim Font8 As Font = New Drawing.Font("Arial", 8, FontStyle.Regular)
Dim sBrush As Drawing.Brush
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Static count As Integer
Static topMargin As Integer = 50
Static line As Integer
Static s, z As Integer
Dim linesPerPage = 65
Dim lineCount = 350
Static totalpages As Integer = IIf(lineCount Mod linesPerPage = 0, (lineCount / linesPerPage), (lineCount / linesPerPage) + 1)
sBrush = Brushes.Black
Dim pageBottom = e.PageBounds.Bottom
For i As Integer = count To lineCount
If z > lineCount Then
sBrush = Brushes.Blue
e.Graphics.DrawString("Page " & s + 1 & "/" & totalpages, Font8, sBrush, 750, pageBottom - 20)
sBrush = Brushes.Red
e.Graphics.DrawString("End of document ", Font8, sBrush, 50, pageBottom - 20)
e.HasMorePages = False
Exit Sub
End If
e.Graphics.DrawString("Testing hasmorepages with different options " & z, Font12, sBrush, 45, (i * 16) + topMargin)
line += 15
z += 1
If i = linesPerPage AndAlso s <= totalpages Then
e.HasMorePages = True
sBrush = Brushes.Blue
s += 1
e.Graphics.DrawString("Page " & s & "/" & totalpages, Font8, sBrush, 750, pageBottom - 20)
e.Graphics.DrawString("Continued...", Font8, sBrush, 50, pageBottom - 20)
i = 0
If i <> lineCount Then REM if it is the last line to print
Exit Sub
End If
End If
Next
End Sub
End Class

Runtime error message Index was outside the bounds of the array. for Visual Basic 2010

I am computing the ROI with a moving rectangle and extracting the ROI to compute the standard deviation, mean, area and Pixel value coordinates X and Y in a seperate form2 by clicking the mouse. At this juncture I am trying to pass a function from the main Form that loads the Image and displays the rectangle to another Form that has the displayed properties of the mean and standard deviation etc. However, I'm receiving errors in runtime in the function that contains the standard deviation. The error displayed is
Index was outside the bounds of the array.
It is displayed at the end of this portion of the code in the function StD, i.e at the end of the mean part'
SD(count) = Double.Parse(pixelcolor.R) + Double.Parse(pixelcolor.G) + Double.Parse(pixelcolor.B) - mean
what is this actually saying and how can I fix this situation. Any tips and ideas, thanks.
My code is at the bottom
enterPublic Function StD(ByVal image As Bitmap, ByVal mean As Double, ByVal meancount As Integer) As Double
Dim SD(SquareHeight * SquareWidth) As Double
Dim count As Integer = 0
For i = 0 To SquareWidth
For j = 0 To SquareHeight
Dim pixelcolor As Color = image.GetPixel(i, j)
SD(count) = Double.Parse(pixelcolor.R) + Double.Parse(pixelcolor.G) + Double.Parse(pixelcolor.B) - mean
count += 1
Next
Next
Dim SDsum As Double = 0
For i = 0 To count
SDsum = SDsum + SD(i)
Next
SDsum = SDsum / (SquareHeight * SquareWidth)
SDsum = ((SDsum) ^ (1 / 2))
Return SDsum
End Function code here
I would like to pass this using the code below
enterPrivate Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Dim mean As Double = 0
Dim meancount As Integer = 0
Dim bmap As New Bitmap(400, 400)
bmap = PictureBox1.Image
Dim colorpixel As Color = bmap.GetPixel(e.X, e.Y)
' Dim pixels As Double = colorpixel.R + colorpixel.G + colorpixel.B
If e.Button = Windows.Forms.MouseButtons.Left AndAlso Rect.Contains(e.Location) Then
If (PictureBox1.Image Is Nothing) Or (PictureBox1.Height - (e.Y + SquareHeight) < 0) Or (PictureBox1.Width - (e.X + SquareWidth) < 0) Then
Else
Dim ROI As New Bitmap(400, 400)
Dim x As Integer = 0
Dim countx As Integer = 0
Dim county As Integer = 0
For i = e.X To (e.X + SquareWidth)
For j = (e.Y + x) To (e.Y + SquareHeight)
Dim pixelcolor As Color = bmap.GetPixel(i, j)
ROI.SetPixel(countx, county, pixelcolor)
mean = mean + pixelcolor.R + pixelcolor.G + pixelcolor.B
county += 1
meancount += 1
Next
county = 0
countx += 1
x = x + 1
Next
mean = mean / (meancount * 3)
Dim SD = mean - 75
Dim area As Integer = (SquareHeight * SquareWidth)
Dim anotherForm As Form2
anotherForm = New Form2(mean, StD(bmap, mean, meancount), area, 34)
anotherForm.Show()
End If
End If
' Catch ex As Exception
' MessageBox.Show(ex.Message())
' End Try
End Sub code here
To be displayed with this code
enter Public Sub New(ByVal mean As Double, ByVal StD As Double, ByVal Area As Integer, ByVal pixel As Double)
MyBase.New()
InitializeComponent()
TextBox1.Text = mean.ToString()
TextBox2.Text = StD.ToString()
TextBox3.Text = Area.ToString()
TextBox4.Text = pixel.ToString()
End Sub code here
The problem probably is because of these lines:
For i = 0 To SquareWidth
For j = 0 To SquareHeight
Try using this instead:
For i = 0 To SquareWidth - 1
For j = 0 To SquareHeight - 1