python实现Flappy Bird源码


Posted in Python onDecember 24, 2018

Flappy Bird是前段时间(好像一年or两年前....)特别火的有一个小游戏,相信大家都玩过。

Flappy Bird操作简单,通过点击手机屏幕使Bird上升,穿过柱状障碍物之后得分,碰到则游戏结束。由于障碍物高低不等,控制Bird上升和下降需要反应快并且灵活,要得到较高的分数并不容易。作为一个游戏渣,我最高纪录是8分......

我记得当时还想,是谁发明了这个小游戏,逼死强迫症,记得当时本科时好多人在玩....

无意间在GitHub上看到了python实现的代码,所以拿来学习了一番。代码思路比较简洁。

因为第一次接触pygame,所以代码注释写的比较详细,也算是一次新体验。

玩法:空格键进入游戏,↑控制小鸟飞行

注意:需要安装pygame模块

代码:

# -*- coding: utf8 -*-
 
from itertools import cycle
import random
import sys
 
import pygame #将pygame库导入到python程序中
from pygame.locals import * #需要引入pygame中的所有常量。
 
 
FPS = 30
SCREENWIDTH = 288 #屏幕宽度
SCREENHEIGHT = 512 #屏幕高度
# amount by which base can maximum shift to left
PIPEGAPSIZE = 100 # gap between upper and lower part of pipe 管道上下之间的间隙
BASEY  = SCREENHEIGHT * 0.79 #base那个条条所在的高度 注意以左上角为坐标起始点 所以这个高度是往下为正
# image, sound and hitmask dicts
IMAGES, SOUNDS, HITMASKS = {}, {}, {} #图像,声音,撞击的文件
 
# list of all possible players (tuple of 3 positions of flap) #三种小鸟造型
PLAYERS_LIST = (
 # red bird
 (
  'assets/sprites/redbird-upflap.png',
  'assets/sprites/redbird-midflap.png',
  'assets/sprites/redbird-downflap.png',
 ),
 # blue bird
 (
  # amount by which base can maximum shift to left
  'assets/sprites/bluebird-upflap.png',
  'assets/sprites/bluebird-midflap.png',
  'assets/sprites/bluebird-downflap.png',
 ),
 # yellow bird
 (
  'assets/sprites/yellowbird-upflap.png',
  'assets/sprites/yellowbird-midflap.png',
  'assets/sprites/yellowbird-downflap.png',
 ),
)
 
# list of backgrounds 两种背景,一种白天,一种黑夜
BACKGROUNDS_LIST = (
 'assets/sprites/background-day.png',
 'assets/sprites/background-night.png',
)
 
# list of pipes 管道的两种颜色,一种绿色,一种红色
PIPES_LIST = (
 'assets/sprites/pipe-green.png',
 'assets/sprites/pipe-red.png',
)
 
 
try:
 xrange
except NameError:
 xrange = range
 
 
