接着做接着做接着做

来源:《Python编程:从入门到实践》

文章目录

  • 5 重构:模块game_functions
    • 5.1 函数check_events()
    • 5.2 函数update_screen()
  • 6 驾驶飞船
    • 6.1 响应按键
    • 6.2 允许不断移动
    • 6.3 左右移动
    • 6.4 调整飞船的速度
    • 6.5 限制飞船的活动范围
    • 6.6 重构check_events()
  • 7 射击
    • 7.1 添加子弹设置
    • 7.2 创建Bullet类
    • 8.3 将子弹存储在编组中
    • 8.4 开火
    • 8.5 删除已消失的子弹
    • 8.6 限制子弹数量
    • 8.7 创建函数update_bullets()
    • 8.8 创建函数fire_bullet()

5 重构:模块game_functions

  • 重构:旨在简化既有代码的结构,使其更容易扩展
  • 下面创建一个名为game_functions的新模块,它存储大量让《外星人入侵》运行的函数
  • 创建模块game_functions,可避免alien_invasion.py太长,逻辑也更易理解

5.1 函数check_events()

  • 管理事件的代码移到check_events()的函数中,以简化run_game()并隔离事件管理循环
  • 隔离事件循环,可将事件管理与游戏的其他方面(如更新屏幕)分离

game_functions.py

import sys
import pygamedef check_events():"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()
  • 导入事件检查循环要使用的sys和pygame
  • 函数check_events()不需要形参,函数体复制alien_invasion.py的事件循环
  • 下面来修改alien_invasion.py,导入模块game_functions,再将事件循环替换为函数check_events():

alien_invasion.py

import pygame
import game_functions as gfdef run_game():--snip--# 开始游戏的主循环while True:gf.check_events()# 每次循环时都重绘屏幕--snip--
  • 主程序文件不再需要直接导入sys,因为模块game_functions中使用了它

5.2 函数update_screen()

  • 进一步简化run_game(),将更新屏幕的代码移到update_screen()的函数中,并将此函数放在模块game_functions中

game_functions.py

--snip--
def check_events():--snip--
def update_screen(ai_settings, screen, ship):"""更新屏幕上的图像,并切换到新屏幕"""# 每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)ship.blitme()# 让最近绘制的屏幕可见pygame.display.flip()
  • update_screen()包含三个形参:ai_settings、screen、ship
  • 现在将主程序的while循环更新屏幕的代码替换为函数update_screen()

alien_invasion.py

--snip--
def run_game():--snip--# 开始游戏的主循环while True:gf.check_events()gf.update_screen(ai_settings, screen, ship)
  • 这两个函数让while更简单,让后续开发更容易:在模块game_functions完成大部分工作而不是run_game()

练习12-1 蓝色天空:创建一个背景为蓝色的Pygame窗口

test12-1.py

import sys
import pygame
from settings import Settingsdef run_game():pygame.init()settings = Settings()screen = pygame.display.set_mode((settings.screen_width, settings.screen_height))pygame.display.set_caption("程浩宇的蓝色天空")# 开始游戏的主循环while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()screen.fill(settings.bg_color)# 让最近绘制的屏幕可见pygame.display.flip()
run_game()

settings.py

class Settings():def __init__(self):self.screen_width = 1200self.screen_height = 800self.bg_color = (70, 130, 180)

运行主程序,结果如图:

练习12-2 游戏角色:找一幅你喜欢的游戏角色位图图像或将一副图像转换为位图。创建一个类,将该角色绘制到屏幕中央,并将该图像的背景色设置为屏幕背景色,或将屏幕背景色设置为该图像的背景色

test12-2.py
直接用现成的小飞船吧,背景色用上面的蓝色,再把小飞船的背景色改成屏幕背景色…
将角色绘制到屏幕中央,设置相应rect对象的属性centerx、centery即可
下面就把模块ship放上来吧,主程序和模块settings变动不大

ship.py

import pygame
class Ship():def __init__(self, screen):"""初始化飞船并设置其初始位置"""self.screen = screen # 加载飞船图形并获取其外界矩形self.image = pygame.image.load('images/ship.bmp')self.rect = self.image.get_rect()self.screen_rect = screen.get_rect()# 将每艘新飞船放在屏幕底部中央self.rect.centerx = self.screen_rect.centerxself.rect.centery = self.screen_rect.centerydef blitme(self):"""在指定位置绘制飞船"""self.screen.blit(self.image, self.rect)

