Beispiel #1
0
class LunarSurface(object):
    def __init__(self, depth=3):
        self.starfield = Starfield()

        self.textures = []
        mul = 0.125 / 2.0
        for _ in range(depth):
            texture = pygame.Surface((512, screen_height * 2))
            texture.set_colorkey((255, 0, 255))
            texture.fill((255, 0, 255))
            heightmap = heightmap_1d(9)
            for x in range(512):
                min_y = int((heightmap[x] * mul + 1.0) / 2.0 * screen_height)
                for y in range(min_y, screen_height * 2):
                    noise = random.uniform(0.9, 1.0)
                    color = tuple(255.0 * noise * mul for _ in range(3))
                    texture.set_at((x, y), color)
            self.textures.append(texture)
            mul *= 2

    def update(self, delta):
        self.starfield.update(delta)

    def render(self, screen, camera):
        self.starfield.render(screen, camera)

        mul = 0.125
        for texture in self.textures:
            x = int(-camera.pos[0] * 10.0 * mul) % 512
            y = camera.pos[1] * 10.0 * mul
            screen.blit(texture, (x, y))
            screen.blit(texture, (x - 512, y))
            mul *= 2
Beispiel #2
0
class SplashScreen(GameState):
    def __init__(self):
        super(SplashScreen, self).__init__()
        self.title = self.font.render("Planet Golf", True, pg.Color("dodgerblue"))
        self.title_rect = self.title.get_rect(center=self.screen_rect.center)
        self.next_state = "GAMEPLAY"
        self.starfield = Starfield(self.screen_rect)
        
    def get_event(self, event):
        if event.type == pg.QUIT:
            self.quit = True
        elif event.type == pg.KEYUP:
            if event.key == pg.K_RETURN:
                self.done = True
            elif event.key == pg.K_ESCAPE:
                self.quit = True
    
    def update(self, dt):
        self.starfield.update()
        self.persist['level'] = "planets.txt"

    def draw(self, surface):
        surface.fill(pg.Color("black"))
        surface.blit(self.title, self.title_rect)        
        self.starfield.draw(surface)
Beispiel #3
0
class FinishScreen(GameState):
    def __init__(self):
        super(FinishScreen, self).__init__()
        self.next_state = "GAMEPLAY"
        self.starfield = Starfield(self.screen_rect)
        
    def get_event(self, event):
        if event.type == pg.QUIT:
            self.quit = True
        elif event.type == pg.KEYUP:
            if event.key == pg.K_RETURN:
                self.done = True
            elif event.key == pg.K_ESCAPE:
                self.next_state = "SPLASH"
                self.done = True
    
    def startup(self, persistent):
        self.persist = {}
        self.persist['level'] = persistent['level']
        self.success = persistent['success']
        self.score = float(persistent['score'])
        self.rank = 0
        self.highscores = []

        if self.success and self.score > 0:
            try:
                for line in open("highscore_" + self.persist['level'], "r+").readlines():
                    self.highscores.append(float(line))
            except:
                pass

            import bisect
            self.rank = bisect.bisect_left(self.highscores, self.score)
            self.highscores.insert(self.rank, self.score)
            with open("highscore_" + self.persist['level'], "w+") as f:
                for score in self.highscores:
                    f.write("{0}\n".format(score))


    def update(self, dt):
        self.starfield.update()

    def draw(self, surface):
        surface.fill(pg.Color("black"))
        self.starfield.draw(surface)

        if self.success:
            title = self.font.render(
                    "Success! You scored {0} points! [Rank {1}].".format(self.score, self.rank),
                    True, pg.Color("dodgerblue"))
            title_rect = title.get_rect(center=self.screen_rect.center)
            surface.blit(title, title_rect)
        else:
            title = self.font.render(
                    "You failed! Press 'return' to restart.",
                    True, pg.Color("dodgerblue"))
            title_rect = title.get_rect(center=self.screen_rect.center)
            surface.blit(title, title_rect)
Beispiel #4
0
    def setup(self):
        # Create the background and star field.
        self.background = Starfield(self.width, self.height)

        # Create the player ship.
        self.create_ship('player')

        # Create an enemy ship.
        self.create_ship('enemy')
Beispiel #5
0
def main():
    WINSIZE = 640, 480
    NUMBER_OF_STARS = 250
    STARTING_ANGLE = 180
    CLOSEST_STAR_COLOR = (255, 255, 255)
    STAR_SIZE_IN_PIXELS = 1
    #_V_ = 1
    pygame.init()
    pygame.key.set_repeat(1, 1)
    screen = pygame.display.set_mode(WINSIZE, pygame.SWSURFACE)
    stars = Starfield(screen, screen.get_rect(), NUMBER_OF_STARS,
                      STARTING_ANGLE, (40, 4), STAR_SIZE_IN_PIXELS,
                      CLOSEST_STAR_COLOR)

    ship1 = Ship(screen)

    done = False
    while not done:
        screen.fill(THECOLORS["black"])
        stars.update()
        ship1.draw()
        ship1.resetSprt()
        pygame.display.update()
        events = pygame.event.get()
        for e in events:
            if (e.type == QUIT):
                done = True
                break
            elif (e.type == KEYDOWN):
                if (e.key == K_ESCAPE):
                    done = True
                    break
                #Test for movement
                dx, dy = 0, 0
                if (e.key == K_DOWN):
                    dy += 1
                if (e.key == K_UP):
                    dy -= 1
                if (e.key == K_LEFT):
                    dx -= 1
                if (e.key == K_RIGHT):
                    dx += 1
                ship1.move(dx, dy)
                #if(e.key == K_PLUS):
                #stars.set_speed((
    print "Exiting!"

    return
Beispiel #6
0
    def startup(self, persistent):
        self.persist = persistent
        self.persist['success'] = False
        self.persist['score'] = 0
        self.entities = []
        self.started = False
        self.paused = False
        self.starfield = Starfield(self.screen_rect)
        self.show_cursor = False
        self.time = 0.0

        # Load level
        for line in open(self.persist['level']).readlines():
            mass, size, pos, vel, mutable, color  = line.split(":")
            pos = pos.split(",")
            vel = vel.split(",")
            mutable = mutable.startswith('1')

            entity = Planet(
                    float(size),
                    mass=float(mass), 
                    pos=Vector2d(float(pos[0]), float(pos[1])),
                    vel=Vector2d(float(vel[0]), float(vel[1])),
                    elasticity = 0.97,)
            entity.mutable = mutable
            c = map(int, color.split(","))
            entity.color = pg.Color(*c)
            self.entities.append(entity)
    def __init__(self, input_state, game_stats: SessionStats, starfield=None):
        super().__init__(input_state)

        self.stats = game_stats
        self.font = pygame.font.SysFont(None, 48)
        self.prompt_group = pygame.sprite.Group()
        self.high_score_state = HighScore(self.input_state)
        self.starfield = starfield or Starfield()

        new_high_score = self.font.render("New high score!", True,
                                          config.text_color)
        new_high_score = StaticAnimation(new_high_score)
        new_high_score.rect.centerx = config.screen_rect.centerx
        new_high_score.rect.top = 50
        self.prompt_group.add(new_high_score)

        self.entered_name_image = None
        self.entered_name_rect = None
        self.entered_name = ""

        self._update_name_image()
        self.entered_name_rect.centerx = new_high_score.rect.centerx
        self.entered_name_rect.top = new_high_score.rect.bottom + 10

        # if this is not a new high score, this state will just transition directly to displaying the
        # high score list
        self.done = not self.high_score_state.is_new_high_score(
            game_stats.score)
Beispiel #8
0
def main():
	WINSIZE = 640,480	
	NUMBER_OF_STARS = 250
	STARTING_ANGLE = 180
  	CLOSEST_STAR_COLOR = (255, 255, 255)
	STAR_SIZE_IN_PIXELS = 1
	#_V_ = 1
	pygame.init()
	pygame.key.set_repeat(1,1)
	screen = pygame.display.set_mode(WINSIZE,pygame.SWSURFACE)
	stars = Starfield(screen,screen.get_rect(),NUMBER_OF_STARS,STARTING_ANGLE,(40,4),STAR_SIZE_IN_PIXELS,CLOSEST_STAR_COLOR)
	
	ship1 = Ship(screen)
	
	done = False
	while not done:
		screen.fill(THECOLORS["black"])
		stars.update()
		ship1.draw()
		ship1.resetSprt()
		pygame.display.update()
		events = pygame.event.get()
		for e in events:
			if(e.type == QUIT):
				done = True
				break
			elif (e.type == KEYDOWN):
				if(e.key == K_ESCAPE):
					done = True
					break
				#Test for movement
				dx,dy = 0,0
				if(e.key == K_DOWN):
					dy += 1
				if(e.key == K_UP):
					dy -= 1
				if(e.key == K_LEFT):
					dx -= 1
				if(e.key == K_RIGHT):
					dx += 1
				ship1.move(dx,dy)
				#if(e.key == K_PLUS):
					#stars.set_speed((
	print "Exiting!"
	
	return