def main():
 global SCREEN, FPSCLOCK
 pygame.init() #经过初始化以后我们就可以尽情地使用pygame了。
 
 #使用Pygame时钟之前,必须先创建Clock对象的一个实例,
 FPSCLOCK = pygame.time.Clock()#控制每个循环多长时间运行一次。这就像一个定时器在控制时间进程,指出“现在开始下一个循环”!现在开始下一个循环!……
 
 SCREEN = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT))#通常来说我们需要先创建一个窗口,方便我们与程序的交互。
 pygame.display.set_caption('Flappy Bird')#设置窗口标题
 
 # numbers sprites for score display #加载并转换图像
 #在pygame中可以使用pygame.image.load()函数来加载位图 (支持jpg,png,gif,bmp,pcx,tif,tga等多种图片格式)。
 #convert_alpha()方法会使用透明的方法绘制前景对象。
 # 因此在加载一个有alpha通道的素材时(比如PNG TGA),需要使用convert_alpha()方法,当然普通的图片也是可以使用这个方法的,用了也不会有什么副作用。
 IMAGES['numbers'] = (
  pygame.image.load('assets/sprites/0.png').convert_alpha(),
  pygame.image.load('assets/sprites/1.png').convert_alpha(),
  pygame.image.load('assets/sprites/2.png').convert_alpha(),
  pygame.image.load('assets/sprites/3.png').convert_alpha(),
  pygame.image.load('assets/sprites/4.png').convert_alpha(),
  pygame.image.load('assets/sprites/5.png').convert_alpha(),
  pygame.image.load('assets/sprites/6.png').convert_alpha(),
  pygame.image.load('assets/sprites/7.png').convert_alpha(),
  pygame.image.load('assets/sprites/8.png').convert_alpha(),
  pygame.image.load('assets/sprites/9.png').convert_alpha()
 )
 
 # game over sprite 游戏结束显示的图像
 IMAGES['gameover'] = pygame.image.load('assets/sprites/gameover.png').convert_alpha()
 # message sprite for welcome screen 欢迎界面显示的图像
 IMAGES['message'] = pygame.image.load('assets/sprites/message.png').convert_alpha()
 # base (ground) sprite 始终显示的base图像
 IMAGES['base'] = pygame.image.load('assets/sprites/base.png').convert_alpha()
 
 # sounds
 # WAV版 OGG版是指游戏的音频格式
 # WAV版是属于游戏原版
 # OGG是大大们通过转换器把音频格式的WAV改成OGG,这样游戏的配置提高要求使游戏本身的体积而缩小节省了空间。
 #可以看一下同一个音频 ogg版的是比wav版的文件小很多
 if 'win' in sys.platform: #判断当前系统平台 来设置声音文件后缀
  soundExt = '.wav'
 else:
  soundExt = '.ogg'
 
 # 音效:pygame.mixer
 # sound = pygame.mixer.Sound('/home/liumin/love.wav')使用指定文件名载入一个音频文件,并创建一个Sound对象。 音频文件可以是wav,ogg等格式。
 # 音频文件的内容会被全部载入到内存中。
 SOUNDS['die'] = pygame.mixer.Sound('assets/audio/die' + soundExt)
 SOUNDS['hit'] = pygame.mixer.Sound('assets/audio/hit' + soundExt)
 SOUNDS['point'] = pygame.mixer.Sound('assets/audio/point' + soundExt)
 SOUNDS['swoosh'] = pygame.mixer.Sound('assets/audio/swoosh' + soundExt)
 SOUNDS['wing'] = pygame.mixer.Sound('assets/audio/wing' + soundExt)
 
 while True:
  # select random background sprites 加载随机背景 (白天或者黑夜)
  randBg = random.randint(0, len(BACKGROUNDS_LIST) - 1)#随机选择0或者1
  IMAGES['background'] = pygame.image.load(BACKGROUNDS_LIST[randBg]).convert()#加载随机背景
 
  # select random player sprites 加载随机角色 (红色、蓝色、黄色小鸟)
  randPlayer = random.randint(0, len(PLAYERS_LIST) - 1)
  IMAGES['player'] = (
   pygame.image.load(PLAYERS_LIST[randPlayer][0]).convert_alpha(),
   pygame.image.load(PLAYERS_LIST[randPlayer][1]).convert_alpha(),
   pygame.image.load(PLAYERS_LIST[randPlayer][2]).convert_alpha(),
  )
 
  # select random pipe sprites 加载随机管道样式
  pipeindex = random.randint(0, len(PIPES_LIST) - 1)
  IMAGES['pipe'] = (
   pygame.transform.rotate(
    pygame.image.load(PIPES_LIST[pipeindex]).convert_alpha(), 180),#旋转180度
   pygame.image.load(PIPES_LIST[pipeindex]).convert_alpha(),
  )#一个上面的管道 一个下面的管道
 
  # hismask for pipes #得到管道的边界mask
  HITMASKS['pipe'] = (
   getHitmask(IMAGES['pipe'][0]),
   getHitmask(IMAGES['pipe'][1]),
  )
 
  # hitmask for player #得到player的边界mask
  HITMASKS['player'] = (
   getHitmask(IMAGES['player'][0]),
   getHitmask(IMAGES['player'][1]),
   getHitmask(IMAGES['player'][2]),
  )
 
  movementInfo = showWelcomeAnimation()#返回'playery'(player所在位置),'basex'(base图像所在位置) 'playerIndexGen'(飞行姿势index)
  crashInfo = mainGame(movementInfo)
  showGameOverScreen(crashInfo)
 
 
