93dac190dba2d7a9d99fa1a10f1e392eadcd17c7
1 # utility functions for the game
5 import xml
.etree
.cElementTree
as ET
8 # function to run through an interactive dialogue and return the response ID
9 def dialogue_play (screen
, bgscreen
, npc
, responder
,
10 marginleft
=0, margintop
=0, marginright
=0, marginbottom
=0):
12 # first check if NPC has a dialogue at all
13 if len (npc
.dialogues
) == 0 or npc
.currentdialog
>= len (npc
.dialogues
):
16 # get the conversation as a dictionary
17 convtree
= xml_to_dict (npc
.dialogues
[npc
.currentdialog
])
19 scrwidth
= screen
.get_width ()
20 scrheight
= screen
.get_height ()
21 bgwidth
= bgscreen
.get_width ()
22 bgheight
= bgscreen
.get_height ()
23 leftedge
= scrwidth
/2 - bgwidth
/2
24 topedge
= scrheight
/2 - bgheight
/2
26 # now initiate the conversation
29 screen
.blit (bgscreen
, (leftedge
, topedge
))
30 if npc
.portrait
is not None:
31 screen
.blit (npc
.portrait
, (leftedge
, topedge
))
33 # get the lines to display wrapped using textwrap module
35 textnpc
= textwrap
.wrap (convtree
[dlg_id
][0], 40)
37 lines
.append ((10, 0, 0, 0, text
))
39 put_lines (screen
, lines
,
40 pygame
.Rect(leftedge
+marginleft
, topedge
+margintop
,
41 bgwidth
-marginleft
-marginright
, bgheight
-margintop
-marginbottom
))
42 pygame
.display
.update ()
44 for event
in pygame
.event
.get ():
45 if event
.type == pygame
.QUIT
:
48 # function to parse a conversation XML into a python dictionary
49 def xml_to_dict (file):
50 # parse the dialogue XML file
51 dlgtree
= ET
.parse (file)
52 # get the root element
53 conversation
= dlgtree
.getroot ()
55 # build the conversation tree as a dictionary
57 for dlg
in conversation
.findall ("dialogue"):
60 convtree
[id].append (dlg
.find ("speech").text
)
61 for resp
in dlg
.findall ("response"):
62 convtree
[id].append ((resp
.text
, resp
.get ("id"), resp
.get ("nextdialogue")))
67 # function to draw text on surface
68 def put_text (surface
, x
, y
, size
, (r
,g
,b
), text
):
69 harisfont
= os
.path
.join ("font", "harisgamefont.ttf")
70 textsurf
= pygame
.font
.Font (harisfont
, size
).render (text
, True, pygame
.Color (r
,g
,b
))
71 surface
.blit (textsurf
, (x
, y
))
73 # function to draw several lines of text, centered horizontally and vertically on screen
74 # or drawn centered on a rectangle
75 def put_lines (surface
, text_lines
, rect
=None):
78 harisfont
= os
.path
.join ("font", "harisgamefont.ttf")
80 for size
, r
, g
, b
, text
in text_lines
:
81 s
= pygame
.font
.Font (harisfont
, size
).render (text
, True, pygame
.Color (r
,g
,b
))
83 height
= height
+ s
.get_height()*1.5
87 # if no rectangle specified, center in screen
89 scrwidth
= surface
.get_width ()
90 scrheight
= surface
.get_height ()
93 surface
.blit (s
, (scrwidth
/2 - s
.get_width()/2, scrheight
/2 - height
/2+ i
* (s
.get_height()*1.5)))
95 # center on specified rectangular region
97 midx
= (rect
.left
+ rect
.right
)/2
98 midy
= (rect
.top
+ rect
.bottom
)/2
99 num
= len (textsurfs
) / 2
101 surface
.blit (s
, (midx
- s
.get_width()/2, midy
- (num
-i
) * s
.get_height() * 3/2))
104 # function to ask a question and return answer
105 def ask_question (surface
, question
, answers
, bgscreen
):
110 textarray
= [ [ 10, 128, 0, 0, question
] ]
113 for answer
in answers
:
118 textarray
.append ( [10, r
, g
, b
, answer
] )
122 surface
.blit (bgscreen
, (surface
.get_width()/2 - bgscreen
.get_width()/2,
123 surface
.get_height()/2 - bgscreen
.get_height()/2))
124 put_lines (surface
, textarray
, pygame
.Rect (surface
.get_width()/2 - bgscreen
.get_width()/2,
125 surface
.get_height()/2 - bgscreen
.get_height()/2,
126 bgscreen
.get_width(), bgscreen
.get_height()))
128 pygame
.display
.update ()
130 for event
in pygame
.event
.get ():
131 if event
.type == pygame
.QUIT
:
133 elif event
.type == pygame
.KEYDOWN
:
134 if event
.key
== pygame
.K_UP
:
138 elif event
.key
== pygame
.K_DOWN
:
140 if sel_answer
> len(answers
):
141 sel_answer
= len(answers
)
142 elif event
.key
== pygame
.K_RETURN
:
145 # function displaying the contents of a container. Object must contain
147 # edgewidth - container edges to avoid drawing items in
148 def get_container_object (surface
, obj
, bgimage
, edgewidth
=0):
150 # get the number of items
151 numitems
= len (obj
.objects
)
153 num_rows
= (bgimage
.get_height () - edgewidth
*2) / 48
155 num_cols
= (bgimage
.get_width () - edgewidth
*2) / 48
157 objposx
= surface
.get_width()/2 - bgimage
.get_width()/2
158 objposy
= surface
.get_height()/2 - bgimage
.get_height()/2
165 # display the background for the container
166 surface
.blit (bgimage
, (objposx
, objposy
))
168 # display each item in the container
172 # display all the items in container
173 for item
in obj
.objects
:
174 surface
.blit (item
.image
, (objposx
+ edgewidth
+ j
*48, objposy
+ edgewidth
+ i
*48))
179 # only draw selector if there is at least one item
181 pygame
.draw
.rect (surface
, pygame
.Color (255,255,255),
182 pygame
.Rect(objposx
+ edgewidth
+ selcol
*48, objposy
+ edgewidth
+ selrow
*48, 48, 48), 1)
184 pygame
.display
.update ()
187 for event
in pygame
.event
.get ():
188 if event
.type == pygame
.QUIT
:
190 elif event
.type == pygame
.KEYDOWN
:
191 if event
.key
== pygame
.K_ESCAPE
:
193 elif event
.key
== pygame
.K_RETURN
:
194 if numitems
> 0 and selitem
>= 0 and selitem
< numitems
:
195 return obj
.objects
[selitem
]
198 elif event
.key
== pygame
.K_UP
or event
.key
== pygame
.K_LEFT
:
199 # go to the prev item
202 selitem
= numitems
- 1
203 selrow
= selitem
/ num_cols
204 selcol
= selitem
% num_cols
206 elif event
.key
== pygame
.K_DOWN
or event
.key
== pygame
.K_RIGHT
:
207 # go to the next item
209 if selitem
> numitems
- 1:
211 selrow
= selitem
/ num_cols
212 selcol
= selitem
% num_cols