The screenshot mechanism

I have just completed the screenshot mechanism for this latest pygame project. Basically, we will need to edit a few files in order to implement that mechanism.

The first file we need to edit is the scene class which will show all the screenshots that player has taken when he presses on the s key during the game stage!

from BgSprite import BgSprite
from GameSprite import GameSprite
from pygame.locals import *
from pygame import math as mt
import pygame

class Scene(object):

    def __init__(self, scene):

        self.scene = scene
        self.screen_folder = 'Screen/'
        self.next_button = 'Asset/back.png'
        self.previous_button = 'Asset/back.png'
        self.home_button = 'Asset/back.png'

        self.bg_rect = Rect(0, 0, 640, 640)
        self.next_button_rect = Rect(0, 0,  40, 30)
        self.previous_button_rect = Rect(0, 0, 40, 30)
        self.home_button_rect = Rect(0, 0, 40, 30)
        self.count = 0
        self.next = 1
        self.open_file()
        self.setup()

        self.previous_button_sprite = GameSprite(self.previous_button, self.previous_button_rect)
        self.next_button_sprite = GameSprite(self.next_button, self.next_button_rect)
        self.sprite_home_button = GameSprite(self.home_button, self.home_button_rect)


        self.previous_button_surface = self.previous_button_sprite.getImage() # get the button sprite surface
        self.next_button_surface = self.next_button_sprite.getImage()  # get the button sprite surface
        self.home_button_surface = self.sprite_home_button.getImage()  # get the button sprite surface

        self.draw_pos = mt.Vector2(0, 0)
        self.draw_next_button_pos = mt.Vector2(597, 330)
        self.draw_previous_button_pos = mt.Vector2(3, 344)
        self.draw_home_button_pos = mt.Vector2(10, 590)

    def open_file(self):

        try:
            f = open("Screen/count.txt", "r")

            try:
                if f.mode == 'r':
                    self.f1 = f.readlines()
                    for x in self.f1:
                        self.count = int(x)
            finally:
                f.close()


        except IOError:
            print('Error')

    def setup(self):

        if(self.count > 0):
            self.general_image = 'Screen/' + str(self.next) + 'game.png'
        else:
            self.general_image = 'Asset/general.png'

        self.screen_sprite = BgSprite(self.general_image, self.bg_rect)
        self.screen_surface = self.screen_sprite.getImage()  # get the screen sprite surface


    def take_screen(self): # take screenshot
        self.count += 1
        self.file_path = 'Screen/' + str(self.count) + 'game.png'
        pygame.image.save(self.scene, self.file_path)
        self.save_file()

    def save_file(self):
        try:

            f = open("Screen/count.txt", "w+")
            try:
                f.write(str(self.count))
            finally:
                f.close()
        except IOError:
            print('cannot save a file')

    def set_next_image(self):

        self.next += 1
        if(self.next > self.count):
            self.next = self.count

        self.setup()

    def set_previous_image(self):

        self.next -= 1

        if(self.next <= 0):
            self.next = 1

        self.setup()

    def draw(self):

        self.scene.blit(self.screen_surface, self.draw_pos)  # draw a game scene sprite
        self.scene.blit(self.previous_button_surface, self.draw_previous_button_pos)  # draw a previous button sprite
        self.scene.blit(pygame.transform.flip(self.next_button_surface, True, False), self.draw_next_button_pos) # draw a next button sprite
        self.scene.blit(self.home_button_surface, self.draw_home_button_pos)  # draw a button sprite

        pygame.display.flip()

The next file we need to edit is the game manager class where it will ask the scene class to display the screenshot when the game state has been set to the scene state or to set the game state to the scene state if the user has pressed on the scene button on the main menu page. Besides that, it will also ask the scene class to take a screenshot and then saves that screenshot file when the user has pressed on the s key during the game stage.

from EnemyManager import EnemyManager
from Overlap import Overlap
from ExplosionManager import ExplosionManager
from Score import Score
from StartScene import StartScene
from pygame.locals import *
from LevelManager import LevelManager
import pygame
import webbrowser
from Scene import Scene
from BackGroundSprite import BackGroundSprite
from BoySprite import BoySprite
from ManaManager import ManaManager

