22 self
.clock
= pygame
.time
.Clock ()
23 self
.screen
= pygame
.display
.set_mode ((720, 512))
24 pygame
.display
.set_caption ("The Adventures of Butaba")
26 # initalize background graphics
27 self
.img_tileset
= pygame
.image
.load (os
.path
.join ("background", "tileset.png")).convert ()
29 self
.img_menu
= pygame
.image
.load (os
.path
.join ("background", "menu_screen.png")).convert ()
31 self
.img_inventory
= pygame
.image
.load (os
.path
.join ("background", "inventory.png")).convert ()
33 self
.img_chestbg
= pygame
.image
.load (os
.path
.join ("background", "chestcontent.png")).convert ()
35 self
.img_dialogue
= pygame
.image
.load (os
.path
.join ("background", "dialog_screen.png")).convert ()
36 self
.img_dialogue
.set_colorkey (pygame
.Color (0, 255, 0))
39 # initialize object graphics
40 self
.img_redpotion
= pygame
.image
.load (os
.path
.join ("objects", "red-potion.png")).convert ()
41 self
.img_redpotion
.set_colorkey (pygame
.Color (0, 255, 0))
42 self
.img_goldcoins
= pygame
.image
.load (os
.path
.join ("objects", "gold-coins.png")).convert ()
43 self
.img_goldcoins
.set_colorkey (pygame
.Color (0, 255, 0))
44 self
.img_wand
= pygame
.image
.load (os
.path
.join ("objects", "wand.png")).convert ()
45 self
.img_wand
.set_colorkey (pygame
.Color (0, 255, 0))
46 self
.img_bulb
= pygame
.image
.load (os
.path
.join ("objects", "bulb.png")).convert ()
47 self
.img_bulb
.set_colorkey (pygame
.Color (0, 255, 0))
48 self
.img_lightning
= pygame
.image
.load (os
.path
.join ("objects", "lightning.png")).convert ()
49 self
.img_lightning
.set_colorkey (pygame
.Color (0, 255, 0))
50 self
.img_key
= pygame
.image
.load (os
.path
.join ("objects", "key.png")).convert ()
51 self
.img_key
.set_colorkey (pygame
.Color (0, 255, 0))
52 self
.img_key2
= pygame
.image
.load (os
.path
.join ("objects", "key2.png")).convert ()
53 self
.img_key2
.set_colorkey (pygame
.Color (0, 255, 0))
54 self
.img_chest
= pygame
.image
.load (os
.path
.join ("objects", "chest.png")).convert ()
55 self
.img_chest
.set_colorkey (pygame
.Color (0, 255, 0))
56 self
.img_bucket
= pygame
.image
.load (os
.path
.join ("objects", "bucket.png")).convert ()
57 self
.img_bucket
.set_colorkey (pygame
.Color (0, 255, 0))
59 # initialize player graphics
60 self
.img_butabafront
= pygame
.image
.load (os
.path
.join ("sprite", "butaba-front.png")).convert ()
61 self
.img_butabafront
.set_colorkey (pygame
.Color (0, 255, 0))
62 self
.img_butababack
= pygame
.image
.load (os
.path
.join ("sprite", "butaba-back.png")).convert ()
63 self
.img_butababack
.set_colorkey (pygame
.Color (0, 255, 0))
64 self
.img_butabaleft
= pygame
.image
.load (os
.path
.join ("sprite", "butaba-left.png")).convert ()
65 self
.img_butabaleft
.set_colorkey (pygame
.Color (0, 255, 0))
66 self
.img_butabaright
= pygame
.image
.load (os
.path
.join ("sprite", "butaba-right.png")).convert ()
67 self
.img_butabaright
.set_colorkey (pygame
.Color (0, 255, 0))
69 # initialize NPC graphics
70 self
.img_bulisafront
= pygame
.image
.load (os
.path
.join ("sprite", "bulisa-front.png")).convert ()
71 self
.img_bulisafront
.set_colorkey (pygame
.Color (0, 255, 0))
73 self
.img_bulisaback
= pygame
.image
.load (os
.path
.join ("sprite", "bulisa-back.png")).convert ()
74 self
.img_bulisaback
.set_colorkey (pygame
.Color (0, 255, 0))
76 self
.img_bulisaleft
= pygame
.image
.load (os
.path
.join ("sprite", "bulisa-left.png")).convert ()
77 self
.img_bulisaleft
.set_colorkey (pygame
.Color (0, 255, 0))
79 self
.img_bulisaright
= pygame
.image
.load (os
.path
.join ("sprite", "bulisa-right.png")).convert ()
80 self
.img_bulisaright
.set_colorkey (pygame
.Color (0, 255, 0))
82 # initialize portraits
83 self
.img_butaba_portrait
= pygame
.image
.load (os
.path
.join ("portraits", "butaba.png")).convert ()
84 self
.img_bulisa_portrait
= pygame
.image
.load (os
.path
.join ("portraits", "bulisa.png")).convert ()
88 # set current level and position of our character
89 self
.currentlevel
= self
.level1
91 # set the status message
92 self
.status_message
= "Game started"
94 self
.butaba
= butaba
.Butaba (5,0, self
.img_butabaleft
,
95 self
.img_butabaright
, self
.img_butabafront
,
96 self
.img_butababack
, self
.img_butaba_portrait
, constants
.RIGHT
)
98 # set up the levels and their interactions
99 def setup_levels (self
):
100 # set up the objects first
101 chest1
= gameobjects
.Chest (2, 6, "chest", self
.img_chest
, constants
.KEY_CHEST1
, True)
102 chest2
= gameobjects
.Chest (6, 6, "chest", self
.img_chest
, constants
.KEY_CHEST2
, True)
103 key2
= gameobjects
.Key (5, 3, "a chest key", self
.img_key
, constants
.KEY_CHEST2
)
104 potion
= gameobjects
.HealthPotion (5, 2, self
.img_redpotion
)
105 gold50
= gameobjects
.GoldCoins (6, 2, self
.img_goldcoins
, 50)
106 gold25
= gameobjects
.GoldCoins (6, 2, self
.img_goldcoins
, 25)
107 gold10
= gameobjects
.GoldCoins (6, 2, self
.img_goldcoins
, 10)
108 bucket
= gameobjects
.Bucket (6, 3, self
.img_bucket
)
110 well1
= gameobjects
.Well (4, 7)
111 well2
= gameobjects
.Well (5, 7)
112 well3
= gameobjects
.Well (4, 8)
113 well4
= gameobjects
.Well (5, 8)
115 npc_bulisa
= npcs
.Bulisa (4, 3, self
.img_bulisaleft
, self
.img_bulisaright
,
116 self
.img_bulisafront
, self
.img_bulisaback
,
117 self
.img_bulisa_portrait
, constants
.FRONT
,
119 [ os
.path
.join ("dialogues", "bulisa1.dlg"),
120 os
.path
.join ("dialogues", "bulisa2.dlg"),
121 os
.path
.join ("dialogues", "bulisa3.dlg"),
122 os
.path
.join ("dialogues", "bulisa4.dlg"),
123 os
.path
.join ("dialogues", "bulisa5.dlg") ] )
125 chest1
.objects
= [ gold50
, gold25
, key2
, gold10
]
128 self
.level1
= level
.Level (cPickle
.load (file (os
.path
.join ("levels", "level1.dat"))),
129 objects
= [ chest1
] )
131 self
.level1w
= level
.Level (cPickle
.load (file (os
.path
.join ("levels", "level1w.dat"))))
133 self
.level1e
= level
.Level (cPickle
.load (file (os
.path
.join ("levels", "level1e.dat"))),
134 objects
= [ potion
, chest2
], npcs
= [ npc_bulisa
])
136 self
.level1ee
= level
.Level (cPickle
.load (file (os
.path
.join ("levels", "level1ee.dat"))),
137 objects
= [ well1
, well2
, well3
, well4
])
139 self
.level1n
= level
.Level (cPickle
.load (file (os
.path
.join ("levels", "level1n.dat"))),
140 objects
= [ bucket
])
142 # set up the interaction between levels
143 self
.level1
.levelright
= self
.level1e
144 self
.level1
.levelleft
= self
.level1w
145 self
.level1e
.levelleft
= self
.level1
146 self
.level1e
.levelright
= self
.level1ee
147 self
.level1ee
.levelleft
= self
.level1e
148 self
.level1w
.levelright
= self
.level1
149 self
.level1
.leveltop
= self
.level1n
150 self
.level1n
.levelbottom
= self
.level1
152 def main_loop (self
):
157 self
.screen
.fill (pygame
.Color (0,0,0))
159 self
.draw_level_background (self
.currentlevel
)
161 self
.draw_level_objects (self
.currentlevel
)
162 # draw the NPCs in the level
163 self
.draw_level_npcs (self
.currentlevel
)
166 # display the character's inventory
167 self
.draw_inventory ()
168 # draw the status info
171 pygame
.display
.update ()
173 # get keyboard events
174 for event
in pygame
.event
.get ():
175 if event
.type == pygame
.QUIT
:
178 if event
.type == pygame
.KEYDOWN
:
179 if event
.key
== pygame
.K_UP
:
180 self
.move_butaba_up ()
181 elif event
.key
== pygame
.K_DOWN
:
182 self
.move_butaba_down ()
183 elif event
.key
== pygame
.K_LEFT
:
184 self
.move_butaba_left ()
185 elif event
.key
== pygame
.K_RIGHT
:
186 self
.move_butaba_right ()
187 # drinking health potion in inventory
188 elif event
.key
== ord ("h") or event
.key
== ord ("H"):
189 self
.inventory_drink_health_potion ()
191 elif event
.key
== ord ("q") or event
.key
== ord ("Q"):
194 # drink a health potion if it is in the player's inventory
195 def inventory_drink_health_potion (self
):
196 # look for a health potion
197 for item
in self
.butaba
.objects
:
198 if isinstance (item
, gameobjects
.HealthPotion
) is True:
199 self
.use_object (self
.butaba
, item
)
202 def move_butaba_up (self
):
203 # clear any status messages
204 self
.status_message
= None
205 # first if butaba is not facing up, make him face up
206 if self
.butaba
.position
<> constants
.BACK
:
207 self
.butaba
.position
= constants
.BACK
210 # if butaba is trying to move off the top of the screen
211 if self
.butaba
.row
<= 0:
212 # if there is a level above set current level to that one
213 if self
.currentlevel
.leveltop
is not None:
214 lastrow
= len (self
.currentlevel
.leveltop
.background
) - 1
215 # interact with objects
216 if self
.level_interact (self
.currentlevel
.leveltop
, lastrow
, self
.butaba
.col
) is False:
219 # make sure there is no obstacle
220 if self
.check_background_obstacle (self
.currentlevel
.leveltop
, lastrow
, self
.butaba
.col
) is False:
221 self
.currentlevel
= self
.currentlevel
.leveltop
222 self
.butaba
.row
= lastrow
223 # normal upward movement
225 # if there is any object in that place interact with it
226 # if any object is a blocking object then avoid movement
227 if self
.level_interact (self
.currentlevel
, self
.butaba
.row
-1, self
.butaba
.col
) is False:
230 if self
.check_background_obstacle (self
.currentlevel
, self
.butaba
.row
-1, self
.butaba
.col
) is False:
233 def move_butaba_down (self
):
234 # clear any status messages
235 self
.status_message
= None
236 # first if butaba is not facing forward, make him face forward/down
237 if self
.butaba
.position
<> constants
.FRONT
:
238 self
.butaba
.position
= constants
.FRONT
241 # if butaba is trying to move off the bottom of the screen
242 if self
.butaba
.row
>= len (self
.currentlevel
.background
)-1:
243 # if there is a level below set current level to that one
244 if self
.currentlevel
.levelbottom
is not None:
245 # interact with objects if any
246 # if any object is a blocking object then avoid movement
247 if self
.level_interact (self
.currentlevel
.levelbottom
, 0, self
.butaba
.col
) is False:
249 # make sure there is no obstacle at that position
250 if self
.check_background_obstacle (self
.currentlevel
.levelbottom
, 0, self
.butaba
.col
) is False:
251 self
.currentlevel
= self
.currentlevel
.levelbottom
253 # normal downward movement
255 # interact with objects if any
256 # if any object is a blocking object then avoid movement
257 if self
.level_interact (self
.currentlevel
, self
.butaba
.row
+1, self
.butaba
.col
) is False:
259 if self
.check_background_obstacle (self
.currentlevel
, self
.butaba
.row
+1, self
.butaba
.col
) is False:
262 # check if a background tile is an obstacle
263 def check_background_obstacle (self
, level
, row
, col
):
264 if (level
.background
[row
][col
][2] == 1):
269 # get and interact with objects and characters if present in a particular row/col
270 def level_interact (self
, level
, row
, col
):
272 # get list of objects at current location
273 for obj
in level
.objects
:
274 if obj
.row
== row
and obj
.col
== col
:
277 notblock
= self
.interact_objects (level
, objs
)
279 # get npc at current location
281 for npc
in level
.npcs
:
282 if npc
.row
== row
and npc
.col
== col
:
286 # npcs always block the tile. So return false if there is an NPC
288 if current_npc
is not None:
289 self
.interact_npc (current_npc
)
294 # interaction with npcs
295 def interact_npc (self
, npc
):
296 # interact with NPC and get the response ID
297 # if the NPC is Bulisa
299 # if the NPC is dead cannot talk with the NPC
300 if npc
.is_dead
is True:
301 self
.status_message
= "%s is dead! RIP..." % npc
.charname
304 if isinstance (npc
, npcs
.Bulisa
):
306 self
.interact_npc_bulisa (npc
)
308 # interact with NPC Bulisa
309 def interact_npc_bulisa (self
, npc
):
310 # set initial response ID to none
312 # not yet started mission drawing water from well and not refused it
313 if (gamestate
.flag
["mission_bulisa_water_from_well"] is False
314 and gamestate
.flag
["mission_bulisa_water_from_well_refused"] is False):
315 # set the current dialogue
316 npc
.currentdialog
= 0
317 # get the response ID
318 resp_id
= utility
.dialogue_play (self
.screen
, self
.img_dialogue
, npc
, self
.butaba
.portrait
, 0, 90)
319 if (gamestate
.flag
["mission_bulisa_water_from_well_refused"] is True and
320 gamestate
.flag
["mission_bulisa_water_from_well"] is False):
321 # set the current dialog
322 npc
.currentdialog
= 2
323 resp_id
= utility
.dialogue_play (self
.screen
, self
.img_dialogue
, npc
, self
.butaba
.portrait
, 0, 90)
324 # mission accepted but not completed - check if completed and set value
326 elif (gamestate
.flag
["mission_bulisa_water_from_well"] is True
327 and gamestate
.flag
["mission_bulisa_water_from_well_complete"] is False):
328 for invobj
in self
.butaba
.objects
:
329 if isinstance (invobj
, gameobjects
.Bucket
) is True:
330 if invobj
.liquid
== "water":
331 gamestate
.flag
["mission_bulisa_water_from_well_complete"] = True
332 self
.butaba
.objects
.remove (invobj
)
333 key1
= gameobjects
.Key (5, 3, "a chest key", self
.img_key2
, constants
.KEY_CHEST1
)
334 self
.butaba
.objects
.append (key1
)
337 # water mission is not completed yet
338 if gamestate
.flag
["mission_bulisa_water_from_well_complete"] is False:
339 npc
.currentdialog
= 1
341 npc
.currentdialog
= 3
342 # get the response ID
343 resp_id
= utility
.dialogue_play (self
.screen
, self
.img_dialogue
, npc
, self
.butaba
.portrait
, 0, 90)
344 # water from well mission is completed
345 elif (gamestate
.flag
["mission_bulisa_water_from_well_complete"]) is True:
346 npc
.currentdialog
= 4
347 resp_id
= utility
.dialogue_play (self
.screen
, self
.img_dialogue
, npc
, self
.butaba
.portrait
, 0, 90)
349 # if response ID is 12, then drawing water from well mission is refused
350 if resp_id
== "12" or resp_id
== "18":
351 gamestate
.flag
["mission_bulisa_water_from_well_refused"] = True
352 # if response ID is 13: that is accepted the drawing water from well mission begins
353 if resp_id
== "13" or resp_id
== "17":
354 gamestate
.flag
["mission_bulisa_water_from_well"] = True
355 # if response ID is none
356 elif resp_id
is None:
357 self
.status_message
= "You cannot initiate a conversation with %s" % npc
.charname
359 # interaction with objects
360 def interact_objects (self
, container
, objs
):
361 # overall flag for blocking/non-blocking objects
364 # now perform interaction
366 # run the object interact function
367 if obj
.interact () is False:
369 # if object can be picked up ask
370 if obj
.can_pickup
is True:
371 ans
= utility
.ask_question (self
.screen
, "Found %s." % obj
.text
, ["Pick up", obj
.use_str
, "Ignore"], self
.img_menu
)
372 # if the answer is "pick up"
374 self
.pickup_object (container
, obj
)
376 # use the object according to its type
377 self
.use_object (container
, obj
)
378 # if it cannot be picked up, try to use it anyway
380 ans
= utility
.ask_question (self
.screen
, "Found %s." % obj
.text
, [obj
.use_str
, "Ignore"], self
.img_menu
)
382 self
.use_object (container
, obj
)
386 # transfer an object from one container to another
387 # container must have an objects list
388 def transfer_object (self
, source
, obj
, dest
):
389 # remove object from source
390 source
.objects
.remove (obj
)
391 # add object to destination
392 dest
.objects
.append (obj
)
394 # picking up an object
395 def pickup_object (self
, container
, obj
):
396 # only if object can be picked up, pick it up or use it
397 if obj
.can_pickup
is True:
398 # check if the inventory is full
399 if len (self
.butaba
.objects
) >= constants
.MAXITEMS
:
400 self
.status_message
= "Cannot pick up item. Inventory full"
402 # add item to inventory
403 self
.transfer_object (container
, obj
, self
.butaba
)
405 self
.status_message
= "You picked up %s" % obj
.text
407 # this method uses the object first by calling the object use () method
408 # and then performing specific actions as necessary
409 def use_object (self
, container
, obj
):
410 # if the object is a health potion
411 if isinstance (obj
, gameobjects
.HealthPotion
) is True:
412 if self
.butaba
.health
< constants
.MAXHEALTH
:
413 obj
.use (self
.butaba
)
414 container
.objects
.remove (obj
)
415 self
.status_message
= "You gained health"
417 self
.status_message
= "You already have maximum health!"
418 # if the object is a chest
419 elif isinstance (obj
, gameobjects
.Chest
) is True:
420 # if chest is locked, try to open it
421 if obj
.locked
is True:
422 # try opening the chest with every item 9the use () function
423 # of the chest determines if item is a key anyway
425 for invobj
in self
.butaba
.objects
:
426 fittedkey
= obj
.use (invobj
)
428 if fittedkey
is not None:
431 if fittedkey
is None:
432 self
.status_message
= "No key found to open %s" % obj
.text
433 # chest successfully unlocked
435 self
.status_message
= "You unlocked the %s" % obj
.text
436 # remove the key from Butaba
437 self
.butaba
.objects
.remove (fittedkey
)
438 # add an experience point for unlocking chest subject
439 # to a limit of KNOWLEDGEMAX_CHEST_UNLOCK
440 if self
.butaba
.experience
< constants
.KNOWLEDGEMAX_CHEST_UNLOCK
:
441 self
.butaba
.experience
+= 1
442 self
.status_message
+= " and gained experience!"
443 # display the contents of the chest
445 item
= utility
.get_container_object (self
.screen
, obj
, self
.img_chestbg
, 30)
447 self
.interact_objects (obj
, [ item
, ])
449 # if the object is gold coins
450 elif isinstance (obj
, gameobjects
.GoldCoins
) is True:
451 obj
.use (self
.butaba
)
452 self
.status_message
= "You picked up %d gold." % obj
.value
453 # remove the gold coins after adding it to Butaba's gold
454 container
.objects
.remove (obj
)
455 # using a bucket means emptying it
456 elif isinstance (obj
, gameobjects
.Bucket
) is True:
457 if obj
.liquid
is not None:
458 self
.status_message
= "You emptied the bucket of %s" % obj
.liquid
459 obj
.use (self
.butaba
)
461 self
.status_message
= "Bucket is already empty."
463 elif isinstance (obj
, gameobjects
.Well
) is True:
464 # if the well is not dry, i.e. it has some liquid
465 if obj
.liquid
is not None:
466 # search butaba inventory for an empty bucket
467 for invobj
in self
.butaba
.objects
:
468 # bucket found, now check if it is empty
469 if isinstance (invobj
, gameobjects
.Bucket
) is True:
471 if invobj
.liquid
is None:
473 self
.status_message
= "You successfully filled the %s with %s" % (invobj
.text
, obj
.liquid
)
474 if self
.butaba
.strength
< constants
.STRENGTHMAX_DRAW_WELL_WATER
:
475 self
.butaba
.strength
+= 2
476 self
.status_message
+= " and gained strength!"
478 self
.status_message
= "You have no empty bucket to draw %s with!" % obj
.liquid
480 self
.status_message
= "%s appears to be dry!" % obj
.text
482 def move_butaba_left (self
):
483 # clear any status messages
484 self
.status_message
= None
486 # first if Butaba is not facing left, make him face left
487 if self
.butaba
.position
<> constants
.LEFT
:
488 self
.butaba
.position
= constants
.LEFT
491 # if butaba is trying to move off the left edge
492 if self
.butaba
.col
<= 0:
493 # if there is a level to the right set current level to that one
494 if self
.currentlevel
.levelleft
is not None:
495 # get the last column of the previous level
496 lastcol
= len (self
.currentlevel
.levelleft
.background
[0]) - 1
497 # interact with objects if any
498 # if any object is a blocking object then avoid movement
499 if self
.level_interact (self
.currentlevel
.levelleft
, self
.butaba
.row
, lastcol
) is False:
501 # make sure there is no obstacle at that position of movement
502 if self
.check_background_obstacle (self
.currentlevel
.levelleft
, self
.butaba
.row
, lastcol
) is False:
503 self
.currentlevel
= self
.currentlevel
.levelleft
504 self
.butaba
.col
= lastcol
505 # normal left movement
507 # interact with objects if any
508 # if any object is a blocking object then avoid movement
509 if self
.level_interact (self
.currentlevel
, self
.butaba
.row
, self
.butaba
.col
-1) is False:
511 if self
.check_background_obstacle (self
.currentlevel
, self
.butaba
.row
, self
.butaba
.col
-1) is False:
514 def move_butaba_right (self
):
515 # clear any status messages
516 self
.status_message
= None
518 # First if Butaba is not facing right make him face right
519 if self
.butaba
.position
<> constants
.RIGHT
:
520 self
.butaba
.position
= constants
.RIGHT
523 # if butaba is trying to move off the right edge
524 if self
.butaba
.col
>= len (self
.currentlevel
.background
[0])-1:
525 # if there is a level to the right swap current level with that one
526 if self
.currentlevel
.levelright
is not None:
527 # interact with objects if any
528 # if any object is a blocking object then avoid movement
529 if self
.level_interact (self
.currentlevel
.levelright
, self
.butaba
.row
, 0) is False:
532 # make sure there is no obstacle at that position of movement
533 # get the last column of the previous level
534 if self
.check_background_obstacle (self
.currentlevel
.levelright
, self
.butaba
.row
, 0) is False:
535 self
.currentlevel
= self
.currentlevel
.levelright
537 # normal right movement
539 # interact with objects if any
540 # if any object is a blocking object then avoid moving
541 if self
.level_interact (self
.currentlevel
, self
.butaba
.row
, self
.butaba
.col
+ 1) is False:
543 if self
.check_background_obstacle (self
.currentlevel
, self
.butaba
.row
, self
.butaba
.col
+ 1) is False:
546 def draw_butaba (self
):
547 if self
.butaba
.position
== constants
.FRONT
:
548 self
.screen
.blit (self
.butaba
.imagefront
, (self
.butaba
.col
*48, self
.butaba
.row
*48))
549 elif self
.butaba
.position
== constants
.BACK
:
550 self
.screen
.blit (self
.butaba
.imageback
, (self
.butaba
.col
*48, self
.butaba
.row
*48))
551 elif self
.butaba
.position
== constants
.LEFT
:
552 self
.screen
.blit (self
.butaba
.imageleft
, (self
.butaba
.col
*48, self
.butaba
.row
*48))
553 elif self
.butaba
.position
== constants
.RIGHT
:
554 self
.screen
.blit (self
.butaba
.imageright
, (self
.butaba
.col
*48, self
.butaba
.row
*48))
557 # Draw the status infodisplay
558 def draw_status (self
):
559 self
.screen
.blit (self
.img_redpotion
, (485, 10))
560 utility
.put_text (self
.screen
, 550, 25, 20, (255, 0, 0), "%d" % self
.butaba
.health
)
562 self
.screen
.blit (self
.img_lightning
, (620, 10))
563 utility
.put_text (self
.screen
, 660, 25, 20, (255,255,255), "%d" % self
.butaba
.strength
)
565 self
.screen
.blit (self
.img_wand
, (485, 65))
566 utility
.put_text (self
.screen
, 550, 75, 20, (0, 0, 255), "%d" % self
.butaba
.magic
)
568 self
.screen
.blit (self
.img_bulb
, (620, 65))
569 utility
.put_text (self
.screen
, 660, 75, 20, (0, 255, 0), "%d" % self
.butaba
.experience
)
571 self
.screen
.blit (self
.img_goldcoins
, (485, 110))
572 utility
.put_text (self
.screen
, 550, 130, 20, (255, 255, 0), "%d" % self
.butaba
.gold
)
574 if self
.status_message
is not None:
575 utility
.put_text (self
.screen
, 10, 485, 10, (255,255, 0), "%s" % self
.status_message
)
577 # display the inventory of the player
578 def draw_inventory (self
):
579 # draw the inventory slots
582 utility
.put_text (self
.screen
, 490, 170, 16, (255,255 , 0), "Inventory")
583 for i
in range (constants
.MAXITEMS
):
584 self
.screen
.blit (self
.img_inventory
, (440+c
*54, 150+r
*54))
593 for obj
in self
.butaba
.objects
:
594 self
.screen
.blit (obj
.image
, (440+c
*54+2, 150+r
*54+2))
601 # Draw the level background tiles on surface
602 def draw_level_background (self
, level
):
604 for row
in level
.background
:
606 for tilerow
, tilecol
, is_solid
in row
:
609 self
.screen
.blit (self
.img_tileset
, (j
*48, i
*48), pygame
.Rect (tilex
, tiley
, 48, 48))
614 # Draw the level objects
615 def draw_level_objects (self
, level
):
616 for obj
in level
.objects
:
617 if obj
.image
is not None:
618 self
.screen
.blit (obj
.image
, (obj
.col
*48, obj
.row
*48))
621 # Draw the NPCs in the level
622 def draw_level_npcs (self
, level
):
623 for npc
in level
.npcs
:
624 # if npc is not dead then move the NPC randomly depending on their
626 if npc
.is_dead
is False:
628 if random
.randint (1, 500) < npc
.movement_speed
:
629 # whether to change direction?
630 if random
.randint (1, 100) < 25:
631 npc
.position
= random
.randint (0, 3)
634 if npc
.position
== constants
.LEFT
:
635 # cannot move beyond level and cannot move beyond the
637 if npc
.col
> 0 and npc
.col
> npc
.initcol
- npc
.leftlimit
:
638 # check if there is any background obstacle
639 if self
.check_background_obstacle (level
, npc
.row
, npc
.col
- 1) is False:
640 # check if there are any objects
643 for lobj
in level
.objects
:
644 if lobj
.row
== npc
.row
and lobj
.col
== npc
.col
- 1:
647 # check if there any any npcs blocking
648 for lnpc
in level
.npcs
:
649 if lnpc
.row
== npc
.row
and lnpc
.col
== npc
.col
- 1:
652 if objblock
is False and npcblock
is False:
653 # if butaba is not blocking
654 if self
.butaba
.row
<> npc
.row
or self
.butaba
.col
<> npc
.col
- 1:
656 elif npc
.position
== constants
.RIGHT
:
657 # cannot move beyond level and cannot move beyond the
659 if npc
.col
< 9 and npc
.col
< npc
.initcol
+ npc
.rightlimit
:
660 # check if there is any background obstacle
661 if self
.check_background_obstacle (level
, npc
.row
, npc
.col
+ 1) is False:
662 # check if there are any objects
665 for lobj
in level
.objects
:
666 if lobj
.row
== npc
.row
and lobj
.col
== npc
.col
+ 1:
669 # check if there any any npcs blocking
670 for lnpc
in level
.npcs
:
671 if lnpc
.row
== npc
.row
and lnpc
.col
== npc
.col
+ 1:
674 if objblock
is False and npcblock
is False:
675 # if butaba is not blocking
676 if self
.butaba
.row
<> npc
.row
or self
.butaba
.col
<> npc
.col
+ 1:
678 elif npc
.position
== constants
.FRONT
:
679 # cannot move beyond level and cannot move beyond the
680 # lower bottom limit area
681 if npc
.row
< 9 and npc
.row
< npc
.initrow
+ npc
.bottomlimit
:
682 # check if there is any background obstacle
683 if self
.check_background_obstacle (level
, npc
.row
+ 1, npc
.col
) is False:
684 # check if there are any objects
687 for lobj
in level
.objects
:
688 if lobj
.row
== npc
.row
+ 1 and lobj
.col
== npc
.col
:
691 # check if there any any npcs blocking
692 for lnpc
in level
.npcs
:
693 if lnpc
.row
== npc
.row
+ 1 and lnpc
.col
== npc
.col
:
696 if objblock
is False and npcblock
is False:
697 # if butaba is not blocking
698 if self
.butaba
.row
<> npc
.row
+ 1 or self
.butaba
.col
<> npc
.col
:
700 elif npc
.position
== constants
.BACK
:
701 # cannot move beyond level and cannot move beyond the
702 # top upper limit area
703 if npc
.row
> 0 and npc
.row
> npc
.initrow
- npc
.toplimit
:
704 # check if there is any background obstacle
705 if self
.check_background_obstacle (level
, npc
.row
- 1, npc
.col
) is False:
706 # check if there are any objects
709 for lobj
in level
.objects
:
710 if lobj
.row
== npc
.row
- 1 and lobj
.col
== npc
.col
:
713 # check if there any any npcs blocking
714 for lnpc
in level
.npcs
:
715 if lnpc
.row
== npc
.row
- 1 and lnpc
.col
== npc
.col
:
718 # if no object is blocking
719 if objblock
is False and npcblock
is False:
720 # if butaba is not blocking
721 if self
.butaba
.row
<> npc
.row
- 1 or self
.butaba
.col
<> npc
.col
:
724 if npc
.position
== constants
.FRONT
:
726 elif npc
.position
== constants
.BACK
:
728 elif npc
.position
== constants
.LEFT
:
733 self
.screen
.blit (img
, (npc
.col
*48, npc
.row
*48))