I'm done.I have one last issue.When i create few items and start moving one of them others loose depth near transparent parts of the image.
Here is my solution for when you move item in inventory:
if _SelectedItem > 0
rem display selected item
if items(_SelectedItem).image > 0
draw to image imgInv
cls 0
draw to bitmap 0
paste image items(_SelectedItem).image, mousex()-(items(_SelectedItem).invWidth/2.0)*ImgSize, mousey()-(items(_SelectedItem).invHeight/2.0)*ImgSize, 1
endif
rem if mouse clicked and is outside the inventory and stat window, drop the item in a puff of smoke
if _MC = 1
if mouseWithin(invX+16, invY+16, invX+456, invY+329) = 0
mFlag = 1
smokeX = mousex()-64
smokeY = mousey()-88
killItemSmoke = 1
_SelectedItem = 0
rem if deleting an item selected from inventory, remove if from array
if TEMP_INV_ITEM > -1
array delete element invItems(), TEMP_INV_ITEM
TEMP_INV_ITEM = -1
gosub _SaveInventory
endif
endif
endif
endif
RETURN
Here is the part that draws items in inventory:
REM ===============================================================
REM Draws all items in the inventory
REM ===============================================================
_DrawInventoryItems:
itemCount = array count(invItems())
for i = 0 to itemCount
if invItems(i).itemPAGE = CURRENT_PAGE
`ix = invX+43 + invItems(i).gridX*ImgSize
`iy = invY+59-invScrollY + invItems(i).gridY*ImgSize
rem don't draw the inventory item if its currently selected
if i <> TEMP_INV_ITEM
rem draw inventory items to image
draw to image imgInv
if items(invItems(i).itemID).image > 0
paste image items(invItems(i).itemID).image, invItems(i).gridX*ImgSize, invItems(i).gridY*ImgSize, 1
`paste image items(invItems(i).itemID).image, invItems(i).gridX*ImgSize, invItems(i).gridY*ImgSize, 1
`paste image items(invItems(i).itemID).image, invItems(i).gridX*ImgSize, invItems(i).gridY*ImgSize, 1
`paste image items(invItems(i).itemID).image, invItems(i).gridX*ImgSize, invItems(i).gridY*ImgSize, 1
`paste image items(invItems(i).itemID).image, invItems(i).gridX*ImgSize, invItems(i).gridY*ImgSize, 1
endif
rem go back to drawing on screen
draw to bitmap 0
endif
endif
next i
RETURN
Here is the whole thing:
REM ***********************************
REM Title: RPG UI System
REM Author: Phaelax
REM Date: Aug 20, 2011
REM ***********************************
set display mode 1280, 720, 32
set window position 0,0
sync on
#CONSTANT TT_BLACK 0xAA000000
#CONSTANT C_GREEN = 0x4400FF00
#CONSTANT C_RED = 0x44FF0000
Global TEMP_INV_ITEM = -1
Global CURRENT_PAGE = 1
Global ImgSize = 64
Global invOffsetY = 0
Global gridWidth = 6
Global gridHeight = 6
maxInvItems = gridWidth*gridHeight
maxInvHeight = gridHeight*64
Type Inventory_Slot
Taken as boolean
Endtype
Type Item_Object
name as string
image as integer
invWidth as byte
invHeight as byte
isStackable as boolean
Endtype
Type Inventory_Item
itemID as integer
itemPAGE as integer
qty as byte
gridX as integer
gridY as integer
Endtype
rem array of different available items in the game
dim items(0) as Item_Object
rem items in the player's inventory
dim invItems(0) as Inventory_Item
rem item slots in the inventory
dim invSlot(maxInvItems) as Inventory_Slot
loadItemDatabase()
d3d_init
load image "inv_window.png", 13, 1
create animated sprite 4, "smoke2.png", 8, 2, 14
load image "cursor.png", 98, 1
d3d_font 1, "Myriad Pro", 26, 0, 0, 0
d3d_font 2, "Myriad Pro", 14, 0, 0, 0
hide mouse
if file exist ("inventory") = 1
`make file "inventory"
open to read 1,"inventory"
read byte 1,items
dim invItems(items)
for i = 0 to items
read byte 1,invItems(i).itemID
read byte 1,invItems(i).itemPAGE
read byte 1,invItems(i).qty
read byte 1,invItems(i).gridX
read byte 1,invItems(i).gridY
read byte 1,items(invItems(i).itemID).image
read byte 1,items(invItems(i).itemID).invWidth
read byte 1,items(invItems(i).itemID).invHeight
read byte 1,items(invItems(i).itemID).isStackable
next i
close file 1
endif
invX = 750 : invY = 120
imgInv = 2
make image imgInv, 385, maxInvHeight
rem this will allow the appearence of precise item scrolling
a2SetClip invX+43, invY+59, invX+428, invY+252
do
`save inventory routine
if _MC = 1 and InventorySaved = 0
gosub _SaveInventory
InventorySaved = 1
endif
if keystate(2) = 1
CURRENT_PAGE = 1
endif
if keystate(3) = 1
CURRENT_PAGE = 2
endif
_MC = mouseclick()
rem controls only needed for this example
if timer() >= timestamp+20
if spacekey() and flag = 0
flag = 1
gosub _Place_Item
endif
if spacekey() = 0 then flag = 0 and placed = 0
timestamp = timer()
endif
gosub _MouseInteraction
gosub _DrawInventoryItems
gosub _DrawInventoryWindow
if _SelectedItem > 0 then gosub _HandleInvItemPlacement
if killItemSmoke > 0 then gosub _DoItemSmoke
rem show mouse cursor
paste image 98, mousex()-4, mousey()-4, 1
rem flags
gosub _CheckFlags
gosub _Frames
set cursor 0,0
print array count(invItems())
text 0,20,"mousex() "+str$(mousex())+" mousey()"+str$(mousey())+" TEMP_INV_ITEM: "+str$(TEMP_INV_ITEM)
text 0,40,"FPS: "+str$(screen fps())
itemCount = array count(invItems())
`if itemCount > 0
if TEMP_INV_ITEM > 0
text 0,60,"invItems().gridX"+str$(invItems(TEMP_INV_ITEM).gridX)
text 0,80,"invItems().gridY"+str$(invItems(TEMP_INV_ITEM).gridY)
text 0,100,"invItems(_SelectedItem).itemID"+str$(invItems(TEMP_INV_ITEM).itemID)
text 0,120,"items(_SelectedItem).image"+str$(items(invItems(TEMP_INV_ITEM).itemID).image)
endif
if _SelectedItem > 0
text 0,140,"invItems(TEMP_INV_ITEM).qty"+str$(invItems(TEMP_INV_ITEM).qty)
endif
`for i = 1 to 18
` text 0,140+(i*20),"invSlot("+str$(i)+")"+str$(invSlot(i).Taken)
`next i
text 0,160,"maxInvHeight"+str$(maxInvHeight)
sync
loop
REM ***************************************************************************************
REM ***************************************************************************************
REM ** **
REM ** SUB-ROUTINES **
REM ** **
REM ***************************************************************************************
REM ***************************************************************************************
REM ===============================================================
REM Frames for Inventory Slots
REM ===============================================================
_Frames:
`Clean Inventory Slots
if _MC = 1
for i = 1 to maxInvItems
invSlot(i).Taken = 0
next i
endif
`Checks every item position
itemCount = array count(invItems())
for i = 1 to itemCount
gxs = invItems(i).gridX
gys = invItems(i).gridY
Frame = ((gys*6)+gxs)+1
if Frame <= maxInvItems
invSlot(Frame).Taken = 1
endif
Frame = 0
next i
`Set Frame to first open slot
repeat
if invSlot(1).Taken = 0
Frame = 1
else
inc Frame
endif
until invSlot(Frame).Taken = 0 or Frame = maxInvItems
RETURN
REM ===============================================================
REM Place item at free spot in inventory
REM ===============================================================
_Place_Item:
if Frame <= maxInvItems
if invSlot(Frame).Taken = 0
PLY=int((Frame-1)/6)
PLX=(Frame-1)-(PLY*6)
placeObjectInInventory(PLX,PLY, rnd(7)+1)
gosub _SaveInventory
endif
endif
RETURN
REM ===============================================================
REM Save inventory routine
REM ===============================================================
_SaveInventory:
if file exist ("inventory") = 1
delete file "inventory"
endif
`make file "inventory"
open to write 1,"inventory"
itemCount = array count(invItems())
write byte 1,itemCount
for i = 0 to itemCount
write byte 1,invItems(i).itemID
write byte 1,invItems(i).itemPAGE
write byte 1,invItems(i).qty
write byte 1,invItems(i).gridX
write byte 1,invItems(i).gridY
write byte 1,items(invItems(i).itemID).image
write byte 1,items(invItems(i).itemID).invWidth
write byte 1,items(invItems(i).itemID).invHeight
write byte 1,items(invItems(i).itemID).isStackable
next i
close file 1
RETURN
REM ===============================================================
REM The final check for any flags that may need set or reset
REM ===============================================================
_CheckFlags:
if _MC = 1
mFlag = 1
else
mFlag = 0
dragInvWindow = 0
InventorySaved = 0
endif
RETURN
REM ===============================================================
REM The puff of smoke seen when dropping an item
REM ===============================================================
_DoItemSmoke:
paste sprite 4, smokeX, smokeY
play sprite 4, 1, 16, 40
if sprite frame(4) = 1 and killItemSmoke = 2
killItemSmoke = 0
else
killItemSmoke = 2
endif
RETURN
REM ===============================================================
REM The final check for any flags that may need set or reset
REM ===============================================================
_HandleInvItemPlacement:
if mouseWithin(invX+43, invY+59, invX+428, invY+252)
gx = (mousex()-(invX+43)) / ImgSize - items(_SelectedItem).invWidth/2
gy = (mousey()-(invY+59-invScrollY)) / ImgSize - items(_SelectedItem).invHeight/2
`i = getPlayerItemAtLoc(gx, gy)
`If it's safe to place the item
safe = isItemPlacementOK(gx, gy, _SelectedItem)
if safe = 1 : c = C_GREEN : else : c = C_RED : endif
if _MC = 1 and mFlag = 0 and safe = 1
mFlag = 1
placeObjectInInventory(gx, gy, _SelectedItem)
_SelectedItem = 0
endif
`If it's not safe to place the item
if _MC = 1 and mFlag = 0 and safe = 0
mFlag = 1
if items(invItems(TEMP_INV_ITEM).itemID).isStackable = 0
placeObjectInInventory(invItems(TEMP_INV_ITEM).gridX, invItems(TEMP_INV_ITEM).gridY, TEMP_INV_ITEM)
endif
_SelectedItem = 0
endif
rem show boundary box for item placement
x = invX+43+gx*ImgSize
y = invY+59-invScrollY+gy*ImgSize
x2 = x + (items(_SelectedItem).invWidth)*ImgSize
y2 = y + (items(_SelectedItem).invHeight)*ImgSize
if x < invX+43 then x = invX+43
if y < invY+59 then y = invY+59
if x2 > invX+427 then x2 = invX+427
if y2 > invY+251 then y2 = invY+251
box x, y, x2, y2, c, c, c, c
endif
if _SelectedItem > 0
rem display selected item
if items(_SelectedItem).image > 0
draw to image imgInv
cls 0
draw to bitmap 0
paste image items(_SelectedItem).image, mousex()-(items(_SelectedItem).invWidth/2.0)*ImgSize, mousey()-(items(_SelectedItem).invHeight/2.0)*ImgSize, 1
endif
rem if mouse clicked and is outside the inventory and stat window, drop the item in a puff of smoke
if _MC = 1
if mouseWithin(invX+16, invY+16, invX+456, invY+329) = 0
mFlag = 1
smokeX = mousex()-64
smokeY = mousey()-88
killItemSmoke = 1
_SelectedItem = 0
rem if deleting an item selected from inventory, remove if from array
if TEMP_INV_ITEM > -1
array delete element invItems(), TEMP_INV_ITEM
TEMP_INV_ITEM = -1
gosub _SaveInventory
endif
endif
endif
endif
RETURN
REM ===============================================================
REM Draws all items in the inventory
REM ===============================================================
_DrawInventoryItems:
itemCount = array count(invItems())
for i = 0 to itemCount
if invItems(i).itemPAGE = CURRENT_PAGE
`ix = invX+43 + invItems(i).gridX*ImgSize
`iy = invY+59-invScrollY + invItems(i).gridY*ImgSize
rem don't draw the inventory item if its currently selected
if i <> TEMP_INV_ITEM
rem draw inventory items to image
draw to image imgInv
if items(invItems(i).itemID).image > 0
paste image items(invItems(i).itemID).image, invItems(i).gridX*ImgSize, invItems(i).gridY*ImgSize, 1
`paste image items(invItems(i).itemID).image, invItems(i).gridX*ImgSize, invItems(i).gridY*ImgSize, 1
`paste image items(invItems(i).itemID).image, invItems(i).gridX*ImgSize, invItems(i).gridY*ImgSize, 1
`paste image items(invItems(i).itemID).image, invItems(i).gridX*ImgSize, invItems(i).gridY*ImgSize, 1
`paste image items(invItems(i).itemID).image, invItems(i).gridX*ImgSize, invItems(i).gridY*ImgSize, 1
endif
rem go back to drawing on screen
draw to bitmap 0
endif
endif
next i
RETURN
REM ===============================================================
REM Various mouse actions, dragging windows, selecting items, etc..
REM ===============================================================
_MouseInteraction:
if _MC = 1 and mFlag = 0
rem if mouse clicked on inventory window header
if mouseWithin(invX+29, invY+24, invX+442, invY+46) and mFlag = 0
mFlag = 1
tempX = mousex() - invX
tempY = mousey() - invY
dragInvWindow = 1
endif
rem if mouse clicked in inventory window
if mouseWithin(invX+43, invY+59, invX+428, invY+252) and mFlag = 0
if _SelectedItem = 0
mFlag = 1
gx = (mousex()-(invX+43)) / ImgSize - items(_SelectedItem).invWidth/2
gy = (mousey()-(invY+59-invScrollY)) / ImgSize - items(_SelectedItem).invHeight/2
i = getPlayerItemAtLoc(gx, gy)
if i > -1
TEMP_INV_ITEM = i
_SelectedItem = invItems(i).itemID
_SelectedItemPage = invItems(i).itemPAGE
endif
endif
endif
endif
rem if user is dragging inventory window
if dragInvWindow = 1
invX = mousex() - tempX
invY = mousey() - tempY
rem update clipping area
a2SetClip invX+43, invY+59, invX+428, invY+252
endif
rem mouse wheel scrolling
if mz <> mousez()
rem scroll up
if mz - mousez() < 0
dec invScrollY, 20
if invScrollY < 0 then invScrollY = 0
rem scroll down
else
inc invScrollY, 20
if invScrollY > maxInvHeight-192 then invScrollY = maxInvHeight-192
endif
mz = mousez()
endif
RETURN
REM ===============================================================
REM Show the inventory window
REM ===============================================================
_DrawInventoryWindow:
rem inventory window
paste image 13, invX, invY, 1
rem draw inventory items
a2DrawImage imgInv, invX+43, invY+59-invScrollY, 0, 0, 0, 1, 0, 0xFFFFFFFF
RETURN
REM ***************************************************************************************
REM ***************************************************************************************
REM ** **
REM ** FUNCTIONS **
REM ** **
REM ***************************************************************************************
REM ***************************************************************************************
REM ===============================================================
REM Returns the array index of the inventory item located at grid[x,y]
REM ===============================================================
function getPlayerItemAtLoc(gridX, gridY)
itemCount = array count(invItems())
for i = 0 to itemCount
if invItems(i).itemPAGE = CURRENT_PAGE
ax = invItems(i).gridX
ay = invItems(i).gridY
bx = ax + items(invItems(i).itemID).invWidth
by = ay + items(invItems(i).itemID).invHeight
if gridX >= ax and gridX < bx and gridY >= ay and gridY < by then exitfunction i
endif
next i
endfunction -1
REM ===============================================================
REM Inserts an item in to the inventory.
REM ===============================================================
function placeObjectInInventory(gridX, gridY, itemId)
`gx = gridX + items(itemID).invWidth - 1
`gy = gridY + items(itemID).invHeight - 1
rem Item being placed in inventory already exists.
rem So it doesn't need to be added to the array, only moved.
if TEMP_INV_ITEM > -1
invItems(TEMP_INV_ITEM).gridX = gridX
invItems(TEMP_INV_ITEM).gridY = gridY
invItems(TEMP_INV_ITEM).itemPAGE = CURRENT_PAGE
TEMP_INV_ITEM = -1
exitfunction
endif
rem check to see if placing a stackable item
itemCount = array count(invItems())
for i = 0 to itemCount
if invItems(i).itemPAGE = CURRENT_PAGE
ax = invItems(i).gridX
ay = invItems(i).gridY
bx = ax + items(invItems(i).itemID).invWidth
by = ay + items(invItems(i).itemID).invHeight
if gridX >= ax and gridX < bx and gridY >= ay and gridY < by
if invItems(i).itemID = itemId
if items(invItems(i).itemID).isStackable
inc invItems(i).qty, 1
exitfunction
endif
endif
endif
endif
next i
rem if item wasn't added to a stack, insert the new item into the inventory
array insert at bottom invItems()
invItems().itemID = itemId
invItems().itemPAGE = CURRENT_PAGE
invItems().qty = 1
invItems().gridX = gridX
invItems().gridY = gridY
endfunction
REM ===============================================================
REM This will verify if it's safe to place an item at the specified
REM grid coordinates. If the item overlaps another or goes outside
REM the inventory grid region, then function returns false.
REM ===============================================================
function isItemPlacementOK(gridX, gridY, itemId)
gx = gridX + items(itemID).invWidth - 1
gy = gridY + items(itemID).invHeight - 1
rem make sure item fits on the inventory grid
if gx >= gridWidth or gy >= gridHeight or gridX < 0 or gridY < 0 then exitfunction 0
itemCount = array count(invItems())
for i = 0 to itemCount
if invItems(i).itemPAGE = CURRENT_PAGE
if i <> TEMP_INV_ITEM
ax = invItems(i).gridX
ay = invItems(i).gridY
bx = ax + items(invItems(i).itemID).invWidth-1
by = ay + items(invItems(i).itemID).invHeight-1
rem detects grid location directly under mouse pointer
if gridX >= ax and gridX <= bx and gridY >= ay and gridY <= by
rem if trying to place an item of the same type on each other
if invItems(i).itemID = itemID
rem if item is stackable
if items(itemId).isStackable then exitfunction 1
exitfunction 0
else
exitfunction 0
endif
endif
rem This makes sure the selected item doesn't overlap any existing items
rem The above IF statement is insufficient because some points of the selected
rem object may lie in unoccupied cells but still have some parts overlapping
rem occupied ones. (Thanks BMacZero)
nleft = max(gridX, ax)
nright = min(gx, bx)
ntop = max(gridY, ay)
nbottom = min(gy, by)
if (nleft <= nright) and (ntop <= nbottom) then exitfunction 0
endif
endif
next i
endfunction 1
REM ===============================================================
REM Displays a tooltip
REM ===============================================================
function showToolTip(x, y, s$)
w = d3d_gettextwidth(2, s$)+10
h = d3d_gettextheight(2, s$)
box x, y-h, x+w, y, TT_BLACK, TT_BLACK, TT_BLACK, TT_BLACK
ink rgb(128,128,128),0
boxOutline(x, y-h, x+w, y)
d3d_color 23, 129, 251, 255
d3d_starttext
d3d_text 2, x+5, y-h, 0, s$
d3d_endtext
endfunction
REM ===============================================================
REM Loads items into the items array
REM ===============================================================
function loadItemDatabase()
REM Load item data and images
restore ItemsData : read count
imgBase = 100
for i = 1 to count
imgId = imgBase + i
read img$
load image "items/"+img$, imgId
`Make Memblock to read from
make memblock from image imgId, imgId
read name$
read width
read height
read stack
array insert at bottom items()
items().image = imgId
items().name = name$
items().invWidth = width
items().invHeight = height
items().isStackable = stack
next i
endfunction
REM ===============================================================
REM Returns true if mouse is within the specified region
REM ===============================================================
function mouseWithin(x1, y1, x2, y2)
if mousex() >= x1 and mousex() <= x2 and mousey() >= y1 and mousey() <= y2 then exitfunction 1
endfunction 0
REM ===============================================================
REM Draws the outline of a box
REM ===============================================================
function boxOutline(x1, y1, x2, y2)
line x1, y1, x1, y2
line x1, y1, x2, y1
line x2, y1, x2, y2
line x1, y2, x2, y2
endfunction
REM ***************************************************************************************
REM ***************************************************************************************
REM ** **
REM ** DATA STATEMENTS **
REM ** **
REM ***************************************************************************************
REM ***************************************************************************************
REM ===============================================================
REM image path, item name, width, height, stackable
REM ===============================================================
ItemsData:
data 8
data "438.png", "WD", 1, 1, 1
data "434.png", "WD", 1, 1, 0
data "487.png", "WD", 1, 1, 0
data "578.png", "WD", 1, 1, 0
data "10218.png", "WD", 1, 1, 0
data "11069.png", "WD", 1, 1, 0
data "11215.png", "WD", 1, 1, 0
data "11215.png", "WD", 1, 1, 0
Coding is My Kung Fu!
And My Kung Fu is better than Yours!