Qualche tempo dopo la pubblicazione (e molto tempo dopo la sua creazione con pygame) ecco la nuova versione di Primitive Shooter II.
Buongiorno a tutti, con molta fatica, molto impegno e poco tempo a disposizione sono riuscito a migliorare un po' il mio modesto tentativo di creare uno shooter a scorrimento verticale con tutti i crismi; ecco perciò la nuova versione di Primitive Shooter II completamente programmata in python e pygame!
Fra le nuove caratteristiche del gioco troviamo:
- Suoni con Stereo Panning.
- Sfondo scorrevole a 3 livelli di parallasse che reagisce ai movimenti della navetta.
- 7 tipi diversi di PowerUps.
- Battaglia col boss ogni 5 livelli.
- Supporto per le vite e schermata di Game Over.
- 3 Tipi di Nemici: Normale, Shooter e Kamikaze.
Nelle prossime pagine analizzeremo in dettaglio le caratteristiche del gioco, per poi vedere il codice sorgente finale scritto in Python e Pygame.
Le Classi
Per prima cosa vediamo un po' che classi abbiamo a disposizione:
Classe | Descrizione |
---|---|
Player | La classe che rappresenta il giocatore ed i "kompanions" |
Enemy | Un nemico generico, con qualche modificatore in più rispetto alla vecchia versione |
Bullet | Un semplice proiettile |
BigBullet | Un Proiettile più grande (e presto pi potente) |
PowerUp | Un Generico PowerUp Raccoglibile |
Star | Una generica stella sullo sfondo |
EnemyBullet | Un proiettile lanciato dal nemico |
Boss | Un grosso, enorme boss arrabbiato |
La maggior parte delle classi sono derivate direttamente da Sprite, ereditando così tutti i metodi che Pygame ci offre per velocizzare e facilitare il disegno delle immagini.
Primitive Shooter II fa ancora uso della Classe Vector Appositamente creata, potete trovarla in questo articolo .
Le Funzioni e i bachi conosciuti
Le funzioni sono davvero poche ma essenziali:
Funzione | Descrizione |
---|---|
Shoot | Sparo temporizzato, che ci permette di sparare senza dover massacrare la tastiera. |
Level | Gestisce la creazione dei livelli, le battaglie col boss e l'aumento di difficoltà |
SoundInit | Un posto separato dove tenere i suoni |
Stereo_Pan | Permette di modificare il volume delle casse destra e sinistra a seconda della posizione sullo schermo dell'evento collegato al suono |
I bachi (bugs) trovati e non risolti finora sono:
- Sotto Windows i suoni vengono riprodotti in ritardo
- A volte uno dei due kompanions si blocca ad un lato dello schermo, seguendo solo i movimenti verticali della navetta
- Le stelle sullo sfondo si "appiccicano" ai lati sinistro e superiore dello schermo.
- Se finite addosso al boss, morirete e il boss sparirà. Il gioco potrebbe non proseguire.
Un po' di parole sul Gioco in sè...
Per quanto riguarda il lato "ludico" del gioco, troviamo per prima cosa una navetta che è in grado di sparare a 9 livelli di potenza diversi.
Successivamente troviamo 4 tipi di nemici + 1 boss:
Nemico | Descrizione |
---|---|
Normale | La classica "Carne da cannone": un nemico inerme che si muove a caso sullo schermo. Se ci finite addosso perderete una vita però... |
Shooter | Un nemico un po' più cattivo che vi lancerà addosso proiettili con lo scopo di colpirvi. |
Kamikaze | Un pazzo scatenato che cercherà in tutti i modi di venirvi addosso. |
Shooter-Kamikaze | Un pazzo veramente cattivo che compare di rado, vi spara addosso mentre cerca di centrarvi con la propria navetta |
Boss | Un grande, grosso, enorme e resistentissimo nemico un po' pigro, non fa altro che andare da destra a sinistra sparandovi addosso. |
Inoltre troviamo ben 7 powerups diversi che permettono di facilitare la nostra battaglia:
PowerUp | Descrizione |
---|---|
Potenza | Aumenta di una unità la potenza di fuoco della vostra navetta |
Velocità Cannone | Aumenta il rateo di fuoco del vostro cannone |
FullPower! | Per 20 secondi vi di massima potenza e ritmo di fuoco, per un rapido sterminio. |
Velocità Nave | Aumenta la velocità della vostra nave, per movimenti più rapidi e repentini. |
Kompanions | Affianca alla vostra nave altre due piccole navette per aumentare la potenza di fuoco. Dura 60 secondi. |
Shield | Fa esattamente quello che dice, vi da uno scudo che vi protegge da tutto per 60 secondi |
Assistance | Un piccolo soccorso dalla base missilistica più vicina, un'orda di grossi proiettili si abbatte sul campo. |
Per giocare è sufficiente una tastiera, si usano le freccette direzionali per muoversi e "Z" per sparare.
Il codice sorgente
14000 righe di codice? Non voglio arrivare a questi livelli per avere un rettangolo che spara...
Ecco qui di seguito il codice sorgente completo del gioco, per un totale di 822 righe:
#!/usr/bin/env python
#Imports
import pygame
from pygame.locals import *
from sys import exit
import Vector
from Vector import *
from math import pi
from random import randint,random
#Dichiarazioni
GameOver=False
tp=0
sht=False
showtime=False
totime=0.
shieldonscreen=False
time=0
xmove=0.
ymove=1.
render_list=pygame.sprite.Group()
enen=1
starlist=pygame.sprite.Group()
enemy_list=pygame.sprite.Group()
bullet_list=pygame.sprite.Group()
pow_list=pygame.sprite.Group()
player_list=pygame.sprite.Group()
enemy_bull_list=pygame.sprite.Group()
shtinterval=0.5
shlvl=1
shieldtime=0.
oldshlvl=0
oldinterval=0
lev=0
komtimer=0.
kom1=None
kom2=None
kompanion=False
komonscreen=False
fptimer=0
fullpower=False
fponscreen=False
charge=0
score=0
pows=""
maxpower=9
enemysm=1
#Classi
class Player(pygame.sprite.Sprite):
move_x=0
move_y=0
player=False
komp=0
speed=1.
lives=3
shielded=False
def __init__(self,x,y,play,kom):
pygame.sprite.Sprite.__init__(self)
if play:
self.image=pygame.Surface((20,20))
else:
self.image=pygame.Surface((20,10))
self.image.fill((255,255,255))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
self.player=play
self.komp=kom
render_list.add(self)
player_list.add(self)
def update(self):
if self.player:
if self.shielded:
self.image.fill((57,255,252))
else:
self.image.fill((255,255,255))
if self.rect.x+self.move_x<=0 or self.rect.x+self.move_x>=620:
self.move_x=0
movex=0
else:
global xmove
self.rect.x+=self.move_x
if pygame.key.get_pressed()[K_LEFT]:
xmove=0.5
elif pygame.key.get_pressed()[K_RIGHT]:
xmove=-0.5
elif not pygame.key.get_pressed()[K_RIGHT] or not pygame.key.get_pressed()[K_LEFT]:
xmove=0
if self.rect.y+self.move_y<=0 or self.rect.y+self.move_y>=460:
self.move_y=0
global ymove
ymove=1.
else:
global ymove
self.rect.y+=self.move_y
if pygame.key.get_pressed()[K_UP]:
ymove=+1.5
elif pygame.key.get_pressed()[K_DOWN]:
ymove=0.5
elif not pygame.key.get_pressed()[K_UP] or not pygame.key.get_pressed()[K_DOWN]:
ymove=1
collide=pygame.sprite.spritecollide(self,enemy_list,True)
collide2=pygame.sprite.spritecollide(self,enemy_bull_list,True)
if (collide or collide2) and not self.shielded:
global shlvl,fullpower,oldshlvl,shtinterval,oldinterval,fptime
self.lives-=1
global pexp_snd
exch=pexp_snd.play()
if exch is not None:
left,right=Stereo_Pan(player.rect.x,640)
exch.set_volume(left,right)
if not fullpower:
if shlvl>=2:
shlvl-=2
if shtinterval<=0.3:
shtinterval+=0.2
else:
if oldshlvl<=2:
oldshlvl-=2
if oldinterval<=0.3:
shtinterval+=0.2
fptime=0
fullpower=False
if player.speed>=1.4:
player.speed-=0.4
self.shield()
global shieldtime
shieldtime=5.
global komtimer
komtimer=0.
if self.lives<=0:
self.kill()
else:
if self.rect.y+self.move_y<=0 or self.rect.y+self.move_y>=460:
self.move_y=0
else:
self.rect.y+=self.move_y
if self.komp==1:
if self.rect.x+self.move_x<=-50 or self.rect.x+self.move_x>=570:
self.move_x=0
else:
self.rect.x+=self.move_x
elif self.komp==2:
if self.rect.x+self.move_x>=670 or self.rect.x+self.move_x<=50:
self.move_x=0
else:
self.rect.x+=self.move_x
def shield(self):
self.shielded=True
def unshield(self):
self.shielded=False
#---------------------------------------------------------
class Enemy(pygame.sprite.Sprite):
state="flying"
waittime=0
direction=Vector()
move_x=0
move_y=0
speed=150
time=0
d=0
endwait=False
shooter=False
kamikaze=False
energy=1
def __init__(self,x,y,speedmod,sh,km,en):
self.d=randint(0,1)
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((20,20))
self.image.fill((255,0,0))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
render_list.add(self)
self.time=0
enemy_list.add(self)
self.direction=Vector.FromAngle((random()*(pi/2))+pi/4)
self.direction.Normalize()
self.move_x=self.direction.to_tuple()[0]
self.move_y=self.direction.to_tuple()[1]
self.speed*=speedmod
self.shooter=sh
self.kamikaze=km
self.energy=en
def update(self):
if self.state=="flying":
if not self.kamikaze:
if self.rect.x>=20 and self.rect.x<=620:
self.rect.x+=self.move_x*(tp/1000.)*self.speed
else:
self.move_x=(-self.move_x)
self.rect.x+=self.move_x*(tp/1000.)*self.speed
else:
v=Vector.FromPoints((self.rect.x,self.rect.y),(player.rect.x+(player.rect.width/2),player.rect.y))
v.Normalize()
self.rect.x+=self.speed*v.to_tuple()[0]*(tp/1000.)
self.rect.y+=self.move_y*(tp/1000.)*self.speed
if self.rect.y in range(220,225):
self.state="waiting"
elif self.state=="waiting" and not self.endwait:
if self.waittime>=2:
self.direction=Vector.FromAngle(random()*3*pi/4)
self.direction.Normalize()
self.move_x=self.direction.to_tuple()[0]
self.move_y=self.direction.to_tuple()[1]
self.state="flying"
self.endwait=True
else:
if self.d:
if self.rect.x+self.move_x<=620:
self.rect.x+=(tp/1000.)*self.speed
else:
self.move_x=0
self.d=0
else:
if self.rect.x-self.move_x>=20:
self.rect.x-=(tp/1000.)*self.speed
else:
self.move_x=0
self.d=1
self.waittime+=tp/1000.
else:
self.state="flying"
if self.shooter:
#E' uno shooter
global tp
self.time+=tp/1000.
if self.time>=3.+randint(0,5) and self.rect.y>=0:
EnemyBullet(self.rect.x+(self.rect.width/2),self.rect.y)
self.time=0
collide=pygame.sprite.spritecollide(self,bullet_list,True)
if collide:
self.energy-=1
n=randint(0,3)
global score
score+=20
if n==1 and self.energy==0:
PowerUp(self.rect.x+self.rect.width/2,self.rect.y)
if self.energy==0:
global exp_snd
expch=exp_snd.play()
if expch is not None:
left,right=Stereo_Pan(self.rect.x,640)
expch.set_volume(left,right)
self.kill()
if self.rect.y>=490:
self.kill()
#----------------------------------------------------------
class Bullet(pygame.sprite.Sprite):
dir_x=0
dir_y=0
speed=500
def __init__(self,x,y,theta,mirror=False):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((2,10))
self.image.fill((255,74,42))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
self.dir_x,self.dir_y=Vector.FromAngle(theta).to_tuple()
if mirror:
self.dir_x*=(-1)
bullet_list.add(self)
render_list.add(self)
def update(self):
self.rect.x+=self.dir_x*(tp/1000.)*self.speed
self.rect.y+=self.dir_y*(tp/1000.)*self.speed
if self.rect.y<=-20:
self.kill()
class BigBullet(pygame.sprite.Sprite):
speed=200
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((20,50))
self.image.fill((255,74,42))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
bullet_list.add(self)
render_list.add(self)
def update(self):
self.rect.y-=tp/1000.*self.speed
if self.rect.y<=-100:
self.kill()
#----------------------------------------------------------
class PowerUp(pygame.sprite.Sprite):
powtype=0
speed=50
def __init__(self,x,y):
self.powtype=randint(1,7)
pygame.sprite.Sprite.__init__(self)
if self.powtype==1:
self.image=PowTxt.render(" S ",True,(255,255,0),(255,0,0))
elif self.powtype==2:
self.image=PowTxt.render(" F ",True,(27,42,255),(255,128,0))
elif self.powtype==3:
global fponscreen
if not fullpower and not fponscreen:
self.image=PowTxt.render(" FP!! ", True, (255,0,0),(255,255,255))
fponscreen=True
else:
return None
elif self.powtype==4:
self.image=PowTxt.render(" SS ", True, (0,0,0),(0,255,0))
elif self.powtype==5:
if not kompanion and not komonscreen:
global komonscreen
komonscreen=True
self.image=PowTxt.render(" K ", True, (255,255,0), (160,39,134))
else:
return None
elif self.powtype==6:
global shieldonscreen
if not shieldonscreen and not player.shielded:
self.image=PowTxt.render(" SH ", True, (0,0,0),(57,255,252))
shieldonscreen=True
else:
return None
elif self.powtype==7:
self.image=PowTxt.render(" A ", True, (255,255,255),(189,0,3))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
render_list.add(self)
pow_list.add(self)
def update(self):
self.rect.y+=(tp/1000.)*self.speed
collide=pygame.sprite.spritecollide(self,player_list,False)
if collide:
#PowerUp Potenza
if self.powtype==1:
global shlvl
if not fullpower:
shlvl+=1
else:
oldshlvl+=1
if shlvl==maxpower:
global score
score+=2000
else:
score+=1000
#PowerUp Velocita' Cannone
elif self.powtype==2:
global shtinterval
global score
if not fullpower:
if shtinterval>0.2:
shtinterval-=0.1
score+=500
else:
shtinterval=0.1
score+=1000
else:
if oldinterval>0.2:
oldinterval-=0.1
score+=500
else:
oldinterval=0.1
score+=1000
#PowerUp FullPower
elif self.powtype==3:
global shlvl
global oldshlvl
global oldinterval
global fponscreen
fponscreen=False
global shtinterval
oldinterval=shtinterval
shtinterval=0.1
oldshlvl=shlvl
shlvl=maxpower
global fullpower
fullpower=True
global fptimer
fptimer=20.
global score
score+=1000
#PowerUp Velocita' Nave
elif self.powtype==4:
player.speed+=0.2
if player.speed>=2:
player.speed=2
global score
score+=500
#PowerUp Kompanion
elif self.powtype==5:
global score
global kompanion
kompanion=True
global komonscreen
komonscreen=False
global kom1,kom2
score+=1000
global komtimer
komtimer=60.
kom1=Player((player.rect.x+(player.rect.width/2))-50,player.rect.y,False,int(1))
kom1.move_x=player.move_x
kom1.move_y=player.move_y
kom2=Player((player.rect.x+(player.rect.width/2))+30,player.rect.y,False,int(2))
kom2.move_x=player.move_x
kom2.move_y=player.move_y
#PowerUp Shield
elif self.powtype==6:
player.shield()
global shieldtime
shieldtime=60.
shieldonscreen=False
global score
score+=750
#PowerUp Assistance
elif self.powtype==7:
for n in xrange(20,620,40):
BigBullet(n,510)
global pow_sound
pow_ch=pow_sound.play()
if pow_ch is not None:
left,right=Stereo_Pan(player.rect.x,640)
pow_ch.set_volume(left,right)
self.kill()
#----------------------------------------------------------
# Classe Star
#----------------------------------------------------------
class Star(pygame.sprite.Sprite):
speed=0
rnd=0
rnd2=0
def __init__(self,mode,ry):
pygame.sprite.Sprite.__init__(self)
while self.rnd<=0.1:
self.rnd=random()
while self.rnd2<=0.2:
self.rnd2=random()
if mode==1:
self.image=pygame.Surface((6*self.rnd2,6*self.rnd2))
self.image.fill((255*self.rnd,255*self.rnd,255*self.rnd))
self.speed=200
elif mode==2:
self.image=pygame.Surface((5*self.rnd2,5*self.rnd2))
self.image.fill((102*self.rnd,255*self.rnd,252*self.rnd))
self.speed=100
elif mode==3:
self.image=pygame.Surface((self.rnd2*4,self.rnd2*4))
self.image.fill((0,255*self.rnd,255*self.rnd))
self.speed=50
self.rect=self.image.get_rect()
self.rect.x=randint(-500,1000)
if ry:
self.rect.y=randint(0,480)
else:
self.rect.y=-10
starlist.add(self)
def update(self):
global xmove,ymove
self.rect.x+=self.speed*xmove*(tp/1000.)
self.rect.y+=self.speed*ymove*(tp/1000.)
if self.rect.y>480:
self.kill()
#----------------------------------------------------------
# Classe Boss
#----------------------------------------------------------
class Boss(pygame.sprite.Sprite):
energy=0
movex=0
speed=0
time=0
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((200,50))
self.image.fill((147,67,10))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
self.energy=500
self.movex=1
self.speed=100
render_list.add(self)
enemy_list.add(self)
def update(self):
global tp
self.time+=tp/1000.
num=randint(0,100)
if num==50:
self.movex=-self.movex
if self.time>=1.+randint(0,3):
EnemyBullet(self.rect.x+(self.rect.width/2),self.rect.y+self.rect.height)
self.time=0
if self.rect.x>=440:
self.movex=-1
elif self.rect.x<=0:
self.movex=1
global tp
self.rect.x+=self.movex*self.speed*(tp/1000.)
collide=pygame.sprite.spritecollide(self,bullet_list,True)
if collide:
self.energy-=1
global bhit_snd
bhch=bhit_snd.play()
if bhch is not None:
left,right=Stereo_Pan(self.rect.x,640)
bhch.set_volume(left,right)
if self.energy==0:
global score
score+=10000
self.kill()
global bossex_snd
bexpch=bossex_snd.play()
if bexpch is not None:
left,right=Stereo_Pan(self.rect.x,640)
bexpch.set_volume(left,right)
global showtime
showtime=False
#----------------------------------------------------------
#Classe EnemyBullet
#----------------------------------------------------------
class EnemyBullet(pygame.sprite.Sprite):
speed=200
movex=0
movey=0
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((10,10))
self.image.fill((255,255,0))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
v=Vector.FromPoints((x,y),(player.rect.x+(player.rect.width/2),player.rect.y+(player.rect.height/2)))
v.Normalize()
self.movex,self.movey=v.to_tuple()
render_list.add(self)
enemy_bull_list.add(self)
global esht_snd
eshtch=esht_snd.play()
if eshtch is not None:
left,right=Stereo_Pan(player.rect.x,640)
eshtch.set_volume(left,right)
def update(self):
global tp
self.rect.x+=self.movex*self.speed*(tp/1000.)
self.rect.y+=self.movey*self.speed*(tp/1000.)
#----------------------------------------------------------
#Funzioni
#----------------------------------------------------------
def Shoot():
global charge
if charge==100 and bool(pygame.key.get_pressed()[122]):
BigBullet(player.rect.x+(player.rect.width/2),player.rect.y-50)
BigBullet(player.rect.x+(player.rect.width/2)+40,player.rect.y-50)
BigBullet(player.rect.x+(player.rect.width/2)-40,player.rect.y-50)
global charge
charge=0
if time>=shtinterval and bool(pygame.key.get_pressed()[122]):
global sht
sht=True
time=0
if charge-(tp/1000.)*600>0:
charge-=(tp/1000.)*600
else:
charge=0.1
else:
global sht
global time
sht=False
time+=tp/1000.
if sht:
global shlvl
if shlvl==1:
Bullet(player.rect.x+player.rect.width/2,player.rect.y-10,-pi/2)
elif shlvl==2:
Bullet(player.rect.x,player.rect.y-10,-pi/2)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-pi/2)
elif shlvl==3:
Bullet(player.rect.x,player.rect.y-10,-pi/2)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-pi/2)
Bullet(player.rect.x+player.rect.width/2,player.rect.y-15,-pi/2)
elif shlvl==4:
Bullet(player.rect.x+player.rect.width/2,player.rect.y-15,-pi/2)
Bullet(player.rect.x,player.rect.y-10,-4*pi/9,True)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-4*pi/9)
elif shlvl==5:
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-pi/2)
Bullet(player.rect.x,player.rect.y-10,-4*pi/9,True)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-4*pi/9)
Bullet(player.rect.x,player.rect.y-10,-pi/2)
elif shlvl==6:
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-pi/2)
Bullet(player.rect.x,player.rect.y-10,-4*pi/9,True)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-4*pi/9)
Bullet(player.rect.x,player.rect.y-10,-pi/2)
Bullet(player.rect.x+player.rect.width/2,player.rect.y-15,-pi/2)
elif shlvl==7:
Bullet(player.rect.x+player.rect.width/2,player.rect.y-15,-pi/2)
Bullet(player.rect.x,player.rect.y-10,-4*pi/9,True)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-4*pi/9)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-2*pi/3,True)
Bullet(player.rect.x,player.rect.y-10,-2*pi/3)
elif shlvl==8:
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-pi/2)
Bullet(player.rect.x,player.rect.y-10,-pi/2)
Bullet(player.rect.x,player.rect.y-10,-4*pi/9,True)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-4*pi/9)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-2*pi/3,True)
Bullet(player.rect.x,player.rect.y-10,-2*pi/3)
elif shlvl==9:
Bullet(player.rect.x+player.rect.width/2,player.rect.y-15,-pi/2)
Bullet(player.rect.x+player.rect.width, player.rect.y-10, -pi/2)
Bullet(player.rect.x,player.rect.y-10, -pi/2)
Bullet(player.rect.x,player.rect.y-10,-4*pi/9,True)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-4*pi/9)
Bullet(player.rect.x+player.rect.width,player.rect.y-10,-2*pi/3,True)
Bullet(player.rect.x,player.rect.y-10,-2*pi/3)
else:
shlvl=9
global sht_snd
shtch=sht_snd.play()
if shtch is not None:
left,right=Stereo_Pan(player.rect.x,640)
shtch.set_volume(left,right)
if kompanion:
Bullet(kom1.rect.x+kom1.rect.width/2,kom1.rect.y-10,-pi/2)
Bullet(kom2.rect.x+kom2.rect.width/2,kom2.rect.y-10,-pi/2)
else:
if charge=3.0:
enemysm=3.0
if lev%10==0:
player.lives+=1
global enen
enen+=1
for n in xrange(0,20*(lev)):
global enen
Enemy(randint(20,620),randint(-5000,-500),enemysm,not bool(randint(0,20)),not bool(randint(0,6)),enen)
if lev%5==0:
global boss
boss=Boss(320,100)
global showtime
showtime=True
def SoundInit():
global pow_sound,pexp_snd,exp_snd,sht_snd,esht_snd,bossex_snd,bhit_snd
pow_sound=pygame.mixer.Sound("pow.wav")
pexp_snd=pygame.mixer.Sound("selfexp.wav")
exp_snd=pygame.mixer.Sound("expl.wav")
sht_snd=pygame.mixer.Sound("sht.wav")
esht_snd=pygame.mixer.Sound("enemysht.wav")
bossex_snd=pygame.mixer.Sound("bossexp.wav")
bhit_snd=pygame.mixer.Sound("bhit.wav")
def Stereo_Pan(x,sw):
rvol=float(x)/sw
lvol=1.-rvol
return (lvol,rvol)
#----------------------------------------------------------
#Inizio Programma
#----------------------------------------------------------
pygame.init()
SoundInit()
screen=pygame.display.set_mode((640,480),0,32)
pygame.display.set_caption("Primitive Shooter II!!!")
clock=pygame.time.Clock()
player=Player(320,455,True,0)
PowTxt=pygame.font.SysFont("Arial",10)
for f in xrange(0,100):
Star(1,True)
Star(2,True)
Star(3,True)
while True:
screen.fill((0,0,0))
for s in starlist:
s.update()
starlist.draw(screen)
for event in pygame.event.get():
if event.type==QUIT:
exit()
if event.type==KEYDOWN:
if event.key==K_LEFT:
player.move_x=-5*player.speed
if kompanion:
kom1.move_x=player.move_x
kom2.move_x=player.move_x
if event.key==K_RIGHT:
player.move_x=5*player.speed
if kompanion:
kom1.move_x=player.move_x
kom2.move_x=player.move_x
if event.key==K_UP:
player.move_y=-5*player.speed
if kompanion:
kom1.move_y=player.move_y
kom2.move_y=player.move_y
if event.key==K_DOWN:
player.move_y=5*player.speed
if kompanion:
kom1.move_y=player.move_y
kom2.move_y=player.move_y
if event.key==K_z:
sht=True
if event.type==KEYUP:
if event.key==K_LEFT:
player.move_x=0
if kompanion:
kom1.move_x=0
kom2.move_x=0
if event.key==K_RIGHT:
player.move_x=0
if kompanion:
kom1.move_x=0
kom2.move_x=0
if event.key==K_UP:
player.move_y=0
if kompanion:
kom1.move_y=0
kom2.move_y=0
if event.key==K_DOWN:
player.move_y=0
if kompanion:
kom1.move_y=0
kom2.move_y=0
if event.key==K_z:
sht=False
#Orologio
tp=clock.tick(40)
#Starfield
global totime
totime+=tp
if totime>2.:
Star(1,False)
Star(2,False)
Star(3,False)
#Sparo Temporizzato
if not GameOver:
Shoot()
#Eventuale Fullpower
if fullpower:
global fptimer
fptimer-=tp/1000.
if fptimer<=0:
global shlvl
global oldshlvl
global oldinterval
global shtinterval
shtinterval=oldinterval
shlvl=oldshlvl
global fullpower
fullpower=False
#Eventuale Kompanion
if kompanion:
global komtimer
komtimer-=tp/1000.
if komtimer<=0:
global kom1,kom2,kompanion
kom1.kill()
kom2.kill()
kompanion=False
#Aggiornamenti di schermo
player.update()
if kompanion:
kom1.update()
kom2.update()
render_list.draw(screen)
ch=PowTxt.render(str(charge)+ " %",True,(255,255,255))
screen.blit(ch,(10,10))
powrec=pygame.Surface((150*(charge/100.),10))
powrec.fill((255-((charge*250)/100),(charge*250)/100,0))
screen.blit(powrec,(60,10))
ch2=PowTxt.render("Score: "+str(score),True,(255,255,255))
screen.blit(ch2,(500,10))
for bullet in bullet_list:
bullet.update()
for powerup in pow_list:
powerup.update()
for enemy in enemy_list:
enemy.update()
if len(enemy_list)==0:
global lev
lev+=1
Level()
if player.lives==0 or GameOver:
go=PowTxt.render("Game Over",True,(255,0,0))
screen.blit(go,(320,240))
GameOver=True
ch3=PowTxt.render("Level: "+str(lev)+", Lives: "+str(player.lives),True,(255,255,255))
pow1=""
pow2=""
pow3=""
if fullpower:
global fptimer
pow1="FP: "+str(round(fptimer,2))
else:
pow1=""
if player.shielded:
global shieldtime
shieldtime-=tp/1000.
pow3="SH: "+str(round(shieldtime,2))
if shieldtime<=0:
player.unshield()
else:
pow3=""
if kompanion:
global komtimer
pow2="K: "+str(round(komtimer,2))
else:
pow2=""
chboss=PowTxt.render("BOSS: ", True, (255,0,0))
if showtime:
screen.blit(chboss,(10,50))
global boss
energy=pygame.Surface((boss.energy/2,10))
energy.fill((255,0,0))
screen.blit(energy,(50,50))
pows=pow1 + " " + pow2 + " " + pow3
for bullet in enemy_bull_list:
bullet.update()
ch4=PowTxt.render(pows,True,(255,255,255))
screen.blit(ch4,(20,470))
screen.blit(ch3, (300,470))
pygame.display.flip()
I Suoni e le differenze
Il pacchetto di suoni che potete scaricare da questo link è stato creato con SFXR.
Il soundPack è necessario affinchè il gioco funzioni. Basta estrarne il contenuto nella stessa cartella dove si trovano Game.py e Vector.py