运行主程序,发现小飞船成功绘制到屏幕中央了:

6 驾驶飞船

  • 用户按左或右箭头时作出响应
  • 首先专注于向右移动,再使用同样的道理来控制向左移动
  • 通过这样做,你将学会如何控制屏幕图像的移动

6.1 响应按键

  • 每当用户按键,都将在Pygame注册一个事件
  • 事件通过方法pygame.event.get()获取的,因此在函数check_events()中,每次按键都将被注册为一个KEYDOWN事件
  • 例如,如果按下的是右箭头键,我们就增大飞船的rect.centerx的值,将飞船右移

game_functions.py

def check_events(ship):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_RIGHT:# 右移飞船ship.rect.centerx += 1
  • 现在函数check_events()中包含形参ship
  • 在函数check_events()内部,在事件循环中添加了一个elif代码块,以便在Pygame检查到KEYDOWN事件时做出响应
  • 读取属性event.key,检查按下的是否是右箭头键(pygame.K_RIGHT),若是,ship.rect.centerx的值加1,飞船右移
  • 在alien_invasion.py中,更新check_events() 代码:

alien_invasion.py

    # 开始游戏的主循环while True:gf.check_events(ship)gf.update_screen(ai_settings, screen, ship)
  • 不过现在运行程序的话,你会发现每按一次右箭头键,飞船向右移动1像素
  • 但并非控制飞船的高效方式。下面改进控制方式,允许持续移动

6.2 允许不断移动

  • 让游戏检测pygame.KEYUP事件,以便玩家松开右箭头键时我们知道这一点
  • 结合使用KEYDOWN和KEYUP事件,以及一个moving_right的标志来实现持续移动
    • 飞船不动时,moving_right为False
    • 玩家按下→时,moving_right为True
    • 玩家松开时,moving_right为False
  • 飞船的属性由Ship类控制,下面添加一个方法update()和一个属性moving_right

ship.py

class Ship():def __init__(self, screen):--snip--# 移动标志self.moving_right = Falsedef update(self):"""根据移动标志调整飞船的位置"""if self.moving_right:self.rect_centerx += 1def blitme(self):--snip--
  • 下面来修改check_events(),玩家按下→时将moving_right设置为True,松开时将moving_right设置为False:

game_functions.py

def check_events(ship):"""响应按键和鼠标事件"""for event in pygame.event.get():--snip--elif event.type == pygame.KEYDOWN:if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.type == pygame.KEYUP:if event.key == pygame.K_RIGHT:ship.moving_right = False
  • 上面修改了按下→时响应的方式:不直接调整飞船的位置,而只是将moving_right设置为True
  • 接着添加了一个elif代码块,用于响应KEYUP事件:玩家松开→时,将moving_right设置为False
  • 最后,我们需要修改alien_invasion.py的while循环,以便每次执行循环时都调用飞船的方法update()

alien_invasion.py

    # 开始游戏的主循环while True:gf.check_events(ship)ship.update()gf.update_screen(ai_settings, screen, ship)
  • 现在运行alien_invasion.py,按住→,飞船能够不断右移,直到你松开为止

6.3 左右移动

  • 飞船能够不断右移后,添加左移的逻辑很容易
  • 下面再次修改Ship类函数check_events()

ship.py

    def __init__(self, screen):--snip--# 移动标志self.moving_right = Falseself.moving_left = Falsedef update(self):"""根据移动标志调整飞船的位置"""if self.moving_right:self.rect.centerx += 1if self.moving_left:self.rect.centerx -= 1
  • 方法__init__()中,添加了标志moving_left
  • 方法update()中,添加了一个if代码块而不是elif代码块:当玩家同时按下左右箭头键,将先增大self.rect.centerx,再降低这个值,即飞船的位置保持不变
  • 下面来修改check_events()

game_functions.py

