青少年Python游戏编程入门(Beginning Game Programming for Teens with Python译文)

青少年Python游戏编程入门
Beginning Game Programming for Teens with Python

 
Julian Meyer on January 22, 2013
作者:朱利安耶, 2013年1月22日    翻译:郑若军,2017年7月21日

让我们一起学习如何用Python编写一个简单的游戏!
本文作者是导师团队成员(Tutorial Team Member)朱利安耶,一个13岁的Python开发者。你可以在Google和Twitter上找到他。

你是否曾经对视频游戏是如何创作出来的百思不得其解实,这并没有你想象的那么复杂!

在这个辅导课程里,你将要创作一个名叫“兔子和毛鼻袋熊”的游戏。在这个游戏中,主人公兔子需要保护一个城堡,抵御一大群毛鼻袋熊的攻击。

你将用Python来编写这个游戏。不,我不是说一条大蟒蛇!

Python是一门计算机编程语言。在这个辅导课程里,我们选择Python,是因为它是一门适合启蒙的简单语言,不仅有趣,而且易学。

如果你没有学过Python,在你开始之前,建议看看这本书:《思考Python:像一个计算机科学家一样思考》(Think Python: How to Think Like a Computer Scientist)。这本书将有助于你加快学习进度。

现在,让我们回到这里,准备开始—在兔子和毛鼻袋熊之间,即将爆发一场战争。接着看,跳进它们的打斗之中!

/span>
开始学习:安装Python

如果你想在一台安装Windows操作系统的个人电脑中学习这个课程,你需要安装Python。请确认你要安装的是2.7.3版本,而不是3.3.0版本!在运行安装程序之后,在你的开始菜单的“所有程序”文件夹中应该可以找到IDLE。请运行IDLE,开始学习。

如果你使用Mac(苹果电脑),你的电脑里已经安装了Python!你只需打开终端(/Applications/Utilities/Terminal.app),输入“Python”,然后按回车键。

注意:如果你从python.org安装Python(你可能需要这样,才能让你PyGame运行),然后你就可以在Mac上使用IDLE。它应该在“/Applications/Python 2.7”这个文件夹。

如果你安装正确,你应该看到这样的画面:
Python 2.7.3 (v2.7.3:70274d53c1dd, Apr  9 2012, 20:52:43) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type “help”, “copyright”, “credits” or “license” for more information.
>>> 
注意:如果你想要退出Python提示符(三个角括号:>>>),你可以在Python提示符后面输入“exit()”并按下回车键,或者按下Control+Z(注:即同时按下Control键和字母Z键)。

一旦你看到了Python提示符,为了测试Python是否正确运行,先输入print 1+1 ,然后按回车键。在屏幕上应该显示2。你刚才已经写了你的第一个Python程序了!

你已经知道Python可以正确运行了,但要想用Python编写游戏,你还需要安装PyGame。

PyGame是一个可以让编写游戏程序容易很多的Python库!这个库提供了诸如图像处理和声音播放的功能,这些功能可以轻松地植入你的游戏程序里。

点击这里,下载适合你的操作系统的PyGame安装程序。你一定要下载Python 2.7版本。
注意:从上述链接下载的PyGame安装程序不能和Mac上苹果公司自带的Python一起工作。你需要从python.org下载Python并安装它,这样你才能使用PyGame。或者,你可以通过MacPorts安装Python 和 PyGame。

(译者注: PyGame的安装方法如下: 在Windows行命令提示符下,输入python -m pip install pygame-1.9.3-cp27-cp27m-win_amd64.whl,然后回车。)

验证一下你是否已经正确安装了PyGame,打开IDLE或者从终端上运行Python,然后在Python提示符后输入import pygame 。如果什么都没有输出,那说明你已经正确安装了。

而如果在屏幕上输出像下面的错误提示,那说明PyGame还没有安装好。
Python 2.7.2 (default, Jun 20 2012, 16:23:33) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import pygame
Traceback (most recent call last):
  File “<stdin>”, line 1, in <module>
ImportError: No module named pygame
>>> 
如果你看到这样的错误提示,可以在论坛里发帖,我将帮助你让它工作。

/span>
从文件中运行Python代码