def showWelcomeAnimation():
 """Shows welcome screen animation of flappy bird"""
 # index of player to blit on screen
 playerIndex = 0
 playerIndexGen = cycle([0, 1, 2, 1])
 # iterator used to change playerIndex after every 5th iteration
 loopIter = 0
 
 #player所在位置
 playerx = int(SCREENWIDTH * 0.2)
 playery = int((SCREENHEIGHT - IMAGES['player'][0].get_height()) / 2)
 #欢迎图像所在位置
 messagex = int((SCREENWIDTH - IMAGES['message'].get_width()) / 2)
 messagey = int(SCREENHEIGHT * 0.12)
 
 basex = 0
 # amount by which base can maximum shift to left 可以最大限度地向左移动的距离
 baseShift = IMAGES['base'].get_width() - IMAGES['background'].get_width()
 
 # player shm for up-down motion on welcome screen 角色在欢迎屏幕上进行上下移动
 playerShmVals = {'val': 0, 'dir': 1}
 
 while True:
  for event in pygame.event.get():#使用pygame.event.get()来处理所有的事件,
   if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):#如果 quit 或者 按键之后又按下esc,就结束游戏
    pygame.quit()
    sys.exit()
   if event.type == KEYDOWN and (event.key == K_SPACE or event.key == K_UP):#如果按键之后点击或者按下↑
    # make first flap sound and return values for mainGame
    SOUNDS['wing'].play()#播放飞的特效声音
    return {#返回初始位置 进入maingame
     'playery': playery + playerShmVals['val'],
     'basex': basex,
     'playerIndexGen': playerIndexGen,
    }
 
  # adjust playery, playerIndex, basex
  if (loopIter + 1) % 5 == 0:
   playerIndex = next(playerIndexGen)#获得匹配元素集合中每个元素紧邻的同胞元素 调整飞行姿势图片
  loopIter = (loopIter + 1) % 30
  basex = -((-basex + 4) % baseShift)
  playerShm(playerShmVals)
 
  # draw sprites
  #screen.blit(space, (0,0))可以绘制位图 第一个参数是加载完成的位图,第二个参数是绘制的起始坐标。
  SCREEN.blit(IMAGES['background'], (0,0))
  SCREEN.blit(IMAGES['player'][playerIndex],
     (playerx, playery + playerShmVals['val']))
  SCREEN.blit(IMAGES['message'], (messagex, messagey))
  SCREEN.blit(IMAGES['base'], (basex, BASEY))
 
  pygame.display.update()#更新整个窗口
  FPSCLOCK.tick(FPS)#循环应该多长时间运行一次
 
 