def check_events(ship):"""响应按键和鼠标事件"""for event in pygame.event.get():--snip--elif event.type == pygame.KEYDOWN:if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.type == pygame.KEYUP:if event.key == pygame.K_RIGHT:ship.moving_right = Falseelif event.key == pygame.K_LEFT:ship.moving_left = False
  • 这里之所以使用elif代码块,是因为每个事件都只与一个键相关联
  • 如果同时按下了←→,将检测到两个不同事件
  • 此时运行主程序,发现能够不断地左右移动飞船;同时按←→键,飞船纹丝不动

6.4 调整飞船的速度

  • 当前,每次执行while循环时,飞船最多移动1像素
  • 现在在Settings类中添加属性ship_speed_factor用于控制飞船的速度

settings.py

class Settings():def __init__(self):--snip--# 飞船的设置self.ship_speed_factor = 1.5
  • 通过将ship_speed_factor速度设置指定为小数值,可在后面加快游戏的节奏时更细致地控制飞船的速度
  • 然而,rect的centerx等属性只能存储整数值,因此需要对Ship类做些修改:

ship.py

def __init__(self, ai_settings, screen):"""初始化飞船并设置其初始位置"""self.screen = screen self.ai_settings = ai_settings--snip--# 将每艘新飞船放在屏幕底部中央--snip--#在飞船的属性center中存储小数值self.center = float(self.rect.centerx)# 移动标志self.moving_right = Falseself.moving_left = Falsedef update(self):"""根据移动标志调整飞船的位置"""# 更新飞船的center值,而不是rectif self.moving_right:self.center += self.ai_settings.ship_speed_factorif self.moving_left:self.center -= self.ai_settings.ship_speed_factor# 根据self.center更新rect对象self.rect.centerx = self.center
  • __init__()的形参列表中添加了ai_settings,让飞船能够获取其速度设置
  • 接下来,将形参ai_settings存储在一个属性中,以便update()使用它
  • 调整飞船的位置时,将增加或减去一个单位为像素的小数值,因此需要将位置存储在一个能够存储小数值的变量中
  • 可以使用小数来设置rect的属性,但rect将只存储这个值的整数部分
  • 为准确地存储飞船的位置,我们定义了一个可存储小数值的新属性self.center
  • 使用函数float()将self.rect.centerx的值转换为小数,并将结果存储到self.center中
  • 现在在update()中调整飞船的位置时,将self.center的值增加或减去ai_settings.ship_speed_factor的值
  • 更新self.center后,再根据它来更新控制飞船位置的self.rect.centerx
  • self.rect.centerx将只存储self.center的整数部分,但对显示飞船而言,这问题不大

alien_invasion.py

def run_game():--snip--# 创建一艘飞船ship = Ship(ai_settings, screen)--snip--

6.5 限制飞船的活动范围

  • 运行程序,你会发现,按住箭头键的时间过长,飞船就跑到屏幕外面去了……
  • 下面修复这个问题,让飞船到达屏幕边缘后停止移动
  • 修改Ship类的方法update():

ship.py

    def update(self):"""根据移动标志调整飞船的位置"""# 更新飞船的center值,而不是rectif self.moving_right and self.rect.right < self.screen_rect.right:self.center += self.ai_settings.ship_speed_factorif self.moving_left and self.rect.left > 0:self.center -= self.ai_settings.ship_speed_factor# 根据self.center更新rect对象self.rect.centerx = self.center
  • self.rect.right返回飞船外接矩形右边缘的x坐标,如果这个值小于self.screen_rect.right的值,就说明飞船未触及屏幕右边缘
  • 左边缘情况与之类似:self.rect.left即rect的左边缘的x坐标,它大于零,就说明未触及屏幕左边缘
  • 这就确保了飞船只有在屏幕内时,才能调整self.center的值
  • 此时运行alien_invasion.py,飞船将在触及左右边缘不能移动

6.6 重构check_events()

  • 随着游戏开发的进行,函数check_events()愈来愈长,现在将其部分代码放在两个函数中:一个处理KEYDOWN事件,另一个处理KEYUP事件:

game_functions.py

def check_keydown_events(event, ship):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Truedef check_keyup_events(event, ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseelif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ship):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN:check_keydown_events(event, ship)elif event.type == pygame.KEYUP:check_keyup_events(event, ship)

