[Python game] How to play tank battle and sokoban games? Learning these will make you a master in seconds—remember those childhood games? (with source code of Pygame collection)

foreword

The next Youth Day is coming soon, I don’t think I will be able to celebrate the festival for a few years! !

There is a photo circulating on social media—according to national regulations, "everyone aged 14 to 28 should take half a day off today!" I have to say,

This span is really a bit big. If you calculate your age by whole natural years, I am really a little excited!

(When I get older, I like to recall my lost youth—not only sigh that I am really old, old, old~)

[----Help Python learning, the following source code and courseware are free at the end of the article! ----】
GIF cover

Let's showdown directly!

Today's editor is tweeting about Amway's childhood "mini-games", but it is not a mini-game within the game.

It is some small games written in Python code. There should be many small games played by many childhood friends.

Now I can relive my childhood (not only lament, but also the fun of childhood games, let me go and let me play all over again )

If you can't help but say the names of most games, then I can only congratulate you, showing your age~

Today, the editor brings you two childhood games - I can guarantee that you must have played these two childhood games!

1) Tank battle mini game single | double mode 2) Classic puzzle game Sokoban

img

Small Science -
May 4th Youth Day originated from China's anti-imperialist and patriotic "May 4th Movement" in 1919. The May 4th Patriotic Movement was a thorough opposition to imperialism

The patriotic movement against feudalism was also the beginning of China's new democratic revolution. In 1939, young people in the northwest of the Shaanxi-Gansu-Ningxia Border Region saved the country

The federation stipulates that May 4th is China Youth Day.

During the Youth Day, various commemorative activities will be held in various parts of China, and young people will also concentrate on various social volunteering and social activities.

There are many practical activities, and many places hold coming-of-age ceremonies during the Youth Festival.

text

1. Material preparation

1) Environment preparation

Environment installation: python 3.8: interpreter, pycharm: code editor,

Corresponding installation packages/installation tutorials/activation codes/use tutorials/learning materials/tool ​​plug-ins can be obtained directly from My Houtai.

Some of the built-in modules can be used directly after installing Python. If you need to install it↓

2) Module installation tutorial

The third-party library is installed as follows:

General installation: pip install + module name

Mirror source installation: pip install -i https://pypi.douban.com/simple/+module name

(There are also many domestic mirror sources, here are Douban's usage habits, other mirror sources can be read in previous articles)

2. Tank battle mini game single | double mode

1) Game introduction

"Tank Battle" was a FC game that was popular all over the country, and it was a must-have for installation in the era of Xiaobawang. Now it seems that the picture has

It's a bit rudimentary, but it was definitely one of the games that you never got tired of playing before.

A wonderful feature of this game is that you can blow up your own bunker by yourself. If you drive too hard, you can get over your head and shoot your old man.

The house exploded, it can be said that it is very happy to hear.

img
[----Help Python learning, the following source code and courseware are free at the end of the article! ----】

2) Code display

The game has two modes: single player and double player. If one's own base camp is destroyed or one's own tank is destroyed, the game will fail. Successfully pass all

The checkpoint is the game victory. In addition, players can make a prop appear randomly on the map by shooting a specific tank.

If the tank picks up the prop, an event will be triggered, such as the enhancement of the tank's ability.

Code effect——

2.1 Players operate as follows

Player 1: wsad key: up, down, left, right; space bar: shoot. Player 2: ↑↓←→ keys: up, down, left, right; keypad 0: shoot.