Beispiel #9
0
    def __init__(self, depth=3):
        self.starfield = Starfield()

        self.textures = []
        mul = 0.125 / 2.0
        for _ in range(depth):
            texture = pygame.Surface((512, screen_height * 2))
            texture.set_colorkey((255, 0, 255))
            texture.fill((255, 0, 255))
            heightmap = heightmap_1d(9)
            for x in range(512):
                min_y = int((heightmap[x] * mul + 1.0) / 2.0 * screen_height)
                for y in range(min_y, screen_height * 2):
                    noise = random.uniform(0.9, 1.0)
                    color = tuple(255.0 * noise * mul for _ in range(3))
                    texture.set_at((x, y), color)
            self.textures.append(texture)
            mul *= 2
Beispiel #10
0
def main():

    pygame.init()

    scale = 4

    screen = pygame.display.set_mode((256 * scale, 240 * scale))

    starfield = Starfield(scale, screen)
    player = Player(scale)

    running = True

    while running:

        pressed = pygame.key.get_pressed()
        player.keys(pressed)

        for event in pygame.event.get():

            if event.type == pygame.KEYDOWN:

                if event.key == pygame.K_F4 and pygame.key.get_mods(
                ) & pygame.KMOD_SHIFT:
                    running = False

            if event.type == pygame.QUIT:
                running = False

        screen.fill((0, 0, 0))

        starfield.draw()
        player.draw(screen)

        pygame.display.update()

    pygame.quit()
    sys.exit()
Beispiel #11
0
    def __init__(self,level=0):
        pygame.init()
        
        self.screen = pygame.display.set_mode(self.screen_size)
        if self.title:
            pygame.display.set_caption(self.title)
        self.fps = 30

        #group definitions
        self.userPlacedObjects = Group()
        self.startItems = RenderUpdates()
        self.playerGroup = RenderUpdates()
        self.tails = RenderUpdates()
        self.blackHoles = RenderUpdates()
        self.obstacles = RenderUpdates()
        self.masslessObstacles = RenderUpdates()
        self.goalCollide = Group()
        self.toolbar = OrderedUpdates()

        #level/transition/player & enemy/obstacle creation hocus pocus
        self.goal = Goal(573,372,self.goalCollide,30)
        self.bar = ToolBar(0,626,self.toolbar,self.screen,self,self.goal)
        self.player = Player(50,535,self.screen,(255,0,0),self.playerGroup,1000,624,(2,-2),self.tails,self)
        
        self.level = level
        self.levelUp = True
        self.stars = Starfield(self.screen,1000,626,200)
        BlackHole(339,70,self.blackHoles,self.screen,80,71,16)
        temp = EarthRounder(513,313,self.masslessObstacles,self.screen,40,0)
        temp.rotate(55)
        temp = Alien(60,188,self.masslessObstacles,self.screen,34,1)
        temp.rotate(-15)
        temp = Alien(107,268,self.masslessObstacles,self.screen,35,1)
        temp.rotate(-75)
        temp = Alien(816,533,self.masslessObstacles,self.screen,39,0)
        temp.rotate(-13)
        temp = BlueUpAnDown(811,227,self.masslessObstacles,self.screen,34,1,97,239)
        temp.rotate(80)
        self.obstacles.add(self.blackHoles)
        self.obstacles.add(self.goalCollide)
        self.freeb = False
        self.gotoLevel = level
        self.loaded = False

        if system.thereIsASaveFile() and level == 0:
            self.intro_screen = Intro(0,0,self.startItems,str('title_w_file.png'))
            self.thereIsAFile = True
        elif level == 0:
            self.intro_screen = Intro(0,0,self.startItems)
            self.thereIsAFile = False
    def __init__(self, input_state, starfield=None):
        super().__init__(input_state)

        self.font = pygame.font.SysFont(None, 48)
        self.high_scores = []
        self.starfield = starfield or Starfield()

        self._load_high_scores()

        # create high score text
        self.high_score_image = self.font.render("High Scores", True,
                                                 config.text_color)
        self.high_score_image = self.high_score_image.convert_alpha(
            pygame.display.get_surface())
        self.high_score_rect = self.high_score_image.get_rect()
        self.high_score_rect.center = config.screen_rect.center
        self.high_score_rect.top = 50

        self.score_group = pygame.sprite.Group()
        self._update_high_score_list()

        self.done = False