7 射击

  • 下面来添加射击功能:玩家按下空格键时发射子弹
  • 子弹将在屏幕中向上穿行,抵达屏幕上边缘后消失

7.1 添加子弹设置

  • 更新settings.py,在其__init__()末尾存储新类Bullet所需的值:

settings.py

    def __init__(self):--snip--# 子弹设置self.bullet_speed_factor = 1self.bullet_width = 3self.bullet_height = 15self.bullet_color = 60, 60, 60
  • 创建宽3像素、高15像素的深灰色子弹
  • 子弹速度比飞船稍低

7.2 创建Bullet类

  • Bullet类,前半部分:

bullet.py

import pygame
from pygame.sprite import Spriteclass Bullet(Sprite):"""一个对飞船发射的子弹进行管理的类"""def __init__(self, ai_settings, screen, ship):"""在飞船所处的位置创建一个子弹对象"""super(Bullet, self).__init__()self.screen = screen # 在(0,0)处创建一个表示子弹的矩形,再设置正确的位置self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,ai_settings.bullet_height)self.rect.centerx = ship.rect.centerxself.rect.top = ship.rect.top# 存储用小数表示的子弹位置self.y = float(self.rect.y)self.color = ai_settings.bullet_colorself.speed_factor = ai_settings.bullet_speed_factor
  • Bullet类继承从模块pygame.sprite中导入的Sprite类
  • 通过使用精灵可将游戏中相关的元素编组,进而同时操作编组中的所有元素
  • 为创建子弹实例,需要向__init__()传递ai_settings、screen和ship实例,还调用了super()来继承Sprite

注意:代码super(Bullet, self).init() 使用了Python2.7语法。这种语法也适用于Python3,但你也可以将这行代码简写为super().init()

  • 下面是bullet.py的第二部分——方法update() 和 draw_bullet()

bullet.py

 def update(self):"""向上移动子弹"""# 更新表示子弹位置的小数值self.y -= self.speed_factor# 更新表示子弹的rect的位置self.rect.y = self.ydef draw_bullet(self):"""在屏幕上绘制子弹"""pygame.draw.rect(self.screen, self.color, self.rect)
  • 方法update()管理子弹的位置
  • 需要绘制子弹时,调用draw_bullet()
  • 函数draw.rect()使用存储在self.color中的颜色填充表示子弹的rect占据的屏幕部分

8.3 将子弹存储在编组中

  • 完成上面的准备后,下面要做的是:在玩家每次按空格键时都射出一发子弹
  • 首先,在alien_invasion.py中创建一个编组(group),存储所有有效的子弹,以便能够管理发射出去的所有子弹
  • 这个group将是pygame.sprite.Group类的一个实例
  • pygame.sprite.Group类 类似于列表,但提供有助于开发游戏的额外功能
  • 在主循环中,使用这个group在屏幕上绘制子弹,以及更新每颗子弹的位置:

alien_invasion.py

from pygame.sprite import Group
--snip--def run_game():--snip--# 创建一艘飞船ship = Ship(ai_settings, screen)# 创建一个用于存储子弹的编组bullets = Group()# 开始游戏的主循环while True:gf.check_events(ai_settings, screen, ship, bullets)ship.update()bullets.update()gf.update_screen(ai_settings, screen, ship, bullets)
--snip--
  • 创建了一个Group实例,将其命名为bullets
  • 这个编组是在while循环外创建的 ,这样就无需每次运行该循环时都创建一个新的子弹编组,导致游戏慢得像蜗牛。如果游戏停滞不前,请仔细查看主while循环中发生的情况

注意:如果在循环内部创建这样的编组,游戏运行时将创建数千个子弹编组

  • 当你对编组调用update()时,编组将自动对其中的每个精灵调用update()因此代码行bullets.update()将为编组bullets中的每颗子弹调用bullet.update()

8.4 开火

  • game_functions.py中,需要修改check_keydown_events(),以便在玩家按空格键时发射一颗子弹
  • 还需修改update_screen(),确保在调用flip()前在屏幕上重绘每颗子弹

game_functions.py

