Más mejoras al juego
[tajundrathegame.git] / qwesprites.py
blob249141965b4582b800273fc6215f4b2bef4b57a6
1 # Quick W Engine
2 # encoding: UTF-8
3 import pygame
4 import math
5 import random
8 class qweSprite(pygame.sprite.Sprite):
9 dx=dy=x=y=0
10 w=h=32
11 alive=True
12 in_ground=False
13 FRICTION_AIR=(0.2,0.2)
14 FRICTION_FLOOR=(8,8)
15 FRICTION_CEIL=(1,4)
16 GRAVITY=5
17 BOUNCE=-.1
18 RADIUS=16
19 psx=-1
20 psy=-1
21 ShowLife=MaxLife=Life=240
22 DIE_IMG='pernil.png'
24 LifeCollisionCost=0
25 LifeCollisionSpriteCost=2
26 MARGIN_LEFT=+2
27 MARGIN_RIGHT=-2
28 MARGIN_TOP=+1
29 MARGIN_BOTTOM=-1
30 fcount=0
31 SOLID=True
32 FSOLID=True
34 def __init__(self, stage):
35 pygame.sprite.Sprite.__init__(self)
36 stage.sprites+=[self]
38 def move(self,x,y):
39 self.x+=x
40 self.y+=y
42 self.rect=self.x,self.y,self.w,self.h
44 def selectImage(self):
45 return self.image
47 def die(self,screen):
48 Life(screen,(int(self.x),int(self.y)),self.DIE_IMG,self.MaxLife)
51 def draw(self,screen):
52 self.fcount+=1
53 if self.fcount>10/(self.Life+1):
54 self.fcount=4
55 screen.blit(self.selectImage(), self.rect)
56 if self.ShowLife>self.Life or (self.Life < 60 and self.ShowLife>0):
58 x,y,h,w=self.rect
59 pp=100.0*self.ShowLife/self.MaxLife
60 pp=pp+math.log(1+1.9*self.ShowLife/self.MaxLife)*100.0
61 if pp>200.0:
62 pp=200
63 if pp>100.0:
64 pp1=100
65 pp2=pp-100
66 else:
67 pp1=pp
68 pp2=0
70 w-=8
71 x+=1
72 y+=0
73 p1=x,y
74 p2=x+pp1*w/100.0,y
75 p1a=x,y+1
76 p2a=x+pp2*w/100.0,y+1
78 p=255.0*pp1/100.0
79 if pp2:
80 p=255.0*pp2/100.0
81 pygame.draw.line(screen, (255-p,255,0) , p1a, p2a,1)
82 pygame.draw.line(screen, (255-p,255,0) , p1, p2,1)
83 else:
84 pygame.draw.line(screen, (255,p,0) , p1, p2,1)
86 def tickms(self, ms, stage):
87 if not self.alive:
88 return []
89 rect1=pygame.Rect(self.rect)
91 if (self.Life<0):
92 self.alive=False
93 self.die(stage)
94 else:
95 self.Life-=ms/1000.0
97 if self.ShowLife>self.Life:
98 self.ShowLife-=ms/100.0
99 if self.ShowLife<self.Life:
100 self.ShowLife=self.Life
102 self.checkpos(stage,ms)
103 self.move(self.dx*ms/1000.0,self.dy*ms/1000.0)
104 self.dx/=1+self.FRICTION_AIR[0]*ms/1000.0
105 self.dy/=1+self.FRICTION_AIR[1]*ms/1000.0
107 rect2=self.rect
108 self.psx,self.psy=self.getpspoint(stage,0,0);
110 return [rect1.union(rect2)]
113 def getpspoint(self,stage,px,py):
114 sx,sy=stage.BlockSize
115 x,y,w,h=self.rect
117 if px>0: x0=x+px
118 elif px<0: x0=x+w+px
119 else: x0=x+w/2
121 if py>0: y0=y+py
122 elif py<0: y0=y+h+py
123 else: y0=y+h/2
125 x0=int(x0)/sx
126 y0=int(y0)/sy
128 return (x0,y0)
130 def checkcell(self,stage,px,py):
131 Pantalla=stage.StageData
133 x0,y0=self.getpspoint(stage,px,py);
135 if y0<0 and x0>=0 and x0<len(Pantalla[0]): return ' '
136 if y0>=0 and y0<len(Pantalla):
137 if x0>=0 and x0<len(Pantalla[y0]):
138 return Pantalla[y0][x0]
140 return 't'
142 def checkpos(self,stage,ms):
143 self.in_ground=False
145 if self.Life<=0.5: return
146 for sprite in stage.sprites:
147 if sprite!=self and sprite.Life>0.5:
148 if ( math.fabs(sprite.psx-self.psx)<=1
149 and math.fabs(sprite.psy-self.psy)<=1):
150 x,y,w,h=self.rect
151 sx,sy,sw,sh=sprite.rect
153 min_d=self.RADIUS+sprite.RADIUS
155 ax=x-sx;ay=y-sy;
156 d1=math.sqrt(ax*ax+ay*ay)
157 if d1<min_d:
158 x+=self.dx/1000.0
159 y+=self.dy/1000.0
160 sx+=sprite.dx/1000.0
161 sy+=sprite.dy/1000.0
163 ax=x-sx;ay=y-sy;
164 d2=math.sqrt(ax*ax+ay*ay)
165 if d2<=d1:
166 sdx=sprite.dx
167 sdy=sprite.dy
168 if sprite.SOLID and self.FSOLID:
169 sprite.dx=self.dx
170 sprite.dy=self.dy
172 if self.SOLID and sprite.FSOLID:
173 self.dx=sdx
174 self.dy=sdy
176 if self.Life<900:
177 self.Life-=sprite.LifeCollisionSpriteCost
178 if self.ShowLife>0:
179 self.ShowLife=self.Life+10
181 if sprite.Life<900:
182 sprite.Life-=self.LifeCollisionSpriteCost
183 if sprite.ShowLife>0:
184 sprite.ShowLife=sprite.Life+10
187 if d2<=d1+0.1:
188 self.in_ground=True
189 x,y,w,h=self.rect
190 ax=x-sx;ay=y-sy;
191 d1=math.sqrt(ax*ax+ay*ay)
192 if self.SOLID and sprite.FSOLID:
193 self.dx+=20*ax/d1
194 self.dy+=20*ay/d1
196 if sprite.SOLID and self.FSOLID:
197 sprite.dx-=20*ax/d1
198 sprite.dy-=20*ay/d1
202 # Colisión Horizontal
203 if ( (self.checkcell(stage,self.MARGIN_RIGHT,0)!=' ' and self.dx>=0) or
204 (self.checkcell(stage,self.MARGIN_RIGHT,12)!=' ' and self.dx>=0) or
205 (self.checkcell(stage,self.MARGIN_RIGHT,-12)!=' ' and self.dx>=0) ) :
206 if self.Life<900: self.Life-=self.LifeCollisionCost
207 self.move(-self.dx*ms/1000.0-.1,0)
208 if (self.BOUNCE>0): self.dx*=-self.BOUNCE
209 else: self.dx/=1-self.BOUNCE
211 if ( (self.checkcell(stage,self.MARGIN_LEFT,0)!=' ' and self.dx<=0) or
212 (self.checkcell(stage,self.MARGIN_LEFT,12)!=' ' and self.dx<=0) or
213 (self.checkcell(stage,self.MARGIN_LEFT,-12)!=' ' and self.dx<=0) ) :
214 if self.Life<900: self.Life-=self.LifeCollisionCost
215 self.move(-self.dx*ms/1000.0+.1,0)
216 if (self.BOUNCE>0): self.dx*=-self.BOUNCE
217 else: self.dx/=1-self.BOUNCE
219 #if ( (self.checkcell(stage,-4,0)!=' ' and self.dx>0) or
220 # (self.checkcell(stage,+4,0)!=' ' and self.dx<0) ) :
221 # self.dx/=1+5*ms/1000.0
224 # Control de hundimiento
225 if self.dy>=0:
226 if (self.checkcell(stage,self.MARGIN_LEFT+4,self.MARGIN_BOTTOM-1)!=' '
227 or self.checkcell(stage,self.MARGIN_RIGHT-4,self.MARGIN_BOTTOM-1)!=' '):
228 self.move(0,-1)
229 self.dy=0
231 # Colisión de techo
232 elif self.dy<0:
233 if (self.checkcell(stage,self.MARGIN_LEFT+4,self.MARGIN_TOP)!=' ' or
234 self.checkcell(stage,self.MARGIN_RIGHT-4,self.MARGIN_TOP)!=' ' or
235 self.checkcell(stage,0,self.MARGIN_TOP)!=' '):
237 if self.Life<900: self.Life-=self.LifeCollisionCost
238 self.move(0,-self.dy*ms/1000.0)
239 if (self.BOUNCE>0): self.dy*=-self.BOUNCE
240 else: self.dy/=1-self.BOUNCE
241 self.dx/=1+self.FRICTION_CEIL[0]*ms/1000.0
242 self.dy/=1+self.FRICTION_CEIL[1]*ms/1000.0
243 if self.checkcell(stage,0,+2)!=' ' and self.dy<0:
244 self.dx/=1+self.FRICTION_CEIL[0]*ms/1000.0
245 self.dy/=1+self.FRICTION_CEIL[1]*ms/1000.0
246 if self.checkcell(stage,0,+3)!=' ' and self.dy<0:
247 self.dy=0
251 # Colisión suelo
252 if (self.checkcell(stage,self.MARGIN_LEFT+4,self.MARGIN_BOTTOM)!=' '
253 or self.checkcell(stage,self.MARGIN_RIGHT-4,self.MARGIN_BOTTOM)!=' '):
254 self.dx/=1+self.FRICTION_FLOOR[0]*ms/1000.0
255 if self.dy>0:
256 if self.Life<900: self.Life-=self.LifeCollisionCost
257 if (self.BOUNCE>0): self.dy*=-self.BOUNCE
258 else: self.dy/=1-self.BOUNCE
259 self.dy/=1+self.FRICTION_FLOOR[1]*ms/1000.0
260 self.move(0,-self.dy*ms/1000.0)
262 elif self.dy<0:
263 pass
265 self.in_ground=True
266 else:
267 # Gravedad
268 self.dy+=self.GRAVITY
270 if self.Life<0.5: self.Life=0.5
271 if self.Life>self.MaxLife*1.5: self.Life=self.MaxLife*1.5
273 class Tajundra(qweSprite):
274 image_flip=None
275 estado=0
276 estado_ms=0
277 MARGIN_LEFT=+8
278 MARGIN_RIGHT=-8
279 MARGIN_TOP=+1
280 MARGIN_BOTTOM=-1
281 RADIUS=10
282 DIE_IMG='platano.png'
284 def __init__(self, stage):
286 qweSprite.__init__(self,stage)
287 self.image_right = pygame.image.load('tajuA1.png')
288 self.image_left=pygame.transform.flip(self.image_right,True,False)
290 self.imageb_right = pygame.image.load('tajuA2.png')
291 self.imageb_left=pygame.transform.flip(self.imageb_right,True,False)
294 self.image=self.image_right
295 self.rect = self.image.get_rect()
296 pos=stage.simbolos['@'][0]
297 del stage.simbolos['@'][0]
298 self.rect.bottomright = pos
299 self.rect=self.rect.move(stage.BlockSize)
300 self.x,self.y,self.w,self.h=self.rect
302 def selectImage(self):
303 dx=self.dx
304 if self.estado==0:
305 if dx<0:
306 self.image=self.image_left
307 else:
308 self.image=self.image_right
309 else:
310 if dx<0:
311 self.image=self.imageb_left
312 else:
313 self.image=self.imageb_right
314 self.estado_ms+=1
315 if self.estado_ms>20:
316 self.estado_ms=0
317 if self.estado==0:
318 self.estado=1
319 else:
320 self.estado=0
321 return self.image
327 class Dragon(qweSprite):
328 image_flip=None
329 estado=0
330 estado_ms=0
332 def __init__(self, stage):
334 qweSprite.__init__(self,stage)
335 self.image_left = pygame.image.load('dragonN1.png')
336 self.image_right=pygame.transform.flip(self.image_left,True,False)
338 self.imageb_left = pygame.image.load('dragonN2.png')
339 self.imageb_right=pygame.transform.flip(self.imageb_left,True,False)
342 self.image=self.image_right
343 self.rect = self.image.get_rect()
344 pos=stage.simbolos['$'][0]
345 del stage.simbolos['$'][0]
347 self.rect.bottomright = pos
348 self.rect=self.rect.move(stage.BlockSize)
349 self.x,self.y,self.w,self.h=self.rect
351 def selectImage(self):
352 dx=self.dx
353 if self.estado==0:
354 if dx<0:
355 self.image=self.image_left
356 else:
357 self.image=self.image_right
358 else:
359 if dx<0:
360 self.image=self.imageb_left
361 else:
362 self.image=self.imageb_right
363 self.estado_ms+=1
364 if self.estado_ms>20:
365 self.estado_ms=0
366 if self.estado==0:
367 self.estado=1
368 else:
369 self.estado=0
370 return self.image
374 class LanzaBolas(qweSprite):
375 image_flip=None
376 estado=0
377 estado_ms=0
378 BOUNCE=0
379 DIE_IMG='safanoria.png'
380 def __init__(self, stage):
382 qweSprite.__init__(self,stage)
383 self.image = pygame.image.load('lanzabolas1.png')
385 self.rect = self.image.get_rect()
386 pos=stage.simbolos['|'][0]
387 del stage.simbolos['|'][0]
389 self.rect.bottomright = pos
390 self.rect=self.rect.move(stage.BlockSize)
391 self.x,self.y,self.w,self.h=self.rect
392 self.estado_ms=random.randint(0,12000)
394 def selectImage(self):
395 return self.image
397 def tickms(self, ms, stage):
398 v=qweSprite.tickms(self, ms, stage)
399 self.estado_ms+=ms
400 if self.estado_ms>10000:
401 random.seed()
402 self.estado_ms=random.randint(0,1000)
403 r=random.randint(-1000,1000)/3.0
404 disparo=Bola(stage,(int(self.x),int(self.y)),r,-200)
405 disparo.move(0,-10)
406 disparo.GRAVITY=1
408 return v
412 class qweShoot(qweSprite):
413 estado=0
414 estado_ms=0
415 FRICTION_AIR=(0.0,0.0)
416 FRICTION_FLOOR=(0.0,0.0)
417 FRICTION_CEIL=(0.0,0.0)
418 GRAVITY=0
419 BOUNCE=.5
420 MaxLife=Life=2.0
421 ShowLife=0
422 LifeCollisionCost=1
423 LifeCollisionSpriteCost=10
425 fcount=0
426 accum_ms=0
428 MARGIN_LEFT=+10
429 MARGIN_RIGHT=-10
430 MARGIN_TOP=+10
431 MARGIN_BOTTOM=-10
433 def __init__(self, stage, pos,dx,dy):
435 qweSprite.__init__(self,stage)
436 self.image = pygame.image.load('bola1.png')
438 self.rect = self.image.get_rect()
440 self.rect.topleft = pos
441 self.dx=dx
442 self.dy=dy
443 self.x,self.y,self.w,self.h=self.rect
444 self.tickms(5,stage);
446 def die(self,screen):
447 pass
449 class Bola(qweShoot):
450 GRAVITY=20
451 BOUNCE=.5
452 MaxLife=Life=12.0
453 LifeCollisionCost=1
454 RADIUS=5
456 class Hacha(qweShoot):
457 FRICTION_AIR=(0.5,0.0)
458 BOUNCE=.8
459 MaxLife=60
460 Life=2
461 LifeCollisionCost=0.1
462 fcountrot=0
463 angle=0
464 GRAVITY=5
465 RADIUS=10
467 MARGIN_LEFT=+12
468 MARGIN_RIGHT=-12
469 MARGIN_TOP=+7
470 MARGIN_BOTTOM=-7
472 def __init__(self, stage, pos,dx,dy):
474 qweSprite.__init__(self,stage)
475 self.image1 = pygame.image.load('hacha1.png')
476 if dx<0: self.image1=pygame.transform.flip(self.image1, True, False)
477 self.image = self.image1.copy()
478 self.rect = self.image.get_rect()
480 self.rect.topleft = pos
481 self.dx=dx
482 self.dy=dy
483 self.x,self.y,self.w,self.h=self.rect
484 self.tickms(15,stage);
486 def draw(self,screen):
487 self.fcountrot+=1
488 if self.fcountrot>5/self.Life:
489 self.image=pygame.transform.rotate(self.image1, self.angle)
490 if self.dx>0:
491 self.angle-=90
492 else:
493 self.angle+=90
494 self.fcountrot=0
495 if self.Life>2:
496 self.SOLID=False
497 else:
498 self.SOLID=True
500 qweShoot.draw(self,screen)
502 def tickms(self, ms, stage):
503 if self.Life>2:
504 self.dx*=1.01
505 self.dy*=1.01
507 v=qweSprite.tickms(self, ms, stage)
508 return v
512 class Life(qweShoot):
513 FRICTION_AIR=(10.0,10.0)
514 BOUNCE=-.8
515 ShowLife=MaxLife=Life=10
516 LifeCollisionCost=0
517 LifeCollisionSpriteCost=-2
519 GRAVITY=1
520 SOLID=False
521 FSOLID=False
523 RADIUS=16
525 MARGIN_LEFT=+4
526 MARGIN_RIGHT=-4
527 MARGIN_TOP=+4
528 MARGIN_BOTTOM=-4
530 def __init__(self, stage, pos,imgfile, life):
532 qweSprite.__init__(self,stage)
534 self.image1 = pygame.image.load(imgfile)
535 self.image = self.image1.copy()
536 self.rect = self.image.get_rect()
537 self.ShowLife=self.MaxLife=self.Life=life
539 self.rect.topleft = pos
540 self.dx=0
541 self.dy=-20
542 self.x,self.y,self.w,self.h=self.rect
543 self.tickms(5,stage);
545 def tickms(self, ms, stage):
546 v=qweSprite.tickms(self, ms, stage)
547 if self.psx<0: self.move(8,0)
548 if self.psx>20: self.move(-8,0)
550 if self.psy<0: self.move(0,8)
551 if self.psy>15: self.move(0,-8)
552 return v