Inventory System and Equipment System for RPG Game

Answered Inventory System and Equipment System for RPG Game

  • martes, 14 de agosto de 2012 19:35
     
      Tiene código

    Hey guys, I've been working on a RPG game in VB 2010 and I've gotten to the point where I am adding items and giving them properties but I'm a bit confused and stuck. I currently have a form with 28 picture boxes and 28 'inventory settings & amounts' (inv1, inv2, etc) and on loading the inventory form the pictures are updated accordingly to the setting and a number below it to show the amount you currently have of the item. Then I want to be able to click the items and it "equips" it which will then show up on a different form called the 'Character Screen'.

    Here is some of my current coding for it:

    Inventory updating on load

            If My.Settings.inv4 = "fvisage" Then
                inv4.Image = My.Resources.fVisage
                inve4.Text = My.Settings.fvisage
            ElseIf My.Settings.inv4 = "draBody" Then
                inv4.Image = My.Resources.draBody
                inve4.Text = My.Settings.drabody
            ElseIf My.Settings.inv4 = "dralegs" Then
                inv4.Image = My.Resources.draLegs
                inve4.Text = My.Settings.dralegs
            ElseIf My.Settings.inv4 = "draboots" Then
                inv4.Image = My.Resources.draBoots
                inve4.Text = My.Settings.draboots
            ElseIf My.Settings.inv4 = "drahelm" Then
                inv4.Image = My.Resources.draHelm
                inve4.Text = My.Settings.drahelm
            ElseIf My.Settings.inv4 = "clothbody" Then
                inv4.Image = My.Resources.clothBody
                inve4.Text = My.Settings.clothbody
            ElseIf My.Settings.inv4 = "clothlegs" Then
                inv4.Image = My.Resources.clothLegs
                inve4.Text = My.Settings.clothlegs
            ElseIf My.Settings.inv4 = "clothboots" Then
                inv4.Image = My.Resources.clothBoots
                inve4.Text = My.Settings.clothboots
            ElseIf My.Settings.inv4 = "clothhat" Then
                inv4.Image = My.Resources.clothHelm
                inve4.Text = My.Settings.clothhat
            ElseIf My.Settings.inv4 = "plaBody" Then
                inv4.Image = My.Resources.plaBody
                inve4.Text = My.Settings.plabody
            ElseIf My.Settings.inv4 = "plalegs" Then
                inv4.Image = My.Resources.plaLegs
                inve4.Text = My.Settings.plalegs
            ElseIf My.Settings.inv4 = "plaboots" Then
                inv4.Image = My.Resources.plaBoots
                inve4.Text = My.Settings.plaboots
            ElseIf My.Settings.inv4 = "plahelm" Then
                inv4.Image = My.Resources.plaHelm
                inve4.Text = My.Settings.plahelm
            ElseIf My.Settings.inv4 = "maiBody" Then
                inv4.Image = My.Resources.maiBody
                inve4.Text = My.Settings.maibody
            ElseIf My.Settings.inv4 = "mailegs" Then
                inv4.Image = My.Resources.maiLegs
                inve4.Text = My.Settings.mailegs
            ElseIf My.Settings.inv4 = "maiboots" Then
                inv4.Image = My.Resources.maiBoots
                inve4.Text = My.Settings.maiboots
            ElseIf My.Settings.inv4 = "maihelm" Then
                inv4.Image = My.Resources.maiHelm
                inve4.Text = My.Settings.maihelm
            ElseIf My.Settings.inv4 = "leaBody" Then
                inv4.Image = My.Resources.leaBody
                inve4.Text = My.Settings.leabody
            ElseIf My.Settings.inv4 = "lealegs" Then
                inv4.Image = My.Resources.leaLegs
                inve4.Text = My.Settings.lealegs
            ElseIf My.Settings.inv4 = "leaboots" Then
                inv4.Image = My.Resources.leaBoots
                inve4.Text = My.Settings.leaboots
            ElseIf My.Settings.inv4 = "leahelm" Then
                inv4.Image = My.Resources.leaHelm
                inve4.Text = My.Settings.leahelm
            ElseIf My.Settings.inv4 = "fdraBody" Then
                inv4.Image = My.Resources.fdraBody
                inve4.Text = My.Settings.fdraBody
            ElseIf My.Settings.inv4 = "fdralegs" Then
                inv4.Image = My.Resources.fdraLegs
                inve4.Text = My.Settings.fdraLegs
            ElseIf My.Settings.inv4 = "fdraboots" Then
                inv4.Image = My.Resources.fdraBoots
                inve4.Text = My.Settings.fdraBoots
            ElseIf My.Settings.inv4 = "fdrahelm" Then
                inv4.Image = My.Resources.fdraHelm
                inve4.Text = My.Settings.fdraHelm
            ElseIf My.Settings.inv4 = "bAm" Then
                inv4.Image = My.Resources.bAm
                inve4.Text = My.Settings.bAm
            ElseIf My.Settings.inv4 = "fstaff" Then
                inv4.Image = My.Resources.fStaff
                inve4.Text = My.Settings.fStaff
            ElseIf My.Settings.inv4 = "gAm" Then
                inv4.Image = My.Resources.gAm
                inve4.Text = My.Settings.gAm
            ElseIf My.Settings.inv4 = "glbCape" Then
                inv4.Image = My.Resources.GlbCape
                inve4.Text = My.Settings.glbCape
            ElseIf My.Settings.inv4 = "legCape" Then
                inv4.Image = My.Resources.legCape
                inve4.Text = My.Settings.legCape
            ElseIf My.Settings.inv4 = "legAm" Then
                inv4.Image = My.Resources.legAm
                inve4.Text = My.Settings.legAm
            ElseIf My.Settings.inv4 = "gring" Then
                inv4.Image = My.Resources.gRing
                inve4.Text = My.Settings.gRing
            ElseIf My.Settings.inv4 = "legring" Then
                inv4.Image = My.Resources.legRing
                inve4.Text = My.Settings.legRing
            ElseIf My.Settings.inv4 = "legstaff" Then
                inv4.Image = My.Resources.legStaff
                inve4.Text = My.Settings.legStaff
            ElseIf My.Settings.inv4 = "oring" Then
                inv4.Image = My.Resources.oRing
                inve4.Text = My.Settings.oRing
            ElseIf My.Settings.inv4 = "pring" Then
                inv4.Image = My.Resources.pRing
                inve4.Text = My.Settings.pRing
            ElseIf My.Settings.inv4 = "yam" Then
                inv4.Image = My.Resources.yAm
                inve4.Text = My.Settings.yAm
            ElseIf My.Settings.inv4 = "pam" Then
                inv4.Image = My.Resources.pAm
                inve4.Text = My.Settings.pAm
            ElseIf My.Settings.inv4 = "lstaff" Then
                inv4.Image = My.Resources.lStaff
                inve4.Text = My.Settings.lStaff
            ElseIf My.Settings.inv4 = "pstaff" Then
                inv4.Image = My.Resources.pStaff
                inve4.Text = My.Settings.pStaff
            ElseIf My.Settings.inv4 = "wstaff" Then
                inv4.Image = My.Resources.wStaff
                inve4.Text = My.Settings.wStaff
            ElseIf My.Settings.inv4 = "rpcape" Then
                inv4.Image = My.Resources.rpCape
                inve4.Text = My.Settings.rpCape
            ElseIf My.Settings.inv4 = "tbcape" Then
                inv4.Image = My.Resources.tBCape
                inve4.Text = My.Settings.tbCape
            ElseIf My.Settings.inv4 = "legdagger" Then
                inv4.Image = My.Resources.legDagger
                inve4.Text = My.Settings.legDagger
            ElseIf My.Settings.inv4 = "legsword" Then
                inv4.Image = My.Resources.legSword
                inve4.Text = My.Settings.legSword
            ElseIf My.Settings.inv4 = "gdagger" Then
                inv4.Image = My.Resources.gDagger
                inve4.Text = My.Settings.gdagger
            ElseIf My.Settings.inv4 = "odagger" Then
                inv4.Image = My.Resources.oDagger
                inve4.Text = My.Settings.odagger
            ElseIf My.Settings.inv4 = "rdagger" Then
                inv4.Image = My.Resources.rDagger
                inve4.Text = My.Settings.rdagger
            ElseIf My.Settings.inv4 = "gsword" Then
                inv4.Image = My.Resources.gSword
                inve4.Text = My.Settings.gsword
            ElseIf My.Settings.inv4 = "psword" Then
                inv4.Image = My.Resources.pSword
                inve4.Text = My.Settings.psword
            ElseIf My.Settings.inv4 = "rsword" Then
                inv4.Image = My.Resources.rSword
                inve4.Text = My.Settings.rsword
            ElseIf My.Settings.inv4 = "cpbadge" Then
                inv4.Image = My.Resources.cpPoint
                inve4.Text = My.Settings.cpPoints
            ElseIf My.Settings.inv4 = "hp25" Then
                inv4.Image = My.Resources.hp25
                inve4.Text = My.Settings.hp25
            ElseIf My.Settings.inv4 = "hp50" Then
                inv4.Image = My.Resources.hp50
                inve4.Text = My.Settings.hp50
            ElseIf My.Settings.inv4 = "hp100" Then
                inv4.Image = My.Resources.hp100
                inve4.Text = My.Settings.hp100
            ElseIf My.Settings.inv4 = "en25" Then
                inv4.Image = My.Resources.pow25
                inve4.Text = My.Settings.en25
            ElseIf My.Settings.inv4 = "en50" Then
                inv4.Image = My.Resources.pow50
                inve4.Text = My.Settings.en50
            ElseIf My.Settings.inv4 = "en100" Then
                inv4.Image = My.Resources.pow100
                inve4.Text = My.Settings.en100
            ElseIf My.Settings.inv4 = "poke" Then
                inv4.Image = My.Resources.poke
                inve4.Text = My.Settings.Poke
            End If

    Gaining item loot from a fight and it being stored in the first open inventory slot

    If My.Settings.inv2 = "" Or My.Settings.inv2 = "fvisage" Then
                                        My.Settings.inv2 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv3 = "" Or My.Settings.inv3 = "fvisage" Then
                                        My.Settings.inv3 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv4 = "" Or My.Settings.inv4 = "fvisage" Then
                                        My.Settings.inv4 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv5 = "" Or My.Settings.inv5 = "fvisage" Then
                                        My.Settings.inv5 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv6 = "" Or My.Settings.inv6 = "fvisage" Then
                                        My.Settings.inv6 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv7 = "" Or My.Settings.inv7 = "fvisage" Then
                                        My.Settings.inv7 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv8 = "" Or My.Settings.inv8 = "fvisage" Then
                                        My.Settings.inv8 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv9 = "" Or My.Settings.inv9 = "fvisage" Then
                                        My.Settings.inv9 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv10 = "" Or My.Settings.inv10 = "fvisage" Then
                                        My.Settings.inv10 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv11 = "" Or My.Settings.inv11 = "fvisage" Then
                                        My.Settings.inv11 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv12 = "" Or My.Settings.inv12 = "fvisage" Then
                                        My.Settings.inv12 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv13 = "" Or My.Settings.inv13 = "fvisage" Then
                                        My.Settings.inv13 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv14 = "" Or My.Settings.inv14 = "fvisage" Then
                                        My.Settings.inv14 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv15 = "" Or My.Settings.inv15 = "fvisage" Then
                                        My.Settings.inv15 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv16 = "" Or My.Settings.inv16 = "fvisage" Then
                                        My.Settings.inv16 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv17 = "" Or My.Settings.inv17 = "fvisage" Then
                                        My.Settings.inv17 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv18 = "" Or My.Settings.inv18 = "fvisage" Then
                                        My.Settings.inv18 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv19 = "" Or My.Settings.inv19 = "fvisage" Then
                                        My.Settings.inv19 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    ElseIf My.Settings.inv20 = "" Or My.Settings.inv2 = "fvisage" Then
                                        My.Settings.inv20 = "fvisage"
                                        My.Settings.fvisage = My.Settings.fvisage + 1
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "You've also found a Flaming Visage!", vbOKOnly, "Loot")
                                    Else
                                        MsgBox("You gained: " + fgold.ToString + " gold" & vbNewLine & "You gained: " + fExp.ToString + " experience." & vbNewLine & "Due to lack of inventory space, you had to leave the Flaming visage behind.", vbOKOnly, "Better than nothing!")
                                    End If

    This is my "equip" method that occurs when clicking one of the picture boxes
    it is in a switch case that switches to, in this perticular case, what is stored in my.settings.inv2

    Case clothbody
                    If My.Settings.clothbody - 1 = 0 Then
                        If My.Settings.body = "" Then
                            inv2.Image = My.Resources.nothng
                            My.Settings.inv2 = ""
                            inve2.Text = "-"
                            chrScreen.body.Image = My.Resources.clothBody
                            My.Settings.armor = My.Settings.armor + 30
                            My.Settings.body = "clothbody"
                            My.Settings.clothbody = My.Settings.clothbody - 1
                        ElseIf My.Settings.body = "clothbody" Then
                        Else
                            Dim x As String
                            Dim mre As String
                            x = My.Settings.body
                            mre = "my.resources." & x
                            My.Settings.body = "clothbody"
                            If My.Settings.inv2 = x Then
                                inv2.Image = My.Resources.nothng
                                inve2.Text = "-"
                            ElseIf My.Settings.inv3 = x Then
                                inv3.Image.Tag = mre
                                inv3.Image = inv3.Image.Tag
                                inve3.Text = "-"
                            ElseIf My.Settings.inv4 = x Then
                                inv4.Image = My.Resources.nothng
                                inve4.Text = "-"
                            ElseIf My.Settings.inv5 = x Then
                                inv5.Image = My.Resources.nothng
                                inve5.Text = "-"
                            ElseIf My.Settings.inv6 = x Then
                                inv6.Image = My.Resources.nothng
                                inve6.Text = "-"
                            ElseIf My.Settings.inv7 = x Then
                                inv7.Image = My.Resources.nothng
                                inve7.Text = "-"
                            ElseIf My.Settings.inv8 = x Then
                                inv8.Image = My.Resources.nothng
                                inve8.Text = "-"
                            ElseIf My.Settings.inv9 = x Then
                                inv9.Image = My.Resources.nothng
                                inve9.Text = "-"
                            ElseIf My.Settings.inv10 = x Then
                                inv10.Image = My.Resources.nothng
                                inve10.Text = "-"
                            ElseIf My.Settings.inv11 = x Then
                                inv11.Image = My.Resources.nothng
                                inve11.Text = "-"
                            ElseIf My.Settings.inv12 = "" Then
                                inv12.Image = My.Resources.nothng
                                inve12.Text = "-"
                            ElseIf My.Settings.inv13 = x Then
                                inv13.Image = My.Resources.nothng
                                inve13.Text = "-"
                            ElseIf My.Settings.inv14 = x Then
                                inv14.Image = My.Resources.nothng
                                inve14.Text = "-"
                            ElseIf My.Settings.inv15 = x Then
                                inv15.Image = My.Resources.nothng
                                inve15.Text = "-"
                            ElseIf My.Settings.inv16 = x Then
                                inv16.Image = My.Resources.nothng
                                inve16.Text = "-"
                            ElseIf My.Settings.inv17 = x Then
                                inv17.Image = My.Resources.nothng
                                inve17.Text = "-"
                            ElseIf My.Settings.inv18 = x Then
                                inv18.Image = My.Resources.nothng
                                inve18.Text = "-"
                            ElseIf My.Settings.inv19 = x Then
                                inv19.Image = My.Resources.nothng
                                inve19.Text = "-"
                            ElseIf My.Settings.inv20 = x Then
                                inv20.Image = My.Resources.nothng
                                inve20.Text = "-"
                            End If
                            End If
                    ElseIf My.Settings.clothbody = 0 Then
                            inv2.Image = My.Resources.nothng
                            My.Settings.inv2 = ""
                            inve2.Text = "-"
                    Else
                            chrScreen.body.Image = My.Resources.clothBody
                            My.Settings.armor = My.Settings.armor + 30
                            My.Settings.clothbody = My.Settings.clothbody - 1
                            inve2.Text = My.Settings.clothbody
                            My.Settings.body = "clothbody"
                    End If
                Case clothlegs
                        If My.Settings.clothlegs - 1 = 0 Then
                            inv2.Image = My.Resources.nothng
                            My.Settings.inv2 = ""
                            inve2.Text = "-"
                            chrScreen.legs.Image = My.Resources.clothLegs
                            My.Settings.armor = My.Settings.armor + 25
                            My.Settings.legs = "clothlegs"
                            My.Settings.clothlegs = My.Settings.clothlegs - 1
                        ElseIf My.Settings.clothlegs = 0 Then
                            inv2.Image = My.Resources.nothng
                            My.Settings.inv2 = ""
                            inve2.Text = "-"
                        Else
                            chrScreen.legs.Image = My.Resources.clothLegs
                            My.Settings.armor = My.Settings.armor + 25
                            My.Settings.clothlegs = My.Settings.clothlegs - 1
                            inve2.Text = My.Settings.clothlegs
                            My.Settings.legs = "clothlegs"
                        End If

    The whole 'Elseif my.settings.inv2 = x then' thing was suppossed to be for in cases where you already have a item equipped in that slot but that seems to not work and I can't seem to grab the 'item' from the character screen and bring it back to the inventory screen without causing a problem.

    Now, I know my code is very inefficient and long and probably overall unnecessary but I'm stuck and confused and have no idea what I should be doing. By looking at this could anyone please be able to teach me a more efficient and easier method of doing this? I tried creating a new class and making a function, that I'd be able to call on in a different, to find the next available slot starting with inv2 (inv1 always has gold in it no matter what, even if you have 0 gold) but that didn't work cause I again didn't even know where to start.

    I need to know how to do this the right and most efficient way possible. I read other threads where people said to make a new class define the item and blah blah blah like this:

    Public Class Item
     
        Private itemName As String
        Private Const itemStrength as int = 100
        
        Property Line() As String
            Get
               Return itemName
            End Get
            Set(ByVal Value As String)
                mstrLine = Value
            End Set
        End Property
         
        ReadOnly Property strength() As Integer
           Get
               Return itemStrength
           End Get
        End Property
    End Class

    then using this to populate the array list:

    inherits System.Collections;
     
    ...
     
     dim ar as new Arraylist()
     dim Itm as new Item()
     itm.Type = "Armor"
     itm.Damage = itm.itemStrength
     ar.Add(itm);
     
    Can someone show me how to do this because I am lost.

    Thank you in advance and I hope you all have a great day. :)

