Source

Fat x Fast / FatxFast / scenes / gamescene.py

Full commit

# This file is part of FatxFast.
#
#    FatxFast is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    FatxFast is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with FatxFast.  If not, see <http://www.gnu.org/licenses/>.

# Versioning based on: 
# http://en.wikipedia.org/wiki/Versioning#Designating_development_stage
__author__ = "dryatu (c) 2013"
__version__ = "1.2.5"

import pygame
from FatxFast import camera
from FatxFast.scenes import basescene
from FatxFast.objects import triggers
from FatxFast.objects import buffs
from FatxFast.modes import (classicmode, practicemode, 
    timedmode, mapmode, multimode)
from FatxFast.tilemap import gamemap
from FatxFast import levelsystem
from FatxFast import pointsystem
from FatxFast.gamesave import GameSave
from FatxFast.gui.hud.hud import GameHud
from FatxFast.fileio import LOGGER
import threading
import copy

class GameScene(basescene.Scene):
    
    def __init__(self, manager, **kwargs):
        manager.clear()
        super(GameScene, self).__init__(manager, **kwargs)
        self.game = manager.game        

        #self.game.audio.load_sound("coffeedrink.wav")
        self.game.audio.stop_music()
        self.game.audio.load_music("swooprandomperse3.mp3")
        self.game.audio.play_music(-1) 
        # Create an empty save if one is not supplied
        if kwargs.get("save") is None:
            self.save = GameSave()
            self.save.game["mode"] = kwargs.get("mode", "timedmode")
            self.save.game["time"] = kwargs.get("time")
        else:
            self.save = kwargs["save"]
        self.tilemap = gamemap.TileMap()

        self.players = camera.CameraGroup()
        
        self.levelsystem = levelsystem.LevelSystem(self)
        self.pointsystem = pointsystem.PointSystem(self)
        self.levelparser = levelsystem.LevelSchemeParser("levels.xml")
        self.levelsystem.levels = self.levelparser.load_mode_levels(
            self.save.game["mode"])
        self.time = self.save.game["time"]
        self.levelsystem.leveltime = self.save.game["leveltime"]
        self.levelsystem.level = self.save.game["level"]
        self.paused = False

        self.gamemodes = {
            "timedmode":timedmode.TimedMode,
            "classicmode":classicmode.ClassicMode,
            "practicemode":practicemode.PracticeMode,
            "multimode":multimode.MultiMode}
       

        self.hud = GameHud(self, 
            **self.manager.sceneparser.templates["gamehud"])
        self._mode = None
        self.mode = self.gamemodes[self.save.game["mode"]](self, **kwargs)
        self.gamemode = self._mode
        self.mapmode = mapmode.MapMode(self)
    
    def add_player(self, player, camera):
        self.hud.add_player(player, camera)
        self.players.add(player)
            
    def close_map(self):
        self.mode = self.gamemode
        self.get_widget("minimap").toggle_fullscreen()

    def create_character(self, charatype, pos, add_to_world=False):
        character = charatype(self.tilemap, x=pos[0], y=pos[1])
        if add_to_world:
            self.tilemap.world.add(character)
        return character

    def key_pressed(self, key, utf, mod):
        if key == pygame.K_ESCAPE:
            self.manager.push_scene("menuscene", 
                bg=self.game.graphics.screen.copy(),
                gamescene=self, name="gamemenuscene", type="gamemenuscene")
        elif (key == pygame.K_F1 and mod & pygame.KMOD_LSHIFT and
            __debug__):
            if self.game.graphifier.is_running():
                self.game.graphifier.stop()
            else:
                self.game.run_thread(
                    self.game.create_thread(self.game.graphifier.run))
                self.game.graphifier.add_animated_line(
                    self.gamemode.player1.physics, 
                        "speedvector", further_attr="x", 
                        layout="r-")
                self.game.graphifier.add_animated_line(
                    self.gamemode.player1.physics, 
                        "speedvector", further_attr="y")
         
    @property
    def mode(self):
        return self._mode
    
    @mode.setter
    def mode(self, value):
        if self.mode:
            self.mode.pause()
        value.resume()
        self._mode = value

    def open_map(self):
        self.mode = self.mapmode
        self.get_widget("minimap").toggle_fullscreen()
    
    def pause(self):
        super(GameScene, self).pause()
        self.mode.pause()
        self.paused = True
    
    def remove_players(self):
        for player in self.players:
            player.kill()
        self.hud.remove_players()

    def resume(self):
        super(GameScene, self).resume()
        self.mode.start()
        self.game.clock = pygame.time.Clock()
        self.paused = False

    def save_game(self, index):
        current_mode = self.mode.__class__.__name__.lower()
        if current_mode == "mapmode":
            return False
        save= GameSave()
        settings = self.levelsystem.level_complexity.copy() 
        if "coffee_count" in self.tilemap.properties:
            self.tilemap.properties["coffee_count"] = len(
                [entity for entity in self.tilemap.world 
                    if entity.entity_id is triggers.COFFEE_ID])
        settings.update(self.tilemap.properties)
        save.game["level_complexity"] = settings
        save.game["time"] = self.time
        save.game["mode"] = current_mode
        save.game["leveltime"] = self.levelsystem.leveltime
        save.game["level"] = self.levelsystem.level
        
        # Save player related info
        for player in self.players:
            save.playerdata[player.name] = {}
#            save.playerdata[player.name]["maps_left"] = player.maps_left
            save.playerdata[player.name]["points"] = player.points
            save.playerdata[player.name]["pos"] = player.get_position()
#            save.playerdata[player.name]["turbo"] = player.get_turbo()
            if player.buffs:
                save.playerdata[player.name]["buffs"] = {}
                for buff in player.buffs:
                    save.playerdata[player.name]["buffs"][id(buff)] = \
                        (buff.entity_id, buff.duration)
            if player.items:
                save.playerdata[player.name]["items"] = {}
                for item in player.items.values():
                    if item.entity_id == buffs.COFFEE_BUFF_ID:
                        save.playerdata[player.name]["items"][item.name] = \
                            (item.entity_id, item.duration)
        
        # Save spawnarea variables.

        for spawnarea in self.tilemap.spawnareas:
            save.mapdata[spawnarea.name] = {
                "spawntimer":spawnarea.spawntimer,
                "entity_count":spawnarea.entity_count}

        save.mapdata["items"] = {}
        for item in self.tilemap.world:
            if item.entity_id == triggers.COFFEE_ID:
                save.mapdata["items"][item.name] = {
                    "name": item.name,
                    "entity_id": item.entity_id,
                    "x": item.rect.x,
                    "y": item.rect.y}


        save.mapdata["minimap_overlay"] = pygame.image.tostring(
            self.get_widget("minimap").overlay_surf, 'RGBA')

        self.game.savemanager.edit_save(index, save)
        LOGGER.log_message("Game saved at index {0}".format(index))
    
    def start(self):
        super(GameScene, self).start()
        self.game.clock = pygame.time.Clock()
        self.paused = False
    
    def update(self, dt):
        if not self.paused:
            self.mode.update(dt)
        self.hud.update(dt)
        super(GameScene, self).update(dt)