Python Pygame实战之塔防游戏的实现


Posted in Python onMarch 17, 2022

一、环境要求

windows系统,python3.6+

安装模块

pip install pyqt5
pip install pygame

二、游戏介绍

1、游戏目标

按照关卡,设计不同的塔防地图(博主只设计了三关,有兴趣的同学,学会之后,可以自己画地图),设置三种炮台,每种炮台发射不同的炮弹,每种炮弹对敌人杀伤力不一样,每种

炮台的价格也不一样。玩家通过钱币购买炮台,并设有剪出炮台的操作(有点类似植物大战僵尸里的铲子)。敌人成功抵达塔楼,游戏结束。

2、先上游戏效果图

Python Pygame实战之塔防游戏的实现

三、完整开发流程

1、项目主结构

首先,先整理一下项目的主结构,其实看一下主结构,基本就清晰了

Python Pygame实战之塔防游戏的实现

2、详细配置

config.py

配置文件中,需要引入os模块,并且配置打开游戏的屏幕大小,并将资源中引用到的图片、音频插入到合适的位置。

因为我们的迷宫游戏,需要划开模块。

'''配置文件'''
import os
 
 
'''屏幕大小'''
SCREENSIZE = (800, 600)
'''图片路径'''
IMAGEPATHS = {
    'choice': {
        'load_game': os.path.join(os.getcwd(), 'resources/images/choice/load_game.png'),
        'map1': os.path.join(os.getcwd(), 'resources/images/choice/map1.png'),
        'map1_black': os.path.join(os.getcwd(), 'resources/images/choice/map1_black.png'),
        'map1_red': os.path.join(os.getcwd(), 'resources/images/choice/map1_red.png'),
        'map2': os.path.join(os.getcwd(), 'resources/images/choice/map2.png'),
        'map2_black': os.path.join(os.getcwd(), 'resources/images/choice/map2_black.png'),
        'map2_red': os.path.join(os.getcwd(), 'resources/images/choice/map2_red.png'),
        'map3': os.path.join(os.getcwd(), 'resources/images/choice/map3.png'),
        'map3_black': os.path.join(os.getcwd(), 'resources/images/choice/map3_black.png'),
        'map3_red': os.path.join(os.getcwd(), 'resources/images/choice/map3_red.png'),
    },
    'end': {
        'gameover': os.path.join(os.getcwd(), 'resources/images/end/gameover.png'),
        'continue_red': os.path.join(os.getcwd(), 'resources/images/end/continue_red.png'),
        'continue_black': os.path.join(os.getcwd(), 'resources/images/end/continue_black.png'),
    },
    'game': {
        'arrow1': os.path.join(os.getcwd(), 'resources/images/game/arrow1.png'), 
        'arrow2': os.path.join(os.getcwd(), 'resources/images/game/arrow2.png'), 
        'arrow3': os.path.join(os.getcwd(), 'resources/images/game/arrow3.png'), 
        'basic_tower': os.path.join(os.getcwd(), 'resources/images/game/basic_tower.png'), 
        'boulder': os.path.join(os.getcwd(), 'resources/images/game/boulder.png'), 
        'bush': os.path.join(os.getcwd(), 'resources/images/game/bush.png'), 
        'cave': os.path.join(os.getcwd(), 'resources/images/game/cave.png'), 
        'dirt': os.path.join(os.getcwd(), 'resources/images/game/dirt.png'), 
        'enemy_blue': os.path.join(os.getcwd(), 'resources/images/game/enemy_blue.png'), 
        'enemy_pink': os.path.join(os.getcwd(), 'resources/images/game/enemy_pink.png'), 
        'enemy_red': os.path.join(os.getcwd(), 'resources/images/game/enemy_red.png'), 
        'enemy_yellow': os.path.join(os.getcwd(), 'resources/images/game/enemy_yellow.png'), 
        'godark': os.path.join(os.getcwd(), 'resources/images/game/godark.png'), 
        'golight': os.path.join(os.getcwd(), 'resources/images/game/golight.png'), 
        'grass': os.path.join(os.getcwd(), 'resources/images/game/grass.png'), 
        'healthfont': os.path.join(os.getcwd(), 'resources/images/game/healthfont.png'), 
        'heavy_tower': os.path.join(os.getcwd(), 'resources/images/game/heavy_tower.png'), 
        'med_tower': os.path.join(os.getcwd(), 'resources/images/game/med_tower.png'), 
        'nexus': os.path.join(os.getcwd(), 'resources/images/game/nexus.png'), 
        'othergrass': os.path.join(os.getcwd(), 'resources/images/game/othergrass.png'), 
        'path': os.path.join(os.getcwd(), 'resources/images/game/path.png'), 
        'rock': os.path.join(os.getcwd(), 'resources/images/game/rock.png'), 
        'tiles': os.path.join(os.getcwd(), 'resources/images/game/tiles.png'), 
        'unitfont': os.path.join(os.getcwd(), 'resources/images/game/unitfont.png'), 
        'water': os.path.join(os.getcwd(), 'resources/images/game/water.png'), 
        'x': os.path.join(os.getcwd(), 'resources/images/game/x.png'), 
    },
    'pause': {
        'gamepaused': os.path.join(os.getcwd(), 'resources/images/pause/gamepaused.png'), 
        'resume_black': os.path.join(os.getcwd(), 'resources/images/pause/resume_black.png'), 
        'resume_red': os.path.join(os.getcwd(), 'resources/images/pause/resume_red.png'), 
    },
    'start': {
        'play_black': os.path.join(os.getcwd(), 'resources/images/start/play_black.png'), 
        'play_red': os.path.join(os.getcwd(), 'resources/images/start/play_red.png'), 
        'quit_black': os.path.join(os.getcwd(), 'resources/images/start/quit_black.png'), 
        'quit_red': os.path.join(os.getcwd(), 'resources/images/start/quit_red.png'), 
        'start_interface': os.path.join(os.getcwd(), 'resources/images/start/start_interface.png'), 
    },
}
'''地图路径'''
MAPPATHS = {
    '1': os.path.join(os.getcwd(), 'resources/maps/1.map'),
    '2': os.path.join(os.getcwd(), 'resources/maps/2.map'),
    '3': os.path.join(os.getcwd(), 'resources/maps/3.map'),
}
'''字体路径'''
FONTPATHS = {
    'Calibri': os.path.join(os.getcwd(), 'resources/fonts/Calibri.ttf'),
    'm04': os.path.join(os.getcwd(), 'resources/fonts/m04.ttf'),
    'Microsoft Sans Serif': os.path.join(os.getcwd(), 'resources/fonts/Microsoft Sans Serif.ttf'),
}
'''不同难度的settings'''
DIFFICULTYPATHS = {
    'easy': os.path.join(os.getcwd(), 'resources/difficulties/easy.json'),
    'hard': os.path.join(os.getcwd(), 'resources/difficulties/hard.json'),
    'medium': os.path.join(os.getcwd(), 'resources/difficulties/medium.json'),
}
'''音频路径'''
AUDIOPATHS = {
    'bgm': os.path.join(os.getcwd(), 'resources/audios/bgm.mp3'),
}