虽然你可以在Python提示符下运行很短的Python代码,但是如果你要运行一个大一点的程序(例如游戏),你可能想要把你的代码保存到一个文件中,这样你就不必一再地输入它。

有几种方法可以让你从文件中运行Python程序。一种方法是使用简单的文本编辑器,例如Windows中的写字板(Notepad),Mac中的文本编辑器(TextEdit)。打开一个新的文本文件,输入你的Python代码(例如print 1+1)。然后把它保存为XXX.py(XXX可以是任何描述性的文件名)。

然后在Windows中双击这个文件来运行它。在Mac上,打开终端,输入Python,然后把保存的文件拖到终端窗口并按回车。

另外一种方法是用IDLE的编辑器来输入你的代码。在这个课程里,你将使用这个方法。要运行idle,只要从终端中输入idle就行了。然后从IDLE菜单中选择“文件新建窗口”(FileNew Window),这样你就有了一个可以输入Python代码的文本编辑窗口。你可以通过“文件保存”(FileSave)菜单保存你对代码的修改,还可以通过“运行运行模块(F5)”(RunRun Module (F5))菜单运行你的代码。

请注意,只有在文本窗口打开了一个文件之后,那个“运行”菜单才能使用。

/span>
添加游戏资源

你现在差不多做好了创建游戏的准备工作。但是没有美图和音效,还能算得上什么游戏已经把你开发游戏所需要的图片和音效打包成一个压缩文件。你可以点击这里下载。

你下载了这个文件之后,在硬盘上为你的游戏创建一个文件夹,把资源目录解压到这个文件夹中。这样,在你的游戏文件夹中就有了一个名叫“resources”的子目录,各种资源分组存放在其中附加的文件夹中,就像这样:
 
你现在已经准备好,可以开始创建“兔子和毛鼻袋熊”游戏了。:]

/span>
步骤1:你好! 兔子

运行IDLE并打开一个新的文本编辑窗口,就像在前面的章节讲的那样。将下列代码输入到编辑窗口:
# 1 – Import library
import pygame
from pygame.locals import *

# 2 – Initialize the game
pygame.init()
width, height = 640, 480
screen=pygame.display.set_mode((width, height))

# 3 – Load images
player = pygame.image.load(“resources/images/dude.png”)

# 4 – keep looping through
while 1:
    # 5 – clear the screen before drawing it again
    screen.fill(0)
    # 6 – draw the screen elements
    screen.blit(player, (100,100))
    # 7 – update the screen
    pygame.display.flip()
    # 8 – loop through the events
    for event in pygame.event.get():
        # check if the event is the X button 
        if event.type==pygame.QUIT:
            # if it is quit the game
            pygame.quit() 
            exit(0) 
将这个文件保存到你的游戏文件夹(即存放资源子目录的文件夹)并命名为game.py。

让我们一段一段地把代码检查一遍:
1. 引入PyGame库。这让你可以在你的程序中使用这个库中的函数。
2. 初始化游戏并建立显示窗口。
3. 加载用来做兔子的图像。
4. 使下面缩进排版的代码循环运行。
注意:在面向对象的C语言、Java语言和PHP等其他语言中,用大括号来表示一段代码在一个循环或IF语句中执行,但在Python语言中,使用缩进来标识代码段。因此,一定要记住,在Python中正确缩进是非常重要的。
5. 在画图之前,将屏幕填充为黑色。
6. 在屏幕上x=100,y=100的坐标位置,添加你加载过的兔子图像。
7. 更新屏幕。
8. 检查是否有新的事件,如果有,而且是一个退出命令,则退出程序。
注意:根据PyGame文档,你不用调用pygame.quit() ,因为编译器将在关闭的时候自动调用它。然而,至少在Mac操作系统中,如果不调用pygame.quit() ,游戏将挂在exit语句上(注:而不是真正的退出了)。

如果你现在运行代码(通过Idle菜单中的RunRun Module选项),应该看到像下面一样的屏幕:

哇!兔子出场了,随时准备行动!

但是游戏看起来很可怕,兔子孤零零地站在那里,背景一片漆黑。是时候美化一下了:]/span>

步骤2:添加舞台布景

让我们开始为游戏舞台添加一个背景。只需要调用几个screen.blit()函数就可以了。

