[Source code attached] Using python+pygame to develop Xiaoxiaole game

Using python + pygame to develop Xiaoxiaole game with complete source code

I believe everyone has played the Xiaoxiaole mini game. It is a mini game that both adults and children like to play. So how is it implemented based on the program? Today I will show you how to use python + pygame to implement the function of this fancy Xiaoxiaole game. Friends who are interested should take a look.

Directory
  • 1. Environmental requirements
  • 2. Game introduction
  • 3. Complete development process
    • 1. Main project structure
    • 2. Detailed configuration
    • 3. Load all graphics of Xiaoxiaole
    • 4. Randomly generate initial layout, adjacent elimination, automatic falling
    • 5. Randomly initialize the main picture content of Xiaoxiaole
  • 4. How to start the game?
    • 1. Start using the development tool IDE
    • 2. Command line startup

The effect is like this ↓ ↓ ↓

1. Environmental requirements

windows system, python3.6 + pip21 +

Development environment construction address

Let’s learn pygame together. 30 examples of game development (opening words) – environment construction + game effect display

Install game dependency modules
pip install pygame

2. Game introduction

Everyone should have played or watched Xiaoxiaole. This fancy little game

It is very simple to implement it using python’s pygame.

Today I will show you how to use Python to implement this fancy little game.

3. Complete development process

1. Project main structure

First of all, let’s sort out the main structure of the project. In fact, if you look at the main structure, it will be basically clear.

12345678910111213 modules: The location of the relevant defined Python class ``--game.py: main module`` res: stores referenced pictures, audio, etc. `` --audios: audio resources `` -- imgs: picture resources `` -- fonts: fonts cfg.py: main configuration File`` xxls.py: main program file`` requirements.txt: python dependency package that needs to be introduced

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.

1234567891011121314 '''Main configuration file'''``import os`` '''Screen setting size'''`` SCREENSIZE ``= (``700``, ``700``)``'''Element size'''`` NUMGRID ``= 8`` GRIDSIZE ``= 64`` XMARGIN ``= (SCREENSIZE[``0`` ] ``- GRIDSIZE ``* NUMGRID) ``/``/ 2`` YMARGIN ``= (SCREEENSIZE[ ``1`` ] ``- GRIDSIZE ``* NUMGRID) ``/``/ 2``'''Get root Directory''''`` ROOTDIR ``= os.getcwd()``'''FPS'''`` FPS ``= 30

3. Load all graphics of Xiaoxiaole

game.py: Part 1

Put the entire project under the entire game.py module, disassemble the code file and interpret it.

Puzzle Elf class: First, obtain the path of the block Elf from the configuration file and load it into the game.

Define the function move() to move the module. This movement is relatively simple. Between modules, only adjacent ones can move to each other.

'''
Function:
    main game
'''
importsys
import time
import random
import pygame
  
  
'''Puzzle Elf Class'''
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):
                #Move down
        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
                #Move up
        elif 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
                #shift left
        elif 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
                #Move right
        elif 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
    '''Get current coordinates'''
    def getPosition(self):
        return self.rect.left, self.rect.top
    '''Set star coordinates'''
    def setPosition(self, position):
        self.rect.left, self.rect.top = position

4. Randomly generate initial layout, adjacent elimination, automatic falling

game.py Part 2

Set the title for starting the game’s main window and set the main method for starting the game.

''''Main game category'''
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()
    '''Start game'''
    def start(self):
        clock = pygame.time.Clock()
        # Traverse the entire game interface to update the position
        overall_moving = True
        # Specify individual update locations for certain objects
        individual_moving = False
        # Define 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)
                # You may be able to create multiple 3-connected blocks with one move.
                if not overall_moving:
                    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)

5. Randomly initialize the main image content of Xiaoxiaole

game.py Part 3

Detailed comments are all written in the code. Everyone must read it again, don’t run away and just ignore it.

