Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Facebook Sign In with Google Sign In with OpenID

Categories

We have migrated to a new platform! Please note that you will need to reset your password to log in (your credentials are still in-tact though). Please contact lee@programmersheaven.com if you have questions.
Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Multidimensional array within a structure

ArisanLiamArisanLiam Posts: 2Member
Hey everyone. I'm new to the forums but couldn't find an "Introduce yourself" board. I suppose it's just as well.

I'm a beginner in VB so I need a little help understanding a concept here.
I'm trying to make a map editor for a 2D tile based game.
the maps can be multi-layered so I'm making a layer array as a structure. The structure contains the width and height of the layer and the tile data in a 2D array.
[code]Public Structure layerType
Public tile(,) As Integer
Public width As Integer
Public height As Integer
Sub New(ByVal i As Integer)
ReDim tile(3, 3)
End Sub
End Structure

Public Shared layer() As layerType

Private Sub newMap()
ReDim layer(3)
layer(0).width = 1
layer(0).tile(0, 0) = 1 ' Exception goes here?

End Sub
[/code]

the first command (layer(0).width = 1) works properly but the second (layer(0).tile(0, 0) = 1) gives me an exception:
Object reference not set to an instance of an object.

I'm pretty sure I've messed up the scope somewhere along the line but I just don't have a tight enough grasp on the language yet to figure it out. Any help would be greatly appreciated.

Comments

  • seancampbellseancampbell Pennsylvania, USAPosts: 684Member ✭✭✭
    Hi there! You're pretty close, the problem you're having is that you have not set tile(0) (or any other objects in that array) equal to a new instance of the structure... (In my experience, this tends to be the cause of a Null Reference Errors about 90% of the time).

    Check this out:
    [code]
    Public Structure layerType
    Public tile(,) As Integer
    Public width As Integer
    Public height As Integer
    Sub New(ByVal i As Integer)
    ReDim tile(3, 3)
    End Sub
    End Structure

    Public Shared layer() As layerType

    Private Sub newMap()
    ReDim layer(3)
    layer(0) = New layerType()
    layer(0).width = 1
    layer(0).tile(0, 0) = 1 ' Exception goes here?
    End Sub
    [/code]

    You can check to see if an object is "nothing", which means it has not been initialized with a New instance of the object, with this code:
    [code]
    If Not IsNothing(layer) Then
    'This checks that the Array Layer is not nothing
    'which usually tells if there is or is not Dimensioned Cells in it.
    MsgBox("It wasn't nothing")
    End If

    If layer.Length = 0 Then
    'Sometimes an array will not be Nothing,
    'and it will also have no cells in it, having a Length of 0
    'This is a very rare instance
    End If

    If Not IsNothing(layer(0)) Then
    'This checks that the object in Layer(0) is not nothing
    MsgBox("It wasn't nothing")
    End If

    If Not IsNothing(tile) Then
    MsgBox("It wasn't nothing")
    End If

    If Not IsNothing(tile(0,0)) Then
    'Integers shouldn't ever equal nothing
    'If I remember correctly, they are initialized with a 0 value
    'Most of the basic variable types don't require being initialized
    MsgBox("It wasn't nothing")
    End If
    [/code]

    Hope this helps
  • ArisanLiamArisanLiam Posts: 2Member
    Ok. Well I slept on it and I think I understand it a little better now.
    If I'm not mistaken the constructor is a sub that is called by New command when creating an instance of a structure.

    So here is how I'm seeing it:
    [code]Public Structure layerType
    Public tile(,) as integer
    Sub New(ByVal i As Integer) 'The constructor takes a passed value
    'from the creation command
    ReDim tile(i, i) 'I ReDim to the passed integer
    End Sub
    End Structure

    Public Shared layer() As layerType

    Private Sub newMap()
    ReDim layer(3) 'ReDim the layer array to an
    'upper bound of 3.
    layer(0) = New layerType(3) 'Create new instance of
    'layerType structure. Pass the
    '3 to i in the New sub

    layer(0).tile(0, 0) = 1 'Works finally.

    layer(3).tile(3, 3) = 1 'Gives null reference exception.
    End Sub
    [/code]

    So that's what I [italic]think[/italic] is going on with these commands. I'm still getting a null reference here when I try to use and array index above 0 which makes me believe that I'm still missing something.
  • seancampbellseancampbell Pennsylvania, USAPosts: 684Member ✭✭✭
    When you do
    Redim SeanCampbell(3,3) it DOES NOT set the UPPER BOUNDS to 3, it gives you these cells:

    SeanCampbell(0,0), SeanCampbell(0,1), SeanCampbell(0,2)
    SeanCampbell(1,0), SeanCampbell(1,1), SeanCampbell(2,2)
    SeanCampbell(2,0), SeanCampbell(1,1), SeanCampbell(2,2)

    The number that you enter while Dimensioning an array is the "Total Count". All Array Declaration's Cells go from 0 To (TotalCount - 1)

    Hope this helps...

    (In your code)
    [code]
    Public Structure layerType
    Public tile(,) as integer
    Sub New(ByVal i As Integer) 'The constructor takes a passed value
    'from the creation command
    ReDim tile(i, i) 'I ReDim to the passed integer
    End Sub
    End Structure

    Public Shared layer() As layerType

    Private Sub newMap()
    ReDim layer(3) 'ReDim the layer array to an
    'upper bound of 3.

    'Layer.Count = 3 - Layer.UpperBounds = 2
    layer(0) = New layerType(3) 'Create new instance of
    'layerType structure. Pass the
    '3 to i in the New sub

    layer(0).tile(0, 0) = 1 'Works fine.
    'layer(3) doesn't exist
    '.tile(3,3) doesn't exist
    'layer(3).tile(3, 3) = 1 'Gives null reference exception.
    layer(2).tile(2,2) = 1 'This will work

    End Sub

    [/code]
  • DrMartenDrMarten Posts: 748Member
    Hi ArisanLiam,

    You need 4 instances in your empty shrare 'layer' array variable.>>

    [code]
    Option Strict On
    Public Class Form1

    Public Structure layerType
    Public tile(,) As Integer
    Public Sub New(ByVal i As Integer) 'The constructor takes a passed value
    'from the creation command.
    ReDim tile(i, i) 'I ReDim to the passed integer
    End Sub
    End Structure

    Public Shared layer() As layerType

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    ReDim layer(3) 'Creates 4 entire copies ( 0,1,2 & 3 ) of the STRUCTURE so..

    'Pass the 3 to i in the New SUB for each instance in the layer array.
    layer(0) = New layerType(3) 'Create a new instance of layerType structure for array index 0.
    layer(1) = New layerType(3) 'Create a new instance of layerType structure for array index 1.
    layer(2) = New layerType(3) 'Create a new instance of layerType structure for array index 2.
    layer(3) = New layerType(3) 'Create a new instance of layerType structure for array index 3.

    layer(0).tile(0, 0) = 1 'Works finally.
    layer(3).tile(3, 3) = 1 'No longer gives null reference exception.

    End Sub
    End Class
    [/code]

    Regards,

    Dr M.
Sign In or Register to comment.