Python scripts, Game code

[pastacode provider=”manual” lang=”python” message=”Space Gladiator II The Warrior of Light.”]

#-------------------- Space Gladiator II The Spiritual Warrior ----------------#
                # Concept & Design      : Diliup Gabadamudalige #
                # Coding Commenced      : 2013-12-13            #
                # Coding Completed      : 2013-12-14            #
                #-----------------------------------------------#

import pygame
import pygame._view
from pygame.locals import *
import sys
import os
import math
import time
import random
import copy
import cPickle

wincon=pygame.image.load("resources\grfx\dg.bmp")
pygame.display.set_icon(wincon)
pygame.display.set_caption('"SPACE GLADIATOR II-The Warrior of Light!" - EMorphus Productions 2013')
#initialize pygame, load the 1st. music track and start playing while the game\
# loads in the background
clock = pygame.time.Clock()
pygame.mixer.pre_init(44100, 16, 2, 4096) # setup mixer to avoid sound lag
pygame.init()
if sys.platform == 'win32' or sys.platform == 'win64':
    os.environ['SDL_VIDEO_CENTERED'] = '2'# center of screen
Dlist=pygame.display.list_modes(0,FULLSCREEN)
Swidth=Dlist[0][0]-24
Sheight=Dlist[0][1]-50
screenmode=0
screen = pygame.display.set_mode((Swidth, Sheight),screenmode,0)
pygame.mouse.set_visible(False)
startmusic="resources\snd\SGOpeningtheme.ogg"
pygame.mixer.set_num_channels(64)
pygame.mixer.music.load(startmusic)
pygame.mixer.music.set_volume(0.3)
pygame.mixer.music.play(-1)
font = pygame.font.Font("resources\data\prometheanb.ttf", 22)
text = font.render("Game Loading. Please wait....", 2, (150,150,250))
screen.blit(text,[Swidth/2-text.get_width()/2,Sheight/2-text.get_height()])
pygame.display.update()

#------------------------------------------------------------------------------#
#                        A L L  T H E  F U N C T I O N S                       #
#------------------------------------------------------------------------------#
def update_all(text1,text2,text3):
    global life
    for i in xrange (Hero.lives):
        screen.blit(life,(controls.Swidth-(25*(i+1)),2))
    if Hero.life>0 and Hero.lives>0 and Hero.status=="N":
        Hero.update()

    for g in controls.globelist:
        g.update()

    for e in controls.Alien1: # 1st WAVE of ALIENS
        if e.status=="M":
            e.follow(Hero,7)
            e.update()

    if controls.enemystate=='boss on' and boss1.status<>"E":
        boss1.follow(Hero,8)
        boss1.update()

    if controls.enemystate=='MLA2' and Mothership1.status=="M":
        Mothership1.mship_update(Mothership1.heading)

    for e in controls.Alien2: # 1st WAVE of ALIENS
        if e.status=="M":
            e.follow(Hero,8)
            e.update()

    for e in controls.FinalAliens: # 1st WAVE of ALIENS
        if e.status=="M":
            e.follow(Hero,9)
            e.update()

    for a in asteroids:
        a.update()

    update_score(score,scorestr,realscore)
    update_game_text(text1,text2,text3)
    update_screen()
    star_field()
def update_screen():
    pygame.display.update()
    screen.fill((0,0,0))

def update_score(score,scorestr,realscore):
    if score[6]>=10: score[6]=0; score[5]+=1
    if score[5]>=10: score[5]=0; score[4]+=1
    if score[4]>=10: score[4]=0; score[3]+=1
    if score[3]>=10: score[3]=0; score[2]+=1
    if score[2]>=10: score[2]=0; score[1]+=1
    if score[1]>=10: score[1]=0; score[0]+=1
    for w in score: scorestr+=str(w)
    realscore=int(scorestr)

def update_game_text(text1,text2,text3):
    pygame.draw.rect(screen, (128,128,128), [2, controls.Sheight-(152)\
                                         , 14,152],3)# SHIELD meter border
    pygame.draw.rect(screen, (128,128,128), [18, controls.Sheight-(152)\
                                         , 14,152],3)#GUN TEMP meter border
    if colourvals[0]<0: colourvals[0]=1
    pygame.draw.rect(screen, (255,colourvals[0],0),\
                     [controls.Swidth-controls.Swidth+4,\
                      controls.Sheight-Hero.life/3, 10,295],0)# SHIELD amount
    pygame.draw.rect(screen, (255,colourvals[1],0),\
                     [controls.Swidth-controls.Swidth+20,\
                      controls.Sheight-Hero.guntemp*2+4, 10,295],0)# GUN TEMPERATURE
    font = pygame.font.Font("resources\data\prometheanb.ttf", 22)
    screen.blit(text1, [2,0])# print text->score, colourvals[1]
    text = font.render(scorestr, 2, (150,150,250))
    screen.blit(text, [84,1])# print score
    screen.blit(text2, [1,controls.Sheight-108])# SHIELD
    screen.blit(text3, [18,controls.Sheight-100])# GUN TEMP

    if Hero.bonus[2]=="M":
        screen.blit(text4,(controls.Swidth/2-text4.get_width()/2,5))
        Hero.bonus[3]+=1
        if Hero.bonus[3]>=100:
            Hero.bonus[3]=0
            Hero.bonus[2]="S"
            shipbonus.play()
    if Hero.bombs[0]>0 and controls.CBomb==False:
        font = pygame.font.Font("resources\data\prometheanb.ttf", 22)
        bombamount=font.render('BOMBS '+str(Hero.bombs[0])+\
                               ' : '+'READY TO FIRE! (B)', 2,[200,0,200])
        screen.blit(bombamount,((controls.Swidth-bombamount.get_width())/2,\
                           controls.Sheight-25))
    if Hero.bombs[1]=="R" and controls.CBomb==False:
        R=random.randrange(100,250,25)
    if controls.CBomb=="C":
        R=random.randrange(100,250,25)
        font = pygame.font.Font("resources\data\prometheanb.ttf", 20)
        text7=font.render("CLUSTER BOMB READY! 'C' TO LAUNCH",\
                          2,[R,R,R])
        screen.blit(text7,(controls.Swidth/2-text7.get_width()/2,\
                           controls.Sheight-25))

def initialize_stars():
    global stars
    controls.stars=[]
    for x in xrange (500):
        controls.stars.append([(int(controls.Swidth*random.random())),\
                      (int(controls.Sheight*random.random()))])
def star_field():
    for w in xrange(len(controls.stars)):
        x=random.randrange(100,255,2)
        color1=(x,x,255)
        pygame.draw.line(screen, color1, [controls.stars[w][0],\
                                          controls.stars[w][1]],\
                         [controls.stars[w][0],controls.stars[w][1]], 1)
        controls.stars[w][1]+=starvel[0]
        if controls.stars[w][1]>=controls.Sheight:
            controls.stars[w][1]=0
            controls.stars[w][0]=int(controls.Swidth*random.random())

def show_instructions():
    font = pygame.font.Font("resources\data\prometheanb.ttf", 18)
    while controls.instructions ==True:
        x=60;y=80
        for t in xrange(len(instructions)):
            a=str(instructions[t])#.strip('[]')
##            a=a[1:-1]
            text = font.render(a, 0, [200,200,200])
            screen.blit(text,(x,y))
            y+=36
        for event in pygame.event.get():
            if event.type==KEYDOWN:
                controls.instructions=False
        star_field()
        update_screen()

def player_instructions(akuru,time):
    color=[0,0,0]; x=0
    c=0
    length=(len(akuru))
    t=0
    font = pygame.font.Font("resources\data\prometheanb.ttf", 30)
    while controls.instructions==True:
        pygame.event.pump()
        keys = pygame.key.get_pressed()
        if keys[K_ESCAPE] or keys[K_BACKSPACE] or keys[K_RETURN]:
                controls.instructions=False
        a=str(akuru[t])
        for c in xrange(254):
            text = font.render(a, 0, color)
            textlength=text.get_width()
            screen.blit(text,(controls.Swidth/2-textlength/2,controls.Sheight/2))
            pygame.time.wait(time)
            y=1 if c<127 else -1
            x+=y
            x=0 if x<0 else x
            color[0]=color[1]=color[2]=x
            update_screen()
            pygame.event.pump()
            keys = pygame.key.get_pressed()
            if keys[K_ESCAPE] or keys[K_BACKSPACE] or keys[K_RETURN]:
                controls.instructions=False
        t+=1
        if t==length:
            controls.instructions=False
def save_game():
    yref=yy=(Sheight/4)+100
    slotno=1
    while controls.savegame==True:
        timestamp=time.asctime(time.localtime())[4:]
        x=controls.Swidth/3
        y=controls.Sheight/4
        font = pygame.font.Font("resources\data\prometheanb.ttf", 20)
        empty='<      - e m p t y -     >'
        warning='save slot not empty.  S to overwrite'
        warntext=font.render(warning,0,[200,0,0])
        text=['Save Game','select slot and hit ENTER to SAVE game.',\
              'BACKSPACE to exit without saving.']
        for i in xrange(len(text)):
            itext=font.render(text[i],0,[100,100,255])
            screen.blit(itext,(controls.Swidth/2-itext.get_width()/2,\
                              y-itext.get_height()))
            y+=(itext.get_height()*2)
        if len(savelist[slotno-1])>0:
            screen.blit(warntext,(controls.Swidth/2-\
                                  warntext.get_width()/2,y-itext.get_height()))

        screen.fill([30,30,30],[0,y,controls.Swidth,y],0)
        font = pygame.font.Font("resources\data\prometheanb.ttf", 16)
        cursor=font.render("<<<",0,[100,100,255])
        for i in xrange(len(savelist)): # print the save list from disk file
            if savelist[i]==[]:
                text=font.render(str(i+1)+". "+empty,0,[200,200,200])
            else:
                text=font.render(str(i+1)+'. '+str(savelist[i][0]),0,[200,200,200])
            screen.blit(text,(controls.Swidth/2-text.get_width()/2,y))
            y+=text.get_height()*2
        screen.blit(cursor,(controls.Swidth-controls.Swidth/2.55,yy))

        for event in pygame.event.get():
            if event.type==KEYDOWN:
                if event.key==K_DOWN:
                    yy+=25
                    slotno+=1
                elif event.key==K_UP:
                    yy-=25
                    slotno-=1

                if yy>=yref+250:
                    yy=yref
                    slotno=1
                if yy<yref:
                    yy=yref+225
                    slotno=10

                if event.key==K_RETURN:
                    savegamedata=vars(save_game_data()) # dict
                    print savegamedata
                    newsave=[timestamp,savegamedata] # make the save file
                    savelist[slotno-1]=newsave # put into slot selected
                    f=open('resources\data\saves.sg','wb')
                    cPickle.dump(savelist,f) # write the file to disk
                    f.close()
                    controls.savegame=False

                if event.key==K_BACKSPACE:
                    controls.savegame=False

        star_field()
        update_screen()

