self.img_chestbg = pygame.image.load (os.path.join ("background", "chestcontent.png")).convert ()
+ self.img_dialogue = pygame.image.load (os.path.join ("background", "dialog_screen.png")).convert ()
+ self.img_dialogue.set_colorkey (pygame.Color (0, 255, 0))
+
# initialize object graphics
self.img_redpotion = pygame.image.load (os.path.join ("objects", "red-potion.png")).convert ()
self.img_bulisa = pygame.image.load (os.path.join ("sprite", "bulisa.png")).convert ()
self.img_bulisa.set_colorkey (pygame.Color (0, 255, 0))
+ # initialize NPC portraits
+ self.img_bulisa_portrait = pygame.image.load (os.path.join ("portraits", "bulisa.png")).convert ()
+
# set level data
self.setup_levels ()
# set current level and position of our character
potion2 = gameobjects.HealthPotion (5, 2, self.img_redpotion)
potion3 = gameobjects.HealthPotion (5, 2, self.img_redpotion)
- npc_bulisa = npcs.Bulisa (4, 3, self.img_bulisa, None)
+ npc_bulisa = npcs.Bulisa (4, 3, self.img_bulisa, self.img_bulisa_portrait,
+ [ os.path.join ("dialogues", "bulisa1.dlg") ])
chest1.objects = [ gold50, gold25, potion2, potion3, key2, gold10 ]
# interaction with npcs
def interact_npc (self, npc):
- pass
+ # interact with NPC and get the response ID
+ resp_id = utility.dialogue_play (self.screen, self.img_dialogue, npc, self.butaba, 0, 90)
+
+ # if none
+ if resp_id is None:
+ self.status_message = "You cannot initiate a conversation with %s" % npc.charname
# interaction with objects
def interact_objects (self, container, objs):
class NPC:
# initalize the NPC
- def __init__ (self, charname, row, col, image=None, portrait=None, dialogue_set=set(),
+ def __init__ (self, charname, row, col, image=None, portrait=None, dialogues=[],
currentdialog=0, is_dead=False):
# name of the character
self.charname = charname
self.portrait = portrait
# dialogue set for NPC
# each dialogue in the set is a path to an XML file containing the dialogue
- self.dialogue_set = dialogue_set
+ self.dialogues = dialogues
# index of the current dialogue which will be initiated with the main
# character
self.currentdialog = currentdialog
# Bulisa is Butaba's friend
class Bulisa (NPC):
- def __init__ (self, row, col, image, portrait, dialogue_set=set(), currentdialog=0):
- NPC.__init__ (self, "Bulisa", row, col, image, portrait, dialogue_set, currentdialog)
+ def __init__ (self, row, col, image, portrait, dialogues=[], currentdialog=0):
+ NPC.__init__ (self, "Bulisa", row, col, image, portrait, dialogues, currentdialog)
import pygame
import sys
import os.path
+import xml.etree.cElementTree as ET
+import textwrap
+
+# function to run through an interactive dialogue and return the response ID
+def dialogue_play (screen, bgscreen, npc, responder,
+ marginleft=0, margintop=0, marginright=0, marginbottom=0):
+
+ # first check if NPC has a dialogue at all
+ if len (npc.dialogues) == 0 or npc.currentdialog >= len (npc.dialogues):
+ return None
+
+ # get the conversation as a dictionary
+ convtree = xml_to_dict (npc.dialogues[npc.currentdialog])
+
+ scrwidth = screen.get_width ()
+ scrheight = screen.get_height ()
+ bgwidth = bgscreen.get_width ()
+ bgheight = bgscreen.get_height ()
+ leftedge = scrwidth/2 - bgwidth/2
+ topedge = scrheight/2 - bgheight/2
+
+ # now initiate the conversation
+ dlg_id = "1"
+ while 1:
+ screen.blit (bgscreen, (leftedge, topedge))
+ if npc.portrait is not None:
+ screen.blit (npc.portrait, (leftedge, topedge))
+
+ # get the lines to display wrapped using textwrap module
+ lines = []
+ textnpc = textwrap.wrap (convtree[dlg_id][0], 40)
+ for text in textnpc:
+ lines.append ((10, 0, 0, 0, text))
+
+ put_lines (screen, lines,
+ pygame.Rect(leftedge+marginleft, topedge+margintop,
+ bgwidth-marginleft-marginright, bgheight-margintop-marginbottom))
+ pygame.display.update ()
+
+ for event in pygame.event.get ():
+ if event.type == pygame.QUIT:
+ sys.exit (0)
+
+# function to parse a conversation XML into a python dictionary
+def xml_to_dict (file):
+ # parse the dialogue XML file
+ dlgtree = ET.parse (file)
+ # get the root element
+ conversation = dlgtree.getroot ()
+
+ # build the conversation tree as a dictionary
+ convtree = dict ()
+ for dlg in conversation.findall ("dialogue"):
+ id = dlg.get ("id")
+ convtree[id] = []
+ convtree[id].append (dlg.find ("speech").text)
+ for resp in dlg.findall ("response"):
+ convtree[id].append ((resp.text, resp.get ("id"), resp.get ("nextdialogue")))
+
+ return convtree
+
# function to draw text on surface
def put_text (surface, x, y, size, (r,g,b), text):
textsurf = pygame.font.Font (harisfont, size).render (text, True, pygame.Color (r,g,b))
surface.blit (textsurf, (x, y))
-# function to draw several lines of text, centered horizontally and vertically on surface
-def put_lines (surface, text_lines):
+# function to draw several lines of text, centered horizontally and vertically on screen
+# or drawn centered on a rectangle
+def put_lines (surface, text_lines, rect=None):
textsurfs = []
height = 0
harisfont = os.path.join ("font", "harisgamefont.ttf")
height = height + s.get_height()*1.5
textsurfs.append (s)
- scrwidth = surface.get_width ()
- scrheight = surface.get_height ()
i = 0
- for s in textsurfs:
- surface.blit (s, (scrwidth/2 - s.get_width()/2, scrheight/2 - height/2+ i* (s.get_height()*1.5)))
- i += 1
+ # if no rectangle specified, center in screen
+ if rect is None:
+ scrwidth = surface.get_width ()
+ scrheight = surface.get_height ()
+
+ for s in textsurfs:
+ surface.blit (s, (scrwidth/2 - s.get_width()/2, scrheight/2 - height/2+ i* (s.get_height()*1.5)))
+ i += 1
+ # center on specified rectangular region
+ else:
+ midx = (rect.left + rect.right)/2
+ midy = (rect.top + rect.bottom)/2
+ num = len (textsurfs) / 2
+ for s in textsurfs:
+ surface.blit (s, (midx - s.get_width()/2, midy - (num-i) * s.get_height() * 3/2))
+ i += 1
# function to ask a question and return answer
def ask_question (surface, question, answers, bgscreen):
surface.blit (bgscreen, (surface.get_width()/2 - bgscreen.get_width()/2,
surface.get_height()/2 - bgscreen.get_height()/2))
- put_lines (surface, textarray)
+ put_lines (surface, textarray, pygame.Rect (surface.get_width()/2 - bgscreen.get_width()/2,
+ surface.get_height()/2 - bgscreen.get_height()/2,
+ bgscreen.get_width(), bgscreen.get_height()))
pygame.display.update ()