3、定义敌人、塔楼、子弹的类

Python Pygame实战之塔防游戏的实现

turrent.py 以炮塔类为例

炮塔首先需要初始化,即init函数,另外需要有射击属性、以及重置属性(即我们可以将已经建好的炮塔删除,然后重新添加)

import pygame
from .arrow import Arrow
 
 
'''炮塔类'''
class Turret(pygame.sprite.Sprite):
    def __init__(self, turret_type, cfg):
        assert turret_type in range(3)
        pygame.sprite.Sprite.__init__(self)
        self.cfg = cfg
        self.turret_type = turret_type
        self.imagepaths = [cfg.IMAGEPATHS['game']['basic_tower'], cfg.IMAGEPATHS['game']['med_tower'], cfg.IMAGEPATHS['game']['heavy_tower']]
        self.image = pygame.image.load(self.imagepaths[turret_type])
        self.rect = self.image.get_rect()
        # 箭
        self.arrow = Arrow(turret_type, cfg)
        # 当前的位置
        self.coord = 0, 0
        self.position = 0, 0
        self.rect.left, self.rect.top = self.position
        self.reset()
    '''射击'''
    def shot(self, position, angle=None):
        arrow = None
        if not self.is_cooling:
            arrow = Arrow(self.turret_type, self.cfg)
            arrow.reset(position, angle)
            self.is_cooling = True
        if self.is_cooling:
            self.cool_time -= 1
            if self.cool_time == 0:
                self.reset()
        return arrow
    '''重置'''
    def reset(self):
        if self.turret_type == 0:
            # 价格
            self.price = 500
            # 射箭的冷却时间
            self.cool_time = 30
            # 是否在冷却期
            self.is_cooling = False
        elif self.turret_type == 1:
            self.price = 1000
            self.cool_time = 50
            self.is_cooling = False
        elif self.turret_type == 2:
            self.price = 1500
            self.cool_time = 100
            self.is_cooling = False

4、游戏开始:选择难度地图

在这里我们把游戏主界面初始化,并把三个难度的地图列出来,让玩家选择。

import sys
import pygame
 
 
'''游戏选择主界面'''
class MainInterface(pygame.sprite.Sprite):
    def __init__(self, cfg):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.IMAGEPATHS['choice']['load_game']).convert()
        self.rect = self.image.get_rect()
        self.rect.topleft = (0, 0)
    '''更新函数'''
    def update(self):
        pass
 
 
'''地图1'''
class MapButton1(pygame.sprite.Sprite):
    def __init__(self, cfg, position=(175, 240)):
        pygame.sprite.Sprite.__init__(self)
        self.image_1 = pygame.image.load(cfg.IMAGEPATHS['choice']['map1_black']).convert()
        self.image_2 = pygame.image.load(cfg.IMAGEPATHS['choice']['map1_red']).convert()
        self.image_3 = pygame.image.load(cfg.IMAGEPATHS['choice']['map1']).convert()
        self.image = self.image_1
        self.rect = self.image.get_rect()
        self.rect.center = position
    '''更新函数: 不断地更新检测鼠标是否在按钮上'''
    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            self.image = self.image_2
        else:
            self.image = self.image_1
 
 
'''地图2'''
class MapButton2(pygame.sprite.Sprite):
    def __init__(self, cfg, position=(400, 240)):
        pygame.sprite.Sprite.__init__(self)
        self.image_1 = pygame.image.load(cfg.IMAGEPATHS['choice']['map2_black']).convert()
        self.image_2 = pygame.image.load(cfg.IMAGEPATHS['choice']['map2_red']).convert()
        self.image_3 = pygame.image.load(cfg.IMAGEPATHS['choice']['map2']).convert()
        self.image = self.image_1
        self.rect = self.image.get_rect()
        self.rect.center = position
    '''更新函数: 不断地更新检测鼠标是否在按钮上'''
    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            self.image = self.image_2
        else:
            self.image = self.image_1
 
 
'''地图3'''
class MapButton3(pygame.sprite.Sprite):
    def __init__(self, cfg, position=(625, 240)):
        pygame.sprite.Sprite.__init__(self)
        self.image_1 = pygame.image.load(cfg.IMAGEPATHS['choice']['map3_black']).convert()
        self.image_2 = pygame.image.load(cfg.IMAGEPATHS['choice']['map3_red']).convert()
        self.image_3 = pygame.image.load(cfg.IMAGEPATHS['choice']['map3']).convert()
        self.image = self.image_1
        self.rect = self.image.get_rect()
        self.rect.center = position
    '''更新函数: 不断地更新检测鼠标是否在按钮上'''
    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            self.image = self.image_2
        else:
            self.image = self.image_1
 
 
'''信息显示框'''
class InfoBox(pygame.sprite.Sprite):
    def __init__(self, position=(400, 475)):
        pygame.sprite.Sprite.__init__(self)
        self.ori_image = pygame.Surface((625, 200))
        self.ori_image.fill((255, 255, 255))
        self.ori_image_front = pygame.Surface((621, 196))
        self.ori_image_front.fill((0, 0, 0))
        self.ori_image.blit(self.ori_image_front, (2, 2))
        self.rect = self.ori_image.get_rect()
        self.rect.center = position
    '''更新函数'''
    def update(self, btns):
        self.image = self.ori_image
        mouse_pos = pygame.mouse.get_pos()
        for btn in btns:
            if btn.rect.collidepoint(mouse_pos):
                self.image.blit(btn.image_3, (225, 25))
                break
 
 