def load_game():
    yref=yy=(Sheight/4)+100
    slotno=1
    while controls.loadgame==True:
        timestamp=time.asctime(time.localtime())[4:]
        x=controls.Swidth/3
        y=controls.Sheight/4
        font = pygame.font.Font("resources\data\prometheanb.ttf", 20)
        empty='<      - e m p t y -     >'
        warning='slot empty. nothing to load'
        warntext=font.render(warning,0,[200,0,0])
        text=['Load Game','select slot and hit HNTER to LOAD game.',\
              'BACKSPACE to exit without loading.']
        for i in xrange(len(text)):
            itext=font.render(text[i],0,[100,100,255])
            screen.blit(itext,(controls.Swidth/2-itext.get_width()/2,\
                              y-itext.get_height()))
            y+=(itext.get_height()*2)
        if len(savelist[slotno-1])==0:
            screen.blit(warntext,(controls.Swidth/2-\
                                  warntext.get_width()/2,y-itext.get_height()))

        screen.fill([30,30,30],[0,y,controls.Swidth,250],0)
        font = pygame.font.Font("resources\data\prometheanb.ttf", 16)
        cursor=font.render("<<<",0,[100,100,255])
        for i in xrange(len(savelist)): # print the save list from disk file
            if savelist[i]==[]:
                text=font.render(str(i+1)+". "+empty,0,[200,200,200])
            else:
                text=font.render(str(i+1)+'. '+str(savelist[i][0]),0,[200,200,200])
            screen.blit(text,(controls.Swidth/2-text.get_width()/2,y))
            y+=25
        screen.blit(cursor,(controls.Swidth-controls.Swidth/2.55,yy))

        for event in pygame.event.get():
            if event.type==KEYDOWN:
                if event.key==K_DOWN:
                    yy+=25
                    slotno+=1
                elif event.key==K_UP:
                    yy-=25
                    slotno-=1

                if yy>=yref+250:
                    yy=yref
                    slotno=1
                if yy<yref:
                    yy=yref+225
                    slotno=10

                if event.key==K_RETURN and savelist[slotno-1]!=[]:
                    # Get highscores from disk n close file
                    f=open('resources\data\saves.sg','rb')
                    loadlist=cPickle.load(f)
                    controls.loadgamedata=loadlist[slotno-1][1]
                    # call the routine to load the game data to the vazriables
                    set_game_data(controls.loadgamedata)
                    f.close()
                    controls.loadgame=False

                if event.key==K_BACKSPACE:
                    controls.loadgame=False

        star_field()
        update_screen()

def set_game_data(info):
    global score
    controls.globes=info['globes']
    controls.PUcount=info['PUcount']
    controls.invincibility=info['invincibility']
    controls.TRIPLEgun=info['TRIPLEgun']
    controls.TRIPLEguntime=info['TRIPLEguntime']
    controls.CBombflag=info['CBombflag']
    controls.CBomb=info['CBomb']
    controls.enemystate=info['enemystate']
    controls.gamestate=info['gamestate']
    controls.asteroidcount=info['asteroidcount']
    controls.collected=info['collected']
    controls.gamecounter=info['gamecounter']
    controls.no_of_enemies=info['no_of_enemies']
    controls.enemycount=info['enemycount']
    controls.music=info['music']
    controls.rank=info['rank']
    score=info['score']
    Hero.lives=info['Herolives']
    Hero.life=info['Herolife']
    Hero.nodamage=info['Heronodamage']

    # if player had collected any globes before saving the game, reduce it from
    # the amount to be spawned
    if controls.globes=='Galive':
        globeamount=controls.globequantity[0]-controls.collected
        controls.globelist=[]
        spawn_globes(Gglobe, 0.3,10,globeamount)

    if controls.globes=='Ralive':
        globeamount=controls.globequantity[1]-controls.collected
        controls.globelist=[]
        spawn_globes(Rglobe, 0.4,15,globeamount)

    if controls.globes=='Oalive':
        if controls.asteroidswitch=="OFF":
            controls.asteroidswitch="ON"
        globeamount=controls.globequantity[2]-controls.collected
        controls.globelist=[]
        spawn_globes(Oglobe, 0.5,20,globeamount)

    if controls.globes=='Palive':
        globeamount=controls.globequantity[3]-controls.collected
        controls.globelist=[]
        spawn_globes(Pglobe, 0.6,25,globeamount)

    if controls.gamestate=="Level 2":
        boss1.radar=controls.Swidth/2-100
        boss1.mag=40 # shooting delay
        controls.enemystate="boss on"
        boss1.status='M'

    if controls.gamestate=="Level 3":
        controls.asteroidswitch="OFF"
        controls.globes='OFF'
        Mothership1.status="M"
        controls.globelist=[]
        Hero.BMag=[]
        Hero.bombs=[0,"D"]
        controls.counter=0
        controls.no_of_enemies=12
        controls.spendtime=0
        boss1.status='boss1 dest'

    if controls.gamestate=="Level 4":
        controls.enemystate="REST 2"
        controls.asteroidswitch="ON" 
        controls.asteroidcount=0 
        controls.asteroidlimit=6 
        controls.asteroidamount=100
        controls.spendtime=0

def hall_of_fame_message():
    x=controls.Swidth/4
    y=300
    font = pygame.font.Font("resources\data\prometheanb.ttf", 22)
    akuru=['CONGRATULATIONS! You qualify to enter ',\
           'the Space Gladiator Hall of Fame.','Please enter your name.']

    for t in xrange(len(akuru)):
        a=str(akuru[t])
        text = font.render(a, 0, [175,175,175])
        screen.blit(text,(controls.Swidth/2-text.get_width()/2,y))
        y+=text.get_height()
    return y # y position to print name as it is typed

def random_xyheading(): #generates a random number outside 0 and Swidth
    x=int(random.randrange(-100,100,1))
    y=int(random.randrange(50,(controls.Sheight-50),1))
    h=int(random.randrange(-45,45,1)) # heading
    if x>=-50:
        x+=controls.Swidth+50
        h=h+180
    return x,y,h

def Asteroid_spawn():
    radius=controls.Sheight-100
    x=int(radius*math.cos(controls.asterseed)+controls.Swidth/2)
    y=int(radius*math.sin(controls.asterseed)+controls.Sheight/2)
    h=random.randrange(-180,180,1) # heading
    controls.asterseed=(controls.asterseed+40)%180
    return x,y,h

def spawn_globes(globeimage,gspeed,size,quantity):
    for w in xrange (quantity):
        '''image,x,y,scale,no of items spawned'''
        globe=Collectibles(globeimage,controls.Swidth*random.random(),\
                           controls.Sheight*random.random(),\
                          size,quantity)
        globe.speed=gspeed
        controls.globelist.append(globe)
    return controls.globelist

def add_and_close_file():
    cPickle.dump(highscores,f)
    f.close()

def game_over():
    pygame.mixer.music.stop()
    pygame.quit()
    sys.exit()

def really_quit():
    controls.quitgame=True
    while controls.quitgame==True:
        font = pygame.font.Font("resources\data\prometheanb.ttf", 25)
        y=controls.Sheight/2
        for i in xrange(len(confirm)):
            text=font.render(str(confirm[i]),2,[10,10,250])
            screen.blit(text,(controls.Swidth/2-text.get_width()/2,y))
            y+=text.get_height()
        for event in pygame.event.get():
            if event.type==KEYDOWN:
                if event.key==K_y:
                    game_over()

                elif event.key!=K_y:
                    controls.quitgame=False
        star_field()
        update_screen()

#------------------------------------------------------------------------------#
#                          A L L  T H E  C L A S S E S                         #
#------------------------------------------------------------------------------#

#The Master class with common attributes and methods for all classes
class Master_elements(object):
    def __init__(self,x,y,scale,status,frrate,frsize):
        self.x=x
        self.y=y
        self.scale=scale
        self.status=status
        self.frsize=frsize
        self.frrate=frrate
        self.heading=0 #in degrees
        self.frame=0 # when exploding
        self.rectarea=pygame.Rect(self.x-self.scale/2,\
                                  (controls.Sheight-self.y)-self.scale/2,\
                                  self.scale,self.scale)
        self.centerx=self.rectarea.centerx
        self.centery=self.rectarea.centery
    def posxy(self,x,y):
        if self.x>controls.Swidth:
            self.x=0
        elif self.x<0 :
            self.x=controls.Swidth
        else:
            self.x=x
        if self.y<0:
            self.y=controls.Sheight
        elif self.y>controls.Sheight:
            self.y=0
        else:
            self.y=y
    def setHeading(self,angle):
        self.heading=angle%360

    def getrectarea(self):
        self.rectarea=pygame.Rect(self.x-self.scale/2,\
                                  (controls.Sheight-self.y)-self.scale/2,\
                                  self.scale,self.scale)
        self.centerx=self.rectarea.centerx
        self.centery=self.rectarea.centery

class HeroObject(Master_elements):
    def __init__(self,scale,x,y,status,lives,\
                 bonus,bombs,frrate,frsize):
        Master_elements.__init__(self,x,y,scale,status,frrate,frsize)
        self.image1=pygame.transform.scale(images.Heroa,(self.scale,self.scale))# normal
        self.image2=pygame.transform.scale(images.Herob,(self.scale,self.scale))# thrust
        self.image3=images.Heroc # explode
        self.image4=images.Herod # teleport
        self.speedx=0
        self.speedy=0
        self.thrust=0.02
        self.speedlimit=6
        self.engines=False
        self.firerate=0
        self.maxfirerate=4
        self.life=450 # initial value 450
        self.lives=lives
        self.reinit=100# if Hero dies respawn after reinit becomes 0
        self.ssx=0 # sprite sheet pox
        self.ssy=0 # sprite sheet posy
        self.guntemp=0 # when max value can't fire gun!
        self.nodamage=1500# time invincible after being spawned 250*6=1500
        self.bonus=bonus # ["one",20,"S",0]
        self.shieldradius=22
        self.shieldcolour=[250,250,250]
        self.shieldcolour2=255
        self.CMag=[] # Center Magazine
        self.LMag=[] # Left Magazine
        self.RMag=[] # Right magazine
        self.BMag=[] # Bomb Magazine
        self.CBMag=[]# Cluster Bomb Mag
        self.bombs=bombs

    def move(self,speedx,speedy):
        self.x+=speedx
        self.y+=speedy
        self.posxy(self.x,self.y)
    def teleport(self):
        if (self.frame<16):
            self.ssx=(self.frame%4)*100
            self.ssy=math.floor(self.frame/4)*100
        else:
            self.status="N"
            self.x=controls.Swidth*random.random()
            self.y=controls.Sheight*random.random()
            self.speedx*=-Hero.thrust
            self.speedy*=-Hero.thrust
            self.frame=0
        screen.blit(self.image4,(self.x-self.scale,(controls.Sheight-self.y)-\
                                 self.scale),Rect((self.ssx,self.ssy),\
                                                    (100,100)))
        self.frame+=1
    def explode(self):
        if self.frame < self.frrate:
            self.ssx=(self.frame%self.frrate)*self.frsize
            self.ssy=math.floor(self.frame/self.frrate)*self.frsize
        else:
            self.status="S"
        screen.blit(self.image3,(self.x-self.scale/2,\
                                 (controls.Sheight-self.y)-\
                                 self.scale/2),Rect((self.ssx,self.ssy),\
                                                    (self.frsize,self.frsize)))
        self.frame+=1
    def update(self):
        if self.engines==True:
            rot_image = pygame.transform.rotate(self.image2,self.heading)
            rot_rect=self.image2.get_rect().copy()
        else:
            rot_image = pygame.transform.rotate(self.image1,self.heading)
            rot_rect=self.image1.get_rect().copy()
        rot_rect.center = rot_image.get_rect().center
        rot_image = rot_image.subsurface(rot_rect).copy()
        screen.blit(rot_image,(self.x-self.scale/2,controls.Sheight\
                               -self.y-self.scale/2))

class Gun():
    def __init__(self,image1,image2,speed,status,scale,life,kind,frrate,frsize):
        self.x=0
        self.y=0
        self.scale=scale
        self.life=life
        self.heading=0
        self.rectarea=pygame.Rect(self.x-self.scale/2,\
                                  (controls.Sheight-self.y)-self.scale/2,\
                                  self.scale,self.scale)
        self.image1=pygame.transform.scale(image1, (self.scale,self.scale))
        self.image2=image2
        self.speed=speed
        self.status =status #S=Standby, F=Fired, E=exploding, D=Destroyed
        self.ssx=0
        self.ssy=0
        self.frame=0
        self.frrate=frrate
        self.frsize=frsize
