It looks like this ↓ ↓ ↓

First, environmental requirements

For Windows, PYTHon3.6 + PIp21 +

Development environment setup address

30 examples of Game development (opening word) — Environment building + game effect presentation

Install the game dependency module PIP Install PyGameCopy the code

Ii. Introduction to the game

I think you’ve all played it, or seen it. This fancy little game

Use Python pyGame to implement, very simple.

Today, let’s use Python to implement this fancy little game.

Complete development process

1. Main structure of the project

First of all, sort out the main structure of the project, in fact, look at the main structure, basically clear

Modules: Python class locations defined by the relevant definitions -- game.py: main module res: places referenced images, audio, etc. -- Audios: audio resources -- IMgs: Picture resources -- fonts: cfg.py: main configuration file xxls.py: Main program file requirements. TXT: Python dependencies to importCopy the code

2. Detailed configuration

cfg.py

In the configuration file, you need to introduce the OS module and configure the screen size for opening the game.

SCREENSIZE = (700, XMARGIN = (SCREENSIZE[0] -gridsize * NUMGRID) // 2 YMARGIN = (SCREENSIZE[1] - GRIDSIZE * NUMGRID) // 2 "" get root directory" ROOTDIR = os.getcwd() "" FPS" "FPS = 30Copy the code

3, eliminate all graphics loading

Game.py: Part one

Putting the entire project under the umbrella of the entire game.py module, take the code file apart to decode it.

Puzzle spirit class: first of all through the configuration file, get the path of square spirit, loaded into the game.

Define a function for the move() module, which is relatively simple. Between modules, only adjacent modules can move each other.

''' Function: Import sys Import time Import Random Import PyGame class pacerSprite(Pygame.sprite.sprite): def __init__(self, img_path, size, position, downlen, **kwargs): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load(img_path) self.image = pygame.transform.smoothscale(self.image, size) self.rect = self.image.get_rect() self.rect.left, self.rect.top = position self.downlen = downlen self.target_x = position[0] self.target_y = position[1] + downlen self.type = img_path.split('/')[-1].split('.')[0] self.fixed = False self.speed_x = 9 self.speed_y = 9 self.direction = 'down' def move(self): if self. Direction == 'down': self.rect.top = min(self.target_y, self.rect.top+self.speed_y) if self.target_y == self.rect.top: Self. fixed = True # self.direction == 'up': self.rect.top = max(self.target_y, self.rect.top-self.speed_y) if self.target_y == self.rect.top: Self. fixed = True # self.direction == 'left': self.rect.left = max(self.target_x, self.rect.left-self.speed_x) if self.target_x == self.rect.left: Self. fixed = True # self.direction == 'right': self.rect.left = min(self.target_x, self.rect.left+self.speed_x) if self.target_x == self.rect.left: Self. fixed = True def getPosition(self): Return self.rect.left, self.rect.top "" def setPosition(self, position): self.rect.left, self.rect.top = positionCopy the code

4, random generation of initial layout, adjacent elimination, automatic fall

Game.py Part 2

Set the title of the main window to start the game, and set the main method to start the game.

Class pacerGame(): def __init__(self, screen, sounds, font, pacer_imgs, CFG, **kwargs): self.info = 'pacer' self.screen = screen self.sounds = sounds self.font = font self.pacer_imgs = pacer_imgs self.cfg = CFG self.reset() "" def start(self): Clock = pygame.time.clock () # traverses the entire game interface update location Overall_moving = True # specifies the update location of some individual objects individual_moving = False # defines some necessary variables pacer_selected_xy = None pacer_selected_xy2 = None swap_again = False add_score = 0 add_score_showtimes = 10 time_pre = Int (time.time()) # game main loop while True: for event in pygame.event.get(): if event.type == pygame.QUIT or (event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE): pygame.quit() sys.exit() elif event.type == pygame.MOUSEBUTTONUP: if (not overall_moving) and (not individual_moving) and (not add_score): position = pygame.mouse.get_pos() if pacer_selected_xy is None: pacer_selected_xy = self.checkSelected(position) else: pacer_selected_xy2 = self.checkSelected(position) if pacer_selected_xy2: if self.swappacer(pacer_selected_xy, pacer_selected_xy2): individual_moving = True swap_again = False else: pacer_selected_xy = None if overall_moving: Overall_moving = not self. Droppacers (0, 0) # If not overall_moving = not self. Droppacers (0, 0) # if not overall_moving = not self. res_match = self.isMatch() add_score = self.removeMatched(res_match) if add_score > 0: overall_moving = True if individual_moving: pacer1 = self.getpacerByPos(*pacer_selected_xy) pacer2 = self.getpacerByPos(*pacer_selected_xy2) pacer1.move() pacer2.move() if pacer1.fixed and pacer2.fixed: res_match = self.isMatch() if res_match[0] == 0 and not swap_again: swap_again = True self.swappacer(pacer_selected_xy, pacer_selected_xy2) self.sounds['mismatch'].play() else: add_score = self.removeMatched(res_match) overall_moving = True individual_moving = False pacer_selected_xy = None pacer_selected_xy2 = None self.screen.fill((135, 206, 235)) self.drawGrids() self.pacers_group.draw(self.screen) if pacer_selected_xy: self.drawBlock(self.getpacerByPos(*pacer_selected_xy).rect) if add_score: if add_score_showtimes == 10: random.choice(self.sounds['match']).play() self.drawAddScore(add_score) add_score_showtimes -= 1 if add_score_showtimes < 1: add_score_showtimes = 10 add_score = 0 self.remaining_time -= (int(time.time()) - time_pre) time_pre = int(time.time()) self.showRemainingTime() self.drawScore() if self.remaining_time <= 0: return self.score pygame.display.update() clock.tick(self.cfg.FPS)Copy the code

5. Randomly initialize the content of the main map of xiaoxiao.

Game.py Part 3

Detailed comments, it’s all in the code. You have to watch it, don’t run, leave it alone

    '''初始化'''
    def reset(self):
        # 随机生成各个块(即初始化游戏地图各个元素)
        while True:
            self.all_pacers = []
            self.pacers_group = pygame.sprite.Group()
            for x in range(self.cfg.NUMGRID):
                self.all_pacers.append([])
                for y in range(self.cfg.NUMGRID):
                    pacer = pacerSprite(img_path=random.choice(self.pacer_imgs), size=(self.cfg.GRIDSIZE, self.cfg.GRIDSIZE), position=[self.cfg.XMARGIN+x*self.cfg.GRIDSIZE, self.cfg.YMARGIN+y*self.cfg.GRIDSIZE-self.cfg.NUMGRID*self.cfg.GRIDSIZE], downlen=self.cfg.NUMGRID*self.cfg.GRIDSIZE)
                    self.all_pacers[x].append(pacer)
                    self.pacers_group.add(pacer)
            if self.isMatch()[0] == 0:
                break
        # 得分
        self.score = 0
        # 拼出一个的奖励
        self.reward = 10
        # 时间
        self.remaining_time = 300
    '''显示剩余时间'''
    def showRemainingTime(self):
        remaining_time_render = self.font.render('CountDown: %ss' % str(self.remaining_time), 1, (85, 65, 0))
        rect = remaining_time_render.get_rect()
        rect.left, rect.top = (self.cfg.SCREENSIZE[0]-201, 6)
        self.screen.blit(remaining_time_render, rect)
    '''显示得分'''
    def drawScore(self):
        score_render = self.font.render('SCORE:'+str(self.score), 1, (85, 65, 0))
        rect = score_render.get_rect()
        rect.left, rect.top = (10, 6)
        self.screen.blit(score_render, rect)
    '''显示加分'''
    def drawAddScore(self, add_score):
        score_render = self.font.render('+'+str(add_score), 1, (255, 100, 100))
        rect = score_render.get_rect()
        rect.left, rect.top = (250, 250)
        self.screen.blit(score_render, rect)
    '''生成新的拼图块'''
    def generateNewpacers(self, res_match):
        if res_match[0] == 1:
            start = res_match[2]
            while start > -2:
                for each in [res_match[1], res_match[1]+1, res_match[1]+2]:
                    pacer = self.getpacerByPos(*[each, start])
                    if start == res_match[2]:
                        self.pacers_group.remove(pacer)
                        self.all_pacers[each][start] = None
                    elif start >= 0:
                        pacer.target_y += self.cfg.GRIDSIZE
                        pacer.fixed = False
                        pacer.direction = 'down'
                        self.all_pacers[each][start+1] = pacer
                    else:
                        pacer = pacerSprite(img_path=random.choice(self.pacer_imgs), size=(self.cfg.GRIDSIZE, self.cfg.GRIDSIZE), position=[self.cfg.XMARGIN+each*self.cfg.GRIDSIZE, self.cfg.YMARGIN-self.cfg.GRIDSIZE], downlen=self.cfg.GRIDSIZE)
                        self.pacers_group.add(pacer)
                        self.all_pacers[each][start+1] = pacer
                start -= 1
        elif res_match[0] == 2:
            start = res_match[2]
            while start > -4:
                if start == res_match[2]:
                    for each in range(0, 3):
                        pacer = self.getpacerByPos(*[res_match[1], start+each])
                        self.pacers_group.remove(pacer)
                        self.all_pacers[res_match[1]][start+each] = None
                elif start >= 0:
                    pacer = self.getpacerByPos(*[res_match[1], start])
                    pacer.target_y += self.cfg.GRIDSIZE * 3
                    pacer.fixed = False
                    pacer.direction = 'down'
                    self.all_pacers[res_match[1]][start+3] = pacer
                else:
                    pacer = pacerSprite(img_path=random.choice(self.pacer_imgs), size=(self.cfg.GRIDSIZE, self.cfg.GRIDSIZE), position=[self.cfg.XMARGIN+res_match[1]*self.cfg.GRIDSIZE, self.cfg.YMARGIN+start*self.cfg.GRIDSIZE], downlen=self.cfg.GRIDSIZE*3)
                    self.pacers_group.add(pacer)
                    self.all_pacers[res_match[1]][start+3] = pacer
                start -= 1
    '''移除匹配的pacer'''
    def removeMatched(self, res_match):
        if res_match[0] > 0:
            self.generateNewpacers(res_match)
            self.score += self.reward
            return self.reward
        return 0
    '''游戏界面的网格绘制'''
    def drawGrids(self):
        for x in range(self.cfg.NUMGRID):
            for y in range(self.cfg.NUMGRID):
                rect = pygame.Rect((self.cfg.XMARGIN+x*self.cfg.GRIDSIZE, self.cfg.YMARGIN+y*self.cfg.GRIDSIZE, self.cfg.GRIDSIZE, self.cfg.GRIDSIZE))
                self.drawBlock(rect, color=(0, 0, 255), size=1)
    '''画矩形block框'''
    def drawBlock(self, block, color=(255, 0, 255), size=4):
        pygame.draw.rect(self.screen, color, block, size)
    '''下落特效'''
    def droppacers(self, x, y):
        if not self.getpacerByPos(x, y).fixed:
            self.getpacerByPos(x, y).move()
        if x < self.cfg.NUMGRID - 1:
            x += 1
            return self.droppacers(x, y)
        elif y < self.cfg.NUMGRID - 1:
            x = 0
            y += 1
            return self.droppacers(x, y)
        else:
            return self.isFull()
    '''是否每个位置都有拼图块了'''
    def isFull(self):
        for x in range(self.cfg.NUMGRID):
            for y in range(self.cfg.NUMGRID):
                if not self.getpacerByPos(x, y).fixed:
                    return False
        return True
    '''检查有无拼图块被选中'''
    def checkSelected(self, position):
        for x in range(self.cfg.NUMGRID):
            for y in range(self.cfg.NUMGRID):
                if self.getpacerByPos(x, y).rect.collidepoint(*position):
                    return [x, y]
        return None
    '''是否有连续一样的三个块(无--返回0/水平--返回1/竖直--返回2)'''
    def isMatch(self):
        for x in range(self.cfg.NUMGRID):
            for y in range(self.cfg.NUMGRID):
                if x + 2 < self.cfg.NUMGRID:
                    if self.getpacerByPos(x, y).type == self.getpacerByPos(x+1, y).type == self.getpacerByPos(x+2, y).type:
                        return [1, x, y]
                if y + 2 < self.cfg.NUMGRID:
                    if self.getpacerByPos(x, y).type == self.getpacerByPos(x, y+1).type == self.getpacerByPos(x, y+2).type:
                        return [2, x, y]
        return [0, x, y]
    '''根据坐标获取对应位置的拼图对象'''
    def getpacerByPos(self, x, y):
        return self.all_pacers[x][y]
    '''交换拼图'''
    def swappacer(self, pacer1_pos, pacer2_pos):
        margin = pacer1_pos[0] - pacer2_pos[0] + pacer1_pos[1] - pacer2_pos[1]
        if abs(margin) != 1:
            return False
        pacer1 = self.getpacerByPos(*pacer1_pos)
        pacer2 = self.getpacerByPos(*pacer2_pos)
        if pacer1_pos[0] - pacer2_pos[0] == 1:
            pacer1.direction = 'left'
            pacer2.direction = 'right'
        elif pacer1_pos[0] - pacer2_pos[0] == -1:
            pacer2.direction = 'left'
            pacer1.direction = 'right'
        elif pacer1_pos[1] - pacer2_pos[1] == 1:
            pacer1.direction = 'up'
            pacer2.direction = 'down'
        elif pacer1_pos[1] - pacer2_pos[1] == -1:
            pacer2.direction = 'up'
            pacer1.direction = 'down'
        pacer1.target_x = pacer2.rect.left
        pacer1.target_y = pacer2.rect.top
        pacer1.fixed = False
        pacer2.target_x = pacer1.rect.left
        pacer2.target_y = pacer1.rect.top
        pacer2.fixed = False
        self.all_pacers[pacer2_pos[0]][pacer2_pos[1]] = pacer1
        self.all_pacers[pacer1_pos[0]][pacer1_pos[1]] = pacer2
        return True
    '''信息显示'''
    def __repr__(self):
        return self.info
Copy the code

5. Resource related

This includes background audio, graphics, and font design

Res Main resource directory

Audios: Loads game background music

Fonts: scoreboard-related fonts

Imgs: This store is our various small star graphics, is the key oh. If this doesn’t load,

Our elimination music doesn’t have any graphics

6. Start the main program

xxls.py

In the main program, we import project resources: images, audio, etc., and import all of our modules from our modules by reading configuration files.

Import OS import sys import CFG import pygame from modules import * def main(): Pygame.init () screen = Pygame.display.set_mode (cfg.screensize) PyGame.display.set_caption ('hacklex') # pygame.mixer.init() pygame.mixer.music.load(os.path.join(cfg.ROOTDIR, "Res/Audios /bg.mp3")) Pygame.mixer.music.set_volume (0.6) Pygame.mixer.music.play (-1) # sounds['mismatch'] = pygame.mixer.Sound(os.path.join(cfg.ROOTDIR, 'res/audios/badswap.wav')) sounds['match'] = [] for i in range(6): sounds['match'].append(pygame.mixer.Sound(os.path.join(cfg.ROOTDIR, Font = pygame.font.Font(os.path.join(CFG.ROOTDIR, 'res/font/font.TTF'), 7) # er_imgs = [] for I in range(1, 8): Pacer_imgs. Append (os.path.join(cfg.ROOTDIR, 'res/imgs/pacer%s.png' % I)) # Pacer_imgs, CFG) while True: score = game.start() flag = False for event in pygame.event.get(): if event.type == pygame.QUIT or (event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE): pygame.quit() sys.exit() elif event.type == pygame.KEYUP and event.key == pygame.K_r: flag = True if flag: break screen.fill((136, 207, 236)) text0 = 'Final score: %s' % score text1 = 'Press <R> to restart the game.' text2 = 'Press <Esc> to quit the game.' y = 150 for idx, text in enumerate([text0, text1, text2]): text_render = font.render(text, 1, (85, 65, 0)) rect = text_render.get_rect() if idx == 0: Rect. left, rect.top = (223, y) elif idx == 1: rect.left, rect.top = (133.5, y) else: Rect. left, rect.top = (126.5, y) y += 99 screen.blit(text_render, The rect) pygame. Display. The update () game. The reset () "' 'run' ' 'if __name__ = =" __main__' : the main ()Copy the code

How to start the game?

1. Use the development tool IDE to start

If the development tool IDE environment

For example, VScode, sublimeText, and Notepad +

Pycharm what configured the Python environment

You can run the game directly in the tool.

2. Command line startup

As shown in the figure below

30 games collection download address

Download.csdn.net/download/we…