在#3段代码的末尾,在加载了玩家图像之后,添加下列代码:
grass = pygame.image.load(“resources/images/grass.png”)
castle = pygame.image.load(“resources/images/castle.png”)
这些代码加载图像并把它们赋给具体的变量。现在要把它们画在屏幕上。但是如果你检查一下青草图像,你将注意到它不能覆盖尺寸为640×480的整个屏幕。这就是说,你需要把青草图像铺开,让它完全覆盖屏幕区域。

在game.py中#6号代码段的开始处(在把玩家画在屏幕上之前),添加下列代码:
    for x in range(width/grass.get_width()+1):
        for y in range(height/grass.get_height()+1):
            screen.blit(grass,(x*100,y*100))
    screen.blit(castle,(0,30))
    screen.blit(castle,(0,135))
    screen.blit(castle,(0,240))
    screen.blit(castle,(0,345 ))

如你看到的那样,for语句循环首先经过x。然后,在那个for循环中,经过y并在for循环产生的x和y值处画出青草。接下来的几行代码只是在屏幕上画出城堡。

如果你现在运行程序,你将看到这样的东西:
 
好多了—开始看起来不错了!:]

/span>
步骤3:让兔子移动

下一步你需要添加一些实际的游戏玩法元素,例如让兔子对按键做出反应。

要做到那样,首先你将要实现一个好的方法,用来保持跟踪在一个给定的时刻哪些键被按下了。通过创建一个按键状态的数组,记录你想用于这个游戏的每一个按键的状态,你就可以做到这一点。

将下面的代码添加到game.py 中#2段的末尾(在你设置屏幕高度和宽度之后):

keys = [False, False, False, False]
playerpos=[100,100]
这个代码是相当容易理解的。按键数组按照下面的顺序保持跟踪被按下的按键:WASD。数组中的每一项对一个按键做出响应—第一是W,第二是A,依此类推。

playerpos变量表示程序在哪儿画出玩家。由于游戏要把玩家移动到不同的地方,用一个变量来记录玩家的位置,然后在那个位置画出玩家,这样会更简单一些。

现在你需要修改现有代码,用新的playerpos变量画出玩家。将#6段的以下一行代码:
    screen.blit(player, (100,100))
改为:
    screen.blit(player, playerpos)
接下来,根据哪些键被按下了来更新按键数组。PyGame通过添加event.key函数,使得侦测按键动作易如反掌。

在#8段的末尾,紧跟着判断“event.type==pygame.QUIT”的代码段之后,添加这些代码(与pygame.QUIT if语句段相同的缩进级别):

        if event.type == pygame.KEYDOWN:
            if event.key==K_w:
                keys[0]=True
            elif event.key==K_a:
                keys[1]=True
            elif event.key==K_s:
                keys[2]=True
            elif event.key==K_d:
                keys[3]=True
        if event.type == pygame.KEYUP:
            if event.key==pygame.K_w:
                keys[0]=False
            elif event.key==pygame.K_a:
                keys[1]=False
            elif event.key==pygame.K_s:
                keys[2]=False
            elif event.key==pygame.K_d:
                keys[3]=False

哇!那可是很多行代码哦。如果你把它分解成if语句,它其实并不是那么复杂。

首先,你检查是否有一个键正被按下或释放。然后你检查哪个键正被按下或释放,而且如果正被按下或释放的那个键是你使用的那些键中的一个,你就相应地更新按键变量。

最后,你需要更新 playerpos 变量,对按键动作做出响应。这实际上非常简单。

在game.py的最后添加下列代码(在同一个缩进级别,把它放在与for循环相同的级别):

    # 9 – Move player
    if keys[0]:
        playerpos[1]-=5
    elif keys[2]:
        playerpos[1]+=5
    if keys[1]:
        playerpos[0]-=5
    elif keys[3]:
        playerpos[0]+=5

这些代码不过是检查哪些键正被按下,并增加或减少玩家的x或y坐标(根据被按下的键),从而移动玩家。运行游戏,你应该可以看到像以前一样的玩家。试一试按下WASD。耶!它起作用了!
 
/span>
步骤4:让兔子旋转

哦,当你按键的时候,你的兔子现在就会移动。但是如果你可以用鼠标旋转兔子,让它朝向你选择的方向,而不是总朝着相同的方向,这样会不会更酷呢用三角几何原理就可以足够简单地实现这一点。

