飞机大战

  • 游戏主要特点
  • 一个佛系介绍
  • 游戏玩法
  • 一段没有素材等于废话的全代码

游戏主要特点

  • 游戏自带时间计数和成绩计数。
  • 游戏的子弹有7种,通过拾取道具可以升级子弹,子弹拥有持续时间,超过持续时间会降级。
  • 游戏道具有6种,分别为“伪三连散射”,“EXP X2”,“毫无特效的保护盾”,“升级为好看子弹1号”,“升级为好看子弹2号”,“普通子弹升级”。
  • 游戏我方飞机为4种,为“粉”,“红”,“黄”,“蓝”四种飞机,没有区别,顶多碰撞箱大小不一样,开局随机,吃到“子弹升级”飞机同时升级(碰撞箱变大)。
  • 游戏有四种背景,开局随机。
  • 游戏子弹击中敌机有1分爆炸特效,敌机爆炸也有1毛特效。
  • 游戏敌机分大中小三种,它们的血量不同,分数不同,小敌机8种,中敌机5种,大敌机2种。
  • 游戏飞机只能y轴移动,不会开火,非常沙雕。
  • 游戏敌机血量在一定范围内随机。
  • 我方飞机为鼠标控制,开火鼠标左击。开火有间隔。

一个佛系介绍

素材使用网络素材,腾讯全民飞机大战同款素材,只用于学习(shui文章)

老师要求的python练习题目为飞机大战,使用pygame完成。

由于面向对象掌握不太行,代码可读性。。。能跑就行。
pygame函数众多,学习时间较短,pygame的教程为英文,对于英语渣十分不友好,于是很多的操作使用基础函数魔改而成,没有运用自带的函数。

下面为游戏截图:

游戏没有开始界面,解释编译即玩。
游戏退出极其简单,撞死就行,或右上角X。

游戏玩法

  1. 运行代码
  2. 移动鼠标,控制飞机
  3. 鼠标左击,发射子弹
  4. 捡道具升级飞机
  5. 等待狗带

介绍完毕,放代码。。。

一段没有素材等于废话的全代码

python代码+素材,点击跳转