# AB-alien bullet HB-Hero bullet HM=Hero missile BM=boss missile
        self.kind=kind
    def fire(self,parent):
        self.x=parent.x+(parent.scale/2)*math.cos(math.radians(parent.heading))
        self.y=parent.y+(parent.scale/2)*math.sin(math.radians(parent.heading))
        self.heading=parent.heading
        self.status="F"
    def fireR(self,parent):
        self.x=parent.x+(parent.scale/2)*math.cos(math.radians\
                                                  (parent.heading-30))
        self.y=parent.y+(parent.scale/2)*math.sin(math.radians\
                                                  (parent.heading-30))
        self.heading=parent.heading
        self.status="F"
    def fireL(self,parent):
        self.x=parent.x+(parent.scale/2)*math.cos(math.radians\
                                                  (parent.heading+30))
        self.y=parent.y+(parent.scale/2)*math.sin(math.radians\
                                                  (parent.heading+30))
        self.heading=parent.heading
        self.status="F"

    def fireBombCluster(self,parent,angle,h):
        self.x=parent.x-(parent.scale/2)*math.cos(math.radians\
                                                  (parent.heading-angle))
        self.y=parent.y-(parent.scale/2)*math.sin(math.radians\
                                                  (parent.heading-angle))
        self.heading=h
        self.status="CF"

    def explode(self):
        self.status="E"
    def next_image_frame(self):
        self.frame+=1
        if self.frame < self.frrate*self.frrate:
            self.ssx=(self.frame%self.frrate)*self.frsize
            self.ssy=math.floor(self.frame/self.frrate)*self.frsize
        else:
            self.status="D"
            self.frame=0
            self.ssx=0
            self.ssy=0
    def update(self):
        if self.kind!="HM":
            self.life-=1
        if self.kind=="HM" and self.status=="CF":
            self.life-=1
            if self.x>controls.Swidth or self.x<0 or \
               self.y>controls.Sheight or self.y<0:
                self.life=0
        if self.life<=0:
            self.status="D"
        if self.status=="F" or self.status=="CF":
            if self.status=='CF': # bomb fired so start reducing speed
                self.speed-=0.1
                if self.speed<=0:
                    self.speed=0
            self.x+=self.speed*math.cos(math.radians(self.heading))
            self.y+=self.speed*math.sin(math.radians(self.heading))
            if((self.x<0 or self.x > controls.Swidth) \
               and (self.y < 0 or self.y > controls.Sheight)):
                self.status="D"
        if self.status=="E":
            self.next_image_frame()
        if self.status=="F" or self.status=="CF":
            self.rotate()
            screen.blit(self.new_image,(self.x,\
                                     controls.Sheight-self.y),\
                        Rect((self.ssx,self.ssy),(100,100)))
        if self.status=="E":
            screen.blit(self.image2,(self.x-self.frsize/2,\
                                     controls.Sheight-self.y-self.frsize/2),\
                        Rect((self.ssx,self.ssy),(self.frsize,self.frsize)))
    def getrectarea(self):
        if self.kind=="BM":
            self.rectarea=pygame.Rect(self.x+10-self.scale/2,\
                          (controls.Sheight+10-self.y)-self.scale/2,\
                          self.scale-8,self.scale-8)
        elif self.kind=="HM" and controls.CBomb=="F":
            self.rectarea=pygame.Rect(self.x,\
                                      (controls.Sheight-self.y),\
                                      self.scale,self.scale)
        elif self.kind=="HM" and controls.CBomb=="E":
            self.rectarea=pygame.Rect(self.x-self.frsize/2,\
                                      (controls.Sheight-self.y)-self.frsize/2,\
                                      self.frsize,self.frsize)
        else:
            self.rectarea=pygame.Rect(self.x-self.scale/2,\
                                      (controls.Sheight-self.y)-self.scale/2,\
                                      self.scale,self.scale)

    def rotate(self):
        rot_image = pygame.transform.rotate(self.image1,self.heading)
        rot_rect=self.image1.get_rect().copy()
        rot_rect.center = rot_image.get_rect().center
        self.new_image = rot_image.subsurface(rot_rect).copy()

class Collectibles():
    def __init__(self,image,x,y,scale,noofitems):
        self.x=x
        self.y=y
        self.scale=scale
        self.status="N"# normal when collected becomes "C"
        self.heading=controls.Swidth*random.random()
        self.image=image
        self.image=pygame.transform.scale(image,(self.scale,self.scale))
        self.speed=0.3
        self.noofitems=noofitems
        self.rectarea=pygame.Rect(self.x-self.scale/2,\
                                  (controls.Sheight-self.y)-self.scale/2,\
                                  self.scale,self.scale)
    def update(self):
        self.x+=self.speed*math.cos(math.radians(self.heading))
        self.y+=self.speed*math.sin(math.radians(self.heading))
        """accelerate the collectibles when the Hero gets close"""
        if abs(Hero.x-self.x)<75 and abs(Hero.y-self.y)<100:
            self.x+=self.speed*math.cos(math.radians(self.heading))*\
                     (4*random.random())
            self.y+=self.speed*math.sin(math.radians(self.heading))*\
                     (4*random.random())
        if self.x<0: self.x=controls.Swidth
        if self.x>controls.Swidth: self.x=0
        if self.y<0: self.y=controls.Sheight
        if self.y>controls.Sheight: self.y=0
        screen.blit(self.image,(self.x-self.scale/2,controls.Sheight\
                               -self.y-self.scale/2))
    def getrectarea(self):
        self.rectarea=pygame.Rect(self.x-self.scale/2,\
                                  (controls.Sheight-self.y)-self.scale/2,\
                                  self.scale,self.scale)

class Asteroids():
    """image,x,y,life,scale,width,xfr,frsize,noframes,status"""
    def __init__(self,image,image2,x,y,life,width,frrate,\
                 frsize,noframes,kind,status):
        self.x=x
        self.y=y
        self.scale=frsize
        self.kind=kind # L-Large, M-Medium, S-Small
        self.status=status #  M-moving in space,  E-explode,  D- destroyed
        self.heading=360*random.random()
        self.frame=0
        self.frrate=frrate
        self.frsize=frsize
        """rect smaller than actual size cause of asteroid shape"""
        self.life=life
        self.image=image
        self.expimage=image2
        self.width=width
        self.noframes=noframes
        self.speed=0.6
        self.speedlimit=self.speed
        self.ssx=0
        self.ssy=0
        self.framecount=0
        self.rectarea=pygame.Rect(self.x-self.scale/3,\
                                  (controls.Sheight-self.y)-self.scale/3,\
                                  self.scale-self.scale/2.5,\
                                  self.scale-self.scale/2.5)
        self.centerx=self.rectarea.centerx
        self.centery=self.rectarea.centery

    def update(self):
        """only the number of frames on the x axis is needed"""
        if self.frame<self.noframes:
            self.ssx=(self.frame%self.frrate)*self.frsize
            self.ssy=math.floor(self.frame/self.frrate)*self.frsize
        self.frame+=1

        if self.status=="M" and self.frame==self.noframes:
            self.frame=0
            self.ssx=0
            self.xxy=0

        if self.status=="M":
            self.x+=self.speed*math.cos(math.radians(self.heading))
            self.y+=self.speed*math.sin(math.radians(self.heading))

        if self.y<-self.frsize: self.y=controls.Sheight
        if self.y>controls.Sheight: self.y=0
        if self.x<-self.frsize: self.x=controls.Swidth
        if self.x>controls.Swidth: self.x=0
        if self.status=="M":
            screen.blit(self.image,(self.x-self.scale/2,\
                                    controls.Sheight-self.y-self.scale/2),Rect\
                        ((self.ssx,self.ssy),(self.scale,self.scale)))
        if self.status=="E":
            screen.blit(self.expimage,(self.x-self.scale/2,\
                                       controls.Sheight-self.y-self.scale/2),\
                        Rect((self.ssx,self.ssy),(self.scale,self.scale)))
            if self.frame>=self.noframes:
                self.status="D"

    def getrectarea(self):
        """get the rect a little smaller than the actual size"""
        self.rectarea=pygame.Rect(self.x-self.scale/3,\
                                  (controls.Sheight-self.y)-self.scale/3,\
                                  self.scale-self.scale/2.5,\
                                  self.scale-self.scale/2.5)

class EnemyObject(Master_elements):
    def __init__(self,image,image2,scale,x,y,life,firerate,frrate,\
                 frsize,status):
        """status-"M" move "E"-explode "D"-destroy"""
        Master_elements.__init__(self,x,y,scale,status,frrate,frsize)
        self.life=life
        self.image=pygame.transform.scale(image,(self.scale,self.scale))
        self.image2=image2
        """enemy starts with status 'M' becomes 'E'-life=0 'D'=destroyed"""
        self.a=0.04 # accelleration
        self.fixeda=0.04
        self.firerate=firerate
        self.radar=0 # how close the enemy must be to detect opponent
        self.Mag=[] # The gun bullet magazine
        self.BMag=[] # The bomb mag if any
        """state= flag to show style of movement,counter,accel save loc"""
        self.state='normal'
        self.counter=0
        # safe area for same type collisions
        self.safearea=self.scale/2

    def follow(self,target,speed):
        self_rect=pygame.Rect(self.x-self.scale/2,\
                              controls.Sheight-self.y-self.scale/2,\
                              self.scale,self.scale)
        target_rect=pygame.Rect(target.x-target.scale/2,\
                                controls.Sheight-target.y-target.scale/2,\
                                target.scale,target.scale)
        # follow Hero only if close than radar
        if abs(self.centerx-Hero.centerx)<self.radar and \
           abs(self.centery-Hero.centery)<self.radar and self.state=='normal':
            delta_x=target.x-self.x
            delta_y=target.y-self.y
            self.setHeading(math.degrees(math.atan2(delta_y,delta_x)))
            self.move(speed)
        else:
            self.heading=self.heading
            self.move(speed)

    def move(self,speed):
        new_x=self.x+speed*math.cos(math.radians(self.heading))*\
               constant*self.a
        new_y=self.y+speed*math.sin(math.radians(self.heading))*\
               constant*self.a
        self.ai_behaviour()
        self.posxy(new_x,new_y)

    def ai_behaviour(self):
        if self.state=='turn':
            self.counter=0
            self.state='away' # move away from hero

        # dont get too close to the Hero
        if abs(self.centerx-Hero.centerx)<=((self.scale)+(Hero.scale)) and\
           abs(self.centery-Hero.centery)<=((self.scale)+(Hero.scale)):
            self.state='away'
            self.counter=0

        if self.state=='away' and self.counter<80:
            if self.counter<20: #turn till this value
                self.heading+=2
                self.a=0.06 # move away faster than approaching
            self.counter+=1

        if self.counter>=80: # reach limit of  moving away
            self.state='normal'
            self.a=self.fixeda
            self.counter=0
            self.heading=self.heading+30

    def explode(self):
        if (self.frame <=(self.frrate*self.frrate)):
            self.ssx=(self.frame%self.frrate)*self.frsize
            self.ssy=math.floor(self.frame/self.frrate)*self.frsize
            screen.blit(self.image2,(self.x-self.frsize/2,controls.Sheight-\
                                     self.y-self.frsize/2),Rect\
                        ((self.ssx,self.ssy),(self.frsize,self.frsize)))
        else:
            self.status="D"
        self.frame+=1

    def update(self):
        rot_image = pygame.transform.rotate(self.image,self.heading)
        rot_rect=self.image.get_rect().copy()
        rot_rect.center = rot_image.get_rect().center
        rot_image = rot_image.subsurface(rot_rect).copy()
        screen.blit(rot_image,(self.x-self.scale/2,controls.Sheight-\
                               self.y-self.scale/2))
        self.draw_healthbar()

    def mship_update(self,heading): # use for rotating mothership while moving
        self.x+=self.speed*math.cos(math.radians(self.heading))
        self.y+=self.speed*math.sin(math.radians(self.heading))
        rot_image = pygame.transform.rotate(self.image,self.heading)
        rot_rect=self.image.get_rect().copy()
        rot_rect.center = rot_image.get_rect().center
        rot_image = rot_image.subsurface(rot_rect).copy()
        screen.blit(rot_image,(self.x-self.scale/2,controls.Sheight\
                               -self.y-self.scale/2))
        self.draw_healthbar()

# Draw the Alien Health Bar
    def draw_healthbar(self):
        pygame.draw.rect(screen,(255,0,0),[self.x-self.scale/2\
                                   ,controls.Sheight-self.y-self.scale/2,\
                                           self.life ,3],0)