Beispiel #13
0
    def __init__(self, input_state, starfield=None):
        super().__init__(input_state)
        self.font = pygame.font.SysFont(None, Menu.TitleSize)
        self.starfield = starfield or Starfield()
        self.title = Group()
        # create "Space Invaders" logo

        # green "SPACE"
        space_title = StaticAnimation(
            self.font.render("SPACE", True, config.green_color))
        space_title.rect.centerx = config.screen_rect.centerx
        space_title.rect.centery = config.screen_height // 8

        # white "INVADERS"
        self.font = pygame.font.SysFont(None, Menu.TitleSize // 2)
        invaders_title = StaticAnimation(
            self.font.render("INVADERS", True, pygame.Color('white')))
        invaders_title.rect.left = space_title.rect.left + space_title.rect.width // 8
        invaders_title.rect.top = space_title.rect.bottom + 10

        self.title.add(space_title, invaders_title)

        last_y = config.screen_height - config.screen_height // 3
        self.options = Group()
        self.font = pygame.font.SysFont(None, Menu.MenuItemSize)

        # create options
        for option in [("Play Space Invaders", self._play_game),
                       ("High Scores", self._view_high_scores),
                       ("Quit", self._quit)]:
            option_sprite = StaticAnimation(
                self.font.render(option[0], True, config.text_color))
            option_sprite.callback = option[1]

            option_sprite.rect.centerx = config.screen_width // 2
            option_sprite.rect.top = last_y

            last_y = option_sprite.rect.bottom + Menu.MenuItemSpacing
            self.options.add(option_sprite)

        # create a small sprite to use as menu item selector
        left_selector = config.atlas.load_static("selector")

        # need to flip the arrow...
        right_selector = StaticAnimation(
            pygame.transform.flip(left_selector.image, True, False))
        right_selector.rect.left = config.screen_width

        self.selectors = Group(left_selector, right_selector)

        # point values for aliens
        self.aliens = Group()

        y_pos = invaders_title.rect.bottom + 50

        for alien_stats in config.alien_stats:
            alien = config.atlas.load_animation(
                alien_stats.sprite_name).frames[0]
            spr = self._create_point_sprite(alien, alien_stats.points, y_pos)
            self.aliens.add(spr)
            y_pos = spr.rect.bottom + 10

        ufo = config.atlas.load_animation("ufo").frames[0]
        spr = self._create_point_sprite(ufo, "???", y_pos)

        self.aliens.add(spr)

        # finish creating state values
        self.next_state = None
        self._set_selected(0)

        pygame.mouse.set_visible(True)
        sounds.play_music(sounds.menu_music_name)
Beispiel #14
0
 def __init__(self):
     super(FinishScreen, self).__init__()
     self.next_state = "GAMEPLAY"
     self.starfield = Starfield(self.screen_rect)
Beispiel #15
0
 def __init__(self):
     super(SplashScreen, self).__init__()
     self.title = self.font.render("Planet Golf", True, pg.Color("dodgerblue"))
     self.title_rect = self.title.get_rect(center=self.screen_rect.center)
     self.next_state = "GAMEPLAY"
     self.starfield = Starfield(self.screen_rect)
Beispiel #16
0
class Gameplay(GameState):
    def __init__(self):
        super(Gameplay, self).__init__()
        self.initial_velocity = None
        self.next_state = "FINISHED"
        
    def startup(self, persistent):
        self.persist = persistent
        self.persist['success'] = False
        self.persist['score'] = 0
        self.entities = []
        self.started = False
        self.paused = False
        self.starfield = Starfield(self.screen_rect)
        self.show_cursor = False
        self.time = 0.0

        # Load level
        for line in open(self.persist['level']).readlines():
            mass, size, pos, vel, mutable, color  = line.split(":")
            pos = pos.split(",")
            vel = vel.split(",")
            mutable = mutable.startswith('1')

            entity = Planet(
                    float(size),
                    mass=float(mass), 
                    pos=Vector2d(float(pos[0]), float(pos[1])),
                    vel=Vector2d(float(vel[0]), float(vel[1])),
                    elasticity = 0.97,)
            entity.mutable = mutable
            c = map(int, color.split(","))
            entity.color = pg.Color(*c)
            self.entities.append(entity)
        
    def get_event(self, event):
        if event.type == pg.QUIT:
            self.quit = True
        elif event.type == pg.MOUSEBUTTONUP:
            self.started = True
        elif event.type == pg.KEYUP:
            if event.key == pg.K_p:
                self.paused = not self.paused
            elif event.key == pg.K_ESCAPE:
                self.done = True
        
    def update(self, dt):
        dt /= 100.0
        if not self.started:
            p = pg.mouse.get_pos()
            self.cursor = Vector2d([float(i) for i in p])
            player = self.entities[0].pos
            diff = self.cursor - player
            if diff.length() < 1000:
                self.show_cursor = True
                diff /= 50
                self.initial_velocity = diff
                self.entities[0].vel = Vector2d(
                        float(diff[0]),
                        float(diff[1]))
            else:
                self.show_cursor = False
        elif not self.paused:
            self.time += dt
            entity_set = list(self.entities)
            # Success condition
            if self.entities[0].collides_with(self.entities[-1]):
                self.persist['init_vel'] = self.initial_velocity
                self.persist['success'] = True
                self.persist['score'] = self.time
                self.done = True
                return

            for entity in entity_set:
                entity_set.remove(entity)
                for other in entity_set:
                    if entity.collides_with(other):
                        entity.resolve_collision(other)

                    force = entity.calc_gravity(other)
                    entity.apply_force(entity.pos, force)
                    other.apply_force(other.pos, -force)

            for entity in self.entities:
                if entity.mutable == True:
                    entity.update(0, dt)

            self.starfield.update()
        else:
            pass

    def draw(self, surface):
        surface.fill(pg.Color("Black"))
        self.starfield.draw(screen)
        if not self.started and self.show_cursor:
            pg.draw.aaline(
                    surface,
                    pg.Color("dodgerblue"),
                    self.entities[0].pos,
                    self.cursor)

        for entity in self.entities:
            pg.gfxdraw.aacircle(
                surface,
                int(entity.pos[0]),
                int(entity.pos[1]),
                int(entity.radius),
                entity.color)

            pg.gfxdraw.filled_circle(
                surface,
                int(entity.pos[0]),
                int(entity.pos[1]),
                int(entity.radius),
                entity.color)
        

        label = self.font.render(str(self.initial_velocity), True, pg.Color("dodgerblue"))
        surface.blit(label, (10, 40))

        label = self.font.render(str(self.time), True, pg.Color("dodgerblue"))
        surface.blit(label, (10, 80))

        if not self.started:
            text = "Use mouse to launch satellite."
            title = self.font.render(text, True, pg.Color("dodgerblue"))
            title_rect = title.get_rect(center=self.screen_rect.center)
            surface.blit(title, title_rect)

        elif self.paused:
            title = self.font.render("PAUSED", True, pg.Color("dodgerblue"))
            title_rect = title.get_rect(center=self.screen_rect.center)
            surface.blit(title, title_rect)
Beispiel #17
0
class Game(object):
    title = 'Gravity'
    screen_size = 1000, 750
    
    def __init__(self,level=0):
        pygame.init()
        
        self.screen = pygame.display.set_mode(self.screen_size)
        if self.title:
            pygame.display.set_caption(self.title)
        self.fps = 30

        #group definitions
        self.userPlacedObjects = Group()
        self.startItems = RenderUpdates()
        self.playerGroup = RenderUpdates()
        self.tails = RenderUpdates()
        self.blackHoles = RenderUpdates()
        self.obstacles = RenderUpdates()
        self.masslessObstacles = RenderUpdates()
        self.goalCollide = Group()
        self.toolbar = OrderedUpdates()

        #level/transition/player & enemy/obstacle creation hocus pocus
        self.goal = Goal(573,372,self.goalCollide,30)
        self.bar = ToolBar(0,626,self.toolbar,self.screen,self,self.goal)
        self.player = Player(50,535,self.screen,(255,0,0),self.playerGroup,1000,624,(2,-2),self.tails,self)
        
        self.level = level
        self.levelUp = True
        self.stars = Starfield(self.screen,1000,626,200)
        BlackHole(339,70,self.blackHoles,self.screen,80,71,16)
        temp = EarthRounder(513,313,self.masslessObstacles,self.screen,40,0)
        temp.rotate(55)
        temp = Alien(60,188,self.masslessObstacles,self.screen,34,1)
        temp.rotate(-15)
        temp = Alien(107,268,self.masslessObstacles,self.screen,35,1)
        temp.rotate(-75)
        temp = Alien(816,533,self.masslessObstacles,self.screen,39,0)
        temp.rotate(-13)
        temp = BlueUpAnDown(811,227,self.masslessObstacles,self.screen,34,1,97,239)
        temp.rotate(80)
        self.obstacles.add(self.blackHoles)
        self.obstacles.add(self.goalCollide)
        self.freeb = False
        self.gotoLevel = level
        self.loaded = False

        if system.thereIsASaveFile() and level == 0:
            self.intro_screen = Intro(0,0,self.startItems,str('title_w_file.png'))
            self.thereIsAFile = True
        elif level == 0:
            self.intro_screen = Intro(0,0,self.startItems)
            self.thereIsAFile = False
      
    def quit(self):
        self.done = True
   
    def level_0(self):
        self.clock.tick(self.fps)
        pygame.draw.rect(self.screen,(0,0,0),((0,0),(1000,750)))
        
        for evt in pygame.event.get():
            if evt.type == QUIT:
                self.quit()
            if evt.type == KEYDOWN:
                if evt.key == K_ESCAPE:
                    self.quit()
                elif evt.key == K_RETURN:
                    if not self.thereIsAFile:
                        self.transition = Transition(-1314,0,self.screen,self.startItems)
                        self.intro_screen.begin()
                    else:
                        loadingDial = system.Loading()
                        pygame.draw.rect(self.screen,(0,0,0),((0,0),(1000,750)))
                        self.startItems.draw(self.screen)
                        loadingDial.draw(self.screen)
                        pygame.display.flip()
                        self.loadFile(system.loadFile())
                        
                elif evt.key == K_RIGHT:
                    self.intro_screen.instruct(True)
                elif evt.key == K_LEFT:
                    self.intro_screen.instruct(False)
                elif evt.key == K_n:
                    if self.thereIsAFile:
                        self.transition = Transition(-1314,0,self.screen,self.startItems)
                        self.intro_screen.begin()
                        self.transition = Transition(-1314,0,self.screen,self.startItems)
                elif evt.key == K_d:
                    if self.thereIsAFile:
                        os.remove('save.txt')
                        self.thereIsAFile = False
                        self.startItems.empty()
                        self.intro_screen = Intro(0,0,self.startItems)

       
        if self.intro_screen.next_level():
            self.level = 1
        
        
        self.startItems.update()
        self.stars.draw()
        self.goalCollide.draw(self.screen)
        self.toolbar.draw(self.screen)
        self.masslessObstacles.draw(self.screen)
        self.playerGroup.draw(self.screen)
        self.blackHoles.draw(self.screen)
        self.startItems.draw(self.screen)
        

        pygame.display.flip()

        

    def tick(self):
        self.clock.tick(self.fps)
        pygame.draw.rect(self.screen,(0,0,0),((0,0),(1000,750)))
        pos = pygame.mouse.get_pos()

        #inputs queue
        for evt in pygame.event.get():
            if evt.type == QUIT:
                self.quit()
            elif evt.type == KEYDOWN:
                if evt.key == K_ESCAPE and not self.bar.itemsTab.open and self.bar.grabbed == None:
                    self.bar.menuWidget.dropped()
                elif evt.key == K_ESCAPE and self.bar.grabbed == None:
                    self.bar.itemsTab.dropped()
                    self.bar.menuWidget.dropped()
                                        
            elif evt.type == MOUSEBUTTONDOWN:
                #print pos
                should_freebie = self.bar.collision_test(pos,self.player,evt.button)
                if should_freebie and not self.freeb:
                    self.freebie()
                    self.freeb = True
                if evt.button == 1:
                    for obj in self.userPlacedObjects:
                        if obj.rect.collidepoint(pos) and not self.player.makeANew and not self.bar.menuWidget.open:
                            obj.grab(pos)
                elif evt.button == 3:
                    for obj in self.userPlacedObjects:
                        if obj.rect.collidepoint(pos) and not self.player.makeANew and not self.bar.menuWidget.open:
                            obj.remove()
            elif evt.type == MOUSEBUTTONUP:
                self.bar.clear_grabbed()
                for obj in self.userPlacedObjects:
                    obj.drop(self.blackHoles)
             
   
        if self.level == 4 and self.player.makeANew:
            self.masslessObstacles.update()
   
        #self.masslessObstacles.update(self.player.makeANew)
        self.stars.draw()
        self.player.drawTails()
        self.blackHoles.update()
        self.bar.update(pos)
        self.blackHoles.draw(self.screen)
        self.userPlacedObjects.update(pos)
        self.userPlacedObjects.draw(self.screen)
        self.masslessObstacles.draw(self.screen)
        self.goalCollide.draw(self.screen)
        self.toolbar.draw(self.screen)
        self.playerGroup.update()
        self.playerGroup.draw(self.screen)  

        if len(self.playerGroup) == 0 and self.player.lives >1:
            self.bar.lives_update()
            self.bar.score.update(-200)
            pygame.time.wait(750)
            self.player.lives -= 1
            if self.level == 4:
                self.asteroid.reset()
            self.player.add(self.playerGroup)
        elif len(self.playerGroup) == 0:
            self.bar.score.update(-200)
            self.bar.lives_update()
            self.over_screen = GameOverScreen(293,161,self.screen)
            if self.level == 4:
                self.asteroid.reset()
            self.gameOver()
                
        if pygame.sprite.collide_mask(self.player, self.goal):
            if self.loaded != 0:
                self.level = self.loaded
                self.loaded = 0
            self.next_level()
            

        for obj in self.blackHoles:
            if pygame.sprite.collide_mask(self.player,obj):
                self.player.blackHoleCollision(True,False)

        for obj in self.masslessObstacles:
            if  pygame.sprite.collide_mask(self.player,obj):
                self.player.update(True)
        
        for obj in self.userPlacedObjects:
            if pygame.sprite.collide_mask(self.player,obj) and not obj.grabbed:
                self.player.update(True)
        

        pygame.display.flip()


    def next_level(self,add_score_bool=True,trans_effect=True):
        if self.level < 5:
            print self.level,"pre-adding"
            self.level += 1
            print self.level,"post-adding"
        #print self.level
        if self.level == 5:
            return
        if trans_effect: self.transition.add_to_group()
        changed = False
        while True:
            self.clock.tick(self.fps)
            pygame.draw.rect(self.screen,(0,0,0),((0,0),(1000,750)))
            
            for evt in pygame.event.get():
                if evt.type == QUIT:
                    self.quit()
                if evt.type == KEYDOWN:
                    if evt.key == K_ESCAPE:
                        self.quit()
                        
            if not trans_effect or self.transition.rect.x >= -50 and not changed:
                print self.level
                if self.level == 2:
                    self.make_level_two(add_score_bool)
                if self.level == 3:
                    self.make_level_three(add_score_bool)
                if self.level == 4:
                    self.make_level_four(add_score_bool)

                if add_score_bool:
                    self.bar.score.update(2000)


                self.player.restart(add_score_bool)
                changed = True      

            if not trans_effect:
                print self.level,"load" 
                break
                
            self.startItems.update()
            self.stars.draw()
            self.player.drawTails()
            self.goalCollide.draw(self.screen)
            self.masslessObstacles.draw(self.screen)
            self.userPlacedObjects.draw(self.screen)
            self.toolbar.draw(self.screen)
            self.blackHoles.draw(self.screen)
            self.playerGroup.draw(self.screen)  
            self.startItems.draw(self.screen)
            if self.transition.rect.x > 1000:
                self.transition.kill()
                break


            pygame.display.flip()
        if trans_effect:
            self.transition.reset(-1314)
        print self.level,"end o loop"
        return False

    
    def freebie(self):
        groupus = Group()
        groupus.add(self.blackHoles,self.goal)
        self.player.makeANew = True
        self.player.addTail = False
        while True:
            self.clock.tick(self.fps)
            pygame.draw.rect(self.screen,(0,0,0),((0,0),(1000,750)))
            
            for evt in pygame.event.get():
                if evt.type == QUIT:
                    self.quit()
                if evt.type == KEYDOWN:
                    if evt.key == K_ESCAPE:
                        self.quit()
            
            
            for obj in self.blackHoles:
                if pygame.sprite.collide_mask(self.player,obj):
                    self.player.blackHoleCollision(True,False)

            for obj in self.masslessObstacles:
                if  pygame.sprite.collide_mask(self.player,obj):
                    self.player.update(True)
        
            for obj in self.userPlacedObjects:
                if pygame.sprite.collide_mask(self.player,obj) and not obj.grabbed:
                    self.player.update(True)
            

            self.startItems.update()
            #self.masslessObstacles.update()
            self.stars.draw()
            self.player.drawTails()
            self.goalCollide.draw(self.screen)
            self.masslessObstacles.draw(self.screen)
            self.userPlacedObjects.draw(self.screen)
            self.toolbar.draw(self.screen)
            self.blackHoles.draw(self.screen)
            self.player.update(False,groupus)
            self.playerGroup.draw(self.screen)  
            self.startItems.draw(self.screen)
            if len(self.playerGroup) < 1:
                self.player.addTail = True
                pygame.time.wait(750)
                self.player.add(self.playerGroup)
                break
            pygame.display.flip()
            

    def gameOver(self):
        overing = True
        self.bar.update()
        self.toolbar.draw(self.screen)
        self.over_screen.draw()
        pygame.display.flip()
        while overing:
            self.clock.tick(self.fps)
            
            for evt in pygame.event.get():
                if evt.type == QUIT:
                    overing = False
                    self.quit()
                if evt.type == KEYDOWN:
                    if evt.key == K_ESCAPE:
                        overing = False
                        self.quit()
                    if evt.key == K_RETURN:
                        overing = False
            
            
        
        self.player.add(self.playerGroup)
        self.bar.reset_lives_over()
        self.player.restart()
        self.over_screen.kill()

    def inStructionees(self):
        self.instructions = Instructions(0,-750,self.startItems)
        self.instructions.instruct(True)

        while True:
            self.clock.tick(self.fps)
            pygame.draw.rect(self.screen,(0,0,0),((0,0),(1000,750)))

            if self.instructions.instruct and self.instructions.rect.y < 0:
                self.instructions.rect.y += 50

            elif not self.instructions.instruct and self.instructions.rect.y > -750:
                self.instructions.rect.y -= 50
            elif not self.instructions.instruct and self.instructions.rect.y <= -750:
                self.instructions.kill()
                return
            
            
            for evt in pygame.event.get():
                if evt.type == QUIT:
                    self.quit()
                    return
                elif evt.type == KEYDOWN:
                    if evt.key == K_RETURN:
                        self.instructions.instruct = False
                    elif evt.key == K_ESCAPE:
                        self.quit()
                        return

            self.stars.draw()
            self.player.drawTails()
            self.goalCollide.draw(self.screen)
            self.masslessObstacles.draw(self.screen)
            self.userPlacedObjects.draw(self.screen)
            self.toolbar.draw(self.screen)
            self.blackHoles.draw(self.screen)
            self.playerGroup.draw(self.screen)  
            self.startItems.draw(self.screen)
                
            pygame.display.flip()
    
    def saveFile(self):
        save_confirm = GameOverScreen(293,161,self.screen,str('filesaved.png'))
        save_confirm.draw()
        self.bar.menuWidget.dropped()
        system.saveFile(self.level,self.player.lives,self.bar.score.score)
        pygame.display.flip()
        while True:
            self.clock.tick(self.fps)
            pygame.draw.rect(self.screen,(0,0,0),((0,0),(1000,750)))

            for evt in pygame.event.get():
                if evt.type == QUIT:
                    self.quit()
                    return
                elif evt.type == KEYDOWN:
                    if evt.key == K_RETURN:
                        return
                    elif evt.key == K_ESCAPE:
                        self.quit()
                        return

            
    def loadFile(self,file_tuple):
        gotoLevel,gotoLives,gotoScore = file_tuple
        self.level = gotoLevel
        if self.level > 1:
            self.loaded = self.level
        self.player.lives = gotoLives
        self.bar.lives.next_life = gotoLives+1
        self.bar.lives_update()
        self.bar.score.reset(gotoScore)
        if gotoLevel != 1:
            self.level -= 1
            self.next_level(False,False)
        self.startItems.empty()
        self.intro_screen = Intro(0,0,self.startItems,str('title_w_file.png'))
        self.intro_screen.begin()
        self.transition = Transition(-1314,0,self.screen,self.startItems)

        while True:
            self.clock.tick(self.fps)
            pygame.draw.rect(self.screen,(0,0,0),((0,0),(1000,750)))
            
            
            if self.intro_screen.next_level():
                break
            
            self.startItems.update()
            self.startItems.update()
            self.stars.draw()
            self.goalCollide.draw(self.screen)
            self.toolbar.draw(self.screen)
            self.masslessObstacles.draw(self.screen)
            self.playerGroup.draw(self.screen)
            self.blackHoles.draw(self.screen)
            self.startItems.draw(self.screen)
            
            
            pygame.display.flip()

        
    def gameWinner(self):
        self.clock.tick(self.fps)
        pygame.draw.rect(self.screen,(0,0,0),((0,0),(1000,750)))
            
            
        for evt in pygame.event.get():
            if evt.type == QUIT:
                self.quit()
                
            elif evt.type == KEYDOWN:
                self.quit()
            
        self.winnerScreen.draw()
        pygame.display.flip()
        
    def run(self,level=0):
        self.done = False
        self.clock = pygame.time.Clock()
        if self.gotoLevel > 1 and self.gotoLevel < 4:
            self.transition = Transition(-1314,0,self.screen,self.startItems)
            self.tick()
            self.level = self.gotoLevel
            self.next_level()
        while not self.done:
            while self.level == 0 and not self.done:
                self.level_0()
            while self.level >= 1 and self.level < 5 and not self.done:
                self.tick()
            self.winnerScreen = WinScreen(0,0,self.screen)
            while not self.done:
                self.gameWinner()


    def make_level_two(self,reset_lives_bool):
        self.tails.empty()
        self.goal.next_level(self.level)
        self.bar.next_level(self.level,reset_lives_bool)
        self.userPlacedObjects.empty()
        self.blackHoles.empty()
        self.obstacles.empty()
        self.freeb = False
        self.bar.itemsTab.earth_item.light()
        self.masslessObstacles.empty()
        temp = Alien(55,143,self.masslessObstacles,self.screen,39,1)
        temp.rotate(-66)
        temp = Alien(189,98,self.masslessObstacles,self.screen,36,1)
        temp.rotate(23)
        temp = Alien(107,228,self.masslessObstacles,self.screen,32,1)
        temp.rotate(17)
        temp = BlueUpAnDown(249,244,self.masslessObstacles,self.screen,41,1,204,245)
        temp.rotate(80)
        temp = TwitchyOnes(898,541,self.masslessObstacles,self.screen,45,2)
        temp.rotate(22)
        temp = TwitchyOnes(730,545,self.masslessObstacles,self.screen,40,2)
        temp.rotate(-30)
        temp = Rotator(525,121,self.masslessObstacles,self.screen,50,0,-70)
        BlackHole(842,388,self.blackHoles,self.screen,80,71,16)
        hole = BlackHole(388,189,self.blackHoles,self.screen,80,71,16)
        hole.flip()
        self.obstacles.add(self.blackHoles)
        self.obstacles.add(self.goal)

    def make_level_three(self,reset_lives_bool):
        self.goal.next_level(self.level)
        self.bar.next_level(self.level,reset_lives_bool)
        self.userPlacedObjects.empty()
        self.blackHoles.empty()
        self.obstacles.empty()
        self.freeb = False
        self.bar.itemsTab.earth_item.light()
        self.masslessObstacles.empty()
        temp = Alien(519,257,self.masslessObstacles,self.screen,28,3)
        temp.rotate(18)
        temp = Alien(539,247,self.masslessObstacles,self.screen,27,3)
        temp.rotate(60)
        temp = Alien(555,240,self.masslessObstacles,self.screen,25,3)
        temp.rotate(-20)
        temp = Alien(568,281,self.masslessObstacles,self.screen,29,3)
        temp.rotate(-45)
        temp = Alien(549,291,self.masslessObstacles,self.screen,32,3)
        temp.rotate(10)
        temp = Alien(530,301,self.masslessObstacles,self.screen,26,3)
        temp = Alien(562,265,self.masslessObstacles,self.screen,27,3)
        temp.rotate(25)   
        temp = Alien(519,334,self.masslessObstacles,self.screen,25,3)
        temp.rotate(-70)
        temp = Alien(500,307,self.masslessObstacles,self.screen,25,3)
        temp.rotate(-80)
        temp = Alien(494,356,self.masslessObstacles,self.screen,25,3)
        temp.rotate(-3)
        temp = Alien(560,365,self.masslessObstacles,self.screen,25,3)
        temp.rotate(77)
        temp = Alien(525,374,self.masslessObstacles,self.screen,29,3)
        temp.rotate(33)
        temp = Alien(640,290,self.masslessObstacles,self.screen,26,3)
        temp.rotate(37)
        temp = Alien(607,250,self.masslessObstacles,self.screen,33,3)
        temp.rotate(-27)  
        temp = Alien(518,421,self.masslessObstacles,self.screen,24,3)
        temp.rotate(55)
        temp = Alien(473,419,self.masslessObstacles,self.screen,28,3)
        temp.rotate(-43)
        temp = Alien(480,453,self.masslessObstacles,self.screen,27,3)
        temp = Alien(512,479,self.masslessObstacles,self.screen,31,3)
        temp.rotate(4)
        temp = Alien(422,500,self.masslessObstacles,self.screen,32,3)
        temp = Alien(463,521,self.masslessObstacles,self.screen,27,3)
        temp.rotate(22)
        temp = Alien(471,486,self.masslessObstacles,self.screen,22,3)
        temp.rotate(80)
        temp = Alien(743,713,self.masslessObstacles,self.screen,25,3)
        temp.rotate(13)
        temp = Alien(527,532,self.masslessObstacles,self.screen,28,3)
        temp.rotate(-8)
        temp = Alien(568,559,self.masslessObstacles,self.screen,27,3)
        temp = Alien(527,593,self.masslessObstacles,self.screen,23,3)
        temp.rotate(-60)
        temp = Alien(652,552,self.masslessObstacles,self.screen,25,3)
        temp.rotate(-24)
        temp = Alien(636,581,self.masslessObstacles,self.screen,26,3)
        temp.rotate(-19)
        temp = Alien(714,596,self.masslessObstacles,self.screen,22,3)
        temp.rotate(-88)
        BlackHole(162,42,self.blackHoles,self.screen,80,71,29)
        self.obstacles.add(self.goal)
        self.obstacles.add(self.blackHoles)

    def make_level_four(self,reset_lives_bool):
        self.goal.next_level(self.level)
        self.bar.next_level(self.level,reset_lives_bool)
        self.userPlacedObjects.empty()
        self.blackHoles.empty()
        self.obstacles.empty()
        self.freeb = False
        self.bar.itemsTab.earth_item.light()
        self.masslessObstacles.empty()
        BlackHole(183,61,self.blackHoles,self.screen,80,71,16)
        BlackHole(101,157,self.blackHoles,self.screen,80,71,16)
        BlackHole(234,157,self.blackHoles,self.screen,80,71,16)
        BlackHole(178,250,self.blackHoles,self.screen,80,71,16)
        hole = BlackHole(683,41,self.blackHoles,self.screen,80,71,16)
        hole = BlackHole(577,41,self.blackHoles,self.screen,80,71,16)
        hole = BlackHole(646,133,self.blackHoles,self.screen,80,71,16)
        hole = BlackHole(747,133,self.blackHoles,self.screen,80,71,16)
        self.asteroid = Asteroid(840,530,self.masslessObstacles,self.screen,55,4)
        self.asteroid.rotate(137)

        self.obstacles.add(self.blackHoles)
        self.obstacles.add(self.goal)
Beispiel #18
0
class App(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)

        # Screen dimensions.
        self.width = width
        self.height = height

        # Must keep track of the left or right keys being pressed in case the
        # user overlaps the two key presses. Otherwise the left / right turning
        # behaviour isn't intutive.
        self.is_left_pressed = False
        self.is_right_pressed = False

        # Setup sprite lists.
        self.player_ship_sprite_list = arcade.SpriteList()
        self.enemy_ships_sprite_list = arcade.SpriteList()
        self.laser_sprite_list = arcade.SpriteList()
        self.explosion_sprite_list = arcade.SpriteList()

        # Load the explosion spritesheet here to prevent a delay in the
        # explosion animation.
        Explosion.load_spritesheet()

    def setup(self):
        # Create the background and star field.
        self.background = Starfield(self.width, self.height)

        # Create the player ship.
        self.create_ship('player')

        # Create an enemy ship.
        self.create_ship('enemy')

    def on_draw(self):
        # Draws everything to the screen.
        arcade.start_render()

        self.background.draw()
        self.laser_sprite_list.draw()
        self.enemy_ships_sprite_list.draw()
        self.player_ship_sprite_list.draw()
        self.explosion_sprite_list.draw()

    def on_update(self, delta_time):
        # If a laser hits an enemy ship trigger a small explosion and spawn a
        # new enemy.
        position = self.check_for_list_collisions(self.laser_sprite_list,
                                                  self.enemy_ships_sprite_list)
        if (position != None):
            self.make_explosion(position, scaling=constants.SPRITE_SCALING)
            self.create_ship('enemy')

        # If the player ship collides with an enemy ship trigger a big explosion
        # and spawn a new player and enemy.
        position = self.check_for_list_collisions(self.player_ship_sprite_list,
                                                  self.enemy_ships_sprite_list)
        if (position != None):
            self.make_explosion(position)
            self.create_ship('player')
            self.create_ship('enemy')

        # Update the enemy ships with the player ship's current position.
        for enemy_ship in self.enemy_ships_sprite_list:
            enemy_ship.target_x = self.player_ship.center_x
            enemy_ship.target_y = self.player_ship.center_y

        # Update everything on each frame.
        self.laser_sprite_list.update()
        self.enemy_ships_sprite_list.update()
        self.player_ship_sprite_list.update()
        self.explosion_sprite_list.update()

    def on_key_press(self, key, modifiers):
        # Ignore keyboard input if the player ship is spawning.
        if (self.player_ship.spawning == False):
            if (key == arcade.key.W):
                self.player_ship.thrust = constants.PLAYER_SHIP_THRUST
            elif (key == arcade.key.S):
                self.player_ship.thrust = -constants.PLAYER_SHIP_THRUST
            elif (key == arcade.key.A):
                # Persist the state of the left turning key
                self.is_left_pressed = True
                self.player_ship.change_angle = 3
            elif (key == arcade.key.D):
                # Persist the state of the right turning key
                self.is_right_pressed = True
                self.player_ship.change_angle = -3
            elif (key == arcade.key.ENTER):
                self.fire_weapon(self.player_ship)

    def on_key_release(self, key, modifiers):
        # Handles the key release event.
        # If the left or right turn keys have been released, check if the other
        # turning key is still pressed. If so, turn the ship in the other
        # direction. Otherwise stop turning.
        if (key == arcade.key.A):
            self.is_left_pressed = False
            if (self.is_right_pressed):
                self.player_ship.change_angle = -3
            else:
                self.player_ship.change_angle = 0
        elif (key == arcade.key.D):
            self.is_right_pressed = False
            if (self.is_left_pressed):
                self.player_ship.change_angle = 3
            else:
                self.player_ship.change_angle = 0
        # Kill the ship's thrust if the forward or backward keys are released.
        elif (key == arcade.key.W or key == arcade.key.S):
            self.player_ship.thrust = 0
            self.player_ship.drag = constants.PLAYER_SHIP_DRAG

    def fire_weapon(self, ship):
        # Break the laws of physics by adding the speed of the ship to the
        # speed of the laser. (Looks better than having a constant laser speed)
        laser_speed = ship.speed + constants.LASER_SPEED

        # Adjust the laser position a little toward the front of the ship.
        x = ship.center_x + math.cos(math.radians(ship.angle)) * 20
        y = ship.center_y + math.sin(math.radians(ship.angle)) * 20

        # Create the laser object.
        laser = Laser(constants.ENEMY_LASER_FILENAME, (x, y), laser_speed,
                      ship.angle)

        self.laser_sprite_list.append(laser)

    def check_for_list_collisions(self, list_1, list_2):
        # If a sprite in the first list collides with a sprite in the second
        # list, remove both sprites from their respective lists. Return the
        # position of the sprite in the second list or None if there was no
        # collision.
        position = None

        for sprite in list_1:
            hit_list = sprite.collides_with_list(list_2)
            if (len(hit_list) > 0):
                position = hit_list[0].position
                sprite.remove_from_sprite_lists()
                for hit in hit_list:
                    hit.remove_from_sprite_lists()

        return position

    def make_explosion(self, position, scaling=1):
        # Create an explosion at the specified x y position.
        explosion = Explosion(position, scaling)
        self.explosion_sprite_list.append(explosion)

    def create_ship(self, ship_type=''):
        if (ship_type == ''):
            return

        if (ship_type == 'player'):
            self.player_ship = PlayerShipSprite(constants.PLAYER_SHIP_FILENAME,
                                                constants.PLAYER_SHIP_SCALING)
            self.player_ship_sprite_list.append(self.player_ship)
        elif (ship_type == 'enemy'):
            self.enemy_ship = EnemyShipSprite(
                scale=constants.ENEMY_SHIP_SCALING)
            self.enemy_ships_sprite_list.append(self.enemy_ship)
    def title_screen_loop(self):
        self.current_screen = 'title'
        self.sector = Sector(self.screen_width, self.screen_height, self.buffer)
        self.starfield = Starfield(self.sector, max_stars=50)
        self.nebula = Nebula(self.sector, r_factor=random(), g_factor=random(), b_factor=random(), seed=randrange(1,1000000))
        self.ships = [ [ Ship(self.sector, 0, 0), [self.screen_width/2-16, self.screen_height/2-8] ] for i in range(1) ]

        done = False
        xpos = 0.0
        speed = 3
        galaxy_starting_seed = str(randrange(1,1000000))
        cursor_blinked = 0.0
        cursor = collections.deque(['|', ''])

        title = [
            ' _    _      _ _',
            '| |  | |    | (_)',
            '| |__| | ___| |_  ___  _ __   __ _ _   _ ___  ___',
            '|  __  |/ _ \\ | |/ _ \\| \'_ \\ / _` | | | / __|/ _ \\',
            '| |  | |  __/ | | (_) | |_) | (_| | |_| \\__ \\  __/',
            '|_|  |_|\\___|_|_|\\___/| .__/ \\__,_|\\__,_|___/\\___|',
            '                      | |',
            '                      |_|',
        ]

        while not done:
            libtcod.sys_check_for_event(libtcod.KEY_PRESSED|libtcod.KEY_RELEASED|libtcod.EVENT_MOUSE, self.key, self.mouse)

            self.starfield.scroll(0.0, speed)
            self.starfield.draw()

            self.sector.update_visibility(xpos, 0)
            xpos += speed

            self.nebula.draw()

            for ship, position in self.ships:
                # ship.heading += math.radians(10)
                # if math.degrees(ship.heading) > 350:
                #     ship.heading = 0
                ship.draw(startx=position[0], starty=position[1], hq2x=True)

            self.buffer.blit(self.console)

            t = time.clock()
            if t > cursor_blinked + 0.5:
                cursor_blinked = t
                cursor.rotate()

            for index, line in enumerate(title):
                libtcod.console_print_ex(self.console, (self.screen_width/2)-26, 10+index, libtcod.BKGND_NONE, libtcod.LEFT, line)

            libtcod.console_print_ex(self.console, 1, self.screen_height-2, libtcod.BKGND_NONE, libtcod.LEFT, "Starting Seed: {0}{1}".format(galaxy_starting_seed, cursor[0]))
            libtcod.console_blit(self.console, 0, 0, self.screen_width, self.screen_height, 0, 0, 0)

            libtcod.console_flush()

            self.buffer.clear(self.sector.background[0], self.sector.background[1], self.sector.background[2])

            # player_action = self.handle_keys_titlescreen()
            if self.key.pressed and self.key.vk == libtcod.KEY_ESCAPE:
                exit(0)
            elif self.key.pressed and self.key.vk == libtcod.KEY_ENTER:
                done = True
            elif self.key.pressed and self.key.vk == libtcod.KEY_BACKSPACE:
                if galaxy_starting_seed:
                    galaxy_starting_seed = galaxy_starting_seed[:-1]
            elif self.key.pressed:
                key_character = chr(self.key.c)
                if key_character in '1234567890':
                    galaxy_starting_seed += key_character
                elif key_character == 'G':
                    for ship, position in self.ships:
                        ship.ship_value = getrandbits(32)
                        ship.load_ship_sprites()

        ship_value = self.ships[0][0].ship_value
        del(self.ships)
        return int(galaxy_starting_seed), ship_value
class Game:
    def __init__(self, screen_width=120, screen_height=70):
        self.screen_width = screen_width
        self.screen_height = screen_height

        libtcod.console_init_root(self.screen_width, self.screen_height, 'Heliopause', False)

        self.buffer = libtcod.ConsoleBuffer(self.screen_width, self.screen_height)
        self.console = libtcod.console_new(self.screen_width, self.screen_height)

        self.galaxy_map_console = libtcod.console_new(self.screen_width, self.screen_height)

        self.set_minimap(20)

        self.targeting_width = 20
        self.targeting_height = 26
        self.targeting_buffer  = libtcod.ConsoleBuffer(self.targeting_width, self.targeting_height)
        self.targeting_console = libtcod.console_new(self.targeting_width, self.targeting_height)
        libtcod.console_set_default_foreground(self.targeting_console, libtcod.white)
        libtcod.console_set_default_background(self.targeting_console, libtcod.black)

        self.ship_info_width = 20
        self.ship_info_height = 8
        self.ship_info_buffer  = libtcod.ConsoleBuffer(self.ship_info_width, self.ship_info_height)
        self.ship_info_console = libtcod.console_new(self.ship_info_width, self.ship_info_height)
        libtcod.console_set_default_foreground(self.ship_info_console, libtcod.white)
        libtcod.console_set_default_background(self.ship_info_console, libtcod.black)

        self.message_height = 4
        self.message_width = self.screen_width
        self.messages = collections.deque([])
        self.message_console = libtcod.console_new(self.message_width, self.message_height)
        libtcod.console_set_default_foreground(self.message_console, libtcod.white)
        libtcod.console_set_default_background(self.message_console, libtcod.black)

        self.landing_screen_width = self.screen_width / 2 - 2
        self.landing_screen_height = self.screen_height - 4
        self.landing_console = libtcod.console_new(self.landing_screen_width, self.landing_screen_height)
        libtcod.console_set_default_foreground(self.landing_console, libtcod.white)
        libtcod.console_set_default_background(self.landing_console, libtcod.black)

        self.mouse = libtcod.Mouse()
        self.key = libtcod.Key()

        galaxy_seed, ship_value = self.title_screen_loop()

        # Loading Screen
        libtcod.console_set_default_background(self.console, libtcod.black)
        libtcod.console_clear(self.console)

        self.galaxy = Galaxy(self.screen_width, self.screen_height, seed=galaxy_seed)
        self.sector, self.starfield, self.nebula = self.galaxy.sectors[self.galaxy.current_sector].load_sector(self.console, self.buffer)

        starting_planet = self.sector.planets[randrange(1, len(self.sector.planets))]
        self.player_ship = Ship(self.sector, starting_planet.sector_position_x, starting_planet.sector_position_y, ship_value=ship_value)
        self.add_message("Taking off from {0}".format(starting_planet.name))

        self.current_screen = 'flight'

        # self.add_message("Nebula Colors: r:{0} g:{1} b:{2}".format(
        #     round(self.nebula.r_factor,2),
        #     round(self.nebula.g_factor,2),
        #     round(self.nebula.b_factor,2)))

    def title_screen_loop(self):
        self.current_screen = 'title'
        self.sector = Sector(self.screen_width, self.screen_height, self.buffer)
        self.starfield = Starfield(self.sector, max_stars=50)
        self.nebula = Nebula(self.sector, r_factor=random(), g_factor=random(), b_factor=random(), seed=randrange(1,1000000))
        self.ships = [ [ Ship(self.sector, 0, 0), [self.screen_width/2-16, self.screen_height/2-8] ] for i in range(1) ]

        done = False
        xpos = 0.0
        speed = 3
        galaxy_starting_seed = str(randrange(1,1000000))
        cursor_blinked = 0.0
        cursor = collections.deque(['|', ''])

        title = [
            ' _    _      _ _',
            '| |  | |    | (_)',
            '| |__| | ___| |_  ___  _ __   __ _ _   _ ___  ___',
            '|  __  |/ _ \\ | |/ _ \\| \'_ \\ / _` | | | / __|/ _ \\',
            '| |  | |  __/ | | (_) | |_) | (_| | |_| \\__ \\  __/',
            '|_|  |_|\\___|_|_|\\___/| .__/ \\__,_|\\__,_|___/\\___|',
            '                      | |',
            '                      |_|',
        ]

        while not done:
            libtcod.sys_check_for_event(libtcod.KEY_PRESSED|libtcod.KEY_RELEASED|libtcod.EVENT_MOUSE, self.key, self.mouse)

            self.starfield.scroll(0.0, speed)
            self.starfield.draw()

            self.sector.update_visibility(xpos, 0)
            xpos += speed

            self.nebula.draw()

            for ship, position in self.ships:
                # ship.heading += math.radians(10)
                # if math.degrees(ship.heading) > 350:
                #     ship.heading = 0
                ship.draw(startx=position[0], starty=position[1], hq2x=True)

            self.buffer.blit(self.console)

            t = time.clock()
            if t > cursor_blinked + 0.5:
                cursor_blinked = t
                cursor.rotate()

            for index, line in enumerate(title):
                libtcod.console_print_ex(self.console, (self.screen_width/2)-26, 10+index, libtcod.BKGND_NONE, libtcod.LEFT, line)

            libtcod.console_print_ex(self.console, 1, self.screen_height-2, libtcod.BKGND_NONE, libtcod.LEFT, "Starting Seed: {0}{1}".format(galaxy_starting_seed, cursor[0]))
            libtcod.console_blit(self.console, 0, 0, self.screen_width, self.screen_height, 0, 0, 0)

            libtcod.console_flush()

            self.buffer.clear(self.sector.background[0], self.sector.background[1], self.sector.background[2])

            # player_action = self.handle_keys_titlescreen()
            if self.key.pressed and self.key.vk == libtcod.KEY_ESCAPE:
                exit(0)
            elif self.key.pressed and self.key.vk == libtcod.KEY_ENTER:
                done = True
            elif self.key.pressed and self.key.vk == libtcod.KEY_BACKSPACE:
                if galaxy_starting_seed:
                    galaxy_starting_seed = galaxy_starting_seed[:-1]
            elif self.key.pressed:
                key_character = chr(self.key.c)
                if key_character in '1234567890':
                    galaxy_starting_seed += key_character
                elif key_character == 'G':
                    for ship, position in self.ships:
                        ship.ship_value = getrandbits(32)
                        ship.load_ship_sprites()

        ship_value = self.ships[0][0].ship_value
        del(self.ships)
        return int(galaxy_starting_seed), ship_value

    def set_minimap(self, size):
        self.minimap_width  = size+3
        self.minimap_height = size+3
        self.minimap_buffer  = libtcod.ConsoleBuffer(self.minimap_width, self.minimap_height)
        self.minimap_console = libtcod.console_new(self.minimap_width, self.minimap_height)
        libtcod.console_set_default_foreground(self.minimap_console, libtcod.white)
        libtcod.console_set_default_background(self.minimap_console, libtcod.black)

    def new_sector(self):
        index, distance = self.sector.closest_planet(self.player_ship)
        # if self.sector.distance_from_center(self.player_ship) > 500:
        if distance > 500:
            fade_speed = 10
            # Fade out
            for fade in range(255,0,-1*fade_speed):
                libtcod.console_set_fade(fade,libtcod.black)
                libtcod.console_flush()

            self.sector.clear_selected_planet()

            self.galaxy.current_sector = self.galaxy.sectors[self.galaxy.current_sector].neighbors[self.galaxy.targeted_sector_index]
            self.galaxy.targeted_sector_index = 0
            self.sector, self.starfield, self.nebula = self.galaxy.sectors[self.galaxy.current_sector].load_sector(self.console, self.buffer)

            self.player_ship.sector = self.sector
            self.player_ship.dead_stop()
            self.player_ship.velocity = int(self.player_ship.speed_limit / 2)
            self.player_ship.face_system_center()
            self.player_ship.about_face()
            self.player_ship.velocity_angle = self.player_ship.heading
            self.player_ship.apply_thrust()

            self.clear_messages()
            self.add_message("Arriving in {0}".format(self.galaxy.sectors[self.galaxy.current_sector].name))
            # self.add_message("Nebula Colors: r:{0} g:{1} b:{2}".format(
            #     round(self.nebula.r_factor,2),
            #     round(self.nebula.g_factor,2),
            #     round(self.nebula.b_factor,2)))

            # Fade in
            libtcod.console_set_fade(0,libtcod.black)
            self.render_all()
            for fade in range(0,255,fade_speed):
                libtcod.console_set_fade(fade,libtcod.black)
                libtcod.console_flush()

        else:
            self.add_message("You are not far enough from the nearest planet to jump")

    def check_for_collisions(self):
        asteroid_to_delete = None
        for index, asteroid in enumerate(self.sector.asteroids):
            for p in self.sector.particles:
                if p.bullet:
                    if asteroid.sector_position_x < p.sector_position_x < asteroid.sector_position_x+asteroid.width and \
                       asteroid.sector_position_y+1 < p.sector_position_y < asteroid.sector_position_y+1+asteroid.width:
                        asteroid.hp -= p.damage
                        if asteroid.hp < 0:
                            for a in range(0, 60):
                                self.sector.add_particle(
                                    ExplosionFireBall(
                                        starting_index       = a/10,
                                        sector               = self.sector,
                                        x                    = p.x,
                                        y                    = p.y,
                                        sector_position_x    = p.sector_position_x,
                                        sector_position_y    = p.sector_position_y,
                                        angle                = randrange(0, 359),
                                        velocity             = random() * randrange(1,3)))
                            # self.sector.asteroids.remove(asteroid)
                            asteroid_to_delete = index
                        else:
                            self.sector.add_particle(
                                Fire(
                                    sector               = self.sector,
                                    x                    = p.x,
                                    y                    = p.y,
                                    sector_position_x    = p.sector_position_x,
                                    sector_position_y    = p.sector_position_y))
                        # delete the bullet that hit
                        self.sector.particles.remove(p)
        if asteroid_to_delete is not None:
            self.sector.asteroids.pop(asteroid_to_delete)

    def render_all(self):
        if self.player_ship.velocity > 0.0:
            self.starfield.scroll( self.player_ship.velocity_angle, self.player_ship.velocity )

        self.starfield.draw()

        self.sector.update_particle_positions()
        self.sector.scroll_particles( self.player_ship.velocity_angle, self.player_ship.velocity )

        self.sector.update_visibility(self.player_ship.sector_position_x, self.player_ship.sector_position_y)

        self.nebula.draw()

        for planet in self.sector.planets:
            planet.draw()

        for asteroid in self.sector.asteroids:
            asteroid.draw()
        self.check_for_collisions()

        for particle in self.sector.particles:
            particle.draw()

        self.player_ship.draw()

        if self.sector.selected_planet is not None or self.sector.selected_asteroid is not None:
            self.sector.update_selected_planet_distance(self.player_ship)
            if self.sector.selected_planet_distance() > (self.screen_height/2.0):
                self.player_ship.draw_target_arrow(self.sector.selected_planet_angle)
                # self.sector.draw_target_arrow(self.player_ship)

        self.buffer.blit(self.console)
        libtcod.console_blit(self.console, 0, 0, self.screen_width, self.screen_height, 0, 0, 0)

        if self.sector.selected_planet is not None or self.sector.selected_asteroid is not None:
            # Target window
            planet = self.sector.get_selected_planet()
            planet.draw_target_picture(self.targeting_buffer, 4, 2)
            self.targeting_buffer.blit(self.targeting_console)
            libtcod.console_print_frame(self.targeting_console, 0, 0, self.targeting_width, self.targeting_height, clear=False, flag=libtcod.BKGND_SET, fmt=0)

            name = textwrap.wrap(" Name: {0}".format(planet.name), width=self.targeting_width-4)
            libtcod.console_print_ex(self.targeting_console, 1, 16, libtcod.BKGND_SET, libtcod.LEFT,
                "\n  ".join(name)+"\n"
            )

            planet_class = planet.planet_class.title()
            if planet.star_class:
                planet_class += " ({0})".format(planet.star_class)

            extra_info = ""
            if planet.star_temp:
                extra_info = "\n Temp: {0} K\n".format(planet.star_temp)
            elif planet.planet_class == 'asteroid':
                extra_info = "\n HP: {0} \n".format(planet.hp)

            libtcod.console_print_ex(self.targeting_console, 1, 17+len(name), libtcod.BKGND_SET, libtcod.LEFT,
                ( " Class: {0}\n{1}\n"
                  " Distance: {2}\n"
                ).format(
                    planet_class,
                    extra_info,
                    int(self.sector.selected_planet_distance()),
                )
            )
            libtcod.console_blit(self.targeting_console, 0, 0, self.targeting_width, self.targeting_height, 0, 0, 0, 1.0, 0.25)

        # Ship Info
        libtcod.console_print_frame(self.ship_info_console, 0, 0, self.ship_info_width, self.ship_info_height, clear=True, flag=libtcod.BKGND_SET, fmt=0)
        libtcod.console_print_ex(self.ship_info_console, 1, 1, libtcod.BKGND_SET, libtcod.LEFT,
                ( "  Heading: {0}\n"
                  " Velocity: {1}\n"
                  " VelAngle: {2}\n"
                  "Particles: {3}\n"
                  "Ship\nSeed: {4}\n"
                  # "Nebula Position:\n"
                  # "l:{4} r:{5}\n"
                  # "t:{6} b:{7}\n"
                ).format(
                    round(math.degrees(self.player_ship.heading),2),
                    round(self.player_ship.velocity,2),
                    round(math.degrees(self.player_ship.velocity_angle),2),
                    len(self.sector.particles),
                    hex(self.player_ship.ship_value)
                    # self.nebula.left, self.nebula.right, self.nebula.top, self.nebula.bottom
            ).ljust(self.ship_info_width-2)
        )
        libtcod.console_blit(self.ship_info_console, 0, 0, self.ship_info_width, self.ship_info_height, 0, self.screen_width-self.ship_info_width, self.screen_height-self.ship_info_height-self.message_height, 1.0, 0.25)

        # Bottom Messages
        if len(self.messages) > 0:
            libtcod.console_print_ex(self.message_console, 0, 0, libtcod.BKGND_SET, libtcod.LEFT,
                    "\n".join([message.ljust(self.message_width) for message in self.messages]) )
            libtcod.console_blit(self.message_console, 0, 0, self.message_width, self.message_height, 0, 0, self.screen_height-self.message_height, 1.0, 0.25)

        # Minimap
        self.sector.draw_minimap(self.minimap_buffer, self.minimap_width, self.minimap_height, self.player_ship)
        self.minimap_buffer.blit(self.minimap_console)
        libtcod.console_print_frame(self.minimap_console, 0, 0, self.minimap_width, self.minimap_height, clear=False, flag=libtcod.BKGND_SET, fmt=0)
        libtcod.console_print_ex(self.minimap_console, 1, self.minimap_height-1, libtcod.BKGND_SET, libtcod.LEFT,
            ("[ {0} {1} ]").format(
                int(self.player_ship.sector_position_x),
                int(self.player_ship.sector_position_y),
            ).center(self.minimap_width-2, chr(196))
        )
        libtcod.console_blit(self.minimap_console, 0, 0, self.minimap_width, self.minimap_height, 0, self.screen_width-self.minimap_width, 0, 1.0, 0.25)

        libtcod.console_flush()
        self.buffer.clear(self.sector.background[0], self.sector.background[1], self.sector.background[2])

    def handle_keys(self):
        if self.key.vk == libtcod.KEY_UP:
            self.player_ship.throttle_open = self.key.pressed
        if self.key.vk == libtcod.KEY_DOWN:
            self.player_ship.reversing = self.key.pressed
        if self.key.vk == libtcod.KEY_LEFT:
            self.player_ship.turning_left = self.key.pressed
        if self.key.vk == libtcod.KEY_RIGHT:
            self.player_ship.turning_right = self.key.pressed

        if self.key.vk == libtcod.KEY_SPACE:
            self.player_ship.laser_firing = self.key.pressed

        if self.key.pressed and self.key.vk == libtcod.KEY_ENTER and self.key.lalt:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
        elif self.key.pressed and self.key.vk == libtcod.KEY_ESCAPE:
            return 1  #exit game
        elif self.key.pressed:
            key_character = chr(self.key.c)
            if key_character == 'l' and self.current_screen == 'flight':
                landed, message, planet_index = self.sector.land_at_closest_planet(self.player_ship)
                if message:
                    self.add_message(message)
                if landed:
                    self.landed_loop(planet_index)

            elif key_character == 'G':
                self.player_ship.ship_value = getrandbits(32)
                self.player_ship.load_ship_sprites()
            elif self.key.vk == libtcod.KEY_TAB:
                if self.current_screen == 'flight':
                    self.galaxy_map_loop()
                else:
                    return 1 # exit galaxy loop
            elif key_character == '\\' and self.current_screen == 'galaxy':
                self.galaxy.cycle_sector_target()

            elif key_character == 'm':
                if self.minimap_width == self.screen_height:
                    self.set_minimap(20)
                elif self.minimap_width == 23:
                    self.set_minimap(20 + (self.screen_height-20)/2)
                else:
                    self.set_minimap(self.screen_height-3)

            elif key_character == 'p':
                self.sector.cycle_planet_target(self.player_ship)
            elif key_character == 'P':
                self.sector.target_nearest_planet(self.player_ship)

            elif key_character == 't':
                self.sector.cycle_target(self.player_ship)
            elif key_character == 'T':
                self.sector.target_nearest_asteroid(self.player_ship)

            elif key_character == 'j' and self.current_screen == 'flight':
                self.new_sector()

            elif key_character == 'S':
                libtcod.sys_save_screenshot()
                self.add_message("Saved screenshot")


    def clear_messages(self):
        self.messages.clear()

    def add_message(self, message):
        if len(self.messages) == self.message_height:
            self.messages.popleft()
        self.messages.append(message)

    def galaxy_map_loop(self):
        self.current_screen = 'galaxy'
        done = False
        while not done:
            libtcod.sys_check_for_event(libtcod.KEY_PRESSED|libtcod.KEY_RELEASED|libtcod.EVENT_MOUSE, self.key, self.mouse)
            libtcod.console_clear(self.galaxy_map_console)

            self.starfield.draw()
            self.nebula.draw()
            self.galaxy.draw(self.buffer)
            self.buffer.blit(self.console)
            libtcod.console_blit(self.console, 0, 0, self.screen_width, self.screen_height, 0, 0, 0)

            # Galaxy Map Border/Frame
            libtcod.console_print_frame(self.galaxy_map_console, 0, 0, self.screen_width, self.screen_height,
                    clear=False, flag=libtcod.BKGND_SET, fmt=0)

            # Title in the center of the top border
            top_title = "[ Galaxy Map ]"
            libtcod.console_print_ex(self.galaxy_map_console,
                    (self.screen_width/2) - (len(top_title)/2),
                    0, libtcod.BKGND_SET, libtcod.LEFT, top_title)

            # Title in the center of the bottom border
            bottom_title = "[ Seed: {0} ]".format( self.galaxy.seed )
            libtcod.console_print_ex(self.galaxy_map_console,
                    (self.screen_width/2) - (len(bottom_title)/2),
                    self.screen_height-1, libtcod.BKGND_SET, libtcod.LEFT, bottom_title)

            # Extra info in upper right
            info = ("Current Sector: {0}\n"
                    "Target  Sector: {1}\n").format(
                self.galaxy.sectors[self.galaxy.current_sector].name,
                self.galaxy.sectors[ self.galaxy.sectors[self.galaxy.current_sector].neighbors[self.galaxy.targeted_sector_index] ].name
            )
            libtcod.console_print_ex(self.galaxy_map_console,
                    1, 1, libtcod.BKGND_SET, libtcod.LEFT, info)

            libtcod.console_blit(self.galaxy_map_console, 0, 0, self.screen_width, self.screen_height, 0, 0, 0, 1.0, 0.25)
            libtcod.console_flush()

            self.buffer.clear(self.sector.background[0], self.sector.background[1], self.sector.background[2])

            player_action = self.handle_keys()
            if player_action == 1:
                done = True

        self.current_screen = 'flight'

    def landed_loop(self, planet_index):
        self.current_screen = 'landed'
        done = False
        planet = self.sector.planets[planet_index]
        while not done:
            libtcod.sys_check_for_event(libtcod.KEY_PRESSED|libtcod.KEY_RELEASED|libtcod.EVENT_MOUSE, self.key, self.mouse)

            self.starfield.draw()
            self.nebula.draw()

            planet.render_detail()
            self.buffer.blit(self.console)

            libtcod.console_blit(self.console, 0, 0, self.screen_width, self.screen_height, 0, 0, 0)

            libtcod.console_print_frame(self.landing_console, 0, 0, self.landing_screen_width, self.landing_screen_height, clear=True, flag=libtcod.BKGND_SET, fmt=0)
            title = "[ Landed at {0} ]".format(planet.name)
            libtcod.console_print_ex(self.landing_console,
                    (self.landing_screen_width/2) - (len(title)/2),
                    0, libtcod.BKGND_SET, libtcod.LEFT, title)
            libtcod.console_print_ex(self.landing_console,
                    2, 2, libtcod.BKGND_SET, libtcod.LEFT,
                    "Class: {0}".format(planet.planet_class.title()))
            libtcod.console_print_ex(self.landing_console,
                    2, 3, libtcod.BKGND_SET, libtcod.LEFT,
                    "Diameter: {0}".format(planet.width))
            libtcod.console_print_ex(self.landing_console,
                    2, 4, libtcod.BKGND_SET, libtcod.LEFT,
                    "Seed: {0}".format(planet.seed))
            libtcod.console_blit(self.landing_console, 0, 0, self.landing_screen_width, self.landing_screen_height, 0, self.screen_width/2, 2, 1.0, 0.25)

            libtcod.console_flush()
            self.buffer.clear(self.sector.background[0], self.sector.background[1], self.sector.background[2])

            player_action = self.handle_keys()
            if player_action == 1:
                self.add_message("Taking off from {0}".format(planet.name))
                self.current_screen = 'flight'
                done = True

    def main_loop(self):
        while not libtcod.console_is_window_closed():
            libtcod.sys_check_for_event(libtcod.KEY_PRESSED|libtcod.KEY_RELEASED|libtcod.EVENT_MOUSE, self.key, self.mouse)

            self.render_all()

            player_action = self.handle_keys()
            if player_action == 1:
                break

            if self.player_ship.throttle_open:
                self.player_ship.apply_thrust()

            if self.player_ship.laser_firing:
                self.player_ship.fire_laser()

            if self.player_ship.reversing:
                self.player_ship.reverse_direction()
            elif self.player_ship.turning_left:
                self.player_ship.turn_left()
            elif self.player_ship.turning_right:
                self.player_ship.turn_right()