def mainGame(movementInfo):
 score = playerIndex = loopIter = 0#初始得分以及初始player的姿态以及迭代次数都为0
 playerIndexGen = movementInfo['playerIndexGen']#得到飞行姿势
 playerx, playery = int(SCREENWIDTH * 0.2), movementInfo['playery']#player所在位置
 
 basex = movementInfo['basex']#base图像所在位置
 baseShift = IMAGES['base'].get_width() - IMAGES['background'].get_width()
 
 # get 2 new pipes to add to upperPipes lowerPipes list
 newPipe1 = getRandomPipe()
 newPipe2 = getRandomPipe()
 
 # list of upper pipes
 upperPipes = [
  {'x': SCREENWIDTH + 200, 'y': newPipe1[0]['y']},
  {'x': SCREENWIDTH + 200 + (SCREENWIDTH / 2), 'y': newPipe2[0]['y']},
 ]
 
 # list of lowerpipe
 lowerPipes = [
  {'x': SCREENWIDTH + 200, 'y': newPipe1[1]['y']},
  {'x': SCREENWIDTH + 200 + (SCREENWIDTH / 2), 'y': newPipe2[1]['y']},
 ]
 
 pipeVelX = -4
 
 # player velocity, max velocity, downward accleration, accleration on flap 角色速度,最大速度,向下加速度,襟翼加速度
 playerVelY = -9 # player's velocity along Y, default same as playerFlapped
 playerMaxVelY = 10 # max vel along Y, max descend speed
 playerMinVelY = -8 # min vel along Y, max ascend speed
 playerAccY = 1 # players downward accleration
 playerRot  = 45 # player's rotation
 playerVelRot = 3 # angular speed
 playerRotThr = 20 # rotation threshold
 playerFlapAcc = -9 # players speed on flapping
 playerFlapped = False # True when player flaps
 
 
 while True:
  for event in pygame.event.get():
   if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
    pygame.quit()
    sys.exit()
   if event.type == KEYDOWN and (event.key == K_SPACE or event.key == K_UP):
    if playery > -2 * IMAGES['player'][0].get_height():#如果点击
     playerVelY = playerFlapAcc#上升
     playerFlapped = True
     SOUNDS['wing'].play()#并播放飞行音效
 
  # check for crash here
  crashTest = checkCrash({'x': playerx, 'y': playery, 'index': playerIndex},
        upperPipes, lowerPipes)
  if crashTest[0]:#如果掉在地上或者撞击到了管道,就返回结束游戏
   return {
    'y': playery,
    'groundCrash': crashTest[1],
    'basex': basex,
    'upperPipes': upperPipes,
    'lowerPipes': lowerPipes,
    'score': score,
    'playerVelY': playerVelY,
    'playerRot': playerRot
   }
 
  # check for score
  playerMidPos = playerx + IMAGES['player'][0].get_width() / 2
  for pipe in upperPipes:
   pipeMidPos = pipe['x'] + IMAGES['pipe'][0].get_width() / 2
   if pipeMidPos <= playerMidPos < pipeMidPos + 4:#当角色达到管道缝隙的中间+4时,score+1,并且在此时播放得分音效
    score += 1
    SOUNDS['point'].play()
 
  # playerIndex basex change
  if (loopIter + 1) % 3 == 0:
   playerIndex = next(playerIndexGen)
  loopIter = (loopIter + 1) % 30
  basex = -((-basex + 100) % baseShift)
 
  # rotate the player
  if playerRot > -90:
   playerRot -= playerVelRot
 
  # player's movement
  if playerVelY < playerMaxVelY and not playerFlapped:
   playerVelY += playerAccY
  if playerFlapped:
   playerFlapped = False
 
   # more rotation to cover the threshold (calculated in visible rotation)
   playerRot = 45
 
  playerHeight = IMAGES['player'][playerIndex].get_height()
  playery += min(playerVelY, BASEY - playery - playerHeight)
 
  # move pipes to left
  for uPipe, lPipe in zip(upperPipes, lowerPipes):
   uPipe['x'] += pipeVelX #管道移动
   lPipe['x'] += pipeVelX
 
  # add new pipe when first pipe is about to touch left of screen
  if 0 < upperPipes[0]['x'] < 5:#当第一个管道移动到屏幕左侧边缘时,生成下一个管道
   newPipe = getRandomPipe()
   upperPipes.append(newPipe[0])
   lowerPipes.append(newPipe[1])
 
  # remove first pipe if its out of the screen
  if upperPipes[0]['x'] < -IMAGES['pipe'][0].get_width(): #当管道移动到屏幕外侧后,删除它
   upperPipes.pop(0)
   lowerPipes.pop(0)
 
  # draw sprites
  SCREEN.blit(IMAGES['background'], (0,0))
 
  for uPipe, lPipe in zip(upperPipes, lowerPipes):
   SCREEN.blit(IMAGES['pipe'][0], (uPipe['x'], uPipe['y']))
   SCREEN.blit(IMAGES['pipe'][1], (lPipe['x'], lPipe['y']))
 
  SCREEN.blit(IMAGES['base'], (basex, BASEY))
  # print score so player overlaps the score
  showScore(score) #显示得分
 
  # Player rotation has a threshold
  visibleRot = playerRotThr
  if playerRot <= playerRotThr:
   visibleRot = playerRot
  
  playerSurface = pygame.transform.rotate(IMAGES['player'][playerIndex], visibleRot)#旋转角色
  SCREEN.blit(playerSurface, (playerx, playery))#显示旋转后的角色
 
  pygame.display.update()#更新窗口
  FPSCLOCK.tick(FPS)#循环应该多长时间运行一次
 
 