class Load_images():
    def __init__(self):
        self.Heroa=pygame.image.load\
                    ("resources\grfx\HeroTF.png").convert_alpha()
        self.Herob=pygame.image.load\
                    ("resources\grfx\HeroTT.png").convert_alpha()
        self.Heroc=pygame.image.load\
                    ("resources\grfx\Hexplosion.png").convert_alpha()
        self.Herod=pygame.image.load\
                    ("resources\grfx\Teleport.png").convert_alpha()

class Game_controls():
    def __init__(self):
        self.Swidth=Swidth
        self.Sheight=Sheight
        self.globelist=[] # list for globes
        self.globes='Green'
        """globes come on when the flag shows the color"""
        self.globequantity=[100,75,50,15] # 100 Green,75 Red,50 Orange,15 Purple
        self.PUcount=[1,1,1]    # counter-invincibility, guntytpe,CBomb
        self.invincibility=False
        self.TRIPLEgun=False
        self.TRIPLEguntime=0
        self.CBombflag=False
        self.CBomb=False # Cluster bomb False,True,fired-F,exploding-E,over-D
        self.CBangle=0 # the cluster bomb dispersion angle increase by 36
        self.enemystate='boss off'
        self.gamestate='initial'#(initial,Level 1,Level 2 etc.)
        self.pause=True
        self.instructions=False
        self.titlewidth=0
        self.titleheight=0
        self.titlewidth2=0
        self.titleheight2=0
        self.halloffame=False
        self.asteroidcount=0    # if equal to asteroid amount no more spawned
        self.asteroidlimit=4# minimum no of asteroids in list. 5 at start
        self.asteroidamount=75# total amount of large asteroids spawned
        self.asteroidswitch="OFF" # first time on is with Orange globes
        self.asterseed=int(random.randrange(0,360,36))
        self.collected=0        # amount of globes collected
        self.gamespeed=250
        self.gamecounter=0
        self.no_of_enemies=0
        self.enemycount=0 # count each alienwave
        self.enemy_limit=25  # enemy limit on screen
        self.LreduceA1=6     # life reduce Alien1 life-24
        self.LreduceA2=8     # life reduce Alien2 life-24
        self.LreduceB=0.4   # life reduce Boss  life-100
        self.LreduceM=0.2  # life reduce Mothership life-100
        self.LreduceFA=0.2 # life reduce FinalAliens life-50
        self.FAamount=6
        self.spendtime=0 # a counter to do nothing
        self.glt_sec=clock.tick()/1000 # game looptime in seconds
        self.name=''            # hall of fame name
        self.music='theme'
        self.stars=[] # the star field co ordinates list
        self.Alien1=[]    # amount of enemies
        self.Alien2=[]
        self.FinalAliens=[] # the final Alien attack ships-2
        self.AlienMag=[]
        self.Alien2Mag=[]
        self.Alien3Mag=[]
        self.BossBombMag=[]
        self.musicfader=.5
        self.counter=0 # a counter to do waiting
        self.savegame=False
        self.loadgame=False
        self.loadgamedata=[] # load game data here and distribute to variables
        self.rank="CADET"
        self.quitgame=False

class save_game_data():
    def __init__(self):
        self.globes=controls.globes
        self.PUcount=controls.PUcount
        self.invincibility=controls.invincibility
        self.TRIPLEgun=controls.TRIPLEgun
        self.TRIPLEguntime=controls.TRIPLEguntime
        self.CBombflag=controls.CBombflag
        self.CBomb=controls.CBomb
        self.enemystate=controls.enemystate
        self.gamestate=controls.gamestate
        self.asteroidcount=controls.asteroidcount
        self.collected=controls.collected
        self.gamecounter=controls.gamecounter
        self.no_of_enemies=controls.no_of_enemies
        self.enemycount=controls.enemycount
        self.music=controls.music
        self.rank=controls.rank
        self.score=score
        self.Herolives=Hero.lives
        self.Herolife=Hero.life
        self.Heronodamage=Hero.nodamage

controls=Game_controls() # initialize all game controls
screen = pygame.display.set_mode\
         ((controls.Swidth, controls.Sheight),screenmode,0) #display screen
colourvals=[225,250] # colour grad,temp. color
color1=(255,255,255)
color2=(170,170,170)
color3=(100,100,100)
red=[255,0,0]

# no font specified-NONE
font = pygame.font.Font("resources\data\prometheanb.ttf", 22)
text1 = font.render("Score:", 2, (150,150,250))
font = pygame.font.Font("resources\data\prometheanb.ttf", 18)
text = font.render("S H I E L D", 2, [190,0,0])
text2=pygame.transform.rotozoom(text,90,1)
text = font.render("GUN TEMP.", 2,[200,200,200])
text3=pygame.transform.rotozoom(text,90,1)
font = pygame.font.Font("resources\data\prometheanb.ttf", 22)
text4= font.render("ALIEN SHIP BONUS-1000!", 2,[255,55,35])
text5= font.render("BOMBS: ", 2,[200,0,200])

scorestr=""
score=[0,0,0,0,0,0,0] #mil,hunthous, tenthous,thous,huns,tens,ones
scorestr= "".join(str(i) for i in score)
##for w in score: scorestr+=str(w)
realscore=int(scorestr)
asteroids=[]
starvel=[0.1,0.1,0.05] # velocity of the different star layers
initialize_stars()

f=open('resources\data\scores.sg','rb')# Get highscores from disk n close file
highscores=cPickle.load(f)
f.close()

f=open('resources\data\saves.sg','rb')# Get save list from disk n close file
savelist=cPickle.load(f)
f.close()

intro=['special thanks to','Shanika Amarasoma and Jonathan Stockwell',\
       'Hero Space Ship graphics','Kim Lathrope','other Space Ship graphics',\
       'millionthvector.blogspot.com','Game concept, design, coding,',\
       'music composed and performed by','Diliup Gabadamudalige',\
       ' ','somewhere in the Galaxy','this could be happening.....']

instructions=['You are searching for rare elements in the far corners of the ',\
'Galaxy. You have found a system abundant with rare energy globes much needed on',\
'your home planet.Collect as much as you can while NOT engaging in any battle.',\
'You belong to a new order of Warriors who protect by NOT engaging in any form',\
'of battle which is rare in the universe. Your gun will activate only in the.',\
'vicinity of asteroids. You will not harm any life. By understanding and',\
'eliminating your thoughts of anger you spread pure white energy thruout the',\
'universe thus purifying the cosmic ether. Do not give in to your fellings.',\
'        ',\
'Spacebar to fire',\
'Teleporting causes shield depletion.',\
'continous firing will overheat your gun and prevent further firing.',\
'"UP"-thrust     "DOWN"-brake     "LEFT"/"RIGHT"-to rotate',\
'"P" for High Scores and pause game.',\
'"Esc" to quit game','Good Luck!',' ',\
'Hit a key to get back to the game']

confirm=['Do you really want to quit?','Y to Quit',\
             'any other key to get back to the game']

level3=['Just as you thought it was over','and start breathing again,',\
        'your Radar picks up something','heading your way....']

level4=["The Kroggs who consider themselves","Masters of the Universe,",\
        "are not pleased by your daring actions.",\
        "So now it's time to meet them.","personally.."]

playerwins=["Congratulations!","You completed the game.",\
            'you are hereby','A  S P A C E  G L A D I A T O R !']
#------------------------------------------------------------------------------#
#                                load the sound                                #
#------------------------------------------------------------------------------#

Heromove=pygame.mixer.Sound('resources\snd\Thrust.ogg')
Herofire=pygame.mixer.Sound('resources\snd\LASER1.WAV')
Herofire2=pygame.mixer.Sound('resources\snd\atarifire.WAV')
enemyexp=pygame.mixer.Sound('resources\snd\enemyexplode.WAV')
alienshoot=pygame.mixer.Sound('resources\snd\photon.wav')
warn=pygame.mixer.Sound('resources\snd\warn1.ogg')
Heroexp=pygame.mixer.Sound('resources\snd\Heroexplode.wav')
collect=pygame.mixer.Sound('resources\snd\hiblip.wav')
teleportsound=pygame.mixer.Sound('resources\snd\synthfall.wav')
extralife=pygame.mixer.Sound('resources\snd\extra_life.wav')
shipbonus=pygame.mixer.Sound('resources\snd\asbp.wav')
bosscanfire=pygame.mixer.Sound('resources\snd\podipipireema.wav')
Herofirebomb=pygame.mixer.Sound('resources\snd\HBlaunch.wav')
hkollidea=pygame.mixer.Sound('resources\snd\Kollide.wav')
astexplode=pygame.mixer.Sound('resources\snd\globexplod.wav')
bossexplode=pygame.mixer.Sound('resources\snd\B1exp.wav')
bossmove=pygame.mixer.Sound('resources\snd\badboss1.wav')
invince=pygame.mixer.Sound('resources\snd\invincecollect.ogg')
alien1music="resources\snd\SGAlien1theme.ogg"
alien2music="resources\snd\SGAlien2theme.ogg"
boss1music="resources\snd\SGBoss1theme.ogg"

Herofirech= pygame.mixer.Channel(0)
Herothrustch=pygame.mixer.Channel(1)
bosschannel=pygame.mixer.Channel(2)
collectch=pygame.mixer.Channel(3)
aliench=pygame.mixer.Channel(4)
pygame.mixer.set_reserved(0)
pygame.mixer.set_reserved(1)
pygame.mixer.set_reserved(2)
pygame.mixer.set_reserved(3)
pygame.mixer.set_reserved(4)
Heromove.set_volume(.2); Herofire.set_volume(.2)
enemyexp.set_volume(.5); alienshoot.set_volume(0.06)
teleportsound.set_volume(.3); shipbonus.set_volume(0.9)
bosscanfire.set_volume(0.5); warn.set_volume(0.02)
hkollidea.set_volume(0.4) ;Heroexp.set_volume(0.5)
astexplode.set_volume(0.3);bossexplode.set_volume(.5)
extralife.set_volume(0.2); invince.set_volume(0.02)

#------------------------------------------------------------------------------#
#                              load the Graphics                               #
#------------------------------------------------------------------------------#

# Enemy types
alien1=pygame.image.load("resources\grfx\AlienANew.png").convert_alpha()
alien2=pygame.image.load("resources\grfx\AlienBNew.png").convert_alpha()
bossA=pygame.image.load("resources\grfx\BossA.png").convert_alpha()
bossB=pygame.image.load("resources\grfx\FAlien.png").convert_alpha()
AMSHIP1=pygame.image.load("resources\grfx\mothership1.png").convert_alpha()
# Bullets and Bombs
Herobullet=pygame.image.load("resources\grfx\lazerH.png").convert_alpha()
alienbullet=pygame.image.load("resources\grfx\lazerA.png").convert_alpha()
Herobomb=pygame.image.load("resources\grfx\item4.png").convert_alpha()
bossbomb1=pygame.image.load("resources\grfx\BOSBOM.png").convert_alpha()
# Bomb & Bullet xplosions
alxplode=pygame.image.load("resources\grfx\explosiondg002.png").convert_alpha()#alien
al2xplode=pygame.image.load("resources\grfx\AL2EX.png").convert_alpha()#alien
bsxplode=pygame.image.load("resources\grfx\Boss1explode.png").convert_alpha()#boss
BAexpld=pygame.image.load("resources\grfx\BaddestAlienexp.png").convert_alpha()#last Alien
Abltxpld=pygame.image.load("resources\grfx\Abx.png").convert_alpha()#Ablt
Hbltxpld=pygame.image.load("resources\grfx\Hbx.png").convert_alpha()#Hblt
HBxpld=pygame.image.load("resources\grfx\explosiondg003.png").convert_alpha()#HBOMB
BBxpld=pygame.image.load("resources\grfx\explosiondg004.png").convert_alpha()#BOSBOMB
AMS1EXP=pygame.image.load("resources\grfx\mothershipexp.png").convert_alpha()
# Different collectibles
Gglobe=pygame.image.load("resources\grfx\item1.png").convert_alpha()
Rglobe=pygame.image.load("resources\grfx\item2.png").convert_alpha()
Oglobe=pygame.image.load("resources\grfx\item3.png").convert_alpha()
Pglobe=pygame.image.load("resources\grfx\item4.png").convert_alpha()
clusterbomb=pygame.image.load("resources\grfx\item5.png").convert_alpha()
Bglobe=pygame.image.load("resources\grfx\item6.png").convert_alpha()
Mglobe=pygame.image.load("resources\grfx\item7.png").convert_alpha()
CBombexp=pygame.image.load("resources\grfx\clusterbombex.png").convert_alpha()
CBombe=pygame.image.load("resources\grfx\item8.png").convert_alpha()
# Asteroids
meteor=pygame.image.load("resources\grfx\BIGasters.png").convert_alpha()
meteor2=pygame.image.load("resources\grfx\SMALLasters.png").convert_alpha()
meteor3=pygame.image.load("resources\grfx\TINYasters.png").convert_alpha()
metex1=pygame.image.load("resources\grfx\AEXL.png").convert_alpha()
metex2=pygame.image.load("resources\grfx\AEXM.png").convert_alpha()
metex3=pygame.image.load("resources\grfx\AEXS.png").convert_alpha()