看一下下面的插图:
 
在上图中,如果(5,3)是兔子的位置,(2,4)是鼠标当前的位置,你可以把三角函数atan2应用到两点之间的距离差,从而求出旋转角度(z)。当然,一旦你知道了旋转角度,你就可以根据它轻松地旋转兔子了。

如果你对这一部分有些困惑,别担心—你仍然可以继续。但这就是你应该专心上数学课的原因!:] 在游戏编程的所有过程中,你都要用到这个东西。

现在你需要把这个概念应用到你的游戏中。要做到这一点,你可以利用PyGame的 Surface.rotate(degrees) 函数。顺便,请记住Z值是弧度。:[

atan2函数来自Python的math库。因此,请先在#1段的末尾加上这行代码:
import math
然后,把#6段的最后一行(即player.blit那一行)替换成下列代码:
    # 6.1 – Set player position and rotation
    position = pygame.mouse.get_pos()
    angle = math.atan2(position[1]-(playerpos[1]+32),position[0]-(playerpos[0]+26))
    playerrot = pygame.transform.rotate(player, 360-angle*57.29)
    playerpos1 = (playerpos[0]-playerrot.get_rect().width/2, playerpos[1]-playerrot.get_rect().height/2)
    screen.blit(playerrot, playerpos1) 

让我们检查一下上面代码的基本结构。首先你获取鼠标和玩家的位置。然后把这些提供给atan2函数。之后,你把从atan2函数返回的角度从弧度转换成度数(将弧度乘以57.29或者360/2π)。

由于兔子会被旋转,它的位置也将改变。所以,你现在计算一下兔子的新位置并在屏幕上显示它。

再一次运行游戏。如果你只使用WASD键,游戏和以前的表现一模一样。但如果你移动鼠标,兔子也会旋转。酷毙了!
 

步骤5:射击,兔子,射击!

既然你的兔子可以四周移动,是时候添加更多的动作了。:]让兔子用箭来射击敌人怎么样可不是一只温和的兔子!这一步复杂一点,因为你要跟踪所有箭的轨迹、更新它们、旋转它们,并且在它们跑到屏幕外面的时候删除它们。

首先,把必需的变量添加到初始化段(#2段)的末尾:
acc=[0,0]
arrows=[]
第一个变量跟踪玩家的精度,第二个数组跟踪所有的箭。精度变量本质上是一组记录发射的箭数和击中毛鼻袋熊个数的数组。在后面,我们将用这些信息来计算准确率。

接着,在#3段的末尾加载箭的图像:

arrow = pygame.image.load(“resources/images/bullet.png”)
现在,当一个用户点击鼠标,就需要发射一支箭。在#8段的末尾下列代码,作为一个新的事件处理器:

        if event.type==pygame.MOUSEBUTTONDOWN:
            position=pygame.mouse.get_pos()
            acc[1]+=1
            arrows.append([math.atan2(position[1]-(playerpos1[1]+32),position[0]-(playerpos1[0]+26)),playerpos1[0]+32,playerpos1[1]+32])

这些代码检查鼠标是否被点击,如果被点击,它就获取鼠标的位置并根据旋转之后玩家的位置和光标的位置计算出箭的旋转。这个旋转的值储存在那个箭的数组里。

接下来,我们要在屏幕上实实在在地画出这些箭。紧跟在#6.1段代码的后面添加下列代码:
    # 6.2 – Draw arrows
    for bullet in arrows:
        index=0
        velx=math.cos(bullet[0])*10
        vely=math.sin(bullet[0])*10
        bullet[1]+=velx
        bullet[2]+=vely
        if bullet[1]<-64 or bullet[1]>640 or bullet[2]<-64 or bullet[2]>480:
            arrows.pop(index)
        index+=1
        for projectile in arrows:
            arrow1 = pygame.transform.rotate(arrow, 360-projectile[0]*57.29)
            screen.blit(arrow1, (projectile[1], projectile[2]))

vely 和velx 的值是利用基本的三角原理计算出来的。10是箭的速度。If语句只是判断子弹是否超出边界,如果超出,就把箭删除。第二个for语句遍历所有的箭并用正确的旋转画出它们。

试着运行这个程序。当你点击鼠标的时候,你应该有了一只可以射箭的兔子!:D

 
/span>
步骤6:举起手来!毛鼻袋熊

OK,你有了一个城堡和一个可以移动和射箭的主人公。还落下了什么呢/span>
攻击城堡的敌人,主人公可以射击的敌人!
 

在这一步,你将创建随机产生的在城堡里跑的毛鼻袋熊。随着游戏的推进,会出现越来越多的毛鼻袋熊。因此,让我们把你需要它做的事情列一个清单。
1、 把坏家伙们加到一个列表或数组里。
2、 在每一个画面更新那些坏家伙并检查他们是否离开屏幕。
3、 显示那些坏家伙们。
这很容易,不是吗]