Player one, WSAD moves, space bar shoots

        if tank_player1.num_lifes >= 0:
            if key_pressed[pygame.K_w]:
                player_tanks_group.remove(tank_player1)
                tank_player1.move('up', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
                player_tanks_group.add(tank_player1)
            elif key_pressed[pygame.K_s]:
                player_tanks_group.remove(tank_player1)
                tank_player1.move('down', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
                player_tanks_group.add(tank_player1)
            elif key_pressed[pygame.K_a]:
                player_tanks_group.remove(tank_player1)
                tank_player1.move('left', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
                player_tanks_group.add(tank_player1)
            elif key_pressed[pygame.K_d]:
                player_tanks_group.remove(tank_player1)
                tank_player1.move('right', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
                player_tanks_group.add(tank_player1)
            elif key_pressed[pygame.K_SPACE]:
                bullet = tank_player1.shoot()
                if bullet:
                    self.sounds['fire'].play() if tank_player1.tanklevel < 2 else self.sounds['Gunfire'].play()
                    player_bullets_group.add(bullet)
        # 玩家二, ↑↓←→移动, 小键盘0键射击
        if self.is_dual_mode and (tank_player2.num_lifes >= 0):
            if key_pressed[pygame.K_UP]:
                player_tanks_group.remove(tank_player2)
                tank_player2.move('up', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
                player_tanks_group.add(tank_player2)
            elif key_pressed[pygame.K_DOWN]:
                player_tanks_group.remove(tank_player2)
                tank_player2.move('down', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
                player_tanks_group.add(tank_player2)
            elif key_pressed[pygame.K_LEFT]:
                player_tanks_group.remove(tank_player2)
                tank_player2.move('left', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
                player_tanks_group.add(tank_player2)
            elif key_pressed[pygame.K_RIGHT]:
                player_tanks_group.remove(tank_player2)
                tank_player2.move('right', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
                player_tanks_group.add(tank_player2)
            elif key_pressed[pygame.K_KP0]:
                bullet = tank_player2.shoot()
                if bullet:
                    player_bullets_group.add(bullet)
                    self.sounds['fire'].play() if tank_player2.tanklevel < 2 else self.sounds['Gunfire'].play()

2.2 Code run by the main program

'''
Function:
    经典坦克大战小游戏
'''
import os
import cfg
import pygame
from modules import *
'''主函数'''
def main(cfg):
    # 游戏初始化
    pygame.init()
    pygame.mixer.init()
    screen = pygame.display.set_mode((cfg.WIDTH, cfg.HEIGHT))
    pygame.display.set_caption(cfg.TITLE)
    # 加载游戏素材
    sounds = {}
    for key, value in cfg.AUDIO_PATHS.items():
        sounds[key] = pygame.mixer.Sound(value)
        sounds[key].set_volume(1)
    # 开始界面
    is_dual_mode = gameStartInterface(screen, cfg)
    # 关卡数
    levelfilepaths = [os.path.join(cfg.LEVELFILEDIR, filename) for filename in sorted(os.listdir(cfg.LEVELFILEDIR))]
    # 主循环
    for idx, levelfilepath in enumerate(levelfilepaths):
        switchLevelIterface(screen, cfg, idx+1)
        game_level = GameLevel(idx+1, levelfilepath, sounds, is_dual_mode, cfg)
        is_win = game_level.start(screen)
        if not is_win: break
    is_quit_game = gameEndIterface(screen, cfg, is_win)
    return is_quit_game
'''run'''
if __name__ == '__main__':
    while True:
        is_quit_game = main(cfg)
        if is_quit_game:
            break

3) Effect display

3.1 Game interface

img

3.2 Game loading screen

img

3.3 Game start interface

insert image description here

3. The classic puzzle game Sokoban

1) Game introduction

The mechanism and gameplay of "Sokoban" are actually very simple, just move the worker up, down, left, and right to push the box to the designated position.

It's just that its game process involves a lot of spatial logic reasoning, such as pushing a box to a corner and not being able to move it, or
pushing two boxes at the same time, etc., and it is easy to fall into a dead end.

This combination of game design and gameplay is very playable, so the game quickly became popular all over the world.

img
[----Help Python learning, the following source code and courseware are free at the end of the article! ----】

2) Code display

Code effect——

2.1 Configuration file

'''配置文件'''
import os
'''屏幕大小'''
SCREENSIZE = (500, 500)
'''block大小'''
BLOCKSIZE = 50
'''levels所在文件夹'''
LEVELDIR = os.path.join(os.getcwd(), 'resources/levels')
'''图片所在文件夹'''
IMAGESDIR = os.path.join(os.getcwd(), 'resources/images')
'''字体所在文件夹'''
FONTDIR = os.path.join(os.getcwd(), 'resources/font')
'''音频所在文件夹'''
AUDIODIR = os.path.join(os.getcwd(), 'resources/audios')
'''背景颜色'''
BACKGROUNDCOLOR = (45, 45, 45)

2.2 Run the main program code

'''
Function:
    推箱子小游戏
'''
import os
import sys
import cfg
import pygame
from modules import *
from itertools import chain
'''游戏地图'''
class gameMap():
    def __init__(self, num_cols, num_rows):
        self.walls = []
        self.boxes = []
        self.targets = []
        self.num_cols = num_cols
        self.num_rows = num_rows
    '''增加游戏元素'''
    def addElement(self, elem_type, col, row):
        if elem_type == 'wall':
            self.walls.append(elementSprite('wall.png', col, row, cfg))
        elif elem_type == 'box':
            self.boxes.append(elementSprite('box.png', col, row, cfg))
        elif elem_type == 'target':
            self.targets.append(elementSprite('target.png', col, row, cfg))
    '''画游戏地图'''
    def draw(self, screen):
        for elem in self.elemsIter():
            elem.draw(screen)
    '''游戏元素迭代器'''
    def elemsIter(self):
        for elem in chain(self.targets, self.walls, self.boxes):
            yield elem
    '''该关卡中所有的箱子是否都在指定位置, 在的话就是通关了'''
    def levelCompleted(self):
        for box in self.boxes:
            is_match = False
            for target in self.targets:
                if box.col == target.col and box.row == target.row:
                    is_match = True
                    break
            if not is_match:
                return False
        return True
    '''某位置是否可到达'''
    def isValidPos(self, col, row):
        if col >= 0 and row >= 0 and col < self.num_cols and row < self.num_rows:
            block_size = cfg.BLOCKSIZE
            temp1 = self.walls + self.boxes
            temp2 = pygame.Rect(col * block_size, row * block_size, block_size, block_size)
            return temp2.collidelist(temp1) == -1
        else:
            return False
    '''获得某位置的box'''
    def getBox(self, col, row):
        for box in self.boxes:
            if box.col == col and box.row == row:
                return box
        return None
'''游戏界面'''
class gameInterface():
    def __init__(self, screen):
        self.screen = screen
        self.levels_path = cfg.LEVELDIR
        self.initGame()
    '''导入关卡地图'''
    def loadLevel(self, game_level):
        with open(os.path.join(self.levels_path, game_level), 'r') as f:
            lines = f.readlines()
        # 游戏地图
        self.game_map = gameMap(max([len(line) for line in lines]) - 1, len(lines))
        # 游戏surface
        height = cfg.BLOCKSIZE * self.game_map.num_rows
        width = cfg.BLOCKSIZE * self.game_map.num_cols
        self.game_surface = pygame.Surface((width, height))
        self.game_surface.fill(cfg.BACKGROUNDCOLOR)
        self.game_surface_blank = self.game_surface.copy()
        for row, elems in enumerate(lines):
            for col, elem in enumerate(elems):
                if elem == 'p':
                    self.player = pusherSprite(col, row, cfg)
                elif elem == '*':
                    self.game_map.addElement('wall', col, row)
                elif elem == '#':
                    self.game_map.addElement('box', col, row)
                elif elem == 'o':
                    self.game_map.addElement('target', col, row)
    '''游戏初始化'''
    def initGame(self):
        self.scroll_x = 0
        self.scroll_y = 0
    '''将游戏界面画出来'''
    def draw(self, *elems):
        self.scroll()
        self.game_surface.blit(self.game_surface_blank, dest=(0, 0))
        for elem in elems:
            elem.draw(self.game_surface)
        self.screen.blit(self.game_surface, dest=(self.scroll_x, self.scroll_y))
    '''因为游戏界面面积>游戏窗口界面, 所以需要根据人物位置滚动'''
    def scroll(self):
        x, y = self.player.rect.center
        width = self.game_surface.get_rect().w
        height = self.game_surface.get_rect().h
        if (x + cfg.SCREENSIZE[0] // 2) > cfg.SCREENSIZE[0]:
            if -1 * self.scroll_x + cfg.SCREENSIZE[0] < width:
                self.scroll_x -= 2
        elif (x + cfg.SCREENSIZE[0] // 2) > 0:
            if self.scroll_x < 0:
                self.scroll_x += 2
        if (y + cfg.SCREENSIZE[1] // 2) > cfg.SCREENSIZE[1]:
            if -1 * self.scroll_y + cfg.SCREENSIZE[1] < height:
                self.scroll_y -= 2
        elif (y + 250) > 0:
            if self.scroll_y < 0:
                self.scroll_y += 2
'''某一关卡的游戏主循环'''
def runGame(screen, game_level):
    clock = pygame.time.Clock()
    game_interface = gameInterface(screen)
    game_interface.loadLevel(game_level)
    font_path = os.path.join(cfg.FONTDIR, 'simkai.ttf')
    text = '按R键重新开始本关'
    font = pygame.font.Font(font_path, 15)
    text_render = font.render(text, 1, (255, 255, 255))
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit(0)
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    next_pos = game_interface.player.move('left', is_test=True)
                    if game_interface.game_map.isValidPos(*next_pos):
                        game_interface.player.move('left')
                    else:
                        box = game_interface.game_map.getBox(*next_pos)
                        if box:
                            next_pos = box.move('left', is_test=True)
                            if game_interface.game_map.isValidPos(*next_pos):
                                game_interface.player.move('left')
                                box.move('left')
                    break
                if event.key == pygame.K_RIGHT:
                    next_pos = game_interface.player.move('right', is_test=True)
                    if game_interface.game_map.isValidPos(*next_pos):
                        game_interface.player.move('right')
                    else:
                        box = game_interface.game_map.getBox(*next_pos)
                        if box:
                            next_pos = box.move('right', is_test=True)
                            if game_interface.game_map.isValidPos(*next_pos):
                                game_interface.player.move('right')
                                box.move('right')
                    break
                if event.key == pygame.K_DOWN:
                    next_pos = game_interface.player.move('down', is_test=True)
                    if game_interface.game_map.isValidPos(*next_pos):
                        game_interface.player.move('down')
                    else:
                        box = game_interface.game_map.getBox(*next_pos)
                        if box:
                            next_pos = box.move('down', is_test=True)
                            if game_interface.game_map.isValidPos(*next_pos):
                                game_interface.player.move('down')
                                box.move('down')
                    break
                if event.key == pygame.K_UP:
                    next_pos = game_interface.player.move('up', is_test=True)
                    if game_interface.game_map.isValidPos(*next_pos):
                        game_interface.player.move('up')
                    else:
                        box = game_interface.game_map.getBox(*next_pos)
                        if box:
                            next_pos = box.move('up', is_test=True)
                            if game_interface.game_map.isValidPos(*next_pos):
                                game_interface.player.move('up')
                                box.move('up')
                    break
                if event.key == pygame.K_r:
                    game_interface.initGame()
                    game_interface.loadLevel(game_level)
        game_interface.draw(game_interface.player, game_interface.game_map)
        if game_interface.game_map.levelCompleted():
            return
        screen.blit(text_render, (5, 5))
        pygame.display.flip()
        clock.tick(100)
'''主函数'''
def main():
    pygame.init()
    pygame.mixer.init()
    pygame.display.set_caption('推箱子 —— 源码基地:#959755565#')
    screen = pygame.display.set_mode(cfg.SCREENSIZE)
    pygame.mixer.init()
    audio_path = os.path.join(cfg.AUDIODIR, 'EineLiebe.mp3')
    pygame.mixer.music.load(audio_path)
    pygame.mixer.music.set_volume(0.4)
    pygame.mixer.music.play(-1)
    startInterface(screen, cfg)
    for level_name in sorted(os.listdir(cfg.LEVELDIR)):
        runGame(screen, level_name)
        switchInterface(screen, cfg)
    endInterface(screen, cfg)
'''run'''
if __name__ == '__main__':
    main()

3) Effect display

3.1 Game interface

img

3.2 The game interface of the second level

img

Summarize

Alright~ That’s the end of today’s update. Let me introduce you to two childhood games. If you like this game Didi

I share it for free! Did you play those games in your childhood? (It can be written into code after secretly collecting it~)

img

Data collection

The above-mentioned complete version of the Python game source code and courseware has been uploaded to the official CSDN. If you need it, you can scan the QR code of the CSDN official certification below on WeChat and enter "Receive the game source code" to receive it.

insert image description here

Good article recommendation

Understand the prospect of python: https://blog.csdn.net/weixin_49891576/article/details/127187029

Learn about python's part-time jobs: https://blog.csdn.net/weixin_49891576/article/details/127125308

Guess you like

Origin blog.csdn.net/weixin_49891576/article/details/130100025