def check_keydown_events(event, ai_settings, screen, ship, bullets):--snip--elif event.key == pygame.K_SPACE:# 创建一颗子弹,并将其加入到编组bullets中new_bullet = Bullet(ai_settings, screen, ship)bullets.add(new_bullet)
--snip--def check_events(ai_settings, screen, ship, bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():--snip--elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings, screen, ship, bullets)--snip--def update_screen(ai_settings, screen, ship, bullets):--snip--# 在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()
  • 编组bullets传递给了check_keydown_events()
  • 玩家按空格键时,创建一颗新子弹(一个名为new_bullet的Bullet实例),并使用方法add()将其加入到编组bullets中
  • 方法bullets.sprites()返回一个列表,其中包含编组bullets的所有精灵
  • 为绘制发射的所有子弹,我们遍历编组bullets中的精灵,并对每个精灵都调用draw_bullet()
  • 现在运行alien_invasion.py,能够左右移动飞船,并发射任意数量的子弹

8.5 删除已消失的子弹

  • 现在,子弹到达屏幕顶端后消失,但这些子弹实际上依然存在,y坐标为负数,且越来越小
  • 这个问题将导致它们继续消耗内存和处理能力
  • 我们需要将这些已消失的子弹删除:

alien_invasion.py

    # 开始游戏的主循环while True:--snip--bullets.update()# 删除已消失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)print(len(bullets))--snip--
  • 在for中,不应从列表或编组中删除条目,因此必须遍历编组的副本
  • 使用方法copy()来设置for循环,这能够在循环中修改bullets
  • print语句显示还有多少颗子弹,从而核实已消失的子弹确实删除了
  • 如果这些代码没有问题,将print语句删除。如果留下这个语句,游戏的速度将大大降低

8.6 限制子弹数量

  • 很多设计游戏都对同时出现在屏幕上的子弹数量进行限制,以鼓励玩家有目标地设计
  • 首先,在settings中存储所允许的最大子弹数:

settings.py

        # 子弹设置self.bullet_speed_factor = 1self.bullet_width = 3self.bullet_height = 15self.bullet_color = 60, 60, 60self.bullets_allowed = 3
  • 接着在game_functions.py的check_keydown_events()中,在创建新子弹前检查未消失的子弹数是否小于该设置

game_functions.py

def check_keydown_events(event, ai_settings, screen, ship, bullets):--snip--# 创建一颗子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings, screen, ship)bullets.add(new_bullet)
  • 现在运行这个游戏,屏幕上最多只能有3颗子弹

8.7 创建函数update_bullets()

  • 编写并检查子弹管理代码后,可将其移到模块game_functions中,以让主程序alien_invasion.py尽可能简单
  • 创建一个名为update_bullets()的函数,将其添加到game_functions.py的末尾:

game_functions.py

def update_bullets(bullets):"""更新子弹的位置,并删除已消失的子弹"""# 更新子弹的位置bullets.update()# 删除已消失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)

alien_invasion.py

    while True:gf.check_events(ai_settings, screen, ship, bullets)ship.update()gf.update_bullets(bullets)gf.update_screen(ai_settings, screen, ship, bullets)
  • 让主循环包含尽可能少的代码,这样只看函数名就能迅速知道游戏发生的情况

8.8 创建函数fire_bullet()

  • 下面将发射子弹的代码移到一个独立的函数中:

game_functions.py

def check_keydown_events(event, ai_settings, screen, ship, bullets):--snip--elif event.key == pygame.K_SPACE:fire_bullet(ai_settings, screen, ship, bullets)def fire_bullet(ai_settings, screen, ship,bullets):"""如果还没有达到限制,就发射一颗子弹"""# 创建一颗子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings, screen, ship)bullets.add(new_bullet)

目前,运行游戏,确认发射子弹时依然没有错误

  • Python 外星人入侵游戏(二):外星人(上)