'''简单难度按钮'''
class EasyButton(pygame.sprite.Sprite):
    def __init__(self, cfg, position=(400, 150)):
        pygame.sprite.Sprite.__init__(self)
        self.image_1 = pygame.Surface((285, 100))
        self.image_1_front = pygame.Surface((281, 96))
        self.image_1.fill((255, 255, 255))
        self.image_1_front.fill((0, 0, 0))
        self.image_1.blit(self.image_1_front, (2, 2))
        self.image_2 = pygame.Surface((285, 100))
        self.image_2_front = pygame.Surface((281, 96))
        self.image_2.fill((255, 255, 255))
        self.image_2_front.fill((24, 196, 40))
        self.image_2.blit(self.image_2_front, (2, 2))
        self.text = 'easy'
        self.font = pygame.font.Font(cfg.FONTPATHS['m04'], 42)
        self.text_render = self.font.render(self.text, 1, (255, 255, 255))
        self.image_1.blit(self.text_render, (60, 29))
        self.image_2.blit(self.text_render, (60, 29))
        self.image = self.image_1
        self.rect = self.image.get_rect()
        self.rect.center = position
    '''更新函数: 不断地更新检测鼠标是否在按钮上'''
    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            self.image = self.image_2
        else:
            self.image = self.image_1
 
 
'''中等难度按钮'''
class MediumButton(pygame.sprite.Sprite):
    def __init__(self, cfg, position=(400, 300)):
        pygame.sprite.Sprite.__init__(self)
        self.image_1 = pygame.Surface((285, 100))
        self.image_1_front = pygame.Surface((281, 96))
        self.image_1.fill((255, 255, 255))
        self.image_1_front.fill((0, 0, 0))
        self.image_1.blit(self.image_1_front, (2, 2))
        self.image_2 = pygame.Surface((285, 100))
        self.image_2_front = pygame.Surface((281, 96))
        self.image_2.fill((255, 255, 255))
        self.image_2_front.fill((24, 30, 196))
        self.image_2.blit(self.image_2_front, (2, 2))
        self.text = 'medium'
        self.font = pygame.font.Font(cfg.FONTPATHS['m04'], 42)
        self.text_render = self.font.render(self.text, 1, (255, 255, 255))
        self.image_1.blit(self.text_render, (15, 29))
        self.image_2.blit(self.text_render, (15, 29))
        self.image = self.image_1
        self.rect = self.image.get_rect()
        self.rect.center = position
    '''更新函数: 不断地更新检测鼠标是否在按钮上'''
    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            self.image = self.image_2
        else:
            self.image = self.image_1
 
 
'''困难难度按钮'''
class HardButton(pygame.sprite.Sprite):
    def __init__(self, cfg, position=(400, 450)):
        pygame.sprite.Sprite.__init__(self)
        self.image_1 = pygame.Surface((285, 100))
        self.image_1_front = pygame.Surface((281, 96))
        self.image_1.fill((255, 255, 255))
        self.image_1_front.fill((0, 0, 0))
        self.image_1.blit(self.image_1_front, (2, 2))
        self.image_2 = pygame.Surface((285, 100))
        self.image_2_front = pygame.Surface((281, 96))
        self.image_2.fill((255, 255, 255))
        self.image_2_front.fill((196, 24, 24))
        self.image_2.blit(self.image_2_front, (2, 2))
        self.text = 'hard'
        self.font = pygame.font.Font(cfg.FONTPATHS['m04'], 42)
        self.text_render = self.font.render(self.text, 1, (255, 255, 255))
        self.image_1.blit(self.text_render, (60, 29))
        self.image_2.blit(self.text_render, (60, 29))
        self.image = self.image_1
        self.rect = self.image.get_rect()
        self.rect.center = position
    '''更新函数: 不断地更新检测鼠标是否在按钮上'''
    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            self.image = self.image_2
        else:
            self.image = self.image_1
 
 
'''游戏地图和困难选择界面'''
class ChoiceInterface():
    def __init__(self, cfg):
        # part1
        self.main_interface = MainInterface(cfg)
        self.map_btn1 = MapButton1(cfg)
        self.map_btn2 = MapButton2(cfg)
        self.map_btn3 = MapButton3(cfg)
        self.info_box = InfoBox()
        # part2
        self.easy_btn = EasyButton(cfg)
        self.medium_btn = MediumButton(cfg)
        self.hard_btn = HardButton(cfg)
    '''外部调用'''
    def update(self, screen):
        clock = pygame.time.Clock()
        # part1
        self.map_btns = pygame.sprite.Group(self.map_btn1, self.map_btn2, self.map_btn3)
        map_choice, difficulty_choice = None, None
        while True:
            clock.tick(60)
            self.main_interface.update()
            self.map_btns.update()
            self.info_box.update(self.map_btns)
            screen.blit(self.main_interface.image, self.main_interface.rect)
            self.map_btns.draw(screen)
            screen.blit(self.info_box.image, self.info_box.rect)
            pygame.display.flip()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit(0)
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:
                        mouse_pos = pygame.mouse.get_pos()
                        idx = 0
                        for btn in self.map_btns:
                            idx += 1
                            if btn.rect.collidepoint(mouse_pos):
                                map_choice = idx
            if map_choice:
                break
        # part2
        self.difficulty_btns = pygame.sprite.Group(self.easy_btn, self.medium_btn, self.hard_btn)
        while True:
            clock.tick(60)
            screen.fill((0, 0, 0))
            self.difficulty_btns.update()
            self.difficulty_btns.draw(screen)
            pygame.display.flip()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit(0)
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:
                        mouse_pos = pygame.mouse.get_pos()
                        idx = 0
                        for btn in self.difficulty_btns:
                            idx += 1
                            if btn.rect.collidepoint(mouse_pos):
                                difficulty_choice = btn.text
            if difficulty_choice:
                break
        return map_choice, difficulty_choice

5、游戏开始界面

包括开始按钮,退出游戏等操作

start.py