Todas las respuestas

  • martes, 14 de agosto de 2012 20:56
    Moderador
     
     

    The good news:  You worked hard to figure out that what you have won't work, but you are willing to change it if necessary.

    The bad new:  You will probably need to change everything you've done so far.  =P

    Let me begin by saying that there is no single best way to do this.  There are a number of approaches which could all be valid.  Much depends on the overall design of the game engine.

    The best way to explain this is probably with a small exmaple.  However, "small" is still going to be several classes and code to make them work together.  You could probably find existing examples in the XNA examples on AppHub, but many of them are in C# (I'm not sure if the example RPG was translated to VB or not - you should check though).  Even if you aren't going to use XNA, you may still learn a lot by looking at how they structure their classes.

    I'll see if I can whip you up a small example without getting too complicated.  It may take some thought though, so please be patient.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

  • martes, 14 de agosto de 2012 21:16
     
     
    Haha That's alright if I have to change everything. I head on over to XNA and check out what they have, and an example would be nice. Thank you, I'll be patient as ever. :)
  • martes, 14 de agosto de 2012 21:55
    Moderador
     
     Respondida Tiene código

    Ok, here's a really short and simple example - to simple really as I'm sure you'll want more in your game, but lets take a look at it first:

    Public Class Form1
        Private Hero As New RpgCharacter
        Private SwordPlus1 As New RpgEquipment With {.Name = "+1 Sword", .Slot = RpgEquipmentSlot.Hand}
        Private SwordPlus2 As New RpgEquipment With {.Name = "+2 Sword", .Slot = RpgEquipmentSlot.Hand}
    
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            Hero.Inventory.AddItem(SwordPlus1)
            Hero.Inventory.AddItem(SwordPlus2)
    
            Debug.Print("Inv Count = " & Hero.Inventory.InventoryCount)
    
            Hero.Equip(SwordPlus1)
            Debug.Print("Inv Count = " & Hero.Inventory.InventoryCount)
            Debug.Print(Hero.Equipment(RpgEquipmentSlot.Hand).Name)
    
            Hero.Equip(SwordPlus2)
            Debug.Print("Inv Count = " & Hero.Inventory.InventoryCount)
            Debug.Print(Hero.Equipment(RpgEquipmentSlot.Hand).Name)
        End Sub
    End Class
    
    Public Class RpgCharacter
        Public Property Equipment As New Dictionary(Of RpgEquipmentSlot, RpgEquipment)
        Public Property Inventory As New RpgInventory
    
        Public Function Equip(item As RpgEquipment) As Boolean
            If Inventory.ItemCount(item) = 0 Then Return False
            Inventory.RemoveItem(item)
            If Equipment.ContainsKey(item.Slot) Then
                Dim currentEquipment As RpgEquipment = Equipment(item.Slot)
                If Not Inventory.AddItem(currentEquipment) Then
                    'Inventory is full and previous equipment could not be added to inventory...
                    'drop or discard or overflow as required
                End If
            End If
            Equipment(item.Slot) = item
            Return True
        End Function
    End Class
    
    Public Class RpgItem
        Public Property Name As String
        Public Property Usable As Boolean
        Public Property Charges As Integer
        Public Property Stackable As Boolean
    End Class
    
    Public Class RpgEquipment
        Inherits RpgItem
    
        Public Property Slot As RpgEquipmentSlot
    End Class
    
    Public Class RpgInventory
        Public Property InventorySlots As Integer = 40
    
        Private _ItemList As New Dictionary(Of RpgItem, Integer)
    
        Public Function AddItem(item As RpgItem) As Boolean
            If _ItemList.ContainsKey(item) AndAlso item.Stackable Then
                _ItemList(item) += 1
                Return True
            End If
            If _ItemList.Count < InventorySlots Then
                _ItemList(item) = 1
                Return True
            End If
            Return False
        End Function
    
        Public ReadOnly Property InventoryCount As Integer
            Get
                Return _ItemList.Count
            End Get
        End Property
    
        Public Function ItemCount(item As RpgItem) As Integer
            If _ItemList.ContainsKey(item) Then
                Return _ItemList(item)
            End If
            Return 0
        End Function
    
        Public Function RemoveItem(item As RpgItem) As Boolean
            If _ItemList.ContainsKey(item) Then
                If _ItemList(item) > 1 Then
                    _ItemList(item) -= 1
                    Return True
                Else
                    _ItemList.Remove(item)
                    Return True
                End If
            End If
            Return False
        End Function
    End Class
    
    Public Enum RpgEquipmentSlot
        Head
        Body
        Hand
        Feet
    End Enum
     

    So starting at the bottom, we define the available equipment slots in an Enum. Note that this simple example assumes that a given piece of gear only goes into one slot. But your real game may want an "MainHand" and "OffHand" for instance, and some weapons may go in either while others only go in one or the other. That can certainly be done, and the enum would probably be changed to flags to support multiple possible slots per item, but the equipping code gets too complex so the example is using just one slot per item to keep things simple.

    In the middle we define an RpgItem which is anything the player can pickup.  The item has a few example properties to show that it may be consumable and may have multiple charges (uses) before it runs out.  There is also an example property for saying whether or not we can stack multiple items of the same kind in a single inventory slot.

    After the RpgItem, we define a RpgEquipment object.  Equipment is really just a item that the user can wear.  So it can have charges or be consumable, but it also designates the slot that it equips to.

    Below the Equipment we create an RpgInventory to represent the user inventory.  Note that this class may actually want to implement IList or a dictionary interface, but to keep the example small this was excluded.  I just added a few minimum methods to manipulate the inventory.  We can add an item to the inventory which will stack items if they are stackable or add them if there is still space left.  The method returns true or false to indicate if the addition was successful or not.  We can get a count of all items in the inventory (not counting stack size, just consumed inventory slots) and we can get a count for a particular item (1 for non stackable, and the stack count for stackable items).  Finally we can remove an item from the inventory by either reducing the stack count or completely removing the item if it is the last in the stack or not stackable.

    Finally back up toward the top we define the RpgCharacter.  The character holds its Inventory and Equipment collections (again, Inventory is not a real collection at this point, but could and probably should be expanded into one).  We provide a simple Equip method that takes an item from inventory and equips it on the appropriate slot while removing any existing equipment in that slot already and returning it to the inventory (if there is space - you would have to replace the comments with logic to do whatever you want should the inventory be full).

    This is a VERY oversimplified example.  But hopefully it gives you a rough idea and also makes apparent the places where your game design determine the code functionality.  Everything ultimately depends on how the game works.  Will you have items that fit more than one slot?  If not this logic is a good start, if so, it needs considerable expansion.  And thats just one example...

    So it will be very important to determine all of the desired game functionality ahead of time.  Once you get started on designing these supporting classes, you don't want to decide to do something different in the game-play... it could quickly turn into a major rewrite.

    Hope that helps, but let me know if its all still very confusing!


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marcado como respuesta magnite7 martes, 14 de agosto de 2012 22:37
    • Desmarcado como respuesta magnite7 martes, 14 de agosto de 2012 22:37
    • Marcado como respuesta magnite7 martes, 14 de agosto de 2012 22:38
    •  
  • martes, 14 de agosto de 2012 22:37
     
      Tiene código

    Thank you so very much this will help me a lot in the future and give me something to look off of and to learn from. :) Although it has come to my attention that I'm going to have to start from scratch just to implement something like this. Haha. There are a few things that are still confusing, mainly cause I have never used nor heard of them before:

    I have never heard of Dictionarys before, mind explaing what those are used for? I get the general idea of the code you provided but better ask and know for sure now then have to come back. Along with your statements, "Note that this class may actually want to implement IList or a dictionary interface IList or a dictionary interface" && "collections (again, Inventory is not a real collection at this point, but could and probably should be expanded into one" mind elaborating, how to do so, what they are? :D

    Private _ItemList As New Dictionary(Of RpgItem, Integer)

    Also when you defined this dictionary you have integer, why ineteger?

    You defined the +1 Sword and +2 Sword at the top, would it be possible to define ALL my items in a completely different class then import them into this one? Just so I'm not overcrowding this one.

    You've been mroe help in this hour and half then I've gotten since 9 this morning trying to figure this out and for that I thank you so very much for taking your time to make me that example!

  • miércoles, 15 de agosto de 2012 15:59
    Moderador
     
     

    Well, it looks like you are asking all the right questions and already getting the right ideas about moving forward.  I think you're going to make an excellent programmer.  :)

    I'll try to give you some simple answers to your questions, but also keep in mind that the F1 key is your best friend!  If you put your cursor on Dictionary in the code and press F1 it will take you to the online documentation for the class.  There is a ton of information in the MSDN library and you'll be able to get in-depth information on many standard classes.

    A Dictionary is a list of key-value pairs of information.  The key is constrained to be unique within the dictionary and the value can be any other data (it does not have to be unique).  So in the previous example, a Dictionary(Of RpgItem, Integer) gives us a list of unique RpgItem objects each associated with an Integer value.  The reason for choosing integer is that we want to keep a count of how many of a particular item we have in the inventory.  This is to support "stacking" items.  So when we add a new RpgItem to the inventory, it is added with a quantity of 1 unless it is stackable and we already have some of the item - then we just increment the count.

    Having just talked though this, I realize there is a weakness in the design in that you could not carry two of the same item if it is not stackable.  This is probably not desired so we'd need a different design for the Inventory class.  LOL Like I said, this is too simple of a solution for a real game.  =P

    Rather than use an existing collection object (such as the generic List(Of T) or Dictionary(Of TKey, TValue), you can create your own custom lists by implementing the ICollection, IList, IDictionary, etc. interfaces.  This is getting into some general class design detail that would be better covered by reading up on custom collections in MSDN (it would be a lot to try and cover in a simple forum post).  Here are a few links to get you started:

    http://msdn.microsoft.com/en-us/library/7y3x785f

    http://msdn.microsoft.com/en-us/library/ms172192

    http://msdn.microsoft.com/en-us/library/bb762916.aspx

    http://msdn.microsoft.com/en-us/library/bb762928.aspx

    Now then, onto defining your items... you've got the right idea!  You would likely create a class whose primary purpose is to generate a series of RpgItem instances based on some list of data that you provide with your game.  A simple example would be a text file that provides all of the details for each item.  The "RpgItem Factory" class would be able to read and parse this text file and then use the data to generate a series of RpgItems.  From that point on the rest of the game code would just access instances of these RpgItem objects and use them as needed (or make copies of them if needed).  This part is determined mostly by the resource managment scheme you choose for your game (again, no real single answer for this - there are a number of acceptable ways of storing and loading game data).  And you wouldn't necessarily pre-load every possible item; you might have the item definitions in a database file of some sort and the factory class would just create a single new instance of an RpgItem as needed.

    At this point I think your next step is to outline all of the intended functionality of the game.  Decide what kinds of items you'll have and how the player will store them in their inventory, use them, or equip them.  You probably don't need a strict definition of the entire game, but a rough idea of most of it would be good to have before you start to code.

    Feel free to ask any other questions or seek advice!


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

  • miércoles, 15 de agosto de 2012 17:39
     
     
    Reed, while I was spluttering my two sentences, you came up with a complete solution and description. How good I didn't send mine. ;) Good job (again)!

    Armin

  • miércoles, 15 de agosto de 2012 21:44
    Moderador
     
     

    haha Armin, thanks, but don't let me discourage you!  Multiple viewpoints can be helpful for open-ended situations like this one. :)


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

  • jueves, 16 de agosto de 2012 2:40
     
     

    Haha thanks for the compliment! I'm actually going to be started college here on the 27th for Computer Science on the track of Game and Virtual World Development!

    I never knew about the F1 function, but thanks for pointing that out! Gonna have to start using it a lot more often.

    Also, thanks for the Dictionary explaination that makes it much clearer and puts it into perspective for me. But I'm guessing I can't do Dictionary(Of RpgItem, Integer, Integer) to sovle the stacking problem? ;P The first integer being qauntity stacked, and second being quantity total? Or is that where custom lists would come in?

    And thanks for the links, I'll be sure to go through them thoroughly! I also started my outline like you suggested.

    Four thanks in this post. Just to bad I can't vote as helpful four times! ;)

  • jueves, 16 de agosto de 2012 19:40
    Moderador
     
      Tiene código

    Hi magnite7,

    If you wanted the dictionary to be able to represent an item, a "max stack qty" and a "current stack qty" then you could do it using another custom class.  Please consider the following:

    Public Class RpgInventory
        Private _Items As New Dictionary(Of RpgItem, RpgStack)
    End Class
    
    Public Class RpgStack
        Public Property MaximumStackSize As Integer
        Public Property CurrentStackCount As Integer
    End Class

    So while we can't create a Dictionary(Of RpgItem, Integer, Integer), we can create a new type to encapsulate the two integer values and then use that type as the value for the dictionary.

    =)


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

  • jueves, 16 de agosto de 2012 19:52
     
     

    Well darn I liked my way. lol Thank you for giving that example, as of now I am out of questions but I will be back if any arise. Thank you for all the help that you have given me.

  • martes, 21 de agosto de 2012 20:18
     
      Tiene código

    Hey I've arrived at a brick wall and was hoping for some advice.

    Firstly, I wanted to add a save/load game feature where there are three Load/Save slots (3 different save files basically.)

    I am currently using StreamWriter to write the save files (No problem with this) but loading the save file is where I am having difficulty. I am using System.IO to read the fille and Split it by line into a String Array. The first save file (save001.msav) has no difficultys in being read and correctly splitting the right information but when I try to repeat that process it just duplicates the same variables from the first file and seems to completely ignore the second save file.

    My current code for this is:

    Dim sTemp As String
    Dim save1() As String
    Dim save2() As String
    Dim save3() As String
        Dim temp As New DirectoryInfo("C:\Users\Owner\Desktop\Arena Fighters 2 Dark Ages\")
    saveFilePath = SearchForFile(temp, "save001.msav")
    If IO.File.Exists(saveFilePath) Then
    save1 = IO.File.ReadAllLines(SearchForFiletemp, "save001.msav"))
        sTemp = save1(1).Substring(save1(1).IndexOf("=") + 1)
        _SETTINGS.hasSave = sTemp
        sTemp = save1(2).Substring(save1(2).IndexOf("=") + 1)
        _SETTINGS.s2Name = sTemp
        sTemp = save1(3).Substring(save1(3).IndexOf("=") + 1)
        _SETTINGS.s2Level = sTemp
    End If
    saveFilePath2 = SearchForFile(temp, "save002.msav")
    If IO.File.Exists(saveFilePath) Then
    save2 = IO.File.ReadAllLines(SearchForFiletemp, "save002.msav"))
        sTemp = save2(1).Substring(save2(1).IndexOf("=") + 1)
        _SETTINGS.hasSave = sTemp
        sTemp = save2(2).Substring(save2(2).IndexOf("=") + 1)
        _SETTINGS.s2Name = sTemp
        sTemp = save2(3).Substring(save2(3).IndexOf("=") + 1)
        _SETTINGS.s2Level = sTemp
    End If
    saveFilePath3 = SearchForFile(temp, "save003.msav")
    If IO.File.Exists(saveFilePath) Then
    save3 = IO.File.ReadAllLines(SearchForFiletemp, "save003.msav"))
        sTemp = save3(1).Substring(save3(1).IndexOf("=") + 1)
        _SETTINGS.hasSave = sTemp
        sTemp = save3(2).Substring(save3(2).IndexOf("=") + 1)
        _SETTINGS.s2Name = sTemp
        sTemp = save3(3).Substring(save3(3).IndexOf("=") + 1)
        _SETTINGS.s3Level = sTemp
    End If

    I have each of the variables loaded into a seperate Label.Text for testing purposes but they all come back as the same variables as in Save001, I have even tried manually editing each save file to be 100% positive of this.

    Second, Reed Kimble the class you posted above has come in a lot of use and has helped me a lot but I am stuck on loading the RpgInventory into a visual interface. Right now I have 8 picture boxes that are designated as "Equipped Item Slots" and 21 picture boxes that are designated as "Inventory Slots", 1 item per slot, no Diablo style inventory. I have also added onto the RpgItem to include a .Resource property which links that item with its respective item image. I haven't currently tried to load the dictionary into the inventory slots, but I am working on get the equipped items out of the currentEquipment and grabbing its .Resource and displaying it as the respective pictureboxes images.

    The only thing I have for this so far, since I haven't even got on picturebox to work, is:

    Head.Image.Tag = _HERO.RpgCharacter.Equipment(slot.Head).Resource.ToString

    Any advice? Thanks in advance.
    • Editado magnite7 martes, 21 de agosto de 2012 21:47
    •  
  • martes, 21 de agosto de 2012 20:35
    Moderador
     
      Tiene código

    You would need to use a loop calling IndexOf on the string looking for the first index of "=", and then storing that index.  On the next loop you would pass that index + 1 to IndexOf for the start position parameter.

    However, working with a save game file may be much easier using Serialization.  You could create a simple class with properties to hold the values that you need to save.  Then you mark the class with the Serializable attribute and use a BinaryFormatter to serialze the entire class with all of its property values into a binary file (bytes written to disk).  You can then later use another instance of BinaryFormatter to turn the byte file back into an instance of the save-game class, with all of the property values in-tact.

    Here's a real short example:

    Public Class Form1
    
        Public Sub SaveGame(data As SaveGameData, path As String)
            Dim baseStream As System.IO.FileStream = System.IO.File.Create(path)
            Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            formatter.Serialize(baseStream, data)
            baseStream.Close()
            baseStream.Dispose() 'not explicity required since Close() does this, but its good habit and won't hurt anything
        End Sub
    
        Public Function LoadGame(path As String) As SaveGameData
            Dim baseStream As System.IO.FileStream = System.IO.File.Open(path, IO.FileMode.Open)
            Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            Dim result As SaveGameData = formatter.Deserialize(baseStream)
            baseStream.Close()
            baseStream.Dispose()
            Return result
        End Function
    
    End Class
    
    <Serializable()>
    Public Class SaveGameData
        Public Property PlayTime As TimeSpan
        Public Property SaveDate As Date
        Public Property PlayerData As RpgCharacter
    End Class
    
    <Serializable()>
    Public Class RpgCharacter
        'the character class definition
    End Class
     

    There is also an XML serializer if you prefer, but for a saved game, you typically don't want the user mucking around changing values in clear text.  =)

    -EDIT-

    Oh, I forgot to mention that the one limitation on simple serialization like that is that every Type serialized must have the Serializable attribute.  Notice how I added that attribute to the RpgCharacter class since the SaveGameData includes an instance of RpgCharacter.  This attribute must exist on every type in the chain of data that you are storing.

    Note that intrinsic types such as Int, Double, String, Boolean, etc are all serializable by default.

    You can also implement complex serialization in which you write the code process that serializes the object.  Then your SaveGameData class could contain instances of other classes which do not have the serializable attribute and you could manually save enough information to manually recreate a new instance when loading.

    For more information on simple serialization see:

    http://msdn.microsoft.com/en-us/library/y50tb888(v=vs.100)

    For more information on complex serialization see:

    http://msdn.microsoft.com/en-us/library/wf4375ks(v=vs.100)


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


  • martes, 21 de agosto de 2012 21:49
     
     

    Thanks, that actually seems way simpler.

    Any advice on the second part?

  • miércoles, 22 de agosto de 2012 2:53
     
      Tiene código

    I played around with the dictionarys and was finally able to retrieve the item from the dict.

    Heres the code for anyone else who reads this thread:

    Dim item as RpgEquipment = _ITEMS.dScaleHelm

    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click _HERO.RpgInventory.AddItem(item) _HERO.RpgCharacter.Equip(item) Dim output As String output = _HERO.RpgCharacter.Equipment.Item(RpgEquipmentSlot.Head).Name MsgBox(output, vbOKOnly) End Sub

    When the button is clicked the item is automatically added to the inventory then equiped at which point output is defined with the name of the item equiped in the Head slot.

    When I did this though, I made a HERO class a lot like the example Reed gave me above. And in order to call the equip and additem outside of that class I had to add 'Shared' to almost every function inside my HERO class. Is that bad? Or will the Shared being there not really hurt anything?