title=pygame.image.load("resources\grfx\SGtitle2.png").convert_alpha()
WOLtitle=pygame.image.load("resources\grfx\warrioroflight.png").convert_alpha()
prana=pygame.image.load("resources\grfx\HeroTF.png").convert_alpha()
podiprana=pygame.transform.scale(prana,(25,25))
life=pygame.transform.rotate(podiprana, 90)

images=Load_images()
#------------------------------------------------------------------------------#
#                          Prepare Game Characters                             #
#------------------------------------------------------------------------------#

# image1 image2 speed status size,life,kind,firerate, framesize
Hbullet=Gun(Herobullet,Hbltxpld,9,"S",9,45,"HB",4,25)# Hero BULLET
Abullet=Gun(alienbullet,Abltxpld,8.3,"S",9,40,"AB",4,25)# ALIEN BULLET
HBOMB=Gun(Herobomb,HBxpld,8,"S",25,100,"HM",6,100)# Hero BOMB
BBOMB=Gun(bossbomb1,BBxpld,7,"S",20,100,"BM",6,50)# BOSS BOMB
CBOMB=Gun(CBombe,CBombexp,6,"S",20,250,"HM",10,250)# CBOMB

#1-scale, 2-posx,3-posy,4-status,5-lives,6-bonus\
#(7-extra life,enemycount,bonus,bombs),8-frrate,-frsize,9-bonus message
Hero =HeroObject(46,controls.Swidth/2,controls.Sheight/2,"N",6,\
                 ["one",20,"S",0],[0,"D"],5,64)
#new attribute created for the clusterbomb in the class Gun
CBOMB.explode=100 # cluster bomb will explode when this turn 0

# BOSS1 initialized
#image,image2(expld),scale,x,y,life,firerate,frame rate,frame size,status
bosx=-100
bosy=random.randrange(50,controls.Sheight-100)
# create boss1 off screen but passive-P
boss1=EnemyObject(bossA,bsxplode,80,bosx,bosy,100,30,8,400,"P")
mx=random.randrange(50,100,5)
Mothership1=EnemyObject(AMSHIP1,AMS1EXP,110,mx,0,100.0,0,10,250,"P")
Mothership1.heading=90
Mothership1.speed=2
controls.musicfader=pygame.mixer.music.get_volume()
Hero.setHeading(90)
controls.instructions=True
##player_instructions(intro,10)

#------------------------------------------------------------------------------#
#                             MAIN GAME LOOP                                   #
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#                           LEVEL 1  THE ENERGY GLOBES                         #                                     #
#------------------------------------------------------------------------------#
while True:
    timestamp=time.asctime(time.localtime())[4:]

    Hero.getrectarea()
    # reduce the size of the Hero rect by 10 pixels
    Hero.rectarea=Hero.rectarea.inflate(-10,-10)
    controls.gamecounter+=1
    controls.glt_sec=clock.tick(50)/1000.0# time taken to run game loop in seconds
##    controls.timegone+=controls.glt_sec
    constant=controls.gamespeed*controls.glt_sec
    scorestr= "".join(str(i) for i in score)
    realscore=int(scorestr)

    if Hero.bonus[0]=="one" and realscore>=20000:
        Hero.lives+=1
        extralife.play()
        Hero.bonus[0]="two"
    elif Hero.bonus[0]=="two" and realscore>=40000:
        Hero.lives+=1
        extralife.play()
        Hero.bonus[0]="three"
    elif Hero.bonus[0]=="three" and realscore>=60000:
        Hero.lives+=1
        extralife.play()
        Hero.bonus[0]="four"
# short period where Hero has no damage from enemy fire
    Hero.nodamage-=1
    if Hero.nodamage<=0:
        Hero.nodamage=0
        Hero.shieldcolour=[250,250,250]
# increase number of Alien1s by one every 750 increase of score
    if controls.globes<>'Palive' and realscore>750 and\
       controls.gamestate=="Level 1":
        controls.no_of_enemies=realscore//750
    if controls.no_of_enemies>controls.enemy_limit:
        controls.no_of_enemies=controls.enemy_limit

    pygame.event.pump()
    keys = pygame.key.get_pressed()
    if keys[K_ESCAPE]:
        really_quit()

    for event in pygame.event.get():
        if event.type==KEYDOWN:
            # PAUSE GAME,high scores and instructions
            if event.key==K_p: 
                controls.pause=not controls.pause

            if event.key==K_t:              # TELEPORT
                teleportsound.play()
                Hero.status="T"

            if event.key==K_f and screenmode==0: # toggle fullscreen on/off
                screenmode=FULLSCREEN
                screen = pygame.display.set_mode((Swidth, Sheight),screenmode,0)
            elif event.key==K_f and screenmode==FULLSCREEN:
                screenmode=0
                screen = pygame.display.set_mode((Swidth, Sheight),screenmode,0)

    if Hero.status=="T":
        Hero.teleport()
        Hero.life-=.5
    # MOVE THE Hero
    if keys[K_LEFT]:
        Hero.setHeading(Hero.heading+4)
    if keys[K_RIGHT]:
        Hero.setHeading(Hero.heading-4)
    if keys[K_UP]: # accellerate!
        Herothrustch.play(Heromove)
        Hero.engines=True
        Hero.speedx+=Hero.thrust*math.cos(math.radians(Hero.heading))*constant
        Hero.speedy+=Hero.thrust*math.sin(math.radians(Hero.heading))*constant
        if Hero.speedx>=Hero.speedlimit: Hero.speedx=Hero.speedlimit
        if Hero.speedx<=-Hero.speedlimit: Hero.speedx=-Hero.speedlimit
        if Hero.speedy>=Hero.speedlimit: Hero.speedy=Hero.speedlimit
        if Hero.speedy<=-Hero.speedlimit: Hero.speedy=-Hero.speedlimit
    else:
        Heromove.stop()
        Hero.engines=False
        Hero.speedx-=0
        Hero.speedy-=0
    if keys[K_DOWN]: #brakes! :-)
        Hero.speedx*=0.97
        Hero.speedy*=0.97

    if Hero.life>0:
        Hero.move(Hero.speedx, Hero.speedy)
        Hero.life+=.05 # slow buildup of shield
    if Hero.life>=450:
        Hero.life=450
    if Hero.life<=0 and Hero.status=="N":
        Hero.life=0
        Heroexp.play()
        Hero.status="E"
    if Hero.status=="E":
        Hero.explode()
        for e in controls.Alien1: # when Hero explode enemy moves away
            e.follow(e,4)
            e.firerate=30
            e.update()
    if Hero.status=="S":
        Hero.reinit-=1
    if Hero.life<40 and Hero.life>0: # warn that shield is low
        warn.play()
    if Hero.reinit<=0:
        Hero.lives-=1
    # Hero IS RE-SPAWNED
        tempHerobombs=Hero.bombs
        tempHeroCBMag=Hero.CBMag
        Hero =HeroObject(45,controls.Swidth/2,\
                         controls.Sheight/2,"N",Hero.lives,\
                         Hero.bonus,Hero.bombs, Hero.frrate, Hero.frsize)
        Hero.setHeading(90)
        Hero.CBMag=tempHeroCBMag
        Hero.bombs=tempHerobombs
        for e in controls.Alien1:
            e.firerate=30
        if controls.globes=='Palive':
            boss1.firerate=30
# draw the Hero ship shield
    if Hero.nodamage>0:
        pygame.draw.circle(screen, (Hero.shieldcolour[2]*random.random(),\
                                    Hero.shieldcolour[1]*random.random(),\
                                    Hero.shieldcolour[0]*random.random()), \
                           (int(Hero.x),int(controls.Sheight-Hero.y)),Hero.\
                           shieldradius, 0)
        Hero.shieldcolour[0]-=1
        for x in xrange(2):
            if Hero.shieldcolour[x]<=0:
                Hero.shieldcolour[x]=0
                Hero.shieldcolour[x+1]-=1
        if Hero.shieldcolour[2]<=0:
            Hero.shieldcolour[2]=0
        Hero.shieldradius+=1
        if Hero.shieldradius>28:
            Hero.shieldradius=18

# HERO SHOOT
    if keys[K_SPACE] and Hero.guntemp<=74 and Hero.status=="N" \
       and controls.asteroidswitch=="ON":
        Hero.firerate-=1 # fire the gun
        if Hero.firerate<=0 and controls.TRIPLEguntime<=0:
            Hero.CMag.append(copy.copy(Hbullet))
            Herofirech.play(Herofire)
            Hero.guntemp+=0.4 # GUN TEMPERATURE increases
            colourvals[1]-=10 # GUN TEMP. COLOUR changes
            if colourvals[1]<1:
                colourvals[1]=1
            Hero.CMag[-1].fire(Hero)
            Hero.firerate=Hero.maxfirerate

# HERO GUN COOLS WHEN NOT FIRING
    if not keys[K_SPACE]:
        Hero.guntemp-=.2
        if Hero.guntemp<0:
            Hero.guntemp=0
        colourvals[1]+=5
        if colourvals[1]>100:
            colourvals[1]=100
#------------------------------------------------------------------------------#
#                               THE ASTEROIDS                                  #
#------------------------------------------------------------------------------#
    #image,image2,x,y,life,width,xfr,frsize,noframes.
    #...status(L-Large, M-Medium, S=Small),
    #status-M-moving, E-explode, D-destroyed
    if controls.asteroidswitch=="ON":
        if len(asteroids)<controls.asteroidlimit and \
           controls.asteroidcount<=controls.asteroidamount:
            x,y,h=Asteroid_spawn()
            asteroid=Asteroids(meteor,metex1,x,y,5,1024,8,128,60,"L","M")
            asteroid.heading=h
            asteroids.append(asteroid)
#------------------------------------------------------------------------------#
#                                   THE POWERUPS                               #
#------------------------------------------------------------------------------#

#THE INVINCIBILITY POWERUP
    if realscore>2000 and Hero.nodamage<=0 and controls.invincibility==False:
        controls.PUcount[0]+=1
    if controls.PUcount[0]%750==0 and controls.invincibility==False:
        controls.PUcount[0]+=1
        controls.invincibility=True
        # image,x,y,scale,no of items spawned
        invincibility=Collectibles(Bglobe,controls.Swidth*random.random(),\
                           controls.Sheight*random.random(),35,1)
        invincibility.speed=0.7
        invincibility.life=1000
    if controls.invincibility==True and invincibility.life<=0:
        controls.invincibility=False
        controls.PUcount[0]=1 # reset the invincibilty counter