import sys
import pygame
 
 
'''游戏开始主界面'''
class MainInterface(pygame.sprite.Sprite):
    def __init__(self, cfg):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.IMAGEPATHS['start']['start_interface']).convert()
        self.rect = self.image.get_rect()
        self.rect.center = cfg.SCREENSIZE[0] / 2, cfg.SCREENSIZE[1] / 2
    '''更新函数'''
    def update(self):
        pass
 
 
'''开始游戏按钮'''
class PlayButton(pygame.sprite.Sprite):
    def __init__(self, cfg, position=(220, 415)):
        pygame.sprite.Sprite.__init__(self)
        self.image_1 = pygame.image.load(cfg.IMAGEPATHS['start']['play_black']).convert()
        self.image_2 = pygame.image.load(cfg.IMAGEPATHS['start']['play_red']).convert()
        self.image = self.image_1
        self.rect = self.image.get_rect()
        self.rect.center = position
    '''更新函数: 不断地更新检测鼠标是否在按钮上'''
    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            self.image = self.image_2
        else:
            self.image = self.image_1
 
 
'''结束游戏按钮'''
class QuitButton(pygame.sprite.Sprite):
    def __init__(self, cfg, position=(580, 415)):
        pygame.sprite.Sprite.__init__(self)
        self.image_1 = pygame.image.load(cfg.IMAGEPATHS['start']['quit_black']).convert()
        self.image_2 = pygame.image.load(cfg.IMAGEPATHS['start']['quit_red']).convert()
        self.image = self.image_1
        self.rect = self.image.get_rect()
        self.rect.center = position
    '''更新函数: 不断地更新检测鼠标是否在按钮上'''
    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            self.image = self.image_2
        else:
            self.image = self.image_1
 
 
'''游戏开始界面'''
class StartInterface():
    def __init__(self, cfg):
        self.main_interface = MainInterface(cfg)
        self.play_btn = PlayButton(cfg)
        self.quit_btn = QuitButton(cfg)
        self.components = pygame.sprite.LayeredUpdates(self.main_interface, self.play_btn, self.quit_btn)
    '''外部调用'''
    def update(self, screen):
        clock = pygame.time.Clock()
        while True:
            clock.tick(60)
            self.components.update()
            self.components.draw(screen)
            pygame.display.flip()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit(0)
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:
                        mouse_pos = pygame.mouse.get_pos()
                        if self.play_btn.rect.collidepoint(mouse_pos):
                            return True
                        elif self.quit_btn.rect.collidepoint(mouse_pos):
                            return False

6、游戏运行

gaming.py