import pygame
import sys
import random
import json
import time
from pygame.locals import *
pygame.init()#导入我方飞机模型
with open("data/plane.json","r") as f:plane_data1=json.loads(f.read())
plane_model = pygame.image.load("data/Skin.png")
planeRandom = random.randint(1,4)
plane=plane_data1["plane{}".format(planeRandom)]
plane1_1=plane["level1"]
plane1=plane_model.subsurface(Rect(plane1_1))#对应飞机模型切割导入#导入敌方飞机模型
with open("data/enemy_model.json","r") as f:enemy_data1=json.loads(f.read())
enemy_model = pygame.image.load("data/enemyplane.png")#导入子弹模型
with open("data/bullet.json","r") as f:bullet_data1=json.loads(f.read())
bullet_model = pygame.image.load("data/bullet.png")
bullet_yellow = bullet_data1["yellow"]
bullet_blue = bullet_data1["blue"]
bullet1 = bullet_model.subsurface(bullet_yellow["1"])#导入奖励箱模型
with open("data/luckbox.json","r") as f:luckbox_data1=json.loads(f.read())
luckbox_model = pygame.image.load("data/luckbox.png")#导入数字模型
with open("data/numY.json","r") as f:num_data=json.loads(f.read())
num_model=pygame.image.load("data/num_Y.png")#导入爆炸画面
with open("data/break.json","r") as f:break_data=json.loads(f.read())
break_model=pygame.image.load("data/Break.png")
break_1 = break_data["cratch"]
break_2 = break_data["break"]#显示时间
def digital_time(screen):#63,85#125,261playtime = int(time.time()-start)if playtime//60<10:showmin = "0"+str(playtime//60)else:showmin = str(playtime // 60)if playtime%60<10:showsec = "0"+str(playtime%60)else:showsec = str(playtime%60)j=0for i in showmin:num=num_model.subsurface(Rect(num_data[i]))num=pygame.transform.smoothscale(num,(30,40))screen.blit(num,(30*j,0))j=1j=0for i in showsec:num=num_model.subsurface(Rect(num_data[i]))num=pygame.transform.smoothscale(num,(30,40))screen.blit(num,(65+30*j,0))j=1#显示积分
def digital_num(screen):global scoreshowscore=str(score)j=0for i in showscore[::-1]:num = num_model.subsurface(Rect(num_data[i]))num = pygame.transform.smoothscale(num, (30, 40))screen.blit(num, (482 - 30 * j, 0))j+=1#制造小飞机
def plan_s():modelNum=random.randint(1,8)enemy_rectS = enemy_data1["enemyS"]enemyrect = enemy_rectS["enemy{}".format(modelNum)]whatX = random.randint(-50, 300 - enemyrect[2])position = random.randint(enemyrect[2], enemyrect[2]+30)planeNum=random.randint(3,6)planeHealth=random.randint(2,4)for i in range(planeNum):if whatX+position*i+ enemyrect[2]>550:breakp1=[1,modelNum,[whatX+position*i,-enemyrect[3]]]c1=[p1,enemyrect[2],enemyrect[3],planeHealth]enemyPlane.append(p1)collisionBox.append(c1)#制造中飞机
def plan_m():modelNum=random.randint(1,5)enemy_rectM = enemy_data1["enemyM"]enemyrect = enemy_rectM["enemy{}".format(modelNum)]whatX = random.randint(-60, 230 - enemyrect[2])position = random.randint(enemyrect[2], enemyrect[2] + 30)planeNum = random.randint(2, 4)planeHealth = random.randint(7, 9)for i in range(planeNum):if whatX+position*i+ enemyrect[2] > 570:breakp1 = [2, modelNum, [whatX + position * i, -enemyrect[3]]]c1 = [p1, enemyrect[2], enemyrect[3], planeHealth]enemyPlane.append(p1)collisionBox.append(c1)#制造Boss飞机
def plan_l():modelNum=random.randint(1,2)enemy_rectL = enemy_data1["enemyL"]enemyrect = enemy_rectL["enemy{}".format(modelNum)]whatX = random.randint(0, 512 - enemyrect[2])planeHealth = random.randint(14, 18)p1 = [3, modelNum, [whatX, -enemyrect[3]]]c1 = [p1, enemyrect[2], enemyrect[3], planeHealth]enemyPlane.append(p1)collisionBox.append(c1)#绘制敌人
def blict_enemy(screen):for enemy in enemyPlane:if enemy == None:returnif enemy[0] == 1:if enemy[2][1]>600:try:collisionBox.remove(collisionBox[enemyPlane.index(enemy)])except:passenemyPlane.remove(enemy)continueenemy_rectS = enemy_data1["enemyS"]enemyrect = enemy_rectS["enemy{}".format(enemy[1])]enemyNow=enemy_model.subsurface(Rect(enemyrect))enemy[2][1]+=3screen.blit(enemyNow,enemy[2])continueif enemy[0] == 2:if enemy[2][1]>600:try:collisionBox.remove(collisionBox[enemyPlane.index(enemy)])except:passenemyPlane.remove(enemy)continueenemy_rectM = enemy_data1["enemyM"]enemyrect = enemy_rectM["enemy{}".format(enemy[1])]enemyNow=enemy_model.subsurface(Rect(enemyrect))enemy[2][1]+=2screen.blit(enemyNow,enemy[2])continueif enemy[0] == 3:if enemy[2][1]>600:try:collisionBox.remove(collisionBox[enemyPlane.index(enemy)])except:passenemyPlane.remove(enemy)continueenemy_rectL = enemy_data1["enemyL"]enemyrect = enemy_rectL["enemy{}".format(enemy[1])]enemyNow=enemy_model.subsurface(Rect(enemyrect))enemy[2][1]+=1screen.blit(enemyNow,enemy[2])continue#爆炸动画
def blit_break(screen):for br in breakPos:if br[0]==1:rect = break_1["{}".format(br[1])]img = break_model.subsurface(rect)rect = img.get_rect()rect.center = br[2]screen.blit(img,rect)br[3]-=1if br[3]==0:br[3]=2br[1]+=1if br[1]==10:breakPos.remove(br)if br[0]==2:rect = break_2["{}".format(br[1])]img = break_model.subsurface(rect)rect = img.get_rect()rect.center = br[2]screen.blit(img, rect)br[3] -= 1if br[3] == 0:br[3] = 5br[1] += 1if br[1] == 7:breakPos.remove(br)#检查子弹碰撞
def checkTouch(bulletHeart):global bulletsizefor bullet in bulletPos:if bullet == None:returnfor check in collisionBox:if check == None:returnif bullet[0]+bulletsize//2<check[0][2][0] or bullet[0]-bulletsize//2>check[0][2][0]+check[1]:continueif bullet[1]>check[0][2][1]+check[2] or bullet[1]<check[0][2][1]:continuebulletPos.remove(bullet)br=[1,1,bullet,2]breakPos.append(br)check[3]-=bulletHeartif check[3]<=0 :enemyPlane.remove(enemyPlane[collisionBox.index(check)])collisionBox.remove(check)br = [2, 1, [check[0][2][0]+check[1]//2,check[0][2][1]+check[2]//2], 5]breakPos.append(br)global score,exp_valueif check[0][0]==1:score+=1*exp_valueelif check[0][0]==2:score+=5*exp_valueelif check[0][0]==3:score+=20*exp_valueif check[0][2][1]>600:collisionBox.remove(check)break#飞机碰撞
def cratchDetect(nowsPos):global protect_valuefor check in collisionBox:if nowsPos[0]<check[0][2][0] or nowsPos[0]>check[0][2][0]+check[1]:continueif nowsPos[1]<check[0][2][1]+20 or nowsPos[1]>check[0][2][1]+check[2]:continueenemyPlane.remove(enemyPlane[collisionBox.index(check)])collisionBox.remove(check)if protect_value ==0:sys.exit()else:protect_value =0for box in goodluckBox:rect=[]if box[0]==1:rect = luckbox_data1["speed"]elif box[0]==2:rect = luckbox_data1["three"]elif box[0]==3:rect = luckbox_data1["exp"]elif box[0]==4:rect = luckbox_data1["blue1"]elif box[0]==5:rect = luckbox_data1["blue2"]elif box[0]==6:rect = luckbox_data1["protect"]if nowsPos[0]<box[1][0] or nowsPos[0]>box[1][0]+rect[2]:continueif nowsPos[1]<box[1][1] or nowsPos[1]>box[1][1]+rect[3]:continueif box[0]==1:global speedState,levelStatespeedState=900if levelState[0]<4:levelState[0]+=1levelState[1]=1if box[0]==2:global threeState,three_valuethreeState=400three_value=1if box[0]==3:global expState,exp_valueexpState=400exp_value=2if box[0]==4:global blue1State,blue1_valueblue1State=150blue1_value[0] = 1blue1_value[1] = 1if box[0]==5:global blue2State,blue2_valueblue2State=150blue2_value[0] = 1blue2_value[1] = 1if box[0]==6:protect_value=1goodluckBox.remove(box)#增加幸运箱
def add_luckbox():ran = random.random()if ran<0.003:nowX = random.randint(0,434)ranX = random.randint(1,4)ranY = random.randint(-3,3)g1=[1,[nowX,-49],ranX,ranY]goodluckBox.append(g1)elif ran<0.004:nowX = random.randint(0, 434)ranX = random.randint(1, 4)ranY = random.randint(-3, 3)g2 = [2, [nowX, -49], ranX,ranY]goodluckBox.append(g2)elif ran < 0.005:nowX = random.randint(0, 434)ranX = random.randint(1, 4)ranY = random.randint(-3, 3)g3 = [3, [nowX, -49], ranX,ranY]goodluckBox.append(g3)elif ran < 0.006:nowX = random.randint(0, 444)ranX = random.randint(1, 4)ranY = random.randint(-3, 3)g4 = [4, [nowX, -76], ranX,ranY]goodluckBox.append(g4)elif ran < 0.007:nowX = random.randint(0, 390)ranX = random.randint(1, 4)ranY = random.randint(-3, 3)g5 = [5, [nowX, -97], ranX,ranY]goodluckBox.append(g5)elif ran < 0.008:nowX = random.randint(0, 434)ranX = random.randint(1, 4)ranY = random.randint(-3, 3)g6 = [6, [nowX, -78], ranX,ranY]goodluckBox.append(g6)#绘制幸运箱
def blit_luckbox(screen):for box in goodluckBox:if box[0]==1:boxmodel=luckbox_model.subsurface(luckbox_data1["speed"])screen.blit(boxmodel,box[1])box[1][0]+=box[2]box[1][1]+=box[3]if box[1][0]<0 or box[1][0]>434:box[2]=-box[2]if box[1][1]<-49 or box[1][1]>551:box[3]=-box[3]elif box[0]==2:boxmodel=luckbox_model.subsurface(luckbox_data1["three"])screen.blit(boxmodel,box[1])box[1][0]+=box[2]box[1][1]+=box[3]if box[1][0]<0 or box[1][0]>434:box[2]=-box[2]if box[1][1]<-49 or box[1][1]>551:box[3]=-box[3]elif box[0]==3:boxmodel=luckbox_model.subsurface(luckbox_data1["exp"])screen.blit(boxmodel,box[1])box[1][0]+=box[2]box[1][1]+=box[3]if box[1][0]<0 or box[1][0]>434:box[2]=-box[2]if box[1][1]<-49 or box[1][1]>551:box[3]=-box[3]elif box[0]==4:boxmodel=luckbox_model.subsurface(luckbox_data1["blue1"])screen.blit(boxmodel,box[1])box[1][0]+=box[2]box[1][1]+=box[3]if box[1][0]<0 or box[1][0]>444:box[2]=-box[2]if box[1][1]<-76 or box[1][1]>524:box[3]=-box[3]elif box[0]==5:boxmodel=luckbox_model.subsurface(luckbox_data1["blue2"])screen.blit(boxmodel,box[1])box[1][0]+=box[2]box[1][1]+=box[3]if box[1][0]<0 or box[1][0]>390:box[2]=-box[2]if box[1][1]<-97 or box[1][1]>503:box[3]=-box[3]elif box[0]==6:boxmodel=luckbox_model.subsurface(luckbox_data1["protect"])screen.blit(boxmodel,box[1])box[1][0]+=box[2]box[1][1]+=box[3]if box[1][0]<0 or box[1][0]>434:box[2]=-box[2]if box[1][1]<-78 or box[1][1]>552:box[3]=-box[3]#幸运箱效果
def box_effect():global speedState,threeState,expState,blue1State,blue2State,protectState,levelState,blue1_value,blue2_valueglobal plane1,bullet1,bullet_speed,open_fire_speed,bullet_heart,bulletsizeif speedState>0:speedState-=1elif speedState==0 and levelState[0]>1:levelState[0] -= 1levelState[1] = 1speedState =900if threeState>0:threeState-=1elif threeState==0:global three_valuethree_value = 0threeState=-1if expState>0:expState-=1elif expState==0:global exp_valueexp_value=1expState=-1if blue1State>0:blue1State-=1elif blue1State==0:blue1_value[0]=0blue1_value[1]=1blue1State=-1if blue2State>0:blue2State-=1elif blue2State == 0:blue2_value[0]=0blue2_value[1]=1blue2State=-1if levelState[1]==1:plane1 = plane_model.subsurface(plane["level{}".format(levelState[0])])if blue1_value[0]==0 and blue2_value[0]==0:bullet1 = bullet_model.subsurface(bullet_yellow["{}".format(levelState[0])])bullet_heart = 1 + 0.3 * (levelState[0] - 1)else:bullet_heart = 1.7 + 0.3 * (levelState[0] - 1)bullet_speed = 4 * levelState[0]open_fire_speed=50-10*levelState[0]levelState[1]=0if blue1_value[1]==1:if blue1_value[0]==1:bullet1 = bullet_model.subsurface(bullet_blue["1"])bullet_heart = 2 + 0.3 * (levelState[0] - 1)bulletsize = bullet_blue["1"][2]blue1_value[1]=0else:bullet1 = bullet_model.subsurface(bullet_yellow["{}".format(levelState[0])])bullet_heart = 1 + 0.3 * (levelState[0] - 1)bulletsize = bullet_yellow["{}".format(levelState[0])][2]blue1_value[1] = 0if blue2_value[1]==1:if blue2_value[0] == 1:bullet1 = bullet_model.subsurface(bullet_blue["2"])bullet_heart = 2 + 0.3 * (levelState[0] - 1)bulletsize = bullet_blue["2"][2]blue2_value[1] = 0else:bullet1 = bullet_model.subsurface(bullet_yellow["{}".format(levelState[0])])bullet_heart = 1 + 0.3 * (levelState[0] - 1)bulletsize = bullet_yellow["{}".format(levelState[0])][2]blue2_value[1] = 0#主背景加载
size = width,height = 512,600
backLuck = random.randint(1,4)
background = pygame.image.load("data/background{}.jpg".format(backLuck))
screen = pygame.display.set_mode(size)
pygame.display.set_caption("努力施工dog")
clock = pygame.time.Clock()#参数初始化
bulletPos=[]
enemyPlane=[]
collisionBox=[]
breakPos=[]
goodluckBox=[]
bullet_speed=4
bullet_heart=1
open_fire=0
open_fire_speed=40
bgn=0
bgnn=0
Count_fire=open_fire_speed
Count_240=180
Count_boss=1200
bulletsize=0
score=0#状态
levelState=[1,0]
threeState=0
three_value=0
expState=-1
exp_value=1
blue1State=-1
blue1_value=[0,0]
blue2State=-1
blue2_value=[0,0]
speedState=0
protect_value=0#启动游戏
start = time.time()
while True:#game刷新率限制60hzclock.tick(60)# 遍历所有的事件for event in pygame.event.get():# 如果单击关闭窗口,则退出if event.type == pygame.QUIT:sys.exit()# 添加子弹if event.type == pygame.MOUSEBUTTONDOWN:open_fire = 1if event.type == pygame.MOUSEBUTTONUP:open_fire = 0#刷新敌机if Count_fire>0:Count_fire-=1if Count_240>0:Count_240-=1if Count_boss>0:Count_boss-=1if Count_240%120==0:plan_s()if Count_240==0:plan_m()Count_240=239if Count_boss==0:plan_l()Count_boss=1200if open_fire == 1 and Count_fire==0:if three_value==0:bulletPos.append(list(pygame.mouse.get_pos()))Count_fire=open_fire_speedelse:three_pos=list(pygame.mouse.get_pos())bulletPos.append([three_pos[0],three_pos[1]-8])bulletPos.append([three_pos[0]-35,three_pos[1]])bulletPos.append([three_pos[0]+35,three_pos[1]])Count_fire=open_fire_speedadd_luckbox()box_effect()# 背景循环移动效果if bgn !=168:backgroundNOW = background.subsurface(Rect((0, 168 - bgn), (512, 600)))screen.blit(backgroundNOW, (0, 0))bgn+=1else:backgroundOLD = background.subsurface(Rect((0,  0), (512, 600 - bgnn)))backgroundNEW = background.subsurface(Rect((0, 768-bgnn), (512,  bgnn)))screen.blit(backgroundOLD, (0, bgnn))screen.blit(backgroundNEW, (0,0))bgnn+=1if bgnn == 600:bgnn=0bgn=0checkTouch(bullet_heart)# 主机的子弹发射for bullet_one in bulletPos:if bullet_one == None:breakbullet1R = bullet1.get_rect()bulletsize=bullet1R[2]if bullet_one[1] > -bullet1R[3]:bullet1R.center = bullet_onebullet_one[1] -=bullet_speedscreen.blit(bullet1, bullet1R)else:bulletPos.remove(bullet_one)blict_enemy(screen)blit_luckbox(screen)# 主机追随鼠标移动mouse_pos = pygame.mouse.get_pos()cratchDetect(mouse_pos)mou_plane = plane1.get_rect()mou_plane.center = mouse_posscreen.blit(plane1, mou_plane)#爆炸动画blit_break(screen)# 更新界面digital_time(screen)digital_num(screen)pygame.display.flip()