#------------------------------------------------------------------------------#
#                             THE COLLECTIBLES                                 #
#------------------------------------------------------------------------------#
    if controls.globes=='Green':
        # call function with globe image and speed
        spawn_globes(Gglobe, 0.3,10,controls.globequantity[0])
        controls.globes='Galive'

    if controls.globes=='Galive' and \
       controls.collected==controls.globequantity[0]:
        controls.collected=0
        controls.globes='Red'

    if controls.globes=='Red':
        controls.globelist=[]
        spawn_globes(Rglobe, 0.4,15,controls.globequantity[1])
        controls.collected=0
        controls.globes='Ralive'

    if controls.globes=='Ralive' and \
       controls.collected==controls.globequantity[1]:
        controls.collected=0
        controls.globes='Orange'

    if controls.globes=='Orange':
        if controls.asteroidswitch=="OFF":
            controls.asteroidswitch="ON" # bring on asteroids 1st time level 1
        controls.globelist=[]
        spawn_globes(Oglobe, 0.5,20,controls.globequantity[2])
        controls.collected=0
        controls.globes='Oalive'

    if controls.globes=='Oalive' and \
       controls.collected==controls.globequantity[2]:
        controls.collected=0
        controls.globes='Purple'

    if controls.globes=='Purple':
        controls.globelist=[]
        spawn_globes(Pglobe, 0.6,25,controls.globequantity[3])
        controls.collected=0
        controls.globes='Palive'
#------------------------------------------------------------------------------#
#                            THE 1ST. ALIEN WAVE                               #
#------------------------------------------------------------------------------#

    #image,image2(expld),scale,x,y,life,firerate,frame rate,frame size,status
    if len(controls.Alien1)<controls.no_of_enemies \
       and controls.gamecounter%300==0 and controls.globes!='Palive' \
       and controls.gamestate=='Level 1':
        x,y,h=random_xyheading()
        badET=EnemyObject(alien1,alxplode,35,30+x,y,30,30,6,100,"M")
        badET.heading=h
        badET.radar=220
        controls.Alien1.append(badET)
    if len(controls.Alien1)>0 and controls.music=='theme':
        pygame.mixer.music.load(alien1music)
        pygame.mixer.music.set_volume(0.3)
        pygame.mixer.music.play(-1)
        controls.music='level1alien1'

#------------------------------------------------------------------------------#
#                      L E V E L  2 THE ALIEN OVERLORD                         #
#------------------------------------------------------------------------------#

    if controls.globes=='Palive' and controls.enemystate=="boss off"\
       and controls.gamestate=='Level 1':
        boss1.radar=controls.Swidth/2-100
        boss1.mag=40 # shooting delay
        controls.enemystate="boss on"
        boss1.status='M'
        controls.gamestate="Level 2"
    if controls.enemystate=='boss on' and controls.music<>'boss music':
        pygame.mixer.music.load(boss1music)
        pygame.mixer.music.set_volume(0.3)
        pygame.mixer.music.play(-1)
        controls.music='boss music'

    if controls.enemystate=='boss on' and boss1.status<>"E":
        boss1.getrectarea()
        # make the boss rect 20 pixels smaller
        boss1.rectarea=boss1.rectarea.inflate(-20,-20)
##        pygame.draw.rect(screen, (0,255,0), boss1.rectarea,2)
        boss1.firerate-=1
        if boss1.firerate==0 and Hero.life>0:
            controls.BossBombMag.append(copy.copy(BBOMB))
            # fire only if Hero  gets closer tham this
            if abs(Hero.x-boss1.x)<boss1.radar and\
               abs(Hero.y-boss1.y)<boss1.radar:
                controls.BossBombMag[-1].fire(boss1)
                bosschannel.play(bosscanfire)
                boss1.life-=2
            boss1.firerate=30# slow down the alien fire rate
        boss1.mag-=1
        if boss1.mag<=-50:
            boss1.mag=10
        if boss1.life<=0:
            boss1.life=0
            boss1.status="E"
            bosschannel.play(bossexplode)
            score[3]+=5
    if boss1.status=="E":
        boss1.explode()

    if boss1.status=='D' and controls.spendtime<=100:
        controls.spendtime+=1
        controls.enemystate='REST'

    if boss1.status=='D' and controls.spendtime>=100:
        controls.gamestate="Level 3"
        controls.asteroidswitch="OFF" # no asteroids in level 3
        controls.globes='OFF'
        Mothership1.status="M"
        controls.globelist=[]
        Hero.BMag=[]
        Hero.bombs=[0,"D"]
        controls.counter=0
        controls.no_of_enemies=12 # second round of aliens
        controls.spendtime=0
        boss1.status='boss1 dest'
        player_instructions(level3,8) # describe level 3 to player

#------------------------------------------------------------------------------#
#                         L E V E L  3 THE MOTHERSHIP                          #                              #
#------------------------------------------------------------------------------#
# MSA-Mother Ship Active   MLA2- Mothership Launch Alien2

#                                ALIEN WAVE 2                                  #
    if controls.enemystate=='REST' and controls.counter <25:
        controls.counter+=1 # rest a while

    if controls.enemystate=='REST' and controls.counter >=25:
        controls.counter=0
        controls.enemystate='MLA2'

    if controls.enemystate=='MLA2' and Mothership1.status=="M":
        Mothership1.getrectarea()
        Mothership1.heading-=5
        Mothership1.y+=1
        controls.counter+=1
#------------------------------------------------------------------------------#
#                      L E V E L  3 THE 2nd.ALIEN WAVE                         #                              #
#------------------------------------------------------------------------------#

        if controls.counter>=25:
            if len(controls.Alien2)<controls.no_of_enemies: # 10 alien2's
##image,image2(expld),scale,x,y,life,firerate,frame rate,frame size,status
                anotherbadET=EnemyObject(alien2,al2xplode,44,Mothership1.x,\
                                  Mothership1.y,32,25,6,100,"M")
                anotherbadET.heading=random.randrange(0,360,10)
                anotherbadET.radar=280
                controls.Alien2.append(anotherbadET)
            controls.counter=0

    if Mothership1.y>=controls.Sheight+Mothership1.scale and\
       Mothership1.status<>"D" and len(controls.Alien2)<=controls.no_of_enemies:
        mx=random.randrange(75,controls.Swidth-75,10)
        Mothership1=EnemyObject(AMSHIP1,AMS1EXP,110,mx,0,Mothership1.life,\
                                0,10,250,"M")
        Mothership1.speed=2
        controls.enemystate=='MSA'
    if len(controls.Alien2)<=5 and controls.enemystate=='MSA' \
       and Mothership1.status=="M":
        controls.enemystate='MLA2'

    if len(controls.Alien2)>0 and controls.music=='boss music':
        pygame.mixer.music.load(alien2music)
        pygame.mixer.music.set_volume(0.3)
        pygame.mixer.music.play(-1)
        controls.music='level2alien2'

    if Mothership1.life<=0 and Mothership1.status=="M":
        Mothership1.life=0
        Mothership1.status="E"
        score[3]+=5
    if Mothership1.status=="E":
        Mothership1.explode()

    if Mothership1.status=="D":
        Mothership1.status="DESTROYED"
        Mothership1.x=-4000
        Mothership1.y=-4000

    if Mothership1.status=="DESTROYED" and \
       len(controls.Alien2)==0 and controls.gamestate=="Level 3":
        controls.spendtime+=1

    if Mothership1.status=="DESTROYED" and controls.spendtime>=200:
        controls.enemystate="REST 2"
        controls.asteroidswitch="ON" # bring on more asteroids for level 3
        controls.asteroidcount=0 # respawn asteroids for this level with more
        controls.asteroidlimit=6 # should be 6
        controls.asteroidamount=100 # level 3 - double the amount of asteroids
        controls.gamestate="Level 4"
        controls.spendtime=0
        player_instructions(level4,7) # describe level 4 to player

#------------------------------------------------------------------------------#
#                           L E V E L  4 THE FINAL BATTLE                      #
#------------------------------------------------------------------------------#
# the asteroids are activated again and the FinalAien crafts are deployed

    if controls.gamestate=="Level 4" and controls.enemystate=="REST 2":
        for a in xrange(controls.FAamount): # 6 Final Aliens
            x,y,h=random_xyheading()
    #image,image2(expld),scale,x,y,life,firerate,frame rate,frame size,status
            BaddestET=EnemyObject(bossB,BAexpld,50,30+x,y,50,30,8,400,"M")
            BaddestET.heading=h
            BaddestET.radar=controls.Sheight/2
            controls.FinalAliens.append(BaddestET)
        controls.enemystate="FINAL BATTLE"
        controls.enemycount=0

#------------------------------------------------------------------------------#
#                           Fire the Alien Guns                                #
#------------------------------------------------------------------------------#

    for e in controls.Alien1:
        e.firerate-=1
        if e.firerate<=0 and Hero.life>0 and e.state=="normal":
            controls.AlienMag.append(copy.copy(Abullet))
            # fire only if Hero gets closer than this
            if abs(Hero.x-e.x)<e.radar and abs(Hero.y-e.y)<e.radar:
                controls.AlienMag[-1].fire(e)
                alienshoot.play()
                e.life-=.4
                score[6]+=1
            e.firerate=8# slow down the alien fire rate

    for e in controls.Alien2:
        e.firerate-=1
        if e.firerate<=0 and Hero.life>0 and e.state=="normal":
            controls.Alien2Mag.append(copy.copy(Abullet))
            if abs(Hero.x-e.x)<e.radar and abs(Hero.y-e.y)<e.radar:
                controls.Alien2Mag[-1].fire(e)
                alienshoot.play()
                e.life-=.5
                score[6]+=1
            e.firerate=7

    for e in controls.FinalAliens:
        e.firerate-=1
        if e.firerate<=0 and Hero.life>0 and e.state=="normal":
            controls.Alien2Mag.append(copy.copy(Abullet))
            if abs(Hero.x-e.x)<e.radar and abs(Hero.y-e.y)<e.radar:
                controls.Alien2Mag[-1].fire(e)
                alienshoot.play()
                e.life-=.8
                score[6]+=1
            e.firerate=7

#-----------------------------------------------------------------------------#
#                                 COLLISIONS                                  #
#-----------------------------------------------------------------------------#
    alien1INF_rects=[]
    alien1DEF_rects=[]
    alien2INF_rects=[]
    alien2DEF_rects=[]
    FalienINF_rects=[]
    FalienDEF_rects=[]
    globe_rects=[]
    asteroids_rects=[]
    asterINF_rects=[]
    font = pygame.font.Font("resources\data\prometheanb.ttf", 10)
#------------------------------------------------------------------------------#
#                       HERO COLLIDE WITH ALIEN SHIPS                          #
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#                             THE 1ST. ALIEN WAVE                              #
#------------------------------------------------------------------------------#

    for e in controls.Alien1: # 1st WAVE of ALIENS
        e.getrectarea()
        """get DEFLATED rects as enemy surface is not a perfect square and the
        sprite rect will be large"""
        DEFrect=e.rectarea.inflate(-e.safearea, -e.safearea)
        alien1DEF_rects.append(DEFrect)
        """ get INFLATED rect list for same type collisions (STC)"""
        INFrect=e.rectarea.inflate(e.safearea,e.safearea)
        alien1INF_rects.append(INFrect)
##        pygame.draw.rect(screen, (255,0,255), INFrect,2) # draw INFLATED rect
        Alcollide=Hero.rectarea.collidelist(alien1DEF_rects)
        if not Alcollide==-1 and Hero.nodamage<=0 and\
           Hero.life>0:
            Hero.life-=.4
            hkollidea.play()
        else:
            hkollidea.stop()
        if not Alcollide==-1 and Hero.nodamage>0:
            controls.Alien1[Alcollide].life-=1