import sys
import json
import math
import random
import pygame
from ..sprites import Enemy
from ..sprites import Turret
from .pause import PauseInterface
from collections import namedtuple
 
 
'''游戏进行中界面'''
class GamingInterface():
    def __init__(self, cfg):
        self.cfg = cfg
        # 游戏地图大小
        map_w = self.cfg.SCREENSIZE[0]
        map_h = 500
        # 按钮大小和位置
        button_w = 60
        button_h = 60
        button_y = 520
        # 间隙
        gap = 20
        # 按钮放在工具栏, 工具栏两端各有一个信息显示框
        toolbar_w = gap * 7 + button_w * 6
        info_w = (self.cfg.SCREENSIZE[0] - toolbar_w) // 2
        info_h = self.cfg.SCREENSIZE[1] - map_h
        toolbar_h = self.cfg.SCREENSIZE[1] - map_h
        # 界面布置
        self.map_rect = pygame.Rect(0, 0, map_w, map_h)
        self.map_surface = pygame.Surface((map_w, map_h))
        self.leftinfo_rect = pygame.Rect(0, map_h, info_w, info_h)
        self.rightinfo_rect = pygame.Rect(self.cfg.SCREENSIZE[0] - info_w, map_h, info_w, info_h)
        self.toolbar_rect = pygame.Rect(info_w, map_h, toolbar_w, toolbar_h)
        # 草
        self.grass = pygame.image.load(cfg.IMAGEPATHS['game']['grass'])
        # 岩石(铺路用的)
        self.rock = pygame.image.load(cfg.IMAGEPATHS['game']['rock'])
        # 污垢
        self.dirt = pygame.image.load(cfg.IMAGEPATHS['game']['dirt'])
        # 水
        self.water = pygame.image.load(cfg.IMAGEPATHS['game']['water'])
        # 灌木
        self.bush = pygame.image.load(cfg.IMAGEPATHS['game']['bush'])
        # 纽带
        self.nexus = pygame.image.load(cfg.IMAGEPATHS['game']['nexus'])
        # 洞穴
        self.cave = pygame.image.load(cfg.IMAGEPATHS['game']['cave'])
        # 获取地图元素的大小,请保证素材库里组成地图的元素图大小一致
        self.element_size = int(self.grass.get_rect().width)
        # 一些字体
        self.info_font = pygame.font.Font(cfg.FONTPATHS['Calibri'], 14)
        self.button_font = pygame.font.Font(cfg.FONTPATHS['Calibri'], 20)
        # 可以放炮塔的地方
        self.placeable = {0: self.grass}
        # 地图元素字典(数字对应.map文件中的数字)
        self.map_elements = {
            0: self.grass,
            1: self.rock,
            2: self.dirt,
            3: self.water,
            4: self.bush,
            5: self.nexus,
            6: self.cave
        }
        # 用于记录地图中的道路
        self.path_list = []
        # 当前的地图,将地图导入到这里面
        self.current_map = dict()
        # 当前鼠标携带的图标(即选中道具) -> [道具名, 道具]
        self.mouse_carried = []
        # 在地图上建造好了的炮塔
        self.built_turret_group = pygame.sprite.Group()
        # 所有的敌人
        self.enemies_group = pygame.sprite.Group()
        # 所有射出的箭
        self.arrows_group = pygame.sprite.Group()
        # 玩家操作用的按钮
        Button = namedtuple('Button', ['rect', 'text', 'onClick'])
        self.buttons = [
            Button(pygame.Rect((info_w + gap), button_y, button_w, button_h), 'T1', self.takeT1),
            Button(pygame.Rect((info_w + gap * 2 + button_w), button_y, button_w, button_h), 'T2', self.takeT2),
            Button(pygame.Rect((info_w + gap * 3 + button_w * 2), button_y, button_w, button_h), 'T3', self.takeT3),
            Button(pygame.Rect((info_w + gap * 4 + button_w * 3), button_y, button_w, button_h), 'XXX', self.takeXXX),
            Button(pygame.Rect((info_w + gap * 5 + button_w * 4), button_y, button_w, button_h), 'Pause', self.pauseGame),
            Button(pygame.Rect((info_w + gap * 6 + button_w * 5), button_y, button_w, button_h), 'Quit', self.quitGame)
        ]
    '''开始游戏'''
    def start(self, screen, map_path=None, difficulty_path=None):
        # 读取游戏难度对应的参数
        with open(difficulty_path, 'r') as f:
            difficulty_dict = json.load(f)
        self.money = difficulty_dict.get('money')
        self.health = difficulty_dict.get('health')
        self.max_health = difficulty_dict.get('health')
        difficulty_dict = difficulty_dict.get('enemy')
        # 每60s生成一波敌人
        generate_enemies_event = pygame.constants.USEREVENT + 0
        pygame.time.set_timer(generate_enemies_event, 60000)
        # 生成敌人的flag和当前已生成敌人的总次数
        generate_enemies_flag = False
        num_generate_enemies = 0
        # 每0.5秒出一个敌人
        generate_enemy_event = pygame.constants.USEREVENT + 1
        pygame.time.set_timer(generate_enemy_event, 500)
        generate_enemy_flag = False
        # 防止变量未定义
        enemy_range = None
        num_enemy = None
        # 是否手动操作箭塔射击
        manual_shot = False
        has_control = False
        # 游戏主循环
        while True:
            if self.health <= 0:
                return
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.quitGame()
                if event.type == pygame.MOUSEBUTTONUP:
                    # --左键选物品
                    if event.button == 1:
                        # ----鼠标点击在地图上
                        if self.map_rect.collidepoint(event.pos):
                            if self.mouse_carried:
                                if self.mouse_carried[0] == 'turret':
                                    self.buildTurret(event.pos)
                                elif self.mouse_carried[0] == 'XXX':
                                    self.sellTurret(event.pos)
                        # ----鼠标点击在工具栏
                        elif self.toolbar_rect.collidepoint(event.pos):
                            for button in self.buttons:
                                if button.rect.collidepoint(event.pos):
                                    if button.text == 'T1':
                                        button.onClick()
                                    elif button.text == 'T2':
                                        button.onClick()
                                    elif button.text == 'T3':
                                        button.onClick()
                                    elif button.text == 'XXX':
                                        button.onClick()
                                    elif button.text == 'Pause':
                                        button.onClick(screen)
                                    elif button.text == 'Quit':
                                        button.onClick()
                                    break
                    # --右键释放物品
                    if event.button == 3:
                        self.mouse_carried = []
                    # --按中间键手动控制炮塔射箭方向一次,否则自由射箭
                    if event.button == 2:
                        manual_shot = True
                if event.type == generate_enemies_event:
                    generate_enemies_flag = True
                if event.type == generate_enemy_event:
                    generate_enemy_flag = True
            # --生成敌人, 生成的敌人随当前已生成敌人的总次数的增加而变强变多
            if generate_enemies_flag:
                generate_enemies_flag = False
                num_generate_enemies += 1
                idx = 0
                for key, value in difficulty_dict.items():
                    idx += 1
                    if idx == len(difficulty_dict.keys()):
                        enemy_range = value['enemy_range']
                        num_enemy = value['num_enemy']
                        break
                    if num_generate_enemies <= int(key):
                        enemy_range = value['enemy_range']
                        num_enemy = value['num_enemy']
                        break
            if generate_enemy_flag and num_enemy:
                generate_enemy_flag = False
                num_enemy -= 1
                enemy = Enemy(random.choice(range(enemy_range)), self.cfg)
                self.enemies_group.add(enemy)
            # --射箭
            for turret in self.built_turret_group:
                if not manual_shot:
                    position = turret.position[0] + self.element_size // 2, turret.position[1]
                    arrow = turret.shot(position)
                else:
                    position = turret.position[0] + self.element_size // 2, turret.position[1]
                    mouse_pos = pygame.mouse.get_pos()
                    angle = math.atan((mouse_pos[1] - position[1]) / (mouse_pos[0] - position[0] + 1e-6))
                    arrow = turret.shot(position, angle)
                    has_control = True
                if arrow:
                    self.arrows_group.add(arrow)
                else:
                    has_control = False
            if has_control:
                has_control = False
                manual_shot = False
            # --移动箭和碰撞检测
            for arrow in self.arrows_group:
                arrow.move()
                points = [(arrow.rect.left, arrow.rect.top), (arrow.rect.left, arrow.rect.bottom), (arrow.rect.right, arrow.rect.top), (arrow.rect.right, arrow.rect.bottom)]
                if (not self.map_rect.collidepoint(points[0])) and (not self.map_rect.collidepoint(points[1])) and \
                   (not self.map_rect.collidepoint(points[2])) and (not self.map_rect.collidepoint(points[3])):
                    self.arrows_group.remove(arrow)
                    del arrow
                    continue
                for enemy in self.enemies_group:
                    if pygame.sprite.collide_rect(arrow, enemy):
                        enemy.life_value -= arrow.attack_power
                        self.arrows_group.remove(arrow)
                        del arrow
                        break
            self.draw(screen, map_path)
    '''将场景画到游戏界面上'''
    def draw(self, screen, map_path):
        self.drawToolbar(screen)
        self.loadMap(screen, map_path)
        self.drawMouseCarried(screen)
        self.drawBuiltTurret(screen)
        self.drawEnemies(screen)
        self.drawArrows(screen)
        pygame.display.flip()
    '''画出所有射出的箭'''
    def drawArrows(self, screen):
        for arrow in self.arrows_group:
            screen.blit(arrow.image, arrow.rect)
    '''画敌人'''
    def drawEnemies(self, screen):
        for enemy in self.enemies_group:
            if enemy.life_value <= 0:
                self.money += enemy.reward
                self.enemies_group.remove(enemy)
                del enemy
                continue
            res = enemy.move(self.element_size)
            if res:
                coord = self.find_next_path(enemy)
                if coord:
                    enemy.reached_path.append(enemy.coord)
                    enemy.coord = coord
                    enemy.position = self.coord2pos(coord)
                    enemy.rect.left, enemy.rect.top = enemy.position
                else:
                    self.health -= enemy.damage
                    self.enemies_group.remove(enemy)
                    del enemy
                    continue
            # 画血条
            green_len = max(0, enemy.life_value / enemy.max_life_value) * self.element_size
            if green_len > 0:
                pygame.draw.line(screen, (0, 255, 0), (enemy.position), (enemy.position[0] + green_len, enemy.position[1]), 1)
            if green_len < self.element_size:
                pygame.draw.line(screen, (255, 0, 0), (enemy.position[0] + green_len, enemy.position[1]), (enemy.position[0] + self.element_size, enemy.position[1]), 1)
            screen.blit(enemy.image, enemy.rect)
    '''画已经建造好的炮塔'''
    def drawBuiltTurret(self, screen):
        for turret in self.built_turret_group:
            screen.blit(turret.image, turret.rect)
    '''画鼠标携带物'''
    def drawMouseCarried(self, screen):
        if self.mouse_carried:
            position = pygame.mouse.get_pos()
            coord = self.pos2coord(position)
            position = self.coord2pos(coord)
            # 在地图里再画
            if self.map_rect.collidepoint(position):
                if self.mouse_carried[0] == 'turret':
                    screen.blit(self.mouse_carried[1].image, position)
                    self.mouse_carried[1].coord = coord
                    self.mouse_carried[1].position = position
                    self.mouse_carried[1].rect.left, self.mouse_carried[1].rect.top = position
                else:
                    screen.blit(self.mouse_carried[1], position)
    '''画工具栏'''
    def drawToolbar(self, screen):
        # 信息显示框
        info_color = (120, 20, 50)
        # --左
        pygame.draw.rect(screen, info_color, self.leftinfo_rect)
        left_title = self.info_font.render('Player info:', True, (255, 255, 255))
        money_info = self.info_font.render('Money: ' + str(self.money), True, (255, 255, 255))
        health_info = self.info_font.render('Health: ' + str(self.health), True, (255, 255, 255))
        screen.blit(left_title, (self.leftinfo_rect.left + 5, self.leftinfo_rect.top + 5))
        screen.blit(money_info, (self.leftinfo_rect.left + 5, self.leftinfo_rect.top + 35))
        screen.blit(health_info, (self.leftinfo_rect.left + 5, self.leftinfo_rect.top + 55))
        # --右
        pygame.draw.rect(screen, info_color, self.rightinfo_rect)
        right_title = self.info_font.render('Selected info:', True, (255, 255, 255))
        screen.blit(right_title, (self.rightinfo_rect.left + 5, self.rightinfo_rect.top + 5))
        # 中间部分
        pygame.draw.rect(screen, (127, 127, 127), self.toolbar_rect)
        for button in self.buttons:
            mouse_pos = pygame.mouse.get_pos()
            if button.rect.collidepoint(mouse_pos):
                self.showSelectedInfo(screen, button)
                button_color = (0, 200, 0)
            else:
                button_color = (0, 100, 0)
            pygame.draw.rect(screen, button_color, button.rect)
            button_text = self.button_font.render(button.text, True, (255, 255, 255))
            button_text_rect = button_text.get_rect()
            button_text_rect.center = (button.rect.centerx, button.rect.centery)
            screen.blit(button_text, button_text_rect)
    '''显示被鼠标选中按钮的作用信息'''
    def showSelectedInfo(self, screen, button):
        if button.text in ['T1', 'T2', 'T3']:
            turret = Turret({'T1': 0, 'T2': 1, 'T3': 2}[button.text], self.cfg)
            selected_info1 = self.info_font.render('Cost: ' + str(turret.price), True, (255, 255, 255))
            selected_info2 = self.info_font.render('Damage: ' + str(turret.arrow.attack_power), True, (255, 255, 255))
            selected_info3 = self.info_font.render('Affordable: ' + str(self.money >= turret.price), True, (255, 255, 255))
            screen.blit(selected_info1, (self.rightinfo_rect.left + 5, self.rightinfo_rect.top + 35))
            screen.blit(selected_info2, (self.rightinfo_rect.left + 5, self.rightinfo_rect.top + 55))
            screen.blit(selected_info3, (self.rightinfo_rect.left + 5, self.rightinfo_rect.top + 75))
        elif button.text == 'XXX':
            selected_info = self.info_font.render('Sell a turret', True, (255, 255, 255))
            screen.blit(selected_info, (self.rightinfo_rect.left + 5, self.rightinfo_rect.top + 35))
        elif button.text == 'Pause':
            selected_info = self.info_font.render('Pause game', True, (255, 255, 255))
            screen.blit(selected_info, (self.rightinfo_rect.left + 5, self.rightinfo_rect.top + 35))
        elif button.text == 'Quit':
            selected_info = self.info_font.render('Quit game', True, (255, 255, 255))
            screen.blit(selected_info, (self.rightinfo_rect.left + 5, self.rightinfo_rect.top + 35))
    '''出售炮塔(半价)'''
    def sellTurret(self, position):
        coord = self.pos2coord(position)
        for turret in self.built_turret_group:
            if coord == turret.coord:
                self.built_turret_group.remove(turret)
                self.money += int(turret.price * 0.5)
                del turret
                break
    '''建造炮塔'''
    def buildTurret(self, position):
        turret = self.mouse_carried[1]
        coord = self.pos2coord(position)
        position = self.coord2pos(coord)
        turret.position = position
        turret.coord = coord
        turret.rect.left, turret.rect.top = position
        if self.money - turret.price >= 0:
            if self.current_map.get(turret.coord) in self.placeable.keys():
                self.money -= turret.price
                self.built_turret_group.add(turret)
                if self.mouse_carried[1].turret_type == 0:
                    self.mouse_carried = []
                    self.takeT1()
                elif self.mouse_carried[1].turret_type == 1:
                    self.mouse_carried = []
                    self.takeT2()
                elif self.mouse_carried[1].turret_type == 2:
                    self.mouse_carried = []
                    self.takeT3()
    '''拿炮塔1'''
    def takeT1(self):
        T1 = Turret(0, self.cfg)
        if self.money >= T1.price:
            self.mouse_carried = ['turret', T1]
    '''拿炮塔2'''
    def takeT2(self):
        T2 = Turret(1, self.cfg)
        if self.money >= T2.price:
            self.mouse_carried = ['turret', T2]
    '''拿炮塔3'''
    def takeT3(self):
        T3 = Turret(2, self.cfg)
        if self.money >= T3.price:
            self.mouse_carried = ['turret', T3]
    '''出售炮塔'''
    def takeXXX(self):
        XXX = pygame.image.load(self.cfg.IMAGEPATHS['game']['x'])
        self.mouse_carried = ['XXX', XXX]
    '''找下一个路径单元'''
    def find_next_path(self, enemy):
        x, y = enemy.coord
        # 优先级: 下右左上
        neighbours = [(x, y+1), (x+1, y), (x-1, y), (x, y-1)]
        for neighbour in neighbours:
            if (neighbour in self.path_list) and (neighbour not in enemy.reached_path):
                return neighbour
        return None
    '''将真实坐标转为地图坐标, 20个单位长度的真实坐标=地图坐标'''
    def pos2coord(self, position):
        return (position[0] // self.element_size, position[1] // self.element_size)
    '''将地图坐标转为真实坐标, 20个单位长度的真实坐标=地图坐标'''
    def coord2pos(self, coord):
        return (coord[0] * self.element_size, coord[1] * self.element_size)
    '''导入地图'''
    def loadMap(self, screen, map_path):
        map_file = open(map_path, 'r')
        idx_j = -1
        for line in map_file.readlines():
            line = line.strip()
            if not line:
                continue
            idx_j += 1
            idx_i = -1
            for col in line:
                try:
                    element_type = int(col)
                    element_img = self.map_elements.get(element_type)
                    element_rect = element_img.get_rect()
                    idx_i += 1
                    element_rect.left, element_rect.top = self.element_size * idx_i, self.element_size * idx_j
                    self.map_surface.blit(element_img, element_rect)
                    self.current_map[idx_i, idx_j] = element_type
                    # 把道路记下来
                    if element_type == 1:
                        self.path_list.append((idx_i, idx_j))
                except:
                    continue
        # 放洞穴和大本营
        self.map_surface.blit(self.cave, (0, 0))
        self.map_surface.blit(self.nexus, (740, 400))
        # 大本营的血条
        nexus_width = self.nexus.get_rect().width
        green_len = max(0, self.health / self.max_health) * nexus_width
        if green_len > 0:
            pygame.draw.line(self.map_surface, (0, 255, 0), (740, 400), (740 + green_len, 400), 3)
        if green_len < nexus_width:
            pygame.draw.line(self.map_surface, (255, 0, 0), (740 + green_len, 400), (740 + nexus_width, 400), 3)
        screen.blit(self.map_surface, (0, 0))
        map_file.close()
    '''暂停游戏'''
    def pauseGame(self, screen):
        pause_interface = PauseInterface(self.cfg)
        pause_interface.update(screen)
    '''退出游戏'''
    def quitGame(self):
        pygame.quit()
        sys.exit(0)

7、游戏暂停

import sys
import pygame
 
 
'''游戏暂停主界面'''
class MainInterface(pygame.sprite.Sprite):
    def __init__(self, cfg):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.IMAGEPATHS['pause']['gamepaused']).convert()
        self.rect = self.image.get_rect()
        self.rect.center = cfg.SCREENSIZE[0] / 2, cfg.SCREENSIZE[1] / 2
    '''更新函数'''
    def update(self):
        pass
 
 