''''Initialization'''
    def reset(self):
        # Randomly generate each block (i.e. initialize each element of the game map)
        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
        # Score
        self.score = 0
        # Reward for spelling out one
        self.reward = 10
        # time
        self.remaining_time = 300
    '''Display remaining time'''
    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)
    '''Show score'''
    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)
    '''Show bonus points'''
    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)
    '''Generate new puzzle pieces'''
    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
    '''Remove matching pacer'''
    def removeMatched(self, res_match):
        if res_match[0] > 0:
            self.generateNewpacers(res_match)
            self.score + = self.reward
            return self.reward
        return 0
    '''Grid drawing for game interface'''
    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)
    '''Draw a rectangular block'''
    def drawBlock(self, block, color=(255, 0, 255), size=4):
        pygame.draw.rect(self.screen, color, block, size)
    '''Falling effects'''
    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()
    '''Is there a puzzle piece in every position'''
    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
    '''Check if any puzzle piece is selected'''
    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
    '''Whether there are three consecutive identical blocks (none--return 0/horizontal--return 1/vertical--return 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]
    '''Get the puzzle object at the corresponding position based on the coordinates'''
    def getpacerByPos(self, x, y):
        return self.all_pacers[x][y]
    '''Swap puzzles'''
    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
    '''the message says'''
    def __repr__(self):
        return self.info

5. Resource related

Includes game background audio, pictures and font design

res main resource directory

audios: Load game background music

fonts: scoreboard related fonts

imgs: The graphics of our various little stars are stored here, which is the key. If this cannot be loaded,

Our Xiaoxiaole no longer has any graphics.

6. Start the main program

xxls.py

In the main program, by reading the configuration file, the project resources are introduced: including pictures, audio, etc., and all our modules are introduced from our modules.

'''
Function:
    Xiaoxiaole
'''
import os
importsys
importcfg
import pygame
from modules import *
  
  
'''Main program'''
def main():
    pygame.init()
    screen = pygame.display.set_mode(cfg.SCREENSIZE)
    pygame.display.set_caption('hacklex')
    #Load background music
    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)
    # Load sound effects
    sounds = {}
    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, 'res/audios/match%s.wav' % i)))
  
    # Font display
    font = pygame.font.Font(os.path.join(cfg.ROOTDIR, 'res/font/font.TTF'), 25)
    # Star
    pacer_imgs = []
    for i in range(1, 8):
        pacer_imgs.append(os.path.join(cfg.ROOTDIR, 'res/imgs/pacer%s.png' % i))
    # Loop
    game = pacerGame(screen, sounds, font, pacer_imgs, cfg)
    while True:
        score = game.start()
        flag=False
        # Given a choice, the player chooses to replay or quit.
        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.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()
                ifidx==0:
                    rect.left, rect.top = (223, y)
                elifidx==1:
                    rect.left, rect.top = (133.5, y)
                else:
                    rect.left, rect.top = (126.5, y)
                y + = 99
                screen.blit(text_render, rect)
            pygame.display.update()
        game.reset()
  
  
'''Game running'''
if __name__ == '__main__':
    main()

4. How to start the game?

1. Start using the development tool IDE

If the development tool IDE environment

For example: VScode, sublimeText, notepad +

Pycharm or something configures the Python environment

You can run the game directly in the tool.

2. Command line startup

As shown below

The above is an analysis of the process of developing Xiaoxiaole game using python, with complete source code details attached.

The rapid rise of Python is extremely beneficial to the entire industry, but “There are many popular people and not many people“, which has led to a lot of criticism, but it still cannot stop its popularity. development momentum.

If you are interested in Python and want to learn Python, here I would like to share with you a Complete set of Python learning materials, which I compiled during my own study. I hope it can help you, let’s work together!

Friends in need can click the link below to get it for free or Scan the QR code below to get it for free
Click here

1Getting started with zero basics

① Learning route

For students who have never been exposed to Python, we have prepared a detailed Learning and Growth Roadmap for you. It can be said to be the most scientific and systematic learning route. You can follow the above knowledge points to find corresponding learning resources to ensure that you learn more comprehensively.

② Route corresponding learning video

There are also many learning videos suitable for beginners. With these videos, you can easily get started with Python~

③Exercise questions

After each video lesson, there are corresponding exercises to test your learning results haha!

2Domestic and foreign Python books and documents

① Documents and books

3Python toolkit + project source code collection

①Python toolkit

The commonly used development software for learning Python is here! Each one has a detailed installation tutorial to ensure you can install it successfully!

②Python practical case

Optical theory is useless. You must learn to type code along with it and practice it in order to apply what you have learned to practice. At this time, you can learn from some practical cases. 100+ practical case source codes are waiting for you!

③Python mini game source code

If you feel that the practical cases above are a bit boring, you can try writing your own mini-game in Python to add a little fun to your learning process!

4Python interview questions

After we learn Python, we can go out and find a job if we have the skills! The following interview questions are all from first-tier Internet companies such as Alibaba, Tencent, Byte, etc., and Alibaba bosses have given authoritative answers. I believe everyone can find a satisfactory job after reviewing this set of interview materials.

5Python part-time channels

Moreover, after learning Python, you can also take orders and make money on major part-time platforms. I have compiled various part-time channels + part-time precautions + how to communicate with customers into documents.

All the above information , if friends need it, you can scan the QR code below to get it for free