Курсовые - Разработка игры Арконоид на Python

ПРИЛОЖЕНИЕ А

Листинг кода

 

import menu

 

 

if __name__ == "__main__":

    m = menu.Menu()

import random

 

 

class Ball:

 

    def __init__(self, screen_width, screen_height, x=-1, y=-1, sp0=-1,

                 sp1=-1, start=-1, power=1):

        self.screen_width = screen_width

        if x == -1:

            self.x = random.randint(40, screen_width - 40)

            self.start_y = self.y = screen_height - 60

            self.speed = [1, -1]

            self.power = 1

        else:

            self.x = x

            self.y = y

            self.speed = [sp0, sp1]

            self.start_y = start

            self.power = power

        self.basic_speed = 1

        self.top = self.y - 10

        self.bottom = self.y + 10

        self.left = self.x - 10

        self.right = self.x + 10

        self.color = "#c8ff00"

 

    def get_side_of_intersection(self, obj):

        if self.top == obj.bottom:

            return "top"

        if self.bottom == obj.top:

            return "bottom"

        if self.left == obj.right:

            return "left"

        if self.right == obj.left:

            return "right"

 

    # def __init__(self, x, y, speed0, speed1, start):

    #     self.x = x

    #     self.y = y

    #     self.start_y = start

    #     self.top = self.y - 10

    #     self.bottom = self.y + 10

    #     self.left = self.x - 10

    #     self.right = self.x + 10

    #     self.basic_speed = 1

    #     self.speed = [speed0, speed1]

    #     self.color = "#c8ff00"

 

    def move(self):

        self.x += self.speed[0]

        self.y += self.speed[1]

        self.recount_coordinates()

 

    def reincarnate(self):

        self.x = random.randint(20, self.screen_width - 20)

        self.y = self.start_y

        self.recount_coordinates()

        self.basic_speed = 1

        self.speed = [1, -1]

 

    def recount_coordinates(self):

        self.top = self.y - 10

        self.bottom = self.y + 10

        self.left = self.x - 10

        self.right = self.x + 10

 

import pygame as pg

import random

 

 

class Block:

 

    bonuses = [

        "powerup",

        "platform_more",

        "platform_less",

        "destroy_line"

    ]

 

    def __init__(self, x, y, str, bonus=None):

        self.x = x

        self.y = y

        if bonus is None:

            chance = random.randint(0, 14)

            if chance == 10:

                self.bonus = \

                    self.bonuses[random.randint(0, len(self.bonuses) - 1)]

            else:

                self.bonus = None

        else:

            self.bonus = bonus

        self.top = self.y - 10

        self.bottom = self.y + 10

        self.left = self.x - 10

        self.right = self.x + 10

        self.strength = str

        file_name = "Images/block{0}.png".format(self.strength)

        self.image = pg.image.load(file_name)

 

    def recount_coordinates(self):

        self.top = self.y - 10

        self.bottom = self.y + 10

        self.left = self.x - 10

        self.right = self.x + 10

 

    def decrease_and_check_destroying(self, power):

        self.strength -= power

        if self.strength <= 0:

            return True

        else:

            file_name = "Images/block{0}.png".format(self.strength)

            self.image = pg.image.load(file_name)

            return False

 

    def draw(self, screen):

        screen.blit(self.image, (self.left, self.top))

 

    def __str__(self):

        return str(self.x) + " " + str(self.y)

 

import pygame

 

 

class Bonus:

 

    images = {

        "powerup": "Images/powerup.png",

        "platform_more": "Images/platform_more.png",

        "platform_less": "Images/platform_less.png"

    }

 

    def __init__(self, name, x, y):

        self.name = name

        self.image = pygame.image.load(self.images[name])

        self.x = x

        self.y = y

        self.speed = [0, 1]

 

import pygame

import sys

import random

import menu

 

 