Python 外星人入侵游戏(一):武装飞船(下)相关推荐

  1. python随机出现外星人飞船_python外星人入侵游戏如何改变飞船的大小

    Python从入门到实践里的<外星人入侵> Python外星人入侵问题分享助世界上从来不缺少风景,缺少的只是欣赏的心情. Python项目外星人入侵添加爆照效果有没有原码<Pytho ...

  2. Python 外星人入侵游戏(一):武装飞船(上)

    从这周开始Python的实践学习,首先来开发一个外星人入侵游戏,这样可以对之前的概念有更深入的理解,对交互式项目有更深入的认识 来源:<Python编程:从入门到实践> 注意:游戏< ...

  3. Python外星人入侵游戏——添加飞船和外星人图片

    Python外星人入侵游戏是自己在<Python编程从入门到实践>在本书里学到的.本篇主要介绍该游戏中所需要的两个图片.分别为飞船和外星人图片. 1.首先去到 http://www.itu ...

  4. 用python写《外星人入侵》游戏:武装飞船 >1

    昨天的文章,我们设置好了本地环境. 现在,我们有了 python,有了安装 pygame所需的pip,和pygame.接下来我们就开始进入项目阶段. 文章目录 开始游戏项目 创建 pygame 窗口以 ...

  5. 怎么运行python外星人入侵_python编程:从入门到实践 外星人入侵项目:武装飞船 代码运行不显示飞船...

    我的飞船去哪了???!!! 照着书上的项目完整的代码运行一下,结果屏幕上没出现飞船,代码都是对的呀,这是咋回事? 屏幕高度问题 class Settings(): """ ...

  6. python编程:从入门到实践 外星人入侵项目:武装飞船 代码运行不显示飞船

    我的飞船去哪了???!!! 照着书上的项目完整的代码运行一下,结果屏幕上没出现飞船,代码都是对的呀,这是咋回事? 屏幕高度问题 class Settings():"""A ...

  7. python外星人入侵游戏图片_跪求一个问题@关于外星人入侵游戏(《python编程基础从入门到实...

    我在学着编写<python编程基础从入门到实践>的"外星人入侵游戏"的时候,报错如下: Traceback (most recent call last): File ...

  8. python实战游戏开发——添加飞船图像

    1.创建Ship类 import pygame # -*- coding: utf-8 -*- class Ship():       def __init__(self,screen):       ...

  9. python外星人入侵游戏rect报错_Python外星人入侵游戏开发—添加飞船图像

    用法分析 下面将飞船加入到游戏中.为了在屏幕上绘制玩家的飞船,我们将加载一幅图像,再使用Pygame方法blit() 绘制它. 选择用于表示飞船的图像后,需要将其显示到屏幕上.我们将创建一个名为shi ...

最新文章

  1. 两分钟让你知道什么是“Java重载”
  2. crt mysql中文乱码_CRT 和mysql 中文乱码解决方式
  3. predis如何实现phpredis的pconnect方法
  4. 文献记录(part65)--基于用户聚类的异构社交网络推荐算法
  5. java类中自定义函数的调用_关于方法:自定义类中对函数的未解析引用
  6. 【java基础知识】JDK环境下载安装过程(windows环境/Linux环境)+IDEA配置
  7. 奇安信专家:近八成软件存开源漏洞 供应链需全生命周期安全防护
  8. unordered_map 简介
  9. 微信和qq默认表情代码对照表及表情文件下载
  10. 怎么做直播APP软件?
  11. 如何用Python解析JSON数据
  12. Android intent category大全
  13. 常用类库-java.lang.String
  14. 各种类型sizeof大小及C++有符号数与无符号数进行比较
  15. 地下通信管道的管孔都快占满了,新增光缆怎么布放?
  16. Tiled结合Unity实现瓦片地图——Unity实战篇
  17. RT-Thread学习笔记(9):邮箱
  18. Node.js 15 正式版发布
  19. 复制淘宝店需要设置那些?
  20. Indie Maker 一个人的创业

热门文章

  1. 软件外包公司入职须知
  2. 【剑侠情缘服务端】武侠题材角色扮演类手游源码+手工外网端+安卓APP+视频教程
  3. 蓝牙模块在cubemx中应用
  4. spark触发adaptive skewed join的例子code
  5. 不用软件直接查询QQ好友的IP地址
  6. matlab语音频谱,信号与系统:用matlab分析wav音频的频谱
  7. android官方文档翻译,Android API Guide:Search 中文翻译
  8. 医院局域网设计方案计算机,某医院无线网络设计方案
  9. XDS110的固件下载
  10. 不论你技术多牛逼,这13条职场“潜规则”,越早知道越好!