#------------------------------------------------------------------------------#
#                       ALIEN1 colliding with each other                       #
#------------------------------------------------------------------------------#
    for i, e in enumerate(alien1INF_rects):
        A1INFlist=e.collidelistall(alien1INF_rects)
        for j in A1INFlist:
            if j==i:
                continue # this prevents self collision
            dx=controls.Alien1[i].centerx-controls.Alien1[j].centerx
            dy=controls.Alien1[i].centery-controls.Alien1[j].centery
            distance=math.hypot(dx,dy)
            heading=.5*math.pi+(math.atan2(dy,dx))
            if distance<=controls.Alien1[j].safearea+\
               controls.Alien1[i].safearea:
                controls.Alien1[i].heading+=2
                controls.Alien1[i].x-=math.sin(heading)
                controls.Alien1[i].y+=math.cos(heading)
                controls.Alien1[j].heading-=2
                controls.Alien1[j].x+=math.sin(heading)
                controls.Alien1[j].y-=math.cos(heading)
            if distance<=controls.Alien1[j].scale/2+controls.Alien1[i].scale/2:
                controls.Alien1[i].x-=1
                controls.Alien1[j].x-=1

#------------------------------------------------------------------------------#
#                             THE 2ND. ALIEN WAVE                              #
#------------------------------------------------------------------------------#

    for e in controls.Alien2: # 2nd WAVE of ALIENS
        e.getrectarea()
        DEFrect=e.rectarea.inflate(-e.safearea, -e.safearea)
        alien2DEF_rects.append(DEFrect)
        INFrect=e.rectarea.inflate(e.safearea,e.safearea)
        alien2INF_rects.append(INFrect)
        Al2collide=Hero.rectarea.collidelist(alien2DEF_rects)
        if not Al2collide==-1 and Hero.nodamage<=0 and\
           Hero.life>0:
            Hero.life-=.2
            hkollidea.play()
        else:
            hkollidea.stop()
        if not Al2collide==-1 and Hero.nodamage>0:
            controls.Alien2[Al2collide].life-=1

#------------------------------------------------------------------------------#
#                       ALIEN2 colliding with each other                       #
#------------------------------------------------------------------------------#

    for i, e in enumerate(alien2INF_rects):
        A2INFlist=e.collidelistall(alien2INF_rects)
        for j in A2INFlist:
            if j==i:
                continue
            dx=controls.Alien2[i].centerx-controls.Alien2[j].centerx
            dy=controls.Alien2[i].centery-controls.Alien2[j].centery
            distance=math.hypot(dx,dy)
            heading=.5*math.pi+(math.atan2(dy,dx))
            if distance<=controls.Alien2[j].safearea+controls.Alien2[i].safearea:
                controls.Alien2[i].heading+=2
                controls.Alien2[i].x-=math.sin(heading)
                controls.Alien2[i].y+=math.cos(heading)
                controls.Alien2[j].heading-=2
                controls.Alien2[j].x+=math.sin(heading)
                controls.Alien2[j].y-=math.cos(heading)
            if distance<=controls.Alien2[j].scale/2+controls.Alien2[i].scale/2:
                controls.Alien2[i].x-=1
                controls.Alien2[j].x-=1

#------------------------------------------------------------------------------#
#                              THE FINAL ALIENS                                #
#------------------------------------------------------------------------------#

    for e in controls.FinalAliens: # final WAVE of ALIENS
        e.getrectarea()
        DEFrect=e.rectarea.inflate(-e.safearea,-e.safearea)
        FalienDEF_rects.append(e.rectarea)
        INFrect=e.rectarea.inflate(e.safearea,e.safearea)
        FalienINF_rects.append(INFrect)
        Al2collide=Hero.rectarea.collidelist(FalienDEF_rects)

        if not Al2collide==-1 and Hero.nodamage<=0 and\
           Hero.life>0:
            Hero.life-=.3
            hkollidea.play()
        else:
            hkollidea.stop()

# Final Aliens not effected by Hero shield

#------------------------------------------------------------------------------#
#                      FinalAliens colliding with each other                       #
#------------------------------------------------------------------------------#

    for i, e in enumerate(FalienINF_rects):
        FAINFlist=e.collidelistall(FalienINF_rects)
        for j in FAINFlist:
            if j==i:
                continue
            dx=controls.FinalAliens[i].centerx-controls.FinalAliens[j].centerx
            dy=controls.FinalAliens[i].centery-controls.FinalAliens[j].centery
            distance=math.hypot(dx,dy)
            heading=.5*math.pi+(math.atan2(dy,dx))
            if distance<=controls.FinalAliens[j].safearea+\
               controls.FinalAliens[i].safearea:
                controls.FinalAliens[i].heading+=2
                controls.FinalAliens[i].x-=math.sin(heading)
                controls.FinalAliens[i].y+=math.cos(heading)
                controls.FinalAliens[j].heading-=2
                controls.FinalAliens[j].x+=math.sin(heading)
                controls.FinalAliens[j].y-=math.cos(heading)
            if distance<=controls.FinalAliens[j].scale/2+\
               controls.FinalAliens[i].scale/2:
# if two Final Aliens collide with eachother, teleport one elsewhere
                controls.FinalAliens[i].x=random.randrange\
                                           (10,controls.Swidth-100)
                controls.FinalAliens[i].y=random.randrange\
                                           (10,controls.Sheight-100)

    if Hero.rectarea.colliderect(boss1.rectarea):
        Hero.life-=6

#------------------------------------------------------------------------------#
#                    ASTEROIDS COLLIDE WITH ALIENS AND HERO                    #
#------------------------------------------------------------------------------#
    for a in asteroids:
        if a.status=="M":
            a.getrectarea()
            asteroids_rects.append(a.rectarea)
            INFrect=a.rectarea.inflate(5,5)
            asterINF_rects.append(INFrect)
            Ascollide=Hero.rectarea.collidelist(asteroids_rects)

            if not Ascollide==-1 and Hero.nodamage<=0 \
               and Hero.life>0 and a.life>0:
# find which type of asteroid hit the Hero and reduce life accordingly
                if asteroids[Ascollide].kind=="L":
                    Hero.life-=20
                elif asteroids[Ascollide].kind=="M":
                    Hero.life-=10
                else:
                    Hero.life-=5

            if not Ascollide==-1 and Hero.nodamage>0 and a.life>0:
                asteroids[Ascollide].life=0
            Alcollisions=a.rectarea.collidelist(alien1DEF_rects)
            Al2collisions=a.rectarea.collidelist(alien2DEF_rects)

            if not Alcollisions==-1:
                controls.Alien1[Alcollisions].life-=.2
                if controls.Alien1[Alcollisions].life<=0:
                    controls.Alien1[Alcollisions].life=0

            if not Al2collisions==-1:
                controls.Alien2[Al2collisions].life-=.2
                if controls.Alien2[Al2collisions].life<=0:
                    controls.Alien2[Al2collisions].life=0

#------------------------------------------------------------------------------#
#                      Asteroids collide with each other                       #
#------------------------------------------------------------------------------#

    for i, a in enumerate(asterINF_rects):
        if asteroids[i].status=="M":
            asterbumplist=a.collidelistall(asterINF_rects)
            for j in asterbumplist:
                if j==i:
                    continue
##               if asteroids[j].rectarea.colliderect(asteroids[i].rectarea):
                dx=asteroids[i].centerx-asteroids[j].centerx
                dy=asteroids[i].centery-asteroids[j].centery
                distance=math.hypot(dx,dy)
##                if distance<=asteroids[j].scale+asteroids[i].scale:
                angle=0.5*math.pi+(math.atan2(dy,dx))
                asteroids[i].heading=(angle-asteroids[i].heading)%360
                asteroids[j].heading-=(angle-asteroids[j].heading)%360
                asteroids[i].life-=0.01

#------------------------------------------------------------------------------#
#                           A L L  E N E M Y  G U N S                          #
#------------------------------------------------------------------------------#

# AB-alien bullet HB-Hero bullet HM=Hero missile BM=boss missile
    for b in controls.AlienMag:
        b.update()
        b.getrectarea()

        if b.rectarea.colliderect(Hero.rectarea)and Hero.nodamage<=0 \
           and b.kind=="AB" and b.status=="F":
            Hero.life-=4
            b.status="E"

        if b.status=="D":
            try:
                controls.AlienMag.remove(b) #REMOVE SPENT HBULLET
            except:
                pass

    for b in controls.Alien2Mag:
        b.update()
        b.getrectarea()

        if b.rectarea.colliderect(Hero.rectarea)and Hero.nodamage<=0 \
           and b.kind=="AB" and b.status=="F":
            Hero.life-=2
            b.status="E"

        if b.status=="D":
            try:
                controls.Alien2Mag.remove(b) #REMOVE SPENT HBULLET
            except:
                pass

    for b in controls.Alien3Mag:
        b.update()
        b.getrectarea()

        if b.rectarea.colliderect(Hero.rectarea)and Hero.nodamage<=0 \
           and b.kind=="AB" and b.status=="F":
            Hero.life-=5
            b.status="E"

        if b.status=="D":
            try:
                controls.Alien3Mag.remove(b) #REMOVE SPENT HBULLET
            except:
                pass

    for b in controls.BossBombMag:
        b.update()
        b.getrectarea()

        if b.rectarea.colliderect(Hero.rectarea)and Hero.nodamage<=0 \
             and Hero.life>0 and b.kind=="BM" and b.status=='F':
            b.status="E"
            Hero.life-=20

        if b.status=="D":
            try:
                controls.AlienMag.remove(b) #REMOVE SPENT HBULLET
            except:
                pass

#------------------------------------------------------------------------------#
#                             COLLECT ALL POWERUPS                             #
#------------------------------------------------------------------------------#

#INVINCIBILITY POWERUP
    if controls.invincibility==True and invincibility.life>0:
        invincibility.life-=1
        invincibility.update()
        invincibility.getrectarea()
##        pygame.draw.rect(screen, (0,255,0), invincibility.rectarea,2)

        if invincibility.rectarea.colliderect(Hero.rectarea):
            collectch.play(invince)
            invincibility.life=0 # type and life
            controls.PUcount[0]=0
            score[4]+=5
            Hero.nodamage=500

#THE ENERGY GLOBES

    for g in controls.globelist:
        g.getrectarea()

        if g.rectarea.colliderect(Hero.rectarea):
            g.status="C"
            collectch.play(collect)
            if controls.globes=='Galive':
                score[5]+=5
            elif controls.globes=='Ralive':
                score[5]+=7
                score[6]+=5
            elif controls.globes=='Oalive':
                score[4]+=1
            elif controls.globes=='Palive':
                score[4]+=1
                score[5]+=5
                Hero.bombs[0]+=1 # bomb material added to list
            controls.collected+=1
        if g.status=="C":
            try:
                controls.globelist.remove(g)
            except:
                pass
#------------------------------------------------------------------------------#
#                              HERO GUN CONTROLS                               #
#------------------------------------------------------------------------------#

    for b in Hero.CMag: # MAIN GUN
        b.update()
        b.getrectarea()
        Ascollisions=b.rectarea.collidelist(asteroids_rects)

        # ASTEROID COLLISION CHECK
        if not Ascollisions==-1 and b.status=="F" and \
           asteroids[Ascollisions].life>0:
            asteroids[Ascollisions].life-=1
            if asteroids[Ascollisions].life<=0:
                controls.asteroidcount+=1
            if asteroids[Ascollisions].kind=="L":
                score[4]+=1
            if asteroids[Ascollisions].kind=="M":
                score[4]+=2
                score[5]+=1
            if asteroids[Ascollisions].kind=="S":
                score[4]+=4
            b.status="E"

        if b.status=="D":
            try:
                Hero.CMag.remove(b) #REMOVE SPENT HBULLET
            except:
                pass