class Editor:

    images = {0:  pygame.image.load("Images/block.png"),

              1:  pygame.image.load("Images/block1.png"),

              2:  pygame.image.load("Images/block2.png"),

              3:  pygame.image.load("Images/block3.png"),

              4:  pygame.image.load("Images/block4.png"),

              5:  pygame.image.load("Images/block5.png"),

              10: pygame.image.load("Images/cursor.png")}

    alph = "abcdefghijklmnopqrstuvwxyz"

 

    def __init__(self, width, height):

        self.width = width

        self.height = height

        print(width, height)

        self.field_width = width * 20 + 20

        self.field_height = height * 20 + 20

        print(self.field_width, self.field_height)

        self.game_objects = []

        for i in range(0, self.height):

            line = []

            for j in range(0, self.width):

                line.append(' ')

            self.game_objects.append(line)

        print(len(self.game_objects), len(self.game_objects[0]))

        self.cursor = [0, 0]

        self.selected = "1"

        self.display = (self.field_width, self.field_height)

        self.background_color = "#001a82"

        self.screen = pygame.display.set_mode(self.display)

        self.bg = pygame.Surface(self.display)

        self.timer = pygame.time.Clock()

        self.ctrl_pressed = False

        self.start()

 

    def start(self):

        pygame.init()

        pygame.display.set_caption("Editor")

        self.bg.fill(pygame.Color("#14005e"))

        while True:

            self.timer.tick(200)

            for e in pygame.event.get():

                self.handle_keys(e)

            self.draw()

 

    def handle_keys(self, e):

        if e.type == pygame.QUIT:

            sys.exit()

        if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:

            menu.Menu()

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_a:

            if 0 < self.cursor[1]:

                self.cursor[1] -= 1

                print(self.cursor)

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_d:

            if self.cursor[1] < self.width - 1:

                self.cursor[1] += 1

                print(self.cursor)

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_w:

            if 0 < self.cursor[0]:

                self.cursor[0] -= 1

                print(self.cursor)

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_s:

            if self.cursor[0] < self.height - 1:

                self.cursor[0] += 1

                print(self.cursor)

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_e:

            x = self.cursor[0]

            y = self.cursor[1]

            if self.selected == '0':

                self.game_objects[x][y] = ' '

            else:

                self.game_objects[x][y] = self.selected

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_LCTRL:

            self.ctrl_pressed = True

        elif e.type == pygame.KEYUP and e.key == pygame.K_LCTRL:

            self.ctrl_pressed = False

        if e.type == pygame.KEYDOWN and e.key == pygame.K_s:

            if self.ctrl_pressed:

                self.save_map()

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_1:

            self.selected = "1"

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_2:

            self.selected = "2"

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_3:

            self.selected = "3"

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_4:

            self.selected = "4"

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_5:

            self.selected = "5"

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_0:

            self.selected = "0"

 

    def save_map(self):

        l = random.randint(6, 12)

        name = ""

        for i in range(0, l):

            name += self.alph[random.randint(0, len(self.alph) - 1)]

        map = ""

        for i in range(0, self.width + 2):

            map += "B"

        for i in range(0, len(self.game_objects)):

            map += "\nB"

            for j in range(0, len(self.game_objects[i])):

                map += self.game_objects[i][j]

            map += "B"

        print(map)

        for i in range(0, 8):

            map += "\nB"

            for j in range(0, self.width):

                map += " "

            map += "B"

        print(map)

        file = open("CreatedLevels/{0}.txt".format(name), 'w')

        file.write(map)

        file.close()

        menu.Menu()

 

    def draw(self):

        self.screen.blit(self.bg, (0, 0))

        self.bg.fill(pygame.Color(self.background_color))

        x = 10

        y = 10

        for i in range(0, self.height):

            for j in range(0, self.width):

                block = self.game_objects[i][j]

                if block == " ":

                    self.screen.blit(self.images[0], (x, y))

                else:

                    self.screen.blit(self.images[int(block)], (x, y))

                x += 20

            y += 20

            x = 10

        x = self.cursor[1]

        y = self.cursor[0]

        if self.game_objects[y][x] == ' ':

            self.screen.blit(self.images[10], (x*20 + 10, y*20 + 10))

        pygame.display.update()

 

import pygame

import sys

import editor

import menu

 

 