首先,在#2段的末尾添加下列代码:
badtimer=100
badtimer1=0
badguys=[[640,100]]
healthvalue=194
以上代码创建了一个定时器(还有一些其他的值),这样游戏就可以在间隔一些时间之后添加一只新的毛鼻袋熊。你在每一个画面减少badtimer的值,直到它等于0为止,然后你再孵化出一只新的毛鼻袋熊。

现在把下列代码添加到#3段的末尾:
badguyimg1 = pygame.image.load(“resources/images/badguy.png”)
badguyimg=badguyimg1

上面的第一行和前面的图像加载代码有点类似。第二行创建了一个图像的拷贝,这样你可以更加容易地让坏家伙栩栩如生。接下来,你要更新并显示这些坏家伙。在紧接着#6.2段的后面添加这些代码:
    # 6.3 – Draw badgers
    if badtimer==0:
        badguys.append([640, random.randint(50,430)])
        badtimer=100-(badtimer1*2)
        if badtimer1>=35:
            badtimer1=35
        else:
            badtimer1+=5
    index=0
    for badguy in badguys:
        if badguy[0]<-64:
            badguys.pop(index)
        badguy[0]-=7
        index+=1
    for badguy in badguys:
        screen.blit(badguyimg, badguy)

有很多代码了,让我们回顾一下。:]第一行检查badtimer是否为零,如果为零,就创建一只毛鼻袋熊,并根据badtimer到现在为止已运行的次数再次设置badtimer (定时器)。第一个for循环更新毛鼻袋熊的x坐标,检查它是否离开了屏幕,如果离开了屏幕就去除它。第二个for循环画出所有的毛鼻袋熊。

