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 :D
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;
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 |