'''恢复游戏按钮'''
class ResumeButton(pygame.sprite.Sprite):
    def __init__(self, cfg, position=(391, 380)):
        pygame.sprite.Sprite.__init__(self)
        self.image_1 = pygame.image.load(cfg.IMAGEPATHS['pause']['resume_black']).convert()
        self.image_2 = pygame.image.load(cfg.IMAGEPATHS['pause']['resume_red']).convert()
        self.image = self.image_1
        self.rect = self.image.get_rect()
        self.rect.center = position
    '''更新函数: 不断地更新检测鼠标是否在按钮上'''
    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            self.image = self.image_2
        else:
            self.image = self.image_1
 
 
'''游戏暂停界面'''
class PauseInterface():
    def __init__(self, cfg):
        self.main_interface = MainInterface(cfg)
        self.resume_btn = ResumeButton(cfg)
        self.components = pygame.sprite.LayeredUpdates(self.main_interface, self.resume_btn)
    '''外部调用'''
    def update(self, screen):
        clock = pygame.time.Clock()
        background = pygame.Surface(screen.get_size())
        count = 0
        flag = True
        while True:
            count += 1
            clock.tick(60)
            self.components.clear(screen, background)
            self.components.update()
            if count % 10 == 0:
                count = 0
                flag = not flag
            if flag:
                self.components.draw(screen)
            else:
                screen.blit(self.main_interface.image, self.main_interface.rect)
            pygame.display.flip()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit(0)
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:
                        mouse_pos = pygame.mouse.get_pos()
                        if self.resume_btn.rect.collidepoint(mouse_pos):
                            return True

