Diablo Inventory, so far, with bug :(
BlitzMax Forums/BlitzMax Programming/Diablo Inventory, so far, with bug :(
| ||
Hi all, for a matter or weeks now I've been trying to create a diablo inventory system, which handles multi-sized objects, I've tried many different ways but all have failed so far, this is the method where I have got the furthest, okay, every slot created handles it's own collision detection, the inventory creates it's own slots and I have a mouse class which has it's own slots, it's very basic at the moment, just to demostrate to you the problem, if a collision is detected each slot draws a "C" that works, but if I change the color of the slot, it's changes the slot behind it?? Really odd :S See if any of you talented guys can spot the problem :DSuperStrict Type CSlot Field m_ID:Int; Field m_x:Int, m_y:Int; Field m_red:Int, m_green:Int, m_blue:Int; Field m_mouseSelected:Int = False; Field m_hover:Int = False; Function Create:CSlot(x:Int, y:int, red:Int, green:Int, blue:Int) Local slot:CSlot = New CSlot; slot.m_x = x; slot.m_y = y; slot.m_red = red; slot.m_green = green; slot.m_blue = blue; slot_list.AddLast(slot) ; return slot; End Function Method changeColor(red:Int, green:Int, blue:Int) Self.m_red = red; Self.m_green = green; Self.m_blue = blue; End Method Method Draw(x:Int, y:Int) Self.m_x = x; Self.m_y = y; DrawText(Self.m_x, Self.m_x, Self.m_y + 30) ; DrawText(Self.m_y, Self.m_x + 30, Self.m_y + 30) ; SetColor(m_red, m_green, m_blue) ; DrawRect(Self.m_x, Self.m_y, 30, 30) ; If Self.collide() Self.changeColor(255, 255, 255) ; SetColor(255, 0, 0) ; DrawText("C", m_x + 10, m_y + 10) ; Else Self.changeColor(150, 150, 150) ; EndIf End Method Method collide:int() For Local slot:CSlot = EachIn slot_list If slot <> Self Then If RectsOverlap(Self.m_x, Self.m_y, 30, 30, slot.m_x, slot.m_y, 30, 30) return True; End If End If Next End Method Method RectsOverlap:int(x0:Int, y0:Int, w0:Int, h0:Int, x2:Int, y2:Int, w2:Int, h2:Int) If x0 > (x2 + w2) Or (x0 + w0) < x2 Then Return False If y0 > (y2 + h2) Or (y0 + h0) < y2 Then Return False Return True End Method End Type Type CInventory Field m_x:Int, m_y:Int; Field m_slot:CSlot; Field m_columns:Int, m_rows:Int; Function Create:CInventory(x:Int, y:int, columns:Int, rows:Int) Local inv:CInventory = New CInventory; inv.m_x = x; inv.m_y = y; inv.m_columns = columns; inv.m_rows = rows; inv.createSlots(); entity_list.AddLast(inv) ; return inv; End Function Method createSlots() For Local columns:Int = 0 Until m_columns For Local rows:Int = 0 Until m_rows m_slot = CSlot.Create(columns * 31 + m_x, rows * 31 + m_y, 150, 150, 150) ; Next Next End Method Method Draw() For Local columns:Int = 0 Until m_columns For Local rows:Int = 0 Until m_rows m_slot.Draw(columns * 31 + m_x, rows * 31 + m_y) Next Next End Method End Type Type CMouse Field m_x:Int, m_y:Int; Field m_slot:CSlot; Field m_columns:Int, m_rows:Int; Function Create:CMouse(x:Int, y:Int, columns:Int, rows:Int) Local mouse:CMouse = New CMouse; mouse.m_x = x; mouse.m_y = y; mouse.m_columns = columns; mouse.m_rows = rows; mouse.createSlots() ; entity_list.AddLast(mouse) ; return mouse; End Function Method createSlots() For Local columns:Int = 0 Until m_columns For Local rows:Int = 0 Until m_rows m_slot = CSlot.Create(columns * 31 + m_x, rows * 31 + m_y, 150, 150, 150) ; Next Next End Method Method Draw() m_x = MouseX() ; m_y = MouseY() ; For Local columns:Int = 0 Until m_columns For Local rows:Int = 0 Until m_rows m_slot.Draw(columns * 31 + m_x, rows * 31 + m_y) Next Next End Method End Type Graphics(800, 600); Global entity_list:TList = New TList; Global slot_list:TList = New TList; Local inventory:CInventory = CInventory.Create(50, 50, 5, 5) ; Local mouse:CMouse = CMouse.Create(MouseX(), MouseY(), 2, 3) ; 'MoveMouse(300, 300) ; While Not KeyHit(KEY_ESCAPE) Cls SortList(entity_list) ; inventory.Draw() ; mouse.Draw() ; Flip Wend End |
| ||
The main problem comes from the fact that you: 1. Did not modularize it. You check for stuff all over the place. Above that it does not seem to be thought out at all. You have a draw that should be basing on m_x, m_y, yet you still send positions there -> defeats the point of storing anything within. 2. you only draw a single cell actually. You always draw m_slot ... you do not iterate through the slots ... your approach with the outer loops is for arrays but the handling is list ... thats "bullshit" Either put it in an array and use the outer 2 loops or use a single loop over the list. 3. Dont see why you use manual rect collision as you know that the inventory won't move you can build a whole layer of static data that never needs to be cleared and rewritten ... thats several worlds faster than twin loops of math collision. below code works but isn't the "cleanest" ... was a quick hack to yours only SuperStrict Type CSlot Field m_ID:Int; Field m_x:Int, m_y:Int; Field m_red:Int, m_green:Int, m_blue:Int; Field m_mouseSelected:Int = False; Field m_hover:Int = False; Field collision:Int = False Function Create:CSlot(x:Int, y:Int, red:Int, green:Int, blue:Int,list:TList) Local slot:CSlot = New CSlot; slot.m_x = x; slot.m_y = y; slot.m_red = red; slot.m_green = green; slot.m_blue = blue; list.AddLast(slot) ; Return slot; End Function Method changeColor(red:Int, green:Int, blue:Int) Self.m_red = red; Self.m_green = green; Self.m_blue = blue; End Method Method Draw(x:Int, y:Int) DrawText(Self.m_x+x, Self.m_x+x, Self.m_y+y + 30) ; DrawText(Self.m_y+y, Self.m_x+x + 30, Self.m_y+y + 30) ; If Self.collision Self.changeColor(255, 255, 255) ; Else Self.changeColor(150, 150, 150) ; EndIf SetColor(m_red, m_green, m_blue) ; DrawRect(Self.m_x+x, Self.m_y+y, 30, 30) ; If Self.collision SetColor(255, 0, 0) ; DrawText("C", m_x+x + 10, m_y+y + 10) ; EndIf End Method End Type Type CInventory Field m_x:Int, m_y:Int; Field m_slot:CSlot; Field m_columns:Int, m_rows:Int; Field inventorySlotList:TList = New TList Function Create:CInventory(x:Int, y:Int, columns:Int, rows:Int) Local inv:CInventory = New CInventory; inv.m_x = x; inv.m_y = y; inv.m_columns = columns; inv.m_rows = rows; inv.createSlots(inv.inventorySlotList); entity_list.AddLast(inv) ; Return inv; End Function Method createSlots(list:TList) For Local columns:Int = 0 Until m_columns For Local rows:Int = 0 Until m_rows m_slot = CSlot.Create(columns * 31 + m_x, rows * 31 + m_y, 150, 150, 150,list) ; CollideRect(m_slot.m_x,m_slot.m_y,30,30,0,COLLISION_LAYER_30,m_slot) Next Next End Method Method Draw(x:Int, y:Int) For m_slot = EachIn inventorySlotList m_slot.Draw(x, y) Next End Method Method resetCollision() For Local t:cslot = EachIn inventorySlotList t.collision = False Next End Method End Type Type CMouse Field m_x:Int, m_y:Int; Field m_slot:CSlot; Field m_columns:Int, m_rows:Int; Field mouseSlotList:TList = New TList Function Create:CMouse(x:Int, y:Int, columns:Int, rows:Int) Local mouse:CMouse = New CMouse; mouse.m_x = x; mouse.m_y = y; mouse.m_columns = columns; mouse.m_rows = rows; mouse.createSlots(mouse.mouseSlotList) ; entity_list.AddLast(mouse) ; Return mouse; End Function Method createSlots(list:TList) For Local columns:Int = 0 Until m_columns For Local rows:Int = 0 Until m_rows m_slot = CSlot.Create(columns * 31 + m_x, rows * 31 + m_y, 150, 150, 150,list) ; Next Next End Method Method Draw(x:Int, y:Int) For m_slot = EachIn mouseSlotList m_slot.Draw(x,y) Next End Method Method collide:Int(inventory:cinventory) inventory.resetCollision() Local slot:cslot, col:Object[] For slot = EachIn mouseSlotList slot.collision = False col = CollideRect(slot.m_x+MouseX(), slot.m_y+MouseY(), 30, 30, COLLISION_LAYER_30, 0 ) If col <> Null slot.collision = True 'DebugStop Local slot2:cslot For slot2 = EachIn col slot2.collision = True Next EndIf Next End Method End Type Graphics(800, 600); Global entity_list:TList = New TList; Global slot_list:TList = New TList; Local inventory:CInventory = CInventory.Create(50, 50, 5, 5) ; Local mouse:CMouse = CMouse.Create(0, 0, 2, 3) ; MoveMouse(300, 300) ; While Not KeyHit(KEY_ESCAPE) Cls mouse.collide(inventory) inventory.Draw(0,0) ; mouse.Draw(MouseX(), MouseY()) ; Flip Wend End |