class GameManager(object):

    def __init__(self, scene):

        self.scene = scene
        self.load_music()
        self.play_music()
        self.overlap_manager = Overlap()
        self.level_manager = LevelManager(self)
        self.level_manager.set_level()
        self.setup(self.level_manager.get_level())
        self.start_scene = StartScene(scene, self.level_manager)
        self.pause = False # flag to pause the game
        self.game_scene = Scene(self.scene)

        #game state
        self.LOAD = 0
        self.GAME = 1
        self.OVER = 2
        self.NEXT = 3
        self.WIN = 4
        self.ABOUT = 5
        self.MANUAL = 6
        self.PAUSE = 7
        self.SCORE = 8
        self.SCENE = 9

        self.state = self.LOAD

    def setup(self, game_level):

        self.game_level = game_level
        self.score_manager = Score(self.scene, self.level_manager)
        self.background = BackGroundSprite(game_level, self.scene)
        self.enemy_manager = EnemyManager(self.scene, game_level)
        self.mana_manager = ManaManager(self.scene, game_level)
        self.boy_sprite = BoySprite(self.scene, game_level, self.enemy_manager, self.mana_manager, self.level_manager)
        self.explosion_manager = ExplosionManager(self.scene)

    def loop(self):

        if(self.state == self.LOAD):
            self.start_scene.draw(self.state)
        elif(self.state == self.PAUSE or self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.MANUAL or self.state == self.SCORE):
            self.start_scene.draw(self.state)
        elif(self.state == self.SCENE):
            self.game_scene.draw()
        elif(self.state == self.GAME):

            self.update()
            self.draw()

    def isAreaClick(self, x, y):
        if (self.state == self.LOAD or self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.SCORE or self.state == self.SCENE or self.state == self.MANUAL or self.state == self.PAUSE):
            self.rect = Rect(177, 274, 306, 112) # the position of the play button on the scene
            self.rect_play = Rect(229, 200, 200, 53)  # the position of the play button on the home scene
            self.rect_about = Rect(229, 263, 200, 53)  # the position of the about button on the home scene
            #self.rect_exit = Rect(229, 456, 200, 53)  # the position of the exit button on the home scene
            self.rect_pause_home = Rect(229, 263, 200, 53)  # the position of the home button on pause scene
            self.rect_score = Rect(229, 328, 200, 53)  # the position of the score button on the home scene
            self.rect_manual = Rect(229, 393, 200, 53)  # the position of the manual button on the home scene
            self.rect_scene = Rect(229, 519, 200, 53)  # the position of the manual button on the home scene
            self.rect_back = Rect(10, 590, 40, 30)  # the position of the back button on the home scene
            self.rect_sound = Rect(10, 600, 30, 30) # the position of the sound button on the home scene
            self.rect_scene_next = Rect(597, 330, 40, 30)  # the position of the next scene button on scene
            self.rect_scene_previous = Rect(3, 344, 40, 30)  # the position of the previous scene button on scene

            if(self.rect.collidepoint(x, y) and (self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN)):
                self.state = self.GAME
            elif(self.rect_play.collidepoint(x,y) and self.state == self.LOAD):
                self.state = self.GAME
            elif (self.rect_play.collidepoint(x, y) and self.state == self.PAUSE):
                self.state = self.GAME
            elif (self.rect_about.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.ABOUT
            elif (self.rect_score.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.SCORE
            elif (self.rect_scene.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.SCENE
            elif (self.rect_back.collidepoint(x, y) and self.state == self.SCENE):
                self.state = self.LOAD
            elif (self.rect_scene_next.collidepoint(x, y) and self.state == self.SCENE):
                self.game_scene.set_next_image()
            elif (self.rect_scene_previous.collidepoint(x, y) and self.state == self.SCENE):
                self.game_scene.set_previous_image()
            elif (self.rect_pause_home.collidepoint(x, y) and self.state == self.PAUSE):

                self.state = self.LOAD
                self.setup(self.level_manager.get_level())
                self.save_level()

            elif (self.rect_manual.collidepoint(x, y) and self.state == self.LOAD):
                webbrowser.open_new('http://gamingdirectional.com/blog/2018/12/25/air-strike//')
            elif (self.rect_back.collidepoint(x, y) and (self.state == self.ABOUT or self.state == self.MANUAL or self.state == self.SCORE)):
                self.state = self.LOAD
            elif (self.rect_sound.collidepoint(x, y) and self.state == self.LOAD):

                if(self.start_scene.soundon == True):
                    self.start_scene.soundon = False
                    pygame.mixer_music.pause()
                else:
                    self.start_scene.soundon = True
                    pygame.mixer_music.unpause()

    def save_level(self):
        self.level_manager.save_level()

    def set_pause(self, pause):

        self.pause = pause
        if(self.pause == True):

            self.state = self.PAUSE

    def load_music(self):
        pygame.mixer_music.load('Music/winternight.ogg')

    def play_music(self):
        pygame.mixer_music.play(-1) #play the music infinite time

    def set_player_x(self, _x):
        if (self.state == self.GAME):
            self.boy_sprite.setX(_x)

    def save_scene(self):
        self.game_scene.take_screen()

    def set_player_y(self, _y):
        if (self.state == self.GAME):
            self.boy_sprite.setY(_y)

    def update(self):
        self.enemy_manager.update()
        self.mana_manager.update()
        self.boy_sprite.update()

    def draw(self):
        if(self.state == self.GAME):
            self.background.draw()
            #self.score_manager.draw()
            self.boy_sprite.draw()
            self.enemy_manager.draw()
            self.mana_manager.draw()
            pygame.display.flip()

The final file which we need to edit is the main file which we will add in the s key event which will make the game manager class to ask the scene class to save the game scene.

import pygame
from pygame.locals import *
from GameManager import GameManager

pygame.init()

size = width, height = 640, 640
pygame.display.set_caption("Amaze Boy")  # set the title of the window
screen = pygame.display.set_mode(size)
game_manager = GameManager(screen)
rect_exit = Rect(229, 456, 200, 53)  # the position of the exit button on the home scene
running = True
pygame.key.set_repeat(100, 40)

while running:

    for event in pygame.event.get():
        # when the user clicks on the 'x'
        if event.type == pygame.QUIT:
            game_manager.save_level()
            running = False

        # detect key press event
        if event.type == KEYDOWN:

            if (game_manager.state == 1):

                if event.key == K_LEFT:
                    game_manager.set_player_x(-2)
                elif event.key == K_RIGHT:
                    game_manager.set_player_x(2)
                elif event.key == K_UP:
                    game_manager.set_player_y(-2)
                elif event.key == K_DOWN:
                    game_manager.set_player_y(2)

        elif event.type == KEYUP:

            if (game_manager.state == 1):

                if event.key == K_LEFT:
                    game_manager.set_player_x(0)
                elif event.key == K_RIGHT:
                    game_manager.set_player_x(0)
                elif event.key == K_UP:
                    game_manager.set_player_y(0)
                elif event.key == K_DOWN:
                    game_manager.set_player_y(0)
                elif event.key == K_p:
                    game_manager.set_pause(True)  # set the pause state to true
                elif event.key == K_s: # take the game screenshot
                    game_manager.save_scene()

        elif event.type == pygame.MOUSEBUTTONDOWN:
            x, y = event.pos
            if (rect_exit.collidepoint(x, y) and game_manager.state == game_manager.LOAD):
                game_manager.save_level()
                running = False
            # 1 is the left mouse button
            elif event.button == 1:
                game_manager.isAreaClick(x, y)

    game_manager.loop()

If you run the above program again and when you press on the s key on your keyboard during the game stage then this program will take a screenshot and saves it for later use!

Like, share or follow me on Twitter will give me strength to continue developing more pygame projects in the future.

Leave a Reply

Your email address will not be published. Required fields are marked *