8、游戏结束及分数

import sys
import pygame
 
 
'''游戏结束主界面'''
class MainInterface(pygame.sprite.Sprite):
    def __init__(self, cfg):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(cfg.IMAGEPATHS['end']['gameover']).convert()
        self.rect = self.image.get_rect()
        self.rect.center = cfg.SCREENSIZE[0] / 2, cfg.SCREENSIZE[1] / 2
    '''更新函数'''
    def update(self):
        pass
 
 
'''继续游戏按钮'''
class ContinueButton(pygame.sprite.Sprite):
    def __init__(self, cfg, position=(400, 409)):
        pygame.sprite.Sprite.__init__(self)
        self.image_1 = pygame.image.load(cfg.IMAGEPATHS['end']['continue_black']).convert()
        self.image_2 = pygame.image.load(cfg.IMAGEPATHS['end']['continue_red']).convert()
        self.image = self.image_1
        self.rect = self.image.get_rect()
        self.rect.center = position
    '''更新函数: 不断地更新检测鼠标是否在按钮上'''
    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos):
            self.image = self.image_2
        else:
            self.image = self.image_1
 
 
'''游戏结束类'''
class EndInterface():
    def __init__(self, cfg):
        self.main_interface = MainInterface(cfg)
        self.continue_btn = ContinueButton(cfg)
        self.components = pygame.sprite.LayeredUpdates(self.main_interface, self.continue_btn)
    '''外部调用'''
    def update(self, screen):
        clock = pygame.time.Clock()
        background = pygame.Surface(screen.get_size())
        count = 0
        flag = True
        while True:
            count += 1
            clock.tick(60)
            self.components.clear(screen, background)
            self.components.update()
            if count % 10 == 0:
                count = 0
                flag = not flag
            if flag:
                self.components.draw(screen)
            else:
                screen.blit(self.main_interface.image, self.main_interface.rect)
            pygame.display.flip()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit(0)
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:
                        mouse_pos = pygame.mouse.get_pos()
                        if self.continue_btn.rect.collidepoint(mouse_pos):
                            return True

