I've made a kind of sample that might help you understand the drag and drop system. It's not code wise and can be used for quite simple gameplay only. So, if you plan on making fully-functional point and click/escape the room game in Ren'Py, this might be better to ask someone skilled enough to create such a framework for you.
Code: Select all
#### Images
#
image red:
Solid("#500")
image slot_bg:
Solid("#ccc5")
size(100, 100)
image key_1:
Solid("#c00")
size (100, 100)
image key_2:
Solid("#00c")
size (100, 100)
image apple:
Solid("#0c0")
size (100, 100)
image door_1_close:
Solid("#c00")
size (200, 500)
image door_1_open:
contains:
Solid("#ccc")
size (200, 500)
xoffset 0
contains:
Solid("#c00")
size (150, 500)
xoffset 50
size(200, 500)
image door_2_close:
Solid("#00c")
size (200, 500)
image door_2_open:
contains:
Solid("#ccc")
size (200, 500)
xoffset 0
contains:
Solid("#00c")
size (150, 500)
xoffset 50
size(200, 500)
#### Lists to store items and interactable objects (like doors)
#
# Inventory slots (all should have indx's from 0 to ...)
default inv_slots = [
{'indx':0, 'name':'slot', 'img':'slot_bg', 'pos':(50, 50)},
{'indx':1, 'name':'slot', 'img':'slot_bg', 'pos':(200, 50)},
{'indx':2, 'name':'slot', 'img':'slot_bg', 'pos':(350, 50)},
]
# inventory list can hold the same amount of items
# as the slots number
# by default list is filed with None values
# to let us put items in any slot
default inventory = [None] * len(inv_slots)
# lists to store objects for current location
default location_items = []
default location_places = []
default message_to_show = ''
# lists of items/objects for each location
# each item/object is described by dictionary
# (in each list items/objects must have indx's from 0 to ...)
default location_items_1 = [
{'indx':0, 'name':'Red Key', 'img':'key_1', 'pos':(600, 350), 'description':'Red key'},
{'indx':1, 'name':'Apple', 'img':'apple', 'pos':(500, 200), 'description':'An apple'},
]
default location_places_1 = [
{'indx':0, 'name':'door', 'img':{'locked':'door_2_close', 'unlocked':'door_2_open'}, 'pos':(1000, 200), 'item_to_use':'Blue Key', 'state':'locked', 'description':'it needs Blue Key to open', 'label_to_jump_to':'exit_room'},
{'indx':1, 'name':'door', 'img':{'locked':'door_1_close', 'unlocked':'door_1_open'}, 'pos':(200, 200), 'item_to_use':'Red Key', 'state':'locked', 'description':'it needs Red Key to open', 'label_to_jump_to':'red_room'},
]
default location_items_2 = [
{'indx':0, 'name':'Blue Key', 'img':'key_2', 'pos':(300, 450), 'description':'Blue key'},
{'indx':1, 'name':'Apple', 'img':'apple', 'pos':(600, 300), 'description':'An apple 2'},
]
default location_places_2 = [
{'indx':0, 'name':'door', 'img':{'locked':'door_1_close', 'unlocked':'door_1_open'}, 'pos':(900, 200), 'item_to_use':None, 'state':'unlocked', 'description':'to first room', 'label_to_jump_to':'first_room'},
]
#### functions for draggable items
#
init python:
# since items might be in inventory and on location
# (stored in inventory and location_items lists)
# we'll have different functions for them
# function for items in inventory
def inv_item_dragged(drags, drop):
# if inventory item was dragged and dropped somewhere on screen
# and not over droppable object - snap it back to initial position
if not drop:
item_indx = int(drags[0].drag_name.split('-')[1])
x,y = inventory[item_indx]['pos']
drags[0].snap(x, y, delay = 0.1)
return
# if inventory item dropped over dropable object
# store the name and index of the inventory item
# and the droppable object
item_name = drags[0].drag_name.split('-')[0]
item_indx = int(drags[0].drag_name.split('-')[1])
drop_name = drop.drag_name.split('-')[0]
drop_indx = int(drop.drag_name.split('-')[1])
# if inventory item was dropped over slot
if drop_name == 'slot':
# if we already have an item at this slot - snap item back
if inventory[drop_indx]:
x,y = inventory[item_indx]['pos']
drags[0].snap(x, y, delay = 0.1)
return
# if slot is empty - move inventory item to that slot
else:
inventory[drop_indx] = inventory[item_indx]
inventory[drop_indx]['indx'] = drop_indx
inventory[drop_indx]['pos'] = inv_slots[drop_indx]['pos']
inventory[item_indx] = None
x,y = inventory[drop_indx]['pos']
drags[0].snap(x, y, delay = 0.1)
renpy.retain_after_load()
renpy.restart_interaction()
return
# if inventory item was dropped over door
elif drop_name == 'door':
# if this is the right item and door is 'locked' - will 'unlock' it
# and remove item from inventory
if location_places[drop_indx]['item_to_use'] == item_name and location_places[drop_indx]['state'] == 'locked':
location_places[drop_indx]['state'] = 'unlocked'
inventory[item_indx] = None
renpy.retain_after_load()
renpy.restart_interaction()
return
# otherwise - snap item back
else:
x,y = inventory[item_indx]['pos']
drags[0].snap(x, y, delay = 0.1)
return
# if inventory item was dropped over something else - snap it back
else:
x,y = inventory[item_indx]['pos']
drags[0].snap(x, y, delay = 0.1)
return
# function for items on location
def loc_item_dragged(drags, drop):
# if item was dragged and dropped somewhere on screen
# and not over droppable object - snap it back to initial position
if not drop:
item_indx = int(drags[0].drag_name.split('-')[1])
x,y = location_items[item_indx]['pos']
drags[0].snap(x, y, delay = 0.1)
return
# if item dropped over dropable object
# store the name and index of the item
# and the droppable object
item_name = drags[0].drag_name.split('-')[0]
item_indx = int(drags[0].drag_name.split('-')[1])
drop_name = drop.drag_name.split('-')[0]
drop_indx = int(drop.drag_name.split('-')[1])
# if item was dropped over slot
if drop_name == 'slot':
# if we already have an item at this slot - snap item back
if inventory[drop_indx]:
x,y = location_items[item_indx]['pos']
drags[0].snap(x, y, delay = 0.1)
return
# if slot is empty - move item to that slot
else:
inventory[drop_indx] = location_items[item_indx]
inventory[drop_indx]['indx'] = drop_indx
inventory[drop_indx]['pos'] = inv_slots[drop_indx]['pos']
location_items[item_indx] = None
x,y = inventory[drop_indx]['pos']
drags[0].snap(x, y, delay = 0.1)
renpy.retain_after_load()
return
# if item was dropped over door
elif drop_name == 'door':
# if this is the right item and door is 'locked' - will 'unlock' it
# and remove item from inventory
if location_places[drop_indx]['item_to_use'] == item_name and location_places[drop_indx]['state'] == 'locked':
location_places[drop_indx]['state'] = 'unlocked'
location_items[item_indx] = None
renpy.retain_after_load()
renpy.restart_interaction()
return
# otherwise - snap item back
else:
x,y = location_items[item_indx]['pos']
drags[0].snap(x, y, delay = 0.1)
return
# if item was dropped over something else - snap it back
else:
x,y = location_items[item_indx]['pos']
drags[0].snap(x, y, delay = 0.1)
return
#### Screen that will show inventory slots, items and objects on location
#
screen test_game_scr():
# all the items/objects should be in one draggroup
draggroup:
# create all drags from their descriptions in lists
# the order of appearence does matter
# (first shown items will be under the last ones)
# location places
for place in location_places:
if place:
drag:
drag_name '{}-{}'.format(place['name'], place['indx'])
child place['img'][place['state']]
draggable False
droppable True
# if door is 'locked' it will show message
# otherwise - send player to another location
if place['state'] == 'locked':
clicked SetVariable('message_to_show', place['description'])
else:
clicked Jump(place['label_to_jump_to'])
unhovered SetVariable('message_to_show', '')
pos place['pos']
# location items
for loc_item in location_items:
if loc_item:
drag:
drag_name '{}-{}'.format(loc_item['name'], loc_item['indx'])
child loc_item['img']
draggable True
droppable False
clicked SetVariable('message_to_show', loc_item['description'])
unhovered SetVariable('message_to_show', '')
dragged loc_item_dragged # function for item that was dragged
pos loc_item['pos']
# inventory slots
for slot in inv_slots:
drag:
drag_name '{}-{}'.format(slot['name'], slot['indx'])
child slot['img']
draggable False
droppable True
clicked SetVariable('message_to_show', 'Inventory slot')
unhovered SetVariable('message_to_show', '')
pos slot['pos']
# inventory items
for item in inventory:
if item:
drag:
drag_name '{}-{}'.format(item['name'], item['indx'])
child item['img']
draggable True
droppable False
clicked SetVariable('message_to_show', item['description'])
unhovered SetVariable('message_to_show', '')
dragged inv_item_dragged # function for inventory item that was dragged
pos item['pos']
# info frame
frame:
pos (700, 50)
fixed:
xysize (550, 100)
text "[message_to_show]" xoffset 10 align (0.0, 0.5) size 25
text "Info" align(1.0, 1.0) size 15
# The game starts here.
label start:
# we can show and hide game screen
show screen test_game_scr
"Game start"
jump first_room
label first_room:
scene black
# at first we should set
# lists of items and objects for location
$ location_items = location_items_1
$ location_places = location_places_1
"First room"
"..."
"... ..."
window hide
$ renpy.pause(hard=True)
label red_room:
scene red
$ location_items = location_items_2
$ location_places = location_places_2
"Red room"
",,,"
",,, ,,,"
window hide
$ renpy.pause(hard=True)
label exit_room:
scene black
hide screen test_game_scr
"Escaped!"
return