通过pygame实现的python飞机大战项目相关推荐

  1. C++的学习心得和知识总结(十六)|基于EasyX实现小甲鱼Python飞机大战项目(C++版)

    目录结构 注:提前言明 本文借鉴了以下博主.书籍或网站的内容,其列表如下: 1.小甲鱼Python项目 – 飞机大战 2.本文使用的掩码图生成工具 自动生成遮罩图的程序,点击前往 3.EasyX官方链 ...

  2. python飞机大战项目描述_飞机大战项目梳理(一)

    尽力而为和志在必得还是有点差别的. 一.思路梳理 今天的内容:建立一个空白的窗口,在这个窗口里需要有一个小飞机(图片),小飞机可以根据用户按键向右或向左移动. "建立窗口"  就需 ...

  3. python飞机大战任务报告_Python飞机大战实战项目案例

    都说实践是检验知识掌握程度的最好测试.随着Python学习者的增长,越来越多的零基础入门课程让人眼花缭乱.虽然说基础理论的学习十分重要,但是如果仅仅只学习理论知识,也是远远不够的.飞机大战的项目实战可 ...

  4. python飞机大战程序导入_Python飞机大战项目的准备 导入Pygame最全攻略~

    1.导入pygame 首先是导入pygame模块,下面介绍的是pycharm中导入 先建立一个项目 左上角File->Setting->project:飞机大战项目(你自己的文件名字)-& ...

  5. python飞机大战设计思路_python飞机大战pygame游戏背景设计详解

    本文实例讲述了python飞机大战pygame游戏背景设计.分享给大家供大家参考,具体如下: 目标 背景交替滚动的思路确定 显示游戏背景 01. 背景交替滚动的思路确定 运行 备课代码,观察 背景图像 ...

  6. Python飞机大战(究极迫害版)

    最近Python学到了项目开发,里面有一个飞机大战的项目挺感兴趣的,不过只是把别人做过的项目重做一遍未免太无聊,所以打算做一个究极迫害版. 首先是对原来项目图片的处理 在上面的图片中,原来是战机的图片 ...

  7. python飞机大战加背景音乐_python实现飞机大战小游戏 python飞机大战中的音频文件怎么改成MP3...

    怎么样用Python写飞机大战游戏 python开发飞机大战外星人游戏怎么弄双人模式新的一年,哪怕仍是一个人,也要活得像一支队伍,为自己的头脑和心灵招兵买马,不气馁,有召唤,爱自由. 主函数 impo ...

  8. Python“飞机大战”上下左右移动空格发射子弹

    下载点此去 最后面有运行视频 一.项目背景 作为一名学习计算机的学生,在以往,我认为学习计算机要么就是无所不能的黑客,要么就是能制作出各种软件程序的大神.我选择pygame板块,制作一款能随意更改游戏 ...

  9. python飞机大战联网版_Python 飞机大战搞怪版本

    python 飞机大战搞怪版本 (飞机为迷你亚索,外星人为迷你小诺手,由于时间关系和图片素材较难寻找,仅仅做了简易版,没有贴上背景图片.由于篇幅原因,对于函数讲解较为简略,可以自行搜索相应函数的用法) ...