9、引入音频、图片、地图、难度json

启动游戏主程序

tower.py

import cfg
import pygame
from modules import *
 
 
'''主函数'''
def main():
    pygame.init()
    pygame.mixer.init()
    pygame.mixer.music.load(cfg.AUDIOPATHS['bgm'])
    pygame.mixer.music.play(-1, 0.0)
    pygame.mixer.music.set_volume(0.25)
    screen = pygame.display.set_mode(cfg.SCREENSIZE)
    pygame.display.set_caption("塔防游戏 —— hacklex")
    # 调用游戏开始界面
    start_interface = StartInterface(cfg)
    is_play = start_interface.update(screen)
    if not is_play:
        return
    # 调用游戏界面
    while True:
        choice_interface = ChoiceInterface(cfg)
        map_choice, difficulty_choice = choice_interface.update(screen)
        game_interface = GamingInterface(cfg)
        game_interface.start(screen, map_path=cfg.MAPPATHS[str(map_choice)], difficulty_path=cfg.DIFFICULTYPATHS[str(difficulty_choice)])
        end_interface = EndInterface(cfg)
        end_interface.update(screen)
 
 
'''run'''
if __name__ == '__main__':
    main()

四、游戏启动方法

1、开发工具启动

如果你配置了开发工具的环境VScode、sublimeText、notepad+、pycharm什么的,可以直接在工具中,运行游戏。

如果没配置,可以使用命令启动。

2、命令行启动 gif

进入代码根目录,按住shift+鼠标右键,选择 此处运行powershell,然后执行代码:python tower.py

即可 运行。

Python Pygame实战之塔防游戏的实现

以上就是Python Pygame实战之塔防游戏的实现的详细内容,更多关于Python Pygame塔防游戏的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python实现将sqlite数据库导出转成Excel(xls)表的方法
Jul 17 Python
Python算法之求n个节点不同二叉树个数
Oct 27 Python
Python绘制的二项分布概率图示例
Aug 22 Python
selenium python 实现基本自动化测试的示例代码
Feb 25 Python
详解pytorch 0.4.0迁移指南
Jun 16 Python
tensorflow estimator 使用hook实现finetune方式
Jan 21 Python
手把手教你进行Python虚拟环境配置教程
Feb 03 Python
解决python中import文件夹下面py文件报错问题
Jun 01 Python
Python csv文件记录流程代码解析
Jul 16 Python
PyTorch中Tensor的数据类型和运算的使用
Sep 03 Python
matplotlib bar()实现多组数据并列柱状图通用简便创建方法
Feb 24 Python
python 镜像环境搭建总结
Sep 23 Python
pytorch中的 .view()函数的用法介绍
Mar 17 #Python
Python绘画好看的星空图
opencv深入浅出了解机器学习和深度学习
Python与C++中梯度方向直方图的实现
JAVA SpringMVC实现自定义拦截器
Mar 16 #Python
Python Pandas 删除列操作
Mar 16 #Python
Python实现批量自动整理文件
Mar 16 #Python
You might like
PHP操作xml代码
2010/06/17 PHP
php变量作用域的深入解析
2013/06/03 PHP
基于PHP文件操作的详细诠释
2013/06/21 PHP
PHP安全的URL字符串base64编码和解码
2014/06/19 PHP
php中使用session防止用户非法登录后台的方法
2015/01/27 PHP
CodeIgniter视图使用注意事项
2016/01/20 PHP
PHP获取HTTP body内容的方法
2018/12/31 PHP
js跨域问题浅析及解决方法优缺点对比
2014/11/08 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
2015/01/28 Javascript
node.js读取文件到字符串的方法
2015/06/29 Javascript
Bootstrap安装环境配置教程分享
2016/05/27 Javascript
js 将input框中的输入自动转化成半角大写(税号输入框)
2017/02/16 Javascript
教你用十行node.js代码读取docx的文本
2017/03/08 Javascript
js实现会跳动的日历效果(完整实例)
2017/10/18 Javascript
js最简单的双向绑定实例讲解
2018/01/02 Javascript
Layui选项卡制作历史浏览记录的方法
2019/09/28 Javascript
Python实现在Linux系统下更改当前进程运行用户
2015/02/04 Python
python实现连接mongodb的方法
2015/05/08 Python
解决Python requests 报错方法集锦
2017/03/19 Python
TensorFlow实现非线性支持向量机的实现方法
2018/04/28 Python
Python中使用Counter进行字典创建以及key数量统计的方法
2018/07/06 Python
Django-Model数据库操作(增删改查、连表结构)详解
2019/07/17 Python
Python Print实现在输出中插入变量的例子
2019/12/25 Python
推荐技术人员一款Python开源库(造数据神器)
2020/07/08 Python
详细分析Python可变对象和不可变对象
2020/07/09 Python
Python获取指定网段正在使用的IP
2020/12/14 Python
使用CSS3来绘制一个月食图案
2015/07/18 HTML / CSS
巴西最大的家具及装饰用品店:Mobly
2017/10/11 全球购物
Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用?
2015/08/04 面试题
给民警的表扬信
2014/01/08 职场文书
《红军不怕远征难》教学反思
2014/04/14 职场文书
幼儿评语大全
2014/04/30 职场文书
送给客户微信问候语!
2019/07/04 职场文书
python 如何执行控制台命令与操作剪切板
2021/05/20 Python
关于springboot配置druid数据源不生效问题(踩坑记)
2021/09/25 Java/Android
把77A收信机改造成收音机
2022/04/05 无线电