def showGameOverScreen(crashInfo):
 """crashes the player down ans shows gameover image"""
 score = crashInfo['score']#获取得分
 playerx = SCREENWIDTH * 0.2
 playery = crashInfo['y']
 playerHeight = IMAGES['player'][0].get_height()
 playerVelY = crashInfo['playerVelY']
 playerAccY = 2
 playerRot = crashInfo['playerRot']
 playerVelRot = 7
 
 basex = crashInfo['basex']
 
 upperPipes, lowerPipes = crashInfo['upperPipes'], crashInfo['lowerPipes']
 
 # play hit and die sounds
 SOUNDS['hit'].play()
 if not crashInfo['groundCrash']:#如果没有撞击到地面,就播放die音效就可以了
  SOUNDS['die'].play()
 
 while True:
  for event in pygame.event.get():
   if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
    pygame.quit()
    sys.exit()
   if event.type == KEYDOWN and (event.key == K_SPACE or event.key == K_UP):
    if playery + playerHeight >= BASEY - 1:
     return
 
  # player y shift
  if playery + playerHeight < BASEY - 1:
   playery += min(playerVelY, BASEY - playery - playerHeight)
 
  # player velocity change
  if playerVelY < 15:
   playerVelY += playerAccY
 
  # rotate only when it's a pipe crash
  if not crashInfo['groundCrash']:
   if playerRot > -90:
    playerRot -= playerVelRot
 
  # draw sprites
  SCREEN.blit(IMAGES['background'], (0,0))
 
  for uPipe, lPipe in zip(upperPipes, lowerPipes):
   SCREEN.blit(IMAGES['pipe'][0], (uPipe['x'], uPipe['y']))
   SCREEN.blit(IMAGES['pipe'][1], (lPipe['x'], lPipe['y']))
 
  SCREEN.blit(IMAGES['base'], (basex, BASEY))
  showScore(score)
 
  playerSurface = pygame.transform.rotate(IMAGES['player'][1], playerRot)
  SCREEN.blit(playerSurface, (playerx,playery))
 
  FPSCLOCK.tick(FPS)
  pygame.display.update()
 
 
def playerShm(playerShm):
 """oscillates the value of playerShm['val'] between 8 and -8"""
 if abs(playerShm['val']) == 8:
  playerShm['dir'] *= -1
 
 if playerShm['dir'] == 1:
   playerShm['val'] += 1
 else:
  playerShm['val'] -= 1
 
 