为了使用上述代码中的随机函数,你还需要引入random库。因此,在#1段末尾添加下面的代码:
import random
最后,紧接着while语句(#4段)的后面添加这行(代码),使每个画面都减少badtimer的值。
badtimer-=1
现在运行游戏,测试所有这些代码。你现在应该开始看到一些实际的游戏玩法—你可以射击、移动、转弯,毛鼻袋熊也突然进攻你。

 
但是等等!为什么毛鼻袋熊没有进攻你的城堡呢快加上那个…
在#6.3段的第一个for循环中,在index+=1之前添加这些代码:

        # 6.3.1 – Attack castle
        badrect=pygame.Rect(badguyimg.get_rect())
        badrect.top=badguy[1]
        badrect.left=badguy[0]
        if badrect.left<64:
            healthvalue -= random.randint(1,5)
            badguys.pop(index)
        # 6.3.3 – Next bad guy

这些代码相当简单。如果毛鼻袋熊的x值距离右边小于64,那就删除那个坏家伙并把游戏的健康值减少一个5-20之间的随机数。(在后面,你将在屏幕上显示当前的健康值)

如果你编译并运行这个程序,你应该看到一大群进攻的毛鼻袋熊在碰到城堡时消失。尽管你不能看到它,这些毛鼻袋熊实际上还在降低你的健康值。

 
步骤7:毛鼻袋熊和箭之间的碰撞

毛鼻袋熊就要进攻你的城堡了,但你的箭对它们还不起作用!兔子该怎样防御它的家园呢/span>

是时候设置杀死毛鼻袋熊的弓箭了,这样你才能保卫你的城堡并在游戏中获胜!总的来说,你需要循环地找到所有的坏家伙。在每一个这样的循环中,你需要循环找到所有的箭,检查它们是否相撞(箭和毛鼻袋熊)。如果相撞,那就删除毛鼻袋熊,删除弓箭,给你的精确度加一分。

紧接着#6.3.1段,添加这些(代码):
        #6.3.2 – Check for collisions
        index1=0
        for bullet in arrows:
            bullrect=pygame.Rect(arrow.get_rect())
            bullrect.left=bullet[1]
            bullrect.top=bullet[2]
            if badrect.colliderect(bullrect):
                acc[0]+=1
                badguys.pop(index)
                arrows.pop(index1)
            index1+=1

在这段代码中,只有一件重要事情需要说明。那条if语句是一个嵌入的PyGame函数,用来检查两个矩形是否相交。其它的几行语句只是做了我上面解释的事情。

如果你运行程序,你应该可以最终射中并杀死毛鼻袋熊。
 

/span>
步骤8:添加包含健康表和时钟的HUD

你的游戏进展得相当好。有了进攻者,也有防御者。现在只需要找到一个办法,记录分数并显示兔子做得怎么样。

要做到这个,最简单的办法就是添加一个HUD(题头显示器),让它显示城堡当前的健康水平。你还可以添加一个时钟,用来显示城堡已经生存了多久。

先添加时钟。在#7段开始部分的前面添加下列代码:
    # 6.4 – Draw clock
    font = pygame.font.Font(None, 24)
    survivedtext = font.render(str((90000-pygame.time.get_ticks())/60000)+”:”+str((90000-pygame.time.get_ticks())/1000%60).zfill(2), True, (0,0,0))
    textRect = survivedtext.get_rect()
    textRect.topright=[635,5]
    screen.blit(survivedtext, textRect)
上述代码不过是利用PyGame的默认24号字体创建了一个新的字体。然后,用这个字体把时间文本渲染到表面。之后,把文本定位并显示到屏幕。

接下来添加健康条。但是在画健康条之前,你需要装载用作健康条的图像。请在#3段的末尾添加下列代码:
healthbar = pygame.image.load(“resources/images/healthbar.png”)
health = pygame.image.load(“resources/images/health.png”)
第一个是红色图像,用来表示完整的健康条。第二个是绿色图像,用来显示当前的健康水平。

现在请紧接着#6.4段(你刚刚添加的)添加下列代码,用来把健康条画在屏幕上:
    # 6.5 – Draw health bar
    screen.blit(healthbar, (5,5))
    for health1 in range(healthvalue):
        screen.blit(health, (health1+8,8))
上述代码首先画一个全红的健康条。然后,根据城堡还剩下多少生命,在健康条上画一定量的绿色。

如果你编译并运行程序,你应该有了一个时钟和一个健康条。
 
/span>
步骤9:输或赢

可是,这是什么(游戏)果你玩够了,即使你的健康值下降到零,游戏还可以继续!还有,你还可以不停地射击毛鼻袋熊。这还不行,不是吗需要一个某种输赢显示面板,让游戏更值得玩。

因此,让我们添加一个输赢屏幕,在上面显示输赢情况。:]为了做到这一点,你要退出主循环并进入一个输赢循环。在输赢循环里,你要计算出用户的输赢并相应显示到屏幕上。

这是输赢显示面板的基本轮廓:

如果时间到了(90000毫米或90分钟),那么:
/span> 停止游戏。
/span> 把游戏的输出置为1或赢

如果城堡被捣毁了,那么:
/span> 停止游戏。
/span> 把游戏的输出置为0或输。
不论输赢,计算精确度。
注意: acc[0]*1.0只是把acc[0]转换成一个浮点数。如果你不这样做,除法运算将返还一个像1或2的整数,而不是一个像1.5的浮点数。

添加这些代码到game.py的结尾:
    #10 – Win/Lose check
    if pygame.time.get_ticks()>=90000:
        running=0
        exitcode=1
    if healthvalue<=0:
        running=0
        exitcode=0
    if acc[1]!=0:
        accuracy=acc[0]*1.0/acc[1]*100
    else:
        accuracy=0
# 11 – Win/lose display        
if exitcode==0:
    pygame.font.init()
    font = pygame.font.Font(None, 24)
    text = font.render(“Accuracy: “+str(accuracy)+”%”, True, (255

来源:徒步天涯2017

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2017年6月21日
下一篇 2017年6月22日

相关推荐