class EditorMapInfo:

    def __init__(self):

        self.display = (320, 240)

        self.screen = pygame.display.set_mode(self.display)

        self.bg = pygame.Surface(self.display)

        self.timer = pygame.time.Clock()

        self.active = 1

        self.width = 0

        self.width_text = "5"

        self.height = 0

        self.height_text = "5"

        self.active_color = "#325200"

        self.inactive_color = "#383838"

        self.start()

 

    def start(self):

        pygame.init()

        pygame.display.set_caption("New map info")

        self.bg.fill(pygame.Color("#14005e"))

        while True:

            self.timer.tick(200)

            for e in pygame.event.get():

                if e.type == pygame.QUIT:

                    sys.exit()

                if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:

                    menu.Menu()

                if e.type == pygame.KEYDOWN and e.key == pygame.K_LEFT:

                    self.active -= 1

                if e.type == pygame.KEYDOWN and e.key == pygame.K_RIGHT:

                    self.active += 1

                if e.type == pygame.KEYDOWN and e.key == pygame.K_RETURN:

                    self.width = int(self.width_text)

                    self.height = int(self.height_text)

                    if 5 <= self.width <= 25 and 5 <= self.height <= 25:

                        ed = editor.Editor(self.width, self.height)

                elif e.type == pygame.KEYDOWN:

                    if e.key == pygame.K_BACKSPACE:

                        if self.active % 2 == 1:

                            self.width_text = self.width_text[:-1]

                        else:

                            self.height_text = self.height_text[:-1]

                    else:

                        if self.active % 2 == 1:

                            self.width_text += e.unicode

                        else:

                            self.height_text += e.unicode

            self.screen.blit(self.bg, (0, 0))

            font = pygame.font.Font(None, 25)

            text = font.render("Input count of blocks in field",

                               True, (255, 255, 255))

            self.screen.blit(text, [10, 15])

            text = font.render("min = 5, max = 25", True, (255, 255, 255))

            self.screen.blit(text, [10, 40])

            text = font.render("Width", True, (255, 255, 255))

            self.screen.blit(text, [10, 70])

            text = font.render("Height", True, (255, 255, 255))

            self.screen.blit(text, [100, 70])

            if self.active % 2 == 1:

                font = pygame.font.Font(None, 40)

 

                pf = pygame.Surface((80, 50))

                pf.fill(pygame.Color(self.active_color))

                self.screen.blit(pf, (10, 100))

 

                text = font.render(self.width_text, True, (255, 255, 255))

                self.screen.blit(text, [30, 110])

 

                pf.fill(pygame.Color(self.inactive_color))

                self.screen.blit(pf, (100, 100))

 

                text = font.render(self.height_text, True, (255, 255, 255))

                self.screen.blit(text, [120, 110])

            else:

                font = pygame.font.Font(None, 40)

 

                pf = pygame.Surface((80, 50))

                pf.fill(pygame.Color(self.inactive_color))

                self.screen.blit(pf, (10, 100))

 

                text = font.render(self.width_text, True, (255, 255, 255))

                self.screen.blit(text, [30, 110])

 

                pf.fill(pygame.Color(self.active_color))

                self.screen.blit(pf, (100, 100))

 

                text = font.render(self.height_text, True, (255, 255, 255))

                self.screen.blit(text, [120, 110])

 

            try:

                self.width = int(self.width_text)

                if not 5 <= self.width <= 25:

                    pf = pygame.Surface((80, 50))

                    pf.fill(pygame.Color("#ff0000"))

                    self.screen.blit(pf, (10, 100))

                    text = font.render(self.width_text, True, (255, 255, 255))

                    self.screen.blit(text, [30, 110])

            except:

                pf = pygame.Surface((80, 50))

                pf.fill(pygame.Color("#ff0000"))

                self.screen.blit(pf, (10, 100))

                text = font.render(self.width_text, True, (255, 255, 255))

                self.screen.blit(text, [30, 110])

 

            try:

                self.height = int(self.height_text)

                if not 5 <= self.height <= 25:

                    pf = pygame.Surface((80, 50))

                    pf.fill(pygame.Color("#ff0000"))

                    self.screen.blit(pf, (100, 100))

                    text = font.render(self.height_text, True, (255, 255, 255))

                    self.screen.blit(text, [120, 110])

            except:

                pf = pygame.Surface((80, 50))

                pf.fill(pygame.Color("#ff0000"))

                self.screen.blit(pf, (100, 100))

                text = font.render(self.height_text, True, (255, 255, 255))

                self.screen.blit(text, [120, 110])

            pygame.display.update()

 

import pygame

import sys

import platform as pl

import ball as b

import map as m

import statistic

import block as bl

import math

import random

import menu

import datetime

import bonus

 

 

