1 """Isometric tile engine.
3 <p>Note -- this engine is not finished, any may not work for your
4 particular needs. If you are able to update it, help would be
5 greatly appreciated!</p>
7 <p>please note that this file is alpha, and is subject to modification in
8 future versions of pgu!</p>
11 print 'pgu.isovid','This module is alpha, and is subject to change.'
17 """Create an iso vid engine. See [[vid]]"""
18 def update(self
,screen
):
19 return self
.paint(screen
)
21 def paint(self
,screen
):
22 sw
,sh
= screen
.get_width(),screen
.get_height()
27 w
,h
= len(tlayer
[0]),len(tlayer
)
29 iso_w
,iso_h
,iso_z
,tile_w
,tile_h
,base_w
,base_h
= self
.iso_w
,self
.iso_h
,self
.iso_z
,self
.tile_w
,self
.tile_h
,self
.base_w
,self
.base_h
35 todo_max
= sh
/base_h2
+bot
36 todo
= [[] for y
in xrange(0,todo_max
)]
38 self
.view
.w
,self
.view
.h
= sw
,sh
40 adj
= self
.adj
= pygame
.Rect(-self
.view
.x
,-self
.view
.y
,0,0)
42 for s
in self
.sprites
:
43 self
.sprite_calc_irect(s
)
44 x
,y
= self
.iso_to_view((s
.rect
.centerx
,s
.rect
.centery
))
45 v
= (y
+adj
.y
)/base_h2
- 1
46 if v
>= 0 and v
< todo_max
:
47 todo
[v
].append((s
.image
,s
.irect
))
48 #else: print 'doesnt fit',v
50 w
,h
= len(tlayer
[0]),len(tlayer
)
54 if self
.bounds
== None:
55 tmp
,y1
= self
.tile_to_view((0,0))
56 x1
,tmp
= self
.tile_to_view((0,h
+1))
57 tmp
,y2
= self
.tile_to_view((w
+1,h
+1))
58 x2
,tmp
= self
.tile_to_view((w
+1,0))
59 self
.bounds
= pygame
.Rect(x1
,y1
,x2
-x1
,y2
-y1
)
62 if self
.bounds
!= None: self
.view
.clamp_ip(self
.bounds
)
64 ox
,oy
= self
.screen_to_tile((0,0))
65 sx
,sy
= self
.iso_to_view((ox
*iso_w
,oy
*iso_h
))
66 dx
,dy
= sx
- self
.view
.x
,sy
- self
.view
.y
68 for i2
in xrange(-bot
,self
.view
.h
/base_h2
+bot
):
69 tx
,ty
= ox
+ i2
/2 + i2
%2,oy
+ i2
/2
70 x
,y
= (i2
%2)*base_w2
+ dx
,i2
*base_h2
+ dy
72 #to adjust for the -1 in i1
73 x
,tx
,ty
= x
-base_w
,tx
-1,ty
+1
74 for i1
in xrange(-1,self
.view
.w
/base_w
+2): #NOTE: not sure why +2
75 if ty
>= 0 and ty
< h
and tx
>= 0 and tx
< w
:
76 z
= zlayer
[ty
][tx
]*iso_z
81 if t
!= None and t
.image
!= None:
82 screen
.blit(t
.image
,(x
-base_w2
,y
+z
))
86 if t
!= None and t
.image
!= None:
87 screen
.blit(t
.image
,(x
-base_w2
,y
-(t
.image_h
-base_h
)+z
))
92 for img
,irect
in todo
[y
/base_h2
]:
93 screen
.blit(img
,(irect
.x
+adj
.x
,irect
.y
+adj
.y
))
95 return [pygame
.Rect(0,0,screen
.get_width(),screen
.get_height())]
97 def iso_to_view(self
,pos
):
99 w
,h
= len(tlayer
[0]),len(tlayer
)
103 #nx,ny = (h*self.iso_w + x - y)/2, (0 + x + y)/2
104 nx
,ny
= (x
- y
)/2, (0 + x
+ y
)/2
106 return (nx
* self
.base_w
/ self
.iso_w
), (ny
* self
.base_h
/ self
.iso_h
)
108 def view_to_iso(self
,pos
):
110 w
,h
= len(tlayer
[0]),len(tlayer
)
114 x
,y
= x
*self
.iso_w
/self
.base_w
, y
*self
.iso_h
/self
.base_h
116 #x -= (self.iso_w/2) * h
117 #x -= (self.iso_w/2) * h
124 def tile_to_view(self
,pos
):
125 return self
.iso_to_view((pos
[0]*self
.iso_w
,pos
[1]*self
.iso_h
))
127 def screen_to_tile(self
,pos
):
131 x
,y
= self
.view_to_iso((x
,y
))
132 return x
/self
.iso_w
,y
/self
.iso_h
134 def tile_to_screen(self
,pos
):
135 x
,y
= self
.iso_to_view((pos
[0]*self
.iso_w
,pos
[1]*self
.iso_h
))
136 return x
-self
.view
.x
,y
-self
.view
.y
138 def tga_load_tiles(self
,fname
,size
,tdata
={}):
139 Vid
.tga_load_tiles(self
,fname
,size
,tdata
)
141 self
.tile_w
,self
.tile_h
= size
142 self
.iso_w
,self
.iso_h
,self
.iso_z
= self
.tile_w
,self
.tile_w
,1
143 self
.base_w
,self
.base_h
= self
.tile_w
,self
.tile_w
/2
147 def resize(self
,size
,bg
=0):
148 Vid
.resize(self
,size
,bg
)
151 w
,h
= len(tlayer
[0]),len(tlayer
)
153 self
.zlayer
= [[0 for x
in xrange(0,w
)] for y
in xrange(0,h
)]
158 def sprite_calc_irect(self
,s
):
160 w
,h
= len(tlayer
[0]),len(tlayer
)
163 x
,y
= self
.iso_to_view((s
.rect
.centerx
,s
.rect
.centery
))
164 tx
,ty
= s
.rect
.centerx
/self
.iso_w
,s
.rect
.centery
/self
.iso_h
166 if ty
>= 0 and ty
< h
and tx
>= 0 and tx
< w
:
167 z
= zlayer
[ty
][tx
]*self
.iso_z
169 nx
,ny
= x
- s
.shape
.centerx
, y
- s
.shape
.centery
+ z
171 s
.irect
.x
,s
.irect
.y
= nx
,ny
173 def run_codes(self
,cdata
,rect
):
174 #HACK to make run_codes work
175 w
,h
= self
.iso_w
,self
.iso_h
177 img
= self
.tiles
[0].image
179 self
.tiles
[0].image
= pygame
.Surface((w
,h
))
180 r
= Vid
.run_codes(self
,cdata
,rect
)
181 self
.tiles
[0].image
= img