#------------------------------------------------------------------------------#
#                    REMOVE DESTORYED ALIENS AND ASTEROIDS                     #
#------------------------------------------------------------------------------#

    for e in controls.Alien1:
        if e.life<=0 and e.status=="M": # ALIEN LIFE 0 SO EXPLODE
            enemyexp.play()
            e.status="E"
        if e.status=="E":
            e.explode()
        if e.status=="D":
            try:
                controls.Alien1.remove(e) #REMOVE DESTROYED ALIEN
            except:
                pass

    for e in controls.Alien2:
        if e.life<=0 and e.status=="M": # ALIEN LIFE 0 SO EXPLODE
            enemyexp.play()
            e.status="E"
        if e.status=="E":
            e.explode()
        if e.status=="D":
            try:
                controls.Alien2.remove(e) #REMOVE DESTROYED ALIEN
            except:
                pass

    for e in controls.FinalAliens:
        if e.life<=0 and e.status=="M": # ALIEN LIFE 0 SO EXPLODE
            enemyexp.play()
            e.status="E"
        if e.status=="E":
            e.explode()
        if e.status=="D":
            score[3]+=2
            controls.enemycount+=1
            try:
                controls.FinalAliens.remove(e) #REMOVE DESTROYED ALIEN
            except:
                pass

    for a in asteroids:
        if a.life<=0 and a.kind=="L" and a.status=="M":
            astexplode.play()
            x=a.x+40; y=a.y+40
            asteroidA=Asteroids(meteor2,metex2,x,y,5,512,8,64,60,"M","M")
            asteroidA.speed=1.8
            asteroidA.speedlimit=asteroidA.speed
            asteroidA.heading+=90
            asteroidA.life=4
            x=a.x-40; y=a.y-40
            asteroidB=Asteroids(meteor2,metex2,x,y,5,512,8,64,60,"M","M")
            asteroidB.speed=1.5
            asteroidB.speedlimit=asteroidB.speed
            asteroidB.heading-=90
            a.status="E"
            asteroids.append(asteroidA)
            asteroids.append(asteroidB)
        if a.life<=0 and a.kind=="M" and a.status=="M":
            astexplode.play()
            x=a.x+20; y=a.y+20
            asteroidA=Asteroids(meteor3,metex3,x,y,2,128,8,32,60,"S","M")
            asteroidA.speed=2.5
            asteroidA.speedlimit=asteroidA.speed
            asteroidA.heading+=90
            asteroidA.life=2
            x=a.x-20; y=a.y-20
            asteroidB=Asteroids(meteor3,metex3,x,y,2,128,8,32,60,"S","M")
            asteroidB.speed=3.5
            asteroidB.speedlimit=asteroidB.speed
            asteroidB.heading-=90
            a.status="E"
            asteroids.append(asteroidA)
            asteroids.append(asteroidB)
        if a.life<=0 and a.kind=="S" and a.status=="M":
            astexplode.play()
            a.status="E"
        if a.status=="D":
            try:
                asteroids.remove(a) #REMOVE EXPLODED ASTEROID FROM GAME
            except:
                pass

    if Hero.life<=0:
        Hero.life=0

    if controls.enemystate=="FINAL BATTLE" \
       and controls.enemycount==controls.FAamount:
        controls.gamestate="player wins"
        player_instructions(playerwins,10)
        Hero.lives=0

#------------------------------------------------------------------------------#
#                    START, INSTRUCTIONS AND PAUSE SCREENS                     #
#------------------------------------------------------------------------------#

    while controls.pause==True :
        scorepos=55
        font = pygame.font.Font("resources\data\prometheanb.ttf", 30)
        text = font.render("Hall Of Fame", 1, (70,70,255))
        textpos1 = text.get_rect()
        x=controls.Swidth/2-(textpos1[2]/2)
        screen.blit(text,(x,textpos1[3]/2))
        font = pygame.font.Font("resources\data\prometheanb.ttf", 15)
        text = font.render("----------------------------", 1,(80,80,255) )
        textpos2 = text.get_rect()
        screen.blit(text,(x,25+textpos2[3]/2))
        font = pygame.font.Font("resources\data\prometheanb.ttf", 14)
        for t in highscores:
            text = font.render(t[1], 1, (90,90,255)) # player name
            textpos3= text.get_rect()
            y=x-60
            screen.blit(text,(y,scorepos-textpos3[3]/2))
            text = font.render(str(t[0]), 1, (90,90,255)) # player high score
            textpos4 = text.get_rect()
            screen.blit(text,(y+100,scorepos-textpos4[3]/2))
            text = font.render(str(t[2]), 1, (90,90,255)) # player rank
            textpos5 = text.get_rect()
            screen.blit(text,(y+200,scorepos-textpos5[3]/2))
            scorepos+=18
        # Instructions
        font = pygame.font.Font("resources\data\prometheanb.ttf", 18)
        text = font.render("I-Instructions", 0, (128,128,128))
        textpos = text.get_rect()
        x=textpos[3]
        screen.blit(text,(controls.Swidth/2-textpos[2]/2,\
                                             controls.Sheight-x))
        a=random.randrange(0,100)
        b=random.randrange(0,175)
        c=random.randrange(0,255)
        if controls.gamestate=="initial":
            text = font.render("P - to start game", 1,\
                               [40,40,b])
        else:
            text = font.render("Game Paused... P - to continue!",\
                               1, [60,60,a])
        textpos = text.get_rect()
        y=x+textpos[3]+10
        screen.blit(text,(controls.Swidth/2-textpos[2]/2,controls.Sheight-y))

        text = font.render("Music Volume : "+str(int(controls.musicfader*100))\
                            +" -> inc <- dec",1, [50,50,c])
        textpos = text.get_rect()
        z=y+textpos[3]+10
        screen.blit(text,(controls.Swidth/2-textpos[2]/2,\
                          controls.Sheight-z))

        text = font.render("F - FULLSCREEN or WINDOWED mode",0, (128,128,128))
        textpos = text.get_rect()
        zz=z+textpos[3]+10
        screen.blit(text,(controls.Swidth/2-textpos[2]/2,controls.Sheight-zz))

        text = font.render("S - Save Game    L - Load Game",0, (128,128,128))
        textpos = text.get_rect()
        za=zz+textpos[3]+10
        screen.blit(text,(controls.Swidth/2-textpos[2]/2,controls.Sheight-za))

        # animate the game title
        controls.titlewidth+=8
        controls.titleheight+=1
        if controls.titlewidth>=800:
            controls.titlewidth=800; controls.titleheight=100
        p=pygame.transform.scale(title, (controls.titlewidth,\
                                         controls.titleheight))
        w=p.get_rect(); x=(controls.Sheight-w[3])-150; y=x-4
        screen.blit(p,((controls.Swidth-w[2])/2,random.randrange(y,x)))

        # the second title
        controls.titlewidth2+=4
        controls.titleheight2+=1
        if controls.titlewidth2>=800:
            controls.titlewidth2=800; controls.titleheight2=100
        p=pygame.transform.scale(WOLtitle, (controls.titlewidth2,\
                                         controls.titleheight2))
        w=p.get_rect(); x=(controls.Sheight-w[3])-150; y=x/2
        screen.blit(p,((controls.Swidth-w[2])/2,y))

        star_field()
        update_screen()

        #get key input
        for event in pygame.event.get():
            if event.type==KEYDOWN:
                if event.key==K_p :
                    if controls.gamestate=="initial":
                        controls.gamestate="Level 1"
                        pygame.event.clear()
                    controls.pause=not controls.pause
                Hero.setHeading(90)
                if event.key==K_i:
                    controls.instructions=True
                    show_instructions()
                if event.key==K_RIGHT:              # Music vol+
                        controls.musicfader+=0.01
                if event.key==K_LEFT:              # Music vol-
                        controls.musicfader-=0.01
                if controls.musicfader<=0:
                    controls.musicfader=0
                if controls.musicfader>=1:
                    controls.musicfader=1
                pygame.mixer.music.set_volume(controls.musicfader)
                if event.key==K_f and screenmode==0: # toggle fullscreen on/off
                    screenmode=FULLSCREEN
                    screen = pygame.display.set_mode((Swidth, Sheight),\
                                                     screenmode,0)
                elif event.key==K_f and screenmode==FULLSCREEN:
                    screenmode=0
                    screen = pygame.display.set_mode((Swidth, Sheight),\
                                                     screenmode,0)
                if event.key==K_s:
                    controls.savegame=True

                if event.key==K_l:
                    controls.loadgame=True

        if controls.savegame==True:
            save_game()

        if controls.loadgame==True:
            load_game()

    update_all(text1,text2,text3)

#------------------------------------------------------------------------------#
#                        G A  M  E    O  V  E  R                               #
#                            replay or quit                                    #
#------------------------------------------------------------------------------#
    controls.name=''
    f=open('resources\data\scores.sg','wb')
    while Hero.lives<=0 and controls.halloffame==False:
        font = pygame.font.Font("resources\data\prometheanb.ttf", 70)
        akuru="GAME OVER!"
        text = font.render(akuru, 1, red)
        textpos = text.get_rect()
        screen.blit(text,(controls.Swidth/2-(textpos[2]/2),50))
        if realscore>20000 and controls.halloffame==False:
            ypos=hall_of_fame_message()
            # get the rank
            if controls.gamestate=="Level 2":
                controls.rank="Tolerator"
            elif controls.gamestate=="Level 3":
                controls.rank="Passive Attacker"
            elif controls.gamestate=="Level 4":
                controls.rank="Compassioner"
            elif controls.gamestate=="player wins":
                controls.rank="Being of Light"

            for event in pygame.event.get(): # get player name
                if event.type==KEYDOWN:
                    if event.key==K_BACKSPACE and len(controls.name)>0:
                        controls.name=controls.name[:-1]
                    if event.key>=97 and event.key<=122 and \
                       len(controls.name)<10 or event.key>=48 and \
                       event.key<=57 and len(controls.name)<10:
                        text=str(pygame.key.name(event.key))
                        controls.name=controls.name+text

                    if event.key==K_RETURN:
                        newname=controls.name.upper()# convert to uppercase
                        controls.name=newname
                        controls.halloffame=True
                        if len(controls.name)>0:
                            addnew=[realscore,controls.name,controls.rank]
                            if len(highscores)<19:#max 20 items in list
                                highscores.append(addnew)#add new data to file
                            #list is already full so add to last item if bigger
                            # than the number there
                            elif highscores[-1]<addnew:
                                highscores[-1]=addnew
                            highscores.sort(reverse=True)

        font = pygame.font.Font("resources\data\prometheanb.ttf", 20)
        text=font.render((controls.name+'_'),1,[175,175,175])
        textpos = text.get_rect()
        screen.blit(text,(controls.Swidth/2-textpos[2]/2,ypos+10))

        font = pygame.font.Font("resources\data\prometheanb.ttf", 30)
        text = font.render("Hit ESC to Quit!", 1, red)
        textpos1 = text.get_rect()
        screen.blit(text,(controls.Swidth/2-(textpos1[2]/2),120))
        text = font.render("Enter to replay", 1, red)
        textpos2 = text.get_rect()
        screen.blit(text,(controls.Swidth/2-(textpos2[2]/2),150))
        pygame.event.pump()
        key=pygame.key.get_pressed()
        if key[pygame.K_RETURN]:
            Hero.life=450
            Hero.lives=6
            score=[0,0,0,0,0,0,0]#mil,hunthous, tenthous,thous,huns,tens,ones
            scorestr= "".join(str(i) for i in score)
            realscore=int(scorestr)
            controls=Game_controls()
            initialize_stars()
            asteroids=[]
            Hero =HeroObject(45,controls.Swidth/2, controls.Sheight/2,\
                             "N",6,["one",20,"S",0],[0,"D"],5,64)
            Hero.setHeading(90)
            bosx=-100
            bosy=random.randrange(50,controls.Sheight-100)
            # create boss1  and Mothership1 off screen but passive-"P"
            boss1=EnemyObject(bossA,bsxplode,80,bosx,bosy,100,30,8,400,"P")
            mx=random.randrange(50,100,5)
            Mothership1=EnemyObject(AMSHIP1,AMS1EXP,110,mx,0,75.0,0,10,250,"P")
            Mothership1.heading=90
            Mothership1.speed=2
            pygame.mixer.music.load(startmusic)
            pygame.mixer.music.set_volume(0.4)
            pygame.mixer.music.play(-1)
            controls.musicfader=pygame.mixer.music.get_volume()
        if key[pygame.K_ESCAPE]:
            add_and_close_file()
            game_over()
        update_all(text1,text2,text3)
    add_and_close_file()

[/pastacode]

5 thoughts on “Python scripts, Game code

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.