class Game:

    eps = 1.0

    music_files = {1: "Music/megalovania.mp3",

                   2: "Music/limelight.mp3",

                   3: "Music/tripel.mp3",

                   4: "Music/voiceless.mp3",

                   5: "Music/highscore.mp3",

                   6: "Music/monster.mp3",

                   7: "Music/anthem.mp3",

                   8: "Music/ethereal.mp3",

                   9: "Music/mayday.mp3",

                   10: "Music/medal.mp3"}

 

    def __init__(self, id=1, score=0, life=3, f=None, map=None):

        self.custom = False

        if map is not None:

            self.current_level_index = "Custom.{0}".format(map)

            self.custom = True

            self.life = life

            self.score = score

            self.multiplier = 1.0

            self.map = m.Map(map)

            self.current_level = self.map.map

            self.field_width = len(self.current_level[0]) * 20 - 20

            self.win_width = self.field_width + 150

            self.win_height = len(self.current_level) * 20

            self.blocks = self.map.blocks

            self.platform = pl.Platform(self.field_width)

            self.ball = b.Ball(self.field_width, self.win_height)

        elif f is not None:

            args = f.split(";")

            if args[0][:6] == "Custom":

                self.custom = True

            if not self.custom:

                self.current_level_index = int(args[0])

                try:

                    self.map = m.Map("Levels/level" +

                                     str(self.current_level_index) + ".txt")

                except:

                    stat = statistic.Statistic("{0}"

                                               .format

                                               (self.current_level_index),

                                               self.score)

                    stat.draw_stats()

            else:

                self.map = m.Map(args[0][7:])

            self.score = int(args[1])

            self.life = int(args[2])

            self.multiplier = float(args[3])

 

            self.current_level = self.map.map

            self.field_width = len(self.current_level[0]) * 20 - 20

            self.win_width = self.field_width + 150

            self.win_height = len(self.current_level) * 20

            self.platform = pl.Platform(self.win_width,

                                        float(args[4]), float(args[5]))

            b_args = args[6].split(',')

            self.ball = b.Ball(self.field_width, self.win_height,

                               float(b_args[0]), float(b_args[1]),

                               float(b_args[2]),

                               float(b_args[3]),

                               float(self.win_height - 50),

                               float(b_args[4]))

            self.blocks = []

            for i in range(7, len(args)):

                if args[i] == '':

                    break

                block_args = args[i].split(',')

                self.blocks.append(bl.Block(int(block_args[0]),

                                            int(block_args[1]),

                                            int(block_args[2])))

        else:

            self.current_level_index = id

            self.life = life

            self.score = score

            self.multiplier = 1.0

            try:

                self.map = m.Map("Levels/level" +

                                 str(self.current_level_index) + ".txt")

            except:

                stat = statistic.Statistic(

                    "{0}".format(self.current_level_index - 1),

                    self.score)

                stat.draw_stats()

            self.current_level = self.map.map

            self.field_width = len(self.current_level[0]) * 20 - 20

            self.win_width = self.field_width + 150

            self.win_height = len(self.current_level) * 20

            self.blocks = self.map.blocks

            self.platform = pl.Platform(self.field_width)

            self.ball = b.Ball(self.field_width, self.win_height)

        self.active_bonuses = []

        self.display = (self.win_width, self.win_height)

        self.background_color = "#001a82"

        self.border_color = "#000e47"

        self.on_pause = False

        self.lose = False

        self.screen = pygame.display.set_mode(self.display)

        self.bg = pygame.Surface(self.display)

        self.timer = pygame.time.Clock()

        self.ctrl_pressed = False

        self.ball_cant_drop = False

 

    def start(self):

        pygame.init()

        pygame.mouse.set_visible(False)

        pygame.display.set_caption("Arkanoid")

        if not self.custom:

            pygame.mixer.music.load(self.music_files[self.current_level_index])

            pygame.mixer.music.set_volume(0.00)

            pygame.mixer.music.play(25)

        self.bg.fill(pygame.Color(self.background_color))

        while True:

            self.timer.tick(200)

            for e in pygame.event.get():

                if e.type == pygame.QUIT:

                    sys.exit()

                self.handle_pressed_keys(e)

            if not self.on_pause:

                self.move_platform()

                self.ball.move()

                self.reflect_ball_by_wall()

                self.reflect_ball_by_block()

                self.move_bonuses()

                self.draw_elements()

                pygame.display.update()

            else:

                self.draw_pause()

                pygame.display.update()

 

    def handle_pressed_keys(self, e):

        if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:

            pygame.mixer.music.stop()

            menu.Menu()

        if e.type == pygame.KEYDOWN and e.key == pygame.K_a:

            self.platform.MOVING_LEFT = True

        if e.type == pygame.KEYDOWN and e.key == pygame.K_d:

            self.platform.MOVING_RIGHT = True

        if e.type == pygame.KEYUP and e.key == pygame.K_a:

            self.platform.MOVING_LEFT = False

        if e.type == pygame.KEYUP and e.key == pygame.K_d:

            self.platform.MOVING_RIGHT = False

        if e.type == pygame.KEYDOWN and e.key == pygame.K_b:

            self.execute_cheat("destroy block")

        if e.type == pygame.KEYDOWN and e.key == pygame.K_n:

            self.execute_cheat("no lose")

        if e.type == pygame.KEYDOWN and e.key == pygame.K_i:

            self.execute_cheat("decrease speed")

        if e.type == pygame.KEYDOWN and e.key == pygame.K_o:

            self.execute_cheat("increase speed")

        if e.type == pygame.KEYDOWN and e.key == pygame.K_r:

            self.ball.reincarnate()

            self.eps = 1.0

        if e.type == pygame.KEYDOWN and e.key == pygame.K_q:

            if self.on_pause:

                self.on_pause = False

            else:

                self.on_pause = True

        if e.type == pygame.KEYDOWN and e.key == pygame.K_LCTRL:

            self.ctrl_pressed = True

        if e.type == pygame.KEYUP and e.key == pygame.K_LCTRL:

            self.ctrl_pressed = False

        if e.type == pygame.KEYDOWN and e.key == pygame.K_s:

            if self.ctrl_pressed:

                self.save_game()

        if e.type == pygame.KEYDOWN and e.key == pygame.K_KP_MINUS:

            volume = pygame.mixer.music.get_volume()

            volume -= 0.01

            pygame.mixer.music.set_volume(volume)

        if e.type == pygame.KEYDOWN and e.key == pygame.K_KP_PLUS:

            volume = pygame.mixer.music.get_volume()

            volume += 0.01

            pygame.mixer.music.set_volume(volume)

 

    def save_game(self):

        d = datetime.datetime.now()

        filename = "save-{0}-{1}-{2}-{3}-{4}-{5}" \

            .format(d.year, d.month, d.day, d.hour,

                    d.minute, d.second)

        game = str(self.current_level_index) + ";"

        game += str(self.score) + ";"

        game += str(self.life) + ";"

        game += str(self.multiplier) + ";"

        game += str(self.platform.LEFT_COORD) + ";"

        game += str(self.platform.WIDTH) + ";"

        game += str(self.ball.x) + ',' + str(self.ball.y) + ',' + \

            str(self.ball.speed[0]) + ',' + \

            str(self.ball.speed[1]) + ',' + \

            str(self.ball.power) + ";"

        for block in self.blocks:

            game += str(block.x) + ',' + str(block.y) + ',' + \

                    str(block.strength) + ";"

        file = open("Saves/{0}.txt".format(filename), 'w')

        file.write(game)

        file.close()

 

    def execute_cheat(self, cheat):

        # if self.life == 1:

        #     return

        # self.life -= 1

        if cheat == "destroy block":

            index = random.randint(0, len(self.blocks) - 1)

            self.blocks.remove(self.blocks[index])

            self.check_win()

        if cheat == "no lose":

            self.ball_cant_drop = not self.ball_cant_drop

        if cheat == "decrease speed":

            self.ball.speed[0] /= 2

            self.ball.speed[1] /= 2

            self.eps /= 2

        if cheat == "increase speed":

            self.ball.speed[0] *= 2

            self.ball.speed[1] *= 2

            self.eps *= 2

 

    def move_platform(self):

        if self.platform.LEFT_COORD >= 20 and self.platform.MOVING_LEFT:

            self.platform.move(-1)

        if self.platform.RIGHT_COORD <= self.field_width - 20 \

                and self.platform.MOVING_RIGHT:

            self.platform.move(1)

 

    def reflect_ball_by_wall(self):

        if math.fabs(self.ball.left - 20) < self.eps or \

                math.fabs(self.ball.right -

                          (self.field_width - 20)) < self.eps:

            self.ball.speed[0] = -self.ball.speed[0]

            return

        if math.fabs(self.ball.top - 20) < self.eps:

            self.ball.speed[1] = -self.ball.speed[1]

            return

        if math.fabs(self.ball.bottom - (self.win_height - 40)) < self.eps:

            self.reflect_ball_by_platform()

 

    def reflect_ball_by_platform(self):

        if self.ball.right < self.platform.LEFT_COORD or \

                self.ball.left > self.platform.RIGHT_COORD:

            self.multiplier = 1.0

            if not self.ball_cant_drop:

                self.eps = 1.0

                self.score -= int(self.score // 5)

                self.life -= 1

                if self.life == 0:

                    pygame.mixer.music.stop()

                    if not self.custom:

                        stats = statistic.Statistic(

                            str(self.current_level_index - 1), self.score)

                        stats.draw_stats()

                    menu.Menu()

                else:

                    self.ball.reincarnate()

            else:

                self.ball.speed[1] = -self.ball.speed[1]

            return

        self.score += int(10 * self.multiplier)

        self.multiplier = 1.0

        if self.ball.x < self.platform.LEFT_COORD:

            self.ball.speed[0] = -self.ball.basic_speed

            self.ball.speed[1] = -self.ball.basic_speed

        elif self.ball.x > self.platform.RIGHT_COORD:

            self.ball.speed[0] = self.ball.basic_speed

            self.ball.speed[1] = -self.ball.basic_speed

        else:

            middle = self.platform.WIDTH // 2

            pos = self.ball.x - self.platform.LEFT_COORD

            if pos < middle:

                angle = -1 + (pos / middle)

                self.ball.speed[0] = angle

            else:

                angle = (pos / middle) - 1

                self.ball.speed[0] = angle

            self.ball.speed[1] = \

                -math.sqrt(2 - math.pow(self.ball.speed[0], 2))

        print(self.ball.speed)

 

    def reflect_ball_by_block(self):

        for block in self.blocks:

            if math.fabs(self.ball.top - block.bottom) < self.eps or \

                    math.fabs(self.ball.bottom - block.top) < self.eps:

                if block.left <= self.ball.left <= block.right or \

                        block.left <= self.ball.right <= block.right:

                    self.ball.speed[1] = -self.ball.speed[1]

                    self.score += int(20 * self.multiplier)

                    if block.decrease_and_check_destroying(self.ball.power):

                        self.score += int(100 * self.multiplier)

                        if block.bonus is not None:

                            if block.bonus == "destroy_line":

                                destr = []

                                for b in self.blocks:

                                    if b.y == block.y and b != block:

                                        destr.append(b)

                                self.score += len(destr) * 150

                                for d in destr:

                                    self.blocks.remove(d)

                                destr.clear()

                            else:

                                bon = bonus.Bonus(

                                    block.bonus, block.left, block.top)

                                self.active_bonuses.append(bon)

                        self.blocks.remove(block)

                    self.multiplier += 0.1

                    self.check_win()

                    return

            elif math.fabs(self.ball.left - block.right) < self.eps or \

                    math.fabs(self.ball.right - block.left) < self.eps:

                if block.top <= self.ball.top <= block.bottom or \

                        block.top <= self.ball.bottom <= block.bottom:

                    self.ball.speed[0] = -self.ball.speed[0]

                    self.score += int(20 * self.multiplier)

                    if block.decrease_and_check_destroying(self.ball.power):

                        self.score += int(100 * self.multiplier)

                        if block.bonus is not None:

                            if block.bonus == "destroy_line":

                                destr = []

                                for b in self.blocks:

                                    if b.y == block.y and b != block:

                                        destr.append(b)

                                self.score += len(destr) * 150

                                for d in destr:

                                    self.blocks.remove(d)

                                destr.clear()

                            else:

                                bon = bonus.Bonus(

                                    block.bonus, block.left, block.top)

                                self.active_bonuses.append(bon)

                        self.blocks.remove(block)

                    self.multiplier += 0.1

                    self.check_win()

                    return

 

    def move_bonuses(self):

        if len(self.active_bonuses) > 0:

            for bon in self.active_bonuses:

                bon.y += bon.speed[1]

                if bon.y == self.win_height - 40:

                    if self.platform.LEFT_COORD <= bon.x <= \

                            self.platform.RIGHT_COORD:

                        if bon.name == "powerup":

                            self.ball.power *= 2

                        if bon.name == "platform_more":

                            self.platform.WIDTH = self.platform.WIDTH // 2 * 3

                            self.platform.RIGHT_COORD = \

                                self.platform.LEFT_COORD + self.platform.WIDTH

                        if bon.name == "platform_less":

                            self.platform.WIDTH //= 2

                            self.platform.RIGHT_COORD = \

                                self.platform.LEFT_COORD + self.platform.WIDTH

                    else:

                        self.active_bonuses.remove(bon)

 

    def check_win(self):

        if len(self.blocks) == 0:

            pygame.mixer.music.stop()

            if not self.custom:

                g = Game(self.current_level_index + 1,

                         self.score, self.life + 1)

                g.start()

                self.timer = None

            menu.Menu()

 

    def draw_elements(self):

        self.screen.blit(self.bg, (0, 0))

        self.platform.draw(self.screen, self.win_height)

        x = y = 0

        for row in self.current_level:

            for col in row:

                if col == "B":

                    pf = pygame.Surface((20, 20))

                    pf.fill(pygame.Color(self.border_color))

                    self.screen.blit(pf, (x, y))

                x += 20

            y += 20

            x = 0

        for block in self.blocks:

            block.draw(self.screen)

        pf = pygame.Surface((20, 20))

        pf.fill(pygame.Color(self.ball.color))

        self.screen.blit(pf, (self.ball.x - 10, self.ball.y - 10))

        if len(self.active_bonuses) > 0:

            for bon in self.active_bonuses:

                self.screen.blit(bon.image, (bon.x, bon.y))

        if self.ball_cant_drop:

            pf = pygame.Surface((self.field_width - 40, 2))

            pf.fill(pygame.Color("#ffff00"))

            self.screen.blit(pf, (20, self.win_height - 40))

 

        font = pygame.font.Font(None, 25)

        lvl = ""

        if self.custom:

            lvl = "Level: Custom"

        else:

            lvl = "Level: {0}".format(self.current_level_index)

 

        text = font.render(lvl, True, (255, 255, 255))

        self.screen.blit(text, [self.win_width - 140, 15])

        text = font.render("Score: {0}"

                           .format(self.score), True, (255, 255, 255))

        self.screen.blit(text, [self.win_width - 140, 35])

        text = font.render("Multiplier: {0}"

                           .format(self.multiplier), True, (255, 255, 255))

        self.screen.blit(text, [self.win_width - 140, 55])

        text = font.render("Balls: {0}"

                           .format(self.life), True, (255, 255, 255))

        self.screen.blit(text, [self.win_width - 140, 75])

 

    def draw_pause(self):

        if self.lose:

            t = "Final score: {0}".format(self.score)

        else:

            t = "Game paused"

        font = pygame.font.Font(None, 45)

        text = font.render(t, True, (255, 0, 0))

        self.screen.blit(text, [self.field_width // 2 - 60,

                                self.win_height // 2])

 

import block

 

 

class Map:

 

    def __init__(self, filename):

        self.map_in_text = open(filename)

        self.map = []

        self.blocks = []

        self.create_map_from_file()

        self.map_in_text.close()

 

    def create_map_from_file(self):

        self.map = []

        for line in self.map_in_text:

            self.map.append(line)

        self.blocks = []

        i = j = 0

        for row in self.map:

            for col in row:

                if col.isdigit():

                    b = block.Block(i * 20 + 10, j * 20 + 10, int(col))

                    self.blocks.append(b)

                i += 1

            i = 0

            j += 1

 

import pygame

import game

import sys

import editor_info

import select_custom_level

import select_save

 

 

class Menu:

 

    def __init__(self):

        self.display = (220, 120)

        self.screen = pygame.display.set_mode(self.display)

        self.bg = pygame.Surface(self.display)

        self.background_color = "#14005e"

        self.item1 = "1: Start new game"

        self.item2 = "2: Load game"

        self.item3 = "3: Create new level"

        self.item4 = "4: Browse created levels"

        self.timer = pygame.time.Clock()

        self.draw_main_menu()

 

    def draw_main_menu(self):

        pygame.init()

        pygame.display.set_caption("Main menu")

        self.bg.fill(pygame.Color(self.background_color))

        while True:

            self.timer.tick(200)

            self.screen.blit(self.bg, (0, 0))

            font = pygame.font.Font(None, 25)

            text = font.render(self.item1, True, (255, 255, 255))

            self.screen.blit(text, [10, 15])

            text = font.render(self.item2, True, (255, 255, 255))

            self.screen.blit(text, [10, 40])

            text = font.render(self.item3, True, (255, 255, 255))

            self.screen.blit(text, [10, 65])

            text = font.render(self.item4, True, (255, 255, 255))

            self.screen.blit(text, [10, 90])

            for e in pygame.event.get():

                if e.type == pygame.QUIT:

                    sys.exit()

                self.handle_keys(e)

            pygame.display.update()

 

    def handle_keys(self, e):

        if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:

            sys.exit(0)

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_1:

            g = game.Game(id=1, score=0, life=3)

            g.start()

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_2:

            select_save.SaveSelector()

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_3:

            editor_info.EditorMapInfo()

        elif e.type == pygame.KEYDOWN and e.key == pygame.K_4:

            select_custom_level.CustomLevelSelector()

        if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:

            sys.exit(0)

 

import pygame as pg

 

 

class Platform:

 

    def __init__(self, screen_width, left=-1, width=-1):

        self.MOVING_LEFT = False

        self.MOVING_RIGHT = False

        self.COLOR = "#789ABC"

        self.HEIGHT = 20

        if width == -1:

            self.WIDTH = screen_width / 4

        else:

            self.WIDTH = width

        if left == -1:

            self.LEFT_COORD = screen_width / 2 - self.WIDTH / 2

        else:

            self.LEFT_COORD = left

        self.RIGHT_COORD = self.LEFT_COORD + self.WIDTH

        self.MOVE_SPEED = screen_width / 250

 

    def move(self, rotation):

        self.LEFT_COORD += rotation * self.MOVE_SPEED

        self.RIGHT_COORD += rotation * self.MOVE_SPEED

 

    def draw(self, screen, height):

        pf = pg.Surface((self.WIDTH, 20))

        pf.fill(pg.Color(self.COLOR))

        screen.blit(pf, (self.LEFT_COORD, height - 40))

 

class Player:

 

    def __init__(self, name, levels, score):

        self.name = name

        self.levels = levels

        self.score = score

 

    def __str__(self):

        return "{0}/{1}/{2}".format(self.name, self.levels, self.score)

 

import pygame

import player

import sys

import menu

 

 

class RecordsScreen:

 

    def __init__(self, index):

        self.player_index = index

        f = open("records.txt", 'r')

        self.players = []

        for line in f:

            args = line.split('/')

            self.players.append(player.Player(args[0], args[1], int(args[2])))

        f.close()

        self.display = (400, 400)

        self.timer = pygame.time.Clock()

        self.screen = pygame.display.set_mode(self.display)

        self.bg = pygame.Surface(self.display)

        self.draw()

 

    def draw(self):

        pygame.init()

        pygame.display.set_caption("Records")

        while True:

            self.timer.tick(200)

            self.screen.blit(self.bg, (0, 0))

            font = pygame.font.Font(None, 25)

            text = font.render("Name", True, (255, 255, 255))

            self.screen.blit(text, [10, 15])

            text = font.render("Levels", True, (255, 255, 255))

            self.screen.blit(text, [150, 15])

            text = font.render("Score", True, (255, 255, 255))

            self.screen.blit(text, [250, 15])

            x = 50

            for i in range(0, min(10, len(self.players))):

                color = (255, 255, 255)

                if i == self.player_index:

                    color = (0, 255, 0)

                text = font.render(self.players[i].name, True, color)

                self.screen.blit(text, [10, x])

                text = font.render(self.players[i].levels, True, color)

                self.screen.blit(text, [150, x])

                text = font.render(str(self.players[i].score), True, color)

                self.screen.blit(text, [250, x])

                x += 25

            for e in pygame.event.get():

                if e.type == pygame.QUIT:

                    sys.exit()

                if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:

                    menu.Menu()

            pygame.display.update()

 

import pygame

import os

import sys

import game

import menu

 

 

class CustomLevelSelector:

    def __init__(self):

        self.levels = os.listdir("./CreatedLevels")

        self.cursor = 0

        height = 30

        if len(self.levels) > 0:

            height = len(self.levels) * 20

        self.display = (320, height)

        self.screen = pygame.display.set_mode(self.display)

        self.bg = pygame.Surface(self.display)

        self.timer = pygame.time.Clock()

        self.draw()

 

    def draw(self):

        pygame.init()

        pygame.display.set_caption("Created levels")

        self.bg.fill(pygame.Color("#14005e"))

        while True:

            self.timer.tick(200)

            self.screen.blit(self.bg, (0, 0))

            for e in pygame.event.get():

                if e.type == pygame.QUIT:

                    sys.exit()

 

                if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:

                    menu.Menu()

 

                if e.type == pygame.KEYDOWN and e.key == pygame.K_UP:

                    if 0 < self.cursor:

                        self.cursor -= 1

 

                if e.type == pygame.KEYDOWN and e.key == pygame.K_DOWN:

                    if self.cursor < len(self.levels) - 1:

                        self.cursor += 1

 

                if e.type == pygame.KEYDOWN and e.key == pygame.K_RETURN:

                    g = game.Game(map="CreatedLevels/" +

                                      self.levels[self.cursor])

                    g.start()

 

                if e.type == pygame.KEYDOWN and e.key == pygame.K_DELETE:

                    delete = self.levels[self.cursor]

                    self.levels.remove(delete)

                    os.remove("./CreatedLevels/" + delete)

            font = pygame.font.Font(None, 20)

            if len(self.levels) == 0:

                text = font.render("No levels", True, (255, 0, 0))

                self.screen.blit(text, [10, 10])

            else:

                y = 5

                for i in range(0, len(self.levels)):

                    color = (255, 255, 255)

                    if i == self.cursor:

                        color = (0, 255, 0)

                    text = font.render(self.levels[i], True, color)

                    self.screen.blit(text, [10, y])

                    y += 20

 

            pygame.display.update()

import pygame

import os

import sys

import game

import menu

 

 

class SaveSelector:

    def __init__(self):

        self.saves = os.listdir("./Saves")

        self.cursor = 0

        height = 30

        if len(self.saves) > 0:

            height = len(self.saves) * 20

        self.display = (320, height)

        self.screen = pygame.display.set_mode(self.display)

        self.bg = pygame.Surface(self.display)

        self.timer = pygame.time.Clock()

        self.draw()

 

    def draw(self):

        pygame.init()

        pygame.display.set_caption("Saves")

        self.bg.fill(pygame.Color("#14005e"))

        while True:

            self.timer.tick(200)

            self.screen.blit(self.bg, (0, 0))

            for e in pygame.event.get():

                if e.type == pygame.QUIT:

                    sys.exit()

 

                if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:

                    menu.Menu()

 

                if e.type == pygame.KEYDOWN and e.key == pygame.K_UP:

                    if 0 < self.cursor:

                        self.cursor -= 1

 

                if e.type == pygame.KEYDOWN and e.key == pygame.K_DOWN:

                    if self.cursor < len(self.saves) - 1:

                        self.cursor += 1

 

                if e.type == pygame.KEYDOWN and e.key == pygame.K_RETURN:

                    saved = open("Saves/" + self.saves[self.cursor], 'r')

                    g = game.Game(f=saved.read())

                    saved.close()

                    g.start()

 

                if e.type == pygame.KEYDOWN and e.key == pygame.K_DELETE:

                    delete = self.saves[self.cursor]

                    self.saves.remove(delete)

                    os.remove("./Saves/" + delete)

            font = pygame.font.Font(None, 20)

            if len(self.saves) == 0:

                text = font.render("No saves", True, (255, 0, 0))

                self.screen.blit(text, [10, 10])

            else:

                y = 5

                for i in range(0, len(self.saves)):

                    color = (255, 255, 255)

                    if i == self.cursor:

                        color = (0, 255, 0)

                    text = font.render(self.saves[i], True, color)

                    self.screen.blit(text, [10, y])

                    y += 20

 

            pygame.display.update()

 

import pygame

import sys

import player

import records_screen

 

 

class Statistic:

 

    def __init__(self, passed, score):

        self.passed = passed

        self.score = score

        self.display = (320, 240)

        self.timer = pygame.time.Clock()

        self.screen = pygame.display.set_mode(self.display)

        self.bg = pygame.Surface(self.display)

        f = open("records.txt", 'r')

        self.records = []

        for line in f:

            args = line.split('/')

            self.records.append(player.Player(args[0], args[1], int(args[2])))

        f.close()

 

    def draw_stats(self):

        pygame.init()

        pygame.display.set_caption("Statistic")

        name = ""

        while True:

            self.timer.tick(200)

            self.screen.blit(self.bg, (0, 0))

            font = pygame.font.Font(None, 25)

            text = font.render("You have passed {0} levels"

                               .format(self.passed), True, (255, 255, 255))

            self.screen.blit(text, [10, 15])

            text = font.render("Your final score: {0}"

                               .format(self.score), True, (255, 255, 255))

            self.screen.blit(text, [10, 40])

            text = font.render("Enter your name", True, (255, 255, 255))

            self.screen.blit(text, [10, 65])

            text = font.render(name, True, (0, 0, 255))

            self.screen.blit(text, [10, 90])

            for e in pygame.event.get():

                if e.type == pygame.QUIT:

                    sys.exit()

                if e.type == pygame.KEYDOWN and e.key == pygame.K_RETURN:

                    pl = player.Player(name, self.passed, self.score)

                    self.records.append(pl)

                    self.records.sort(key=lambda x: x.score, reverse=True)

                    f = open("records.txt", 'w')

                    f.truncate()

                    for p in self.records:

                        f.write(str(p) + "\n")

                    index = self.records.index(pl)

                    f.close()

                    r = records_screen.RecordsScreen(index)

                if e.type == pygame.KEYDOWN:

                    if e.key == pygame.K_BACKSPACE:

                        name = name[:-1]

                    else:

                        name += e.unicode

                    text = font.render(name, True, (0, 0, 255))

                    self.screen.blit(text, [10, 90])

            pygame.display.update()

 

 

 

Количество комментариев: 0

Для того, чтобы оставить коментарий необходимо зарегистрироваться