def getRandomPipe():#随机生成随机高度的管道 ????????还需要看细节
 """returns a randomly generated pipe"""
 # y of gap between upper and lower pipe
 gapY = random.randrange(0, int(BASEY * 0.6 - PIPEGAPSIZE))
 gapY += int(BASEY * 0.2)
 pipeHeight = IMAGES['pipe'][0].get_height()
 pipeX = SCREENWIDTH + 10
 
 return [
  {'x': pipeX, 'y': gapY - pipeHeight}, # upper pipe
  {'x': pipeX, 'y': gapY + PIPEGAPSIZE}, # lower pipe
 ]
 
 
def showScore(score):
 """displays score in center of screen"""
 scoreDigits = [int(x) for x in list(str(score))]
 totalWidth = 0 # total width of all numbers to be printed
 
 for digit in scoreDigits:
  totalWidth += IMAGES['numbers'][digit].get_width()
 
 Xoffset = (SCREENWIDTH - totalWidth) / 2
 
 for digit in scoreDigits:
  SCREEN.blit(IMAGES['numbers'][digit], (Xoffset, SCREENHEIGHT * 0.1))#显示得分
  Xoffset += IMAGES['numbers'][digit].get_width()
 
 
def checkCrash(player, upperPipes, lowerPipes):
 """returns True if player collders with base or pipes."""
 pi = player['index']#飞行姿势
 player['w'] = IMAGES['player'][0].get_width()
 player['h'] = IMAGES['player'][0].get_height()
 
 # if player crashes into ground 掉在地上
 if player['y'] + player['h'] >= BASEY - 1:
  return [True, True] #返回
 else:
 
  playerRect = pygame.Rect(player['x'], player['y'],
      player['w'], player['h'])
  pipeW = IMAGES['pipe'][0].get_width()
  pipeH = IMAGES['pipe'][0].get_height()
 
  for uPipe, lPipe in zip(upperPipes, lowerPipes):
   # upper and lower pipe rects
   uPipeRect = pygame.Rect(uPipe['x'], uPipe['y'], pipeW, pipeH)
   lPipeRect = pygame.Rect(lPipe['x'], lPipe['y'], pipeW, pipeH)
 
   # player and upper/lower pipe hitmasks
   pHitMask = HITMASKS['player'][pi]
   uHitmask = HITMASKS['pipe'][0]
   lHitmask = HITMASKS['pipe'][1]
 
   # if bird collided with upipe or lpipe
   uCollide = pixelCollision(playerRect, uPipeRect, pHitMask, uHitmask)
   lCollide = pixelCollision(playerRect, lPipeRect, pHitMask, lHitmask)
 
   if uCollide or lCollide:#如果撞击到了上管道或者下管道 返回
    return [True, False]
 
 return [False, False]
 
def pixelCollision(rect1, rect2, hitmask1, hitmask2):
 """Checks if two objects collide and not just their rects"""
 rect = rect1.clip(rect2)#角色和管道之间重合的情况
 
 if rect.width == 0 or rect.height == 0:#没重合就是没撞击到
  return False
 
 x1, y1 = rect.x - rect1.x, rect.y - rect1.y
 x2, y2 = rect.x - rect2.x, rect.y - rect2.y
 
 for x in xrange(rect.width):
  for y in xrange(rect.height):
   if hitmask1[x1+x][y1+y] and hitmask2[x2+x][y2+y]:#撞击到了
    return True
 return False
 
def getHitmask(image):
 """returns a hitmask using an image's alpha."""
 #得到撞击mask
 mask = []
 for x in xrange(image.get_width()):
  mask.append([])
  for y in xrange(image.get_height()):
   mask[x].append(bool(image.get_at((x,y))[3]))
 return mask
 
if __name__ == '__main__':
 main()

游戏截图:

python实现Flappy Bird源码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之总结参数的传递
Oct 10 Python
利用Python的Flask框架来构建一个简单的数字商品支付解决方案
Mar 31 Python
python实现带错误处理功能的远程文件读取方法
Apr 29 Python
Python实现文件按照日期命名的方法
Jul 09 Python
python高手之路python处理excel文件(方法汇总)
Jan 07 Python
python实现SMTP邮件发送功能
Jun 16 Python
django实现同一个ip十分钟内只能注册一次的实例
Nov 03 Python
python3.x实现发送邮件功能
May 22 Python
Python split() 函数拆分字符串将字符串转化为列的方法
Jul 16 Python
Django CSRF跨站请求伪造防护过程解析
Jul 31 Python
keras 权重保存和权重载入方式
May 21 Python
python 如何用urllib与服务端交互(发送和接收数据)
Mar 04 Python
python3安装speech语音模块的方法
Dec 24 #Python
对Python 语音识别框架详解
Dec 24 #Python
python抓取网页内容并进行语音播报的方法
Dec 24 #Python
解决pyttsx3无法封装的问题
Dec 24 #Python
pyttsx3实现中文文字转语音的方法
Dec 24 #Python
python实现flappy bird游戏
Dec 24 #Python
Python爬虫实现获取动态gif格式搞笑图片的方法示例
Dec 24 #Python
You might like
PHP写UltraEdit插件脚本实现方法
2011/12/26 PHP
PHP使用array_fill定义多维数组的方法
2015/03/18 PHP
PHP入门教程之自定义函数用法详解(创建,调用,变量,参数,返回值等)
2016/09/11 PHP
php自定义函数实现统计中文字符串长度的方法小结
2017/04/15 PHP
Javascript图像处理—虚拟边缘介绍及使用方法
2012/12/27 Javascript
window.location.href = window.location.href 跳转无反应 a超链接onclick事件写法
2013/08/21 Javascript
Jquery插件编写简明教程
2014/03/25 Javascript
js去除输入框中所有的空格和禁止输入空格的方法
2014/06/09 Javascript
Jquery自定义button按钮的几种方法
2014/06/11 Javascript
JavaScript实现的浮动层框架用法实例分析
2015/10/10 Javascript
谈谈jQuery Ajax用法详解
2015/11/27 Javascript
jQuery validate+artdialog+jquery form实现弹出表单思路详解
2016/04/18 Javascript
canvas实现流星雨的背景效果
2017/01/13 Javascript
解决ztree搜索中多级菜单展示不全问题
2017/07/05 Javascript
小程序实现列表删除功能
2018/10/30 Javascript
Smartour 让网页导览变得更简单(推荐)
2019/07/19 Javascript
jquery插件开发模式实例详解
2019/07/20 jQuery
vue悬浮可拖拽悬浮按钮的实例代码
2019/08/20 Javascript
vue 设置 input 为不可以编辑的实现方法
2019/09/19 Javascript
[02:12]Dota 2 推出全新英雄—— 电炎绝手
2019/08/23 DOTA
写了个监控nginx进程的Python脚本
2012/05/10 Python
简单介绍Python中的len()函数的使用
2015/04/07 Python
python中尾递归用法实例详解
2015/04/28 Python
对python字典元素的添加与修改方法详解
2018/07/06 Python
python:接口间数据传递与调用方法
2018/12/17 Python
利用Python模拟登录pastebin.com的实现方法
2019/07/12 Python
Python使用正则实现计算字符串算式
2019/12/29 Python
日本PLST在线商店:日本时尚杂志刊载的人气服装
2016/12/10 全球购物
戴尔新加坡官网:Dell Singapore
2020/12/13 全球购物
商务日语专业毕业生求职信
2013/10/26 职场文书
大学校运会广播稿
2014/02/03 职场文书
少先队入队活动方案
2014/02/08 职场文书
外语专业毕业生自荐信
2014/04/14 职场文书
升职感谢信
2015/01/22 职场文书
css display table 自适应高度、宽度问题的解决
2021/05/07 HTML / CSS
python实现自动清理文件夹旧文件
2021/05/10 Python