最新文章

  1. 改善开发进程 微软谈新Visual Studio(zz)
  2. JavaScript实现bellmanFord贝尔曼-福特算法(附完整源码)
  3. 2018 ACM/ICPC 沈阳站小结
  4. python37从零开始学_从零开始学Python【37】--朴素贝叶斯模型(理论部分)
  5. mysql递归查询树,帮你突破瓶颈
  6. UVALive 6884 GREAT + SWERC = PORTO dfs模拟
  7. VMWare 各版本下载地址
  8. 基于darknet的voc数据集训练和mAP测试
  9. Aras Innovator 11 sp2安装
  10. 关于openssl 的几个key的生成方式
  11. dis的前缀单词有哪些_下面是总结的一些英语单词记忆前
  12. 湖南北云科技有限公司2023届校园招聘简章
  13. Python控制结构(二)
  14. 咬肌边上有个滑动疙瘩_腮帮子有个滑动的疙瘩是怎么回事
  15. php五只猴子分椰子_(笔试题)分椰子
  16. 江西靖安推行“村庄清洁革命”:设垃圾兑换银行 大数据管理
  17. C语言大小端数据转换总结
  18. KgoUI(2) 之 vue + layui
  19. A027_MySQL进阶
  20. 计算机网络实验指导书,计算机网络实验指导书51343

热门文章

  1. 2023年程序员前景如何?还值得入坑吗
  2. 选修课:唐宋词课堂鉴赏笔记02
  3. 曙光天阔H系列服务器,曙光天阔 A620r- H服务器系统支持 AMD最新推出的
  4. sql排序(想让字段为空的值放到最后)
  5. P10:数组传递下标,删除数组数据
  6. android-ImageView的拖动、旋转、缩放、边界回弹、双击缩放、单击销毁及源码下载
  7. 给宝宝起名要遵循的几点建议
  8. java实现mysql数据库导出
  9. ThinkPad T440s
  10. 网易博客居然要关了,我写的文章啊!