Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # PyRPG3D.py
- import Tkinter
- import os
- import time
- # build map #
- map = [[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
- [1,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,1,1,1],
- [1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1],
- [1,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1],
- [1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1],
- [1,1,1,1,0,0,0,1,0,0,1,1,5,1,1,0,0,1,1],
- [1,0,7,0,0,0,0,0,1,0,1,0,1,0,0,1,0,1,1],
- [1,0,1,0,0,1,1,0,0,0,0,0,0,0,1,0,1,0,1],
- [1,0,1,1,0,1,0,1,2,0,1,1,1,1,0,0,1,0,1],
- [1,0,0,0,0,0,0,1,0,0,0,0,1,0,1,1,1,1,1],
- [1,0,1,0,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1],
- [1,0,0,0,0,1,0,0,0,0,1,0,0,1,1,0,0,1,1],
- [1,0,1,1,0,0,1,0,1,1,0,0,1,0,0,0,1,0,1],
- [1,1,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,0,1],
- [1,0,0,1,0,0,1,1,0,1,0,1,0,0,0,1,0,1,1],
- [1,4,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,1,1],
- [1,4,1,0,0,1,0,1,1,1,0,0,1,0,1,0,1,0,1],
- [1,0,1,0,1,1,0,1,0,0,6,1,0,0,1,8,1,3,1],
- [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]
- map_height = len( map )
- map_width = len( map[ 0 ] )
- # turn map template into collection of cells #
- def new_cell( state ):
- return { "state": state,
- "visited": 0,
- "contents": [] }
- templateDict = { 0: 'empty',
- 1: 'wall',
- 2: 'enemy',
- 3: 'treasure',
- 4: 'fake_wall',
- 5: 'teleport',
- 6: 'stairs_up',
- 7: 'stairs_down',
- 8: 'stairs_both' }
- for y in range( len( map ) ):
- for x in range( len( map[ y ] ) ):
- map[ y ][ x ] = new_cell( templateDict[ map[ y ][ x ] ] )
- # initial settings #
- pos = [1, 1] # player pos: x, y
- facing = 'S' # N,E,S,W?
- # UI response functions #
- def firstperson_click( event = None ):
- (w,h) = ( canv.winfo_width(), canv.winfo_height() )
- if event.x < w/3: move_left()
- elif event.x > 2*w/3: move_right()
- else:
- if event.y < h/3: print "climb the stairs"
- elif event.y > 2*h/3: print "decend the stairs"
- else: move_forward()
- def overhead_click(self, event):
- pos = [int(event.x/canv2scale),int(event.y/canv2scale)]
- drawmap()
- # player motion functions #
- def move_forward( event = None ):
- global pos, map
- (x,y) = (pos[0], pos[1])
- dx = { "N": 0, "E": 1, "S": 0, "W": -1 }[ facing ]
- dy = { "N": -1, "E": 0, "S": 1, "W": 0 }[ facing ]
- if map[ y+dy ][ x+dx ][ "state" ] != 'wall':
- pos = [ x+dx, y+dy ]
- map[ y ][ x ][ "visited" ] = 1
- drawmap()
- def move_back( event = None ):
- global pos, map
- (x,y) = (pos[0], pos[1])
- dx = { "N": 0, "E": -1, "S": 0, "W": 1 }[ facing ]
- dy = { "N": 1, "E": 0, "S": -1, "W": 0 }[ facing ]
- if map[ y+dy ][ x+dx ][ "state" ] != 'wall':
- pos = [ x+dx, y+dy ]
- map[ y ][ x ][ "visited" ] = 1
- drawmap()
- def turn_right( event = None ):
- global facing
- facing = { "N": "E", "E": "S", "S": "W", "W": "N" }[ facing ]
- drawmap()
- def turn_left( event = None ):
- global facing
- facing = { "N": "W", "E": "N", "S": "E", "W": "S" }[ facing ]
- drawmap()
- def turn_around( event = None ):
- global facing
- facing = { "N": "S", "E": "W", "S": "N", "W": "E" }[ facing ]
- drawmap()
- # UI #
- root = Tkinter.Tk()
- root.title( "PyRPG3D" )
- images = {}
- for filename in filter( lambda x: x[-4:] == ".gif", os.listdir( os.curdir ) ):
- images[ filename[:-4] ] = Tkinter.PhotoImage( file = filename )
- firstperson = Tkinter.Frame( root )
- firstperson.pack( side='left', anchor=Tkinter.NW )
- overhead = Tkinter.Frame( root )
- overhead.pack( side='left', anchor=Tkinter.NW )
- canv = Tkinter.Canvas( firstperson, width=253, height=253, relief='sunken', bd=1 )
- canv.pack()
- root.bind( "<Button 1>", firstperson_click )
- root.bind( "<Control-Key>", turn_around )
- root.bind( "<Up>", move_forward )
- root.bind( "<Down>", move_back )
- root.bind( "<Left>", turn_left )
- root.bind( "<Right>", turn_right )
- canv2 = Tkinter.Canvas( overhead, width=253, height=253, relief='sunken', bd=1 )
- canv2.pack()
- canv2.bind( "<space>", overhead_click )
- side = Tkinter.Frame( firstperson )
- side.pack( side='left' )
- arrows = Tkinter.Frame( firstperson )
- arrows.pack( side='left' )
- title = Tkinter.Label( side, text='PyRPG3D' )
- title.pack( padx=20 )
- '''
- def build_button( imagename, commandval, rowval, colval, bindstr ):
- b = Tkinter.Button( arrows, image=images[ imagename ], command=commandval,
- width=21, height=21 )
- b.grid( row=rowval, column=colval )
- root.bind_all( bindstr, commandval )
- return b
- button_forward = build_button( "up", move_forward, 0, 1, "" )
- button_back = build_button( "down", move_back, 2, 1, "" )
- button_left = build_button( "left", turn_left, 1, 0, "" )
- button_right = build_button( "right", turn_right, 1, 2, "" )
- button_turn = build_button( "rotate", turn_around, 1, 1, "" )
- '''
- label = Tkinter.Label( overhead, text="could put some zooming mode buttons here" )
- label.pack( pady=30 )
- # map windows & calculate drawing scaling factor #
- root.update()
- canv2scale = canv2.winfo_width()/(map_width+1)
- # screen drawing functions #
- def valid_cell( x, y ):
- if (0 <= y < map_height) and (0 <= x < map_width):
- return 1
- return 0
- def getview():
- """
- Return player's point of view
- consisting of three lists,
- closest to farthest.
- """
- view = []
- (xpos,ypos) = (pos[0],pos[1])
- # use facing to determine rasterization #
- across_dx, across_dy = { "N": (+1,0),
- "E": (0,+1),
- "S": (-1,0),
- "W": (0,-1) }[ facing ]
- deep_dx, deep_dy = { "N": (-2,-1),
- "E": (+1,-2),
- "S": (+2,+1),
- "W": (-1,+2) }[ facing ]
- # cue up to start position #
- xpos = xpos + across_dx + deep_dx
- ypos = ypos + across_dy + deep_dy
- for godeep in range( 3 ):
- # clear this level #
- vlevel = []
- # scan this level #
- for goacross in range( 3 ):
- if valid_cell( xpos, ypos ):
- vlevel.append( map[ ypos ][ xpos ] )
- else:
- vlevel.append( new_cell( "wall" ) )
- xpos = xpos + across_dx
- ypos = ypos + across_dy
- # go back to last spot #
- # (Yes, we could get rid of this by changing the deep_dx/dy.)
- xpos = xpos - across_dx
- ypos = ypos - across_dy
- # cue up to start of next across #
- xpos = xpos + deep_dx
- ypos = ypos + deep_dy
- view.append( vlevel )
- return view
- def image( x, y, imagename ):
- canv.create_image( x, y, anchor=Tkinter.NW, image=images[ imagename ] )
- def drawmap():
- local = getview()
- canv.delete( Tkinter.ALL )
- canv2.delete( Tkinter.ALL )
- '''
- image( 0, 0, "back" )
- if len( local ) > 1:
- if local[1][0][ "state" ] == 'wall': image(0, 92, "vlevel-2-left" )
- if local[1][1][ "state" ] == 'wall': image(80, 92, "vlevel-2-mid" )
- if local[1][2][ "state" ] == 'wall': image(153, 92, "vlevel-2-right" )
- if local[0][0][ "state" ] == 'wall': image( 0, 30, "vlevel-1-left" )
- if local[0][2][ "state" ] == 'wall': image( 178, 30, "vlevel-1-right" )
- if local[0][1][ "state" ] == 'wall': image( 0, 30, "vlevel-1-mid" )
- '''
- drawoverhead()
- def drawoverhead():
- # draw map #
- y = 0
- for row in map:
- y = y + 1
- x = 0
- for cell in row:
- x = x + 1
- # call function depending on cell state #
- { "wall": draw_wall,
- "enemy": draw_enemy,
- "treasure": draw_treasure,
- "fake_wall": draw_wall,
- "teleport": draw_teleport,
- "stairs_up": draw_stairs_up,
- "stairs_down": draw_stairs_down,
- "stairs_both": draw_stairs_both,
- "empty": draw_nothing }[ cell[ "state" ] ]( x, y )
- # draw player #
- draw_rect( pos[0]+1, pos[1]+1, "black", 0.7, 1 )
- (_x,_y) = ( (pos[0]+1)*canv2scale, (pos[1]+1)*canv2scale )
- d = (canv2scale / 2) * .9
- (_x1, _y1, _x2, _y2) = { "N": (_x, _y+d, _x, _y-d ),
- "E": (_x-d, _y, _x+d, _y ),
- "S": (_x, _y-d, _x, _y+d ),
- "W": (_x+d, _y, _x-d, _y ) }[ facing ]
- canv2.create_line( _x1, _y1, _x2, _y2, arrow='last', fill='white' )
- def draw_rect( x, y, color, scale, fill ):
- (_x,_y) = ( x * canv2scale, y * canv2scale )
- d = (canv2scale / 2) * scale
- if fill == 0:
- canv2.create_rectangle( _x-d, _y-d, _x+d, _y+d, outline=color )
- else:
- canv2.create_rectangle( _x-d, _y-d, _x+d, _y+d, fill=color, outline=color )
- def draw_wall( x, y ): draw_rect( x, y, "#808080", 1.0, 1 )
- def draw_enemy( x, y ): draw_rect( x, y, "red", 0.7, 1 )
- def draw_treasure( x, y ): draw_rect( x, y, "gold", 0.7, 1 )
- def draw_teleport( x, y ): draw_rect( x, y, "darkgreen", 0.7, 1 )
- def draw_stairs_up( x, y ): draw_rect( x, y, "darkgreen", 0.7, 0 )
- def draw_stairs_down( x, y ): draw_rect( x, y, "darkgreen", 0.7, 0 )
- def draw_stairs_both( x, y ): draw_rect( x, y, "darkgreen", 0.7, 0 )
- def draw_nothing( x, y ): pass
- root.update()
- drawmap()
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement