课程:《Python程序设计》
班级: 2121
姓名: 施铖哲
学号: 20212109
实验教师:王志强
实验日期:2022年5月28日
必修/选修:公选课

一、实验题目:

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。

这里我选择根据飞机大战相似的模式自制游戏。

二、实验过程:

2.1制作目标

2.1.1灵感来源

基于B站教学视频制作魔改游戏,发现飞机大战很好玩,就想根据这个做自己的垃圾大战

2.1.2游戏介绍

把自己操控的飞机改为回收站,把敌方飞机改为pycharm图标,pycharm会不断射出名为python的文件夹和steam的图标,回收站碰到steam图标会挂,而碰到python文件夹可以加分,一次加十分。

操控由键盘的上下左右完成,敌方pycharm会自动左右移动。

如果直接用回收站撞pycharm的话,解锁同归于尽结局,获得500000000000000分。

2.2制作过程

2.2.1我在B站学python

由于上课处于比较懵的状态,类的知识学的还是不扎实的,所以决定跟着B站飞机大战教程重新学习。

但是由于游戏内容相似但不一样,所以我参考了一部分代码,而自己完成了一部分。

2.2.2制作流程

制作游戏必需pycharm,终端下载

先在主函数里面编写,建立窗口,后面添加类

就是这个背景

窗口这里需要注意(542,830)与添加的图片规格一致

先载入图片,然后blit添加,然后display展示

Hero玩家类

使用键盘监听来实现操控,而监听同时需要在while True循环里面出现,否则只会响应一下无法连续响应

而添加入循环之后又有速度太快的问题,这时候需要time.sleep控制

Enemy敌人类

基本与Hero类一样,但是把键盘监听改成自动move,添加自动fire的方法

这里auto_move的范围即界面宽度减去自身图片宽度

auto_fire使用random.randint(1,40)来实现随机开火,这一方法会用在两种子弹中,而根据游戏难度两种子弹生成的概率设置是不一样的

敌人子弹类(一个是加分的python,一个是会死的steam)

bullet1

bullet2

使用矩形rect的方法(pygame自带),kill()即消灭自身

rect方法下的坐标

爆炸类

检测回收站和python、steam两种子弹以及pycharm图标之间的矩形碰撞,并加载动画

(动画就是这两个图片来回切换几次)

注意这一类并不能完全实现功能,还需要管理类中主函数方法的while循环进行控制,从而实现碰撞后图片的清除和分数的记录

管理类

用于管理前面数个类的方法

由于很长,中间略,下面会放源代码

主函数

最后运行主函数

运行效果

死亡动画(没法放视频,截了一下中间的图片)

撞到pycharm之后的结局(加500000000000000分)

2.3相关知识

2.3.1类

初始化

实例化对象时可以传入参数,这些参数会传入__init__()方法中,可以通过重写这个方法来定义对象的初始化操作

加pygame.sprite.Sprite.__init__(self)是为了主要矩形rect的方法调用

self

通常需要将函数的第一个参数定义成self,而self指向对象本身

之后在这个类里面写都要在前面加self,表示自己的参数和函数方法

然后调用别的类中的就是写别的类的名称(例如此处的Enemy.enemy_bullets)

父类和子类继承

此处pygame.sprite.Sprite就是父类,位于pygame模块中,所以不用自己写。

而Enemy就是自己创建的子类

调用父类,继承函数方法

2.3.2pygame的函数

图像和矩形(上面讲过了)

Group()

用于装子弹,使用起来相当于列表list

退出模块

字体

事件判断

碰撞用到的方法

刷新界面(安了两个)

time

pygame.time.set_timer()

功能:在事件队列上重复创建事件

2.3.3文字

分数面板的制作需要用到文字,不难但是比较特殊

在定义函数之后,设置内容、两个颜色和字体,然后导成矩形贴到界面上

2.4源代码

import random
import time
import pygame class Hero(pygame.sprite.Sprite):
def __init__(self,screen):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load("./python/11.png")
self.rect=self.image.get_rect()
self.rect.topleft=[480/2-50,600]
self.speed=10 self.screen=screen self.bullets=pygame.sprite.Group() def key_control(self):
#监听
key_pressed=pygame.key.get_pressed() if key_pressed[pygame.K_w] or key_pressed[pygame.K_UP]:
self.rect.top-=self.speed
if key_pressed[pygame.K_s] or key_pressed[pygame.K_DOWN]:
self.rect.bottom+=self.speed
if key_pressed[pygame.K_d] or key_pressed[pygame.K_RIGHT]:
self.rect.right+=self.speed
if key_pressed[pygame.K_a] or key_pressed[pygame.K_LEFT]:
self.rect.left-=self.speed
if key_pressed[pygame.K_SPACE]:
bullet=Bullet(self.screen,self.rect.left,self.rect.top)
self.bullets.add(bullet) def update(self):
self.key_control()
self.display() def display(self):
self.screen.blit(self.image,self.rect)
self.bullets.update()
self.bullets.draw(self.screen) class Bullet(pygame.sprite.Sprite):
def __init__(self,screen,x,y):
pygame.sprite.Sprite.__init__(self) self.image=pygame.image.load("./python/22.png") self.rect=self.image.get_rect()
self.rect.topleft=[x+50,y-22] self.screen=screen
self.speed=10 def update(self):
self.rect.top-=self.speed
if self.rect.top<-22:
self.kill() class Enemy(pygame.sprite.Sprite):
enemy_bullets1=pygame.sprite.Group()
enemy_bullets2=pygame.sprite.Group()
def __init__(self,screen):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load("./python/33.png")
self.rect=self.image.get_rect()
self.rect.topleft=[0,0] self.speed=10 self.screen=screen self.bullets1=pygame.sprite.Group()
self.bullets2=pygame.sprite.Group()
self.direction='right' def display(self):
#贴飞机图
self.screen.blit(self.image,self.rect)
self.bullets1.update()
self.bullets2.update()
self.bullets1.draw(self.screen)
self.bullets2.draw(self.screen) def update(self):
self.auto_move()
self.auto_fire()
self.display() def auto_move(self):
if self.direction == 'right':
self.rect.right+=self.speed
elif self.direction == 'left':
self.rect.right-=self.speed
if self.rect.right>=542:
self.direction='left'
elif self.rect.right<=57:
self.direction='right' def auto_fire(self):
random_num=random.randint(1,40)
if random_num>37:
bullet1=EnemyBullet1(self.screen,self.rect.left,self.rect.top)
self.bullets1.add(bullet1)
Enemy.enemy_bullets1.add(bullet1)
if random_num<=1:
bullet2=EnemyBullet2(self.screen,self.rect.left,self.rect.top)
self.bullets2.add(bullet2)
Enemy.enemy_bullets2.add(bullet2) class EnemyBullet1(pygame.sprite.Sprite):
def __init__(self,screen,x,y):
pygame.sprite.Sprite.__init__(self) self.image=pygame.image.load("./python/python.png") self.rect=self.image.get_rect()
self.rect.topleft=[x+20,y+20] self.screen=screen
self.speed=10 def update(self):
self.rect.top+=self.speed
if self.rect.top>830:
self.kill() class EnemyBullet2(pygame.sprite.Sprite):
def __init__(self,screen,x,y):
pygame.sprite.Sprite.__init__(self) self.image=pygame.image.load("./python/steam.png") self.rect=self.image.get_rect()
self.rect.topleft=[x+20,y+20] self.screen=screen
self.speed=10 def update(self):
self.rect.top+=self.speed
if self.rect.top>830:
self.kill() class Bomb(object):
def __init__(self,screen,type):
self.screen=screen
if type=='enemy':
self.mImage=[pygame.image.load
("./python/4"+str(v)+".png") for v in range(1,5)] else:
self.mImage=[pygame.image.load
("./python/4"+str(v)+".png") for v in range(1,5)] self.mIndex=0
self.mPos=[0,0]
self.mVisible=False def action(self,rect):
self.mPos[0]=rect.left
self.mPos[1]=rect.top
self.mVisible=True def draw(self):
if not self.mVisible:
return
self.screen.blit(self.mImage[self.mIndex],(self.mPos[0],self.mPos[1]))
self.mIndex+=1
if self.mIndex>=len(self.mImage):
self.mIndex=0
self.mVisible=False class Manager(object):
bg_size=(542,830)
game_over_id=11 #1-32中任意一个
is_game_over=False
is_game_up=False
game_up_id=11
score=0 def __init__(self):
pygame.init()
self.screen=pygame.display.set_mode((542,830),0,32)
#窗口
self.background=pygame.image.load("./python/1.png")
#背景
self.players=pygame.sprite.Group()
#装玩家精灵的group
self.enemys=pygame.sprite.Group()
#装敌机精灵的group
self.player_bomb=Bomb(self.screen,'player')
#玩家爆炸对象
self.enemy_bomb=Bomb(self.screen,'enemy')
#敌机爆炸对象 def exit(self):
print('退出') pygame.quit()
exit() def new_player(self):
player=Hero(self.screen)
self.players.add(player) def new_enemy(self):
enemy=Enemy(self.screen)
self.enemys.add(enemy) def drawText(self,score:int,x,y,textHeight=30,fontColor=(100,200,0),backgroundColor=None):
self.word = f"Score: {score}"
font_obj=pygame.font.Font('./python/方.TTF',textHeight)
text_obj=font_obj.render(self.word,True,fontColor,backgroundColor)
text_rect=text_obj.get_rect()
text_rect.topleft=(x,y)
self.screen.blit(text_obj,text_rect) def main(self):
self.new_player()
self.new_enemy() while True:
self.screen.blit(self.background,(0,0)) self.drawText(Manager.score,0,0) for event in pygame.event.get():
#判断
if event.type==pygame.QUIT:
self.exit() self.player_bomb.draw()
self.enemy_bomb.draw() if self.players.sprites():
isover=pygame.sprite.spritecollide(self.players.sprites()[0],Enemy.enemy_bullets2,True)
if isover:
Manager.is_game_over=True
pygame.time.set_timer(Manager.game_over_id,1000)
print('中弹')
print('游戏结束了')
self.player_bomb.action(self.players.sprites()[0].rect)
self.players.remove(self.players.sprites()[0]) if self.players.sprites():
isup=pygame.sprite.spritecollide(self.players.sprites()[0],Enemy.enemy_bullets1,True)
if isup:
Manager.is_game_up=True
pygame.time.set_timer(Manager.game_up_id,10)
print('获取')
Enemy.enemy_bullets1.remove(Enemy.enemy_bullets1.sprites()[0])
Manager.score += 10
print(Manager.score) iscollide=pygame.sprite.groupcollide(self.players,self.enemys,True,True)
if iscollide:
items=list(iscollide.items())[0]
print(items) x=items[0]
y=items[1][0]
self.player_bomb.action(x.rect)
self.enemy_bomb.action(y.rect)
Manager.score+=500000000000000 self.players.update()
self.enemys.update() pygame.display.flip()
pygame.display.update()
time.sleep(0.01) if __name__=='__main__':
manager=Manager()
manager.main() def main():
#窗口
screen=pygame.display.set_mode((542,830),0,32)
#背景
background=pygame.image.load("./python/1.png") player=Hero(screen) enemy=Enemy(screen) while True: screen.blit(background,(0,0)) for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.qiut()
exit() player.key_control() player.display() enemy.display() enemy.auto_move() enemy.auto_fire() pygame.display.update()
time.sleep(0.01) if __name__=='__main__':
main()

三、服务器上运行:

3.1配置服务器

由于C语言课程也需要用到华为云服务器,所以直接使用上次已经购买好的服务器,就不再进行购买和配置。

3.2在 Linux 系统安装 X11 转发的必要软件包

由于服务器没有自带图形界面,所以首先安装游戏运行所需界面(xming)

# yum install -y xauth
# yum install -y xclock

其中”xauth”用于 X11 转发认证,而”xclock”是一个十分简单的 GUI 程序,用于验证 X11 转发是否成功。

在服务器端vi /etc/ssh/sshd_config,(用vim编辑器打开sshd_config文件)

添加一行:X11Forwarding yes(按i进入编辑模式,按Esc退出编辑,按: 输入wq退出vim)

重启sshd
systemctl restart sshd.service  --重启

3.3下载 Xming

由于华为服务器没有自带的弹出界面,安装xming来提供linux图形界面

安装好xming之后,启动”xlaunch”工具,默认安装位置为”C:\Program Files (x86)\Xming\XLaunch.exe”,会见到如下配置选择界面:

在ssh的x11中勾选enable x11 forwarding

3.4 ECS环境运行

尝试运行惨遭失败

询问课代表解决问题,更换为另一个服务器成功运行~

在xming界面中运行游戏

成功啦~(虽然超级卡根本没法玩)

四、遇到的问题和解决办法

1.窗口刚打开就闪退

解决方案:是因为执行一次之后就结束了,要把screen加到while True循环里面,使其一直运行

2..写到子弹类发现无法运行,窗口刚弹出就消失

解决方法:发现调用Group函数的时候忘记在后面写(),相当于没有执行这个函数,加上括号之后就可以成功射出子弹了

3.计分板一直为0,无法刷新

解决方案:开始以为问题出在没有把score调用好,把score在Manager的开头定义,然后在def main()中调用Manager.score,但是还是不行。后来我把判断if isup==True:改成了if isup:,即可成功使计分板刷新。

4.在华为服务器运行python文件时没有画面,且会报错

解决方案:通过课代表在群里的提醒后,下载了一个xming,并根据群里发的参考链接,结合课代表的热心帮助,最终解决了这个问题

5.运行找不到图片

解决方案:图片路径是原来本地文件夹的,而没有改为当前服务器文件夹。改写为./xxx.png之后成功运行(./指当前文件夹)

五、课程小结

课程总结与感想:

在学习编程之前,我一直对C语言和python这些是有“学习障碍”的。说是“学习障碍”,其实只是我不善于理解那些语法知识,而出现一下子无法解决的错误就觉得很心累,想要放弃。在现在学习的一个学期的编程的我看来,这都是很正常的现象,尽管当时真的对于那些很难理解的东西都感到绝望了,但是随着不断的坚持和时间的积累,自己的水平和技能一定会提高。我认为学习编程就是这样,暂时无法理解的东西,会随着学习的深入而自然瓦解。

python这门课的学习也是如此。在刚开课的时候,我对于python这种语言的理解就是“简洁”,定义一个量不需要像C语言那样写上变量类型,而是只要写等号就行了。然后之后课上演示运行了input和print函数也很容易,后面讲了for和while的循环,continue、break、pass也很好理解记忆,那时候的我还是游刃有余的。但是随着课程的推进,序列list、元组Tuple、字典Dictionary等知识让我觉得这门课忽然变得有些难度,相关的排序、访问什么什么的操作也不太能记得住,后面的正则表达式、类(面向对象编程)、socket(套接字)等知识更是使我在课上反应不过来,根据自己的理解就是检索替换之类的功能、程序分类封装使用、服务器建立连接吧,只能心累地跟着老师做。反思一下,其实我在课后练习的时间也不够,所以才会产生这样的恶行循环。

但是结课之后,我通过做游戏潜心学习了python的类和函数调用等知识,尽管自己写程序还很吃力,但我逐渐理解了序列的使用和面向对象编程的优势和强大,原本无法理解、让我绝望的知识也不过是逻辑框架下设置的工具而已,而且python本就是很方便使用的工具,我现在觉得很有自信继续学好python这门语言了。所以我说“暂时无法理解的东西,会随着学习的深入而自然瓦解”,就是这样的道理。

然而经过一个学期的学习,我的收获相对于老师的付出来说还是少了,但是我决定在假期、在之后的学期里自行学习python,把学习这门语言作为我的阶段目标。

课程体会和建议

王志强老师上课很幽默,而且是一位很负责、敬业的老师,我很喜欢上王老师的课。

我觉得课程后面进度太快了,尽管课后可以看云班课上的文件,正则表达式开始就不太能够跟上,建议除了实验作业之外应该多多布置一些小作业来让我们自行练习。

还有就是下学期还能开这门课就更好了。

20212109《Python程序设计》实验四 Python综合实践实验报告的更多相关文章

  1. 20145308刘昊阳 《Java程序设计》实验四 Android环境搭建 实验报告

    20145308刘昊阳 <Java程序设计>实验四 Android环境搭建 实验报告 实验名称 Android环境搭建 实验内容 搭建Android环境 运行Android 修改代码,能输 ...

  2. # 2016-2017-2 20155319 《Java程序设计》实验四Android程序开发实验报告

    2016-2017-2 20155319 <Java程序设计>实验四Android程序开发实验报告 实验一 实验内容 Android Stuidio的安装测试: 参考<Java和An ...

  3. 20155338 2016-2017-2《Java程序设计》实验四Android程序开发实验报告

    2016-2017-2 20155338 <Java程序设计>实验四Android程序开发实验报告 实验过程及成果展示 1.修改res目录下的layout文件夹中的activity_mai ...

  4. 20155215宣言 实验四 Andoid开发基础实验报告

    20155215宣言 实验四 Andoid开发基础实验报告 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程: 2.完成实验 ...

  5. 20193314白晨阳《Python程序设计》实验四 Python综合实践

    课程:<Python程序设计> 班级: 1933 姓名: 白晨阳 学号:20193314 实验教师:王志强老师 实验日期:2021年6月13日 必修/选修: 公选课 实验内容: Pytho ...

  6. 实验四 Python综合实践

    课程:<Python程序设计> 班级:1843 姓名:章森洋 学号:20184307 实验教师:王志强 实验日期:2020年5月16日 必修/选修: 公选课 1.实验内容 此处填写实验的具 ...

  7. 20211306 实验四 Python综合实践

    学号 20211306 <Python程序设计>实验四报告 课程:<Python程序设计> 班级: 2113 姓名: 丁文博 学号:20211306 实验教师:王志强 实验日期 ...

  8. 20203412马畅若《Python程序设计》实验四Python综合实践报告

    作为初次接触程序设计的我在看到云班课中用python进行游戏编程后感到很有意思,所以我决定这次做一个最经典的小鸟管道游戏.虽然网上许多大佬都说这是最基础的一项游戏编码,但我还是用了许多时间去做成这个游 ...

  9. python面试题四:Python web框架

    1 django.flask.tornado框架的比较? 2 什么是wsgi? WSGI的全称是Web Server Gateway Interface,翻译过来就是Web服务器网关接口.具体的来说, ...

  10. Python学习笔记(四)Python函数的参数

    Python的函数除了正常使用的必选参数外,还可以使用默认参数.可变参数和关键字参数. 默认参数 基本使用 默认参数就是可以给特定的参数设置一个默认值,调用函数时,有默认值得参数可以不进行赋值,如: ...

随机推荐

  1. 获取接口方式(Bean注入方式总结)

    一.在工具类中使用SpringContextHolder获取Bean对象,用来调用各个接口 /** * 获取阿里巴巴属性列表映射 * * @author 王子威 * @param alibabaPro ...

  2. ISO镜像做yum源

    先上传一个镜像文件 centos-7-x86-1708.iso 挂载 mount -o loop /root/centos-7-x86-1708.iso /file 设置开机自动挂载 vi /etc/ ...

  3. Python 变量作用域 LEGB

    回顾 - Decorator 前篇有讲到了, 闭包和装饰器的概念. 闭包就是, 函数内部嵌套函数. 而 装饰器只是闭包的特殊场景而已, 特殊在如果外函数的参数是指向一个, 用来被装饰的函数地址时(不一 ...

  4. 8086汇编(16位汇编)学习笔记00.DEBUG命令使用解析及范例大全

    转载自:https://bpsend.net/thread-99-1-1.html 启动 Debug,它是可用于测试和调试 MS-DOS 可执行文件的程序. Debug [[drive:][path] ...

  5. 初探Iris

    Iris 安装 go get -u github.com/kataras/iris 若遇到下面这种情况: 可删除保存路径中的kataras目录,并执行go get github.com/kataras ...

  6. 东吴证券X袋鼠云:数据轻松可取、毫秒级反应能力,东吴证券做对了什么?

    "所有事情都可以用数字表达." 这句话是1998年一部非典型金融影片<圆周率>的男主独白.影片中,天才数学家Max发现了一套数学模型在"操纵"着股票 ...

  7. 在centos7等旧版linux上用国内源下载源码编译安装gcc并配置环境变量

    原文永久链接:https://forum.piwind.com/d/23-zai-centos7deng-jiu-ban-linuxshang-yong-guo-nei-yuan-xia-zai-yu ...

  8. Linux在线安装JDK1.8+

    Linux在线安装JDK1.8+(默认已发布最新版) 命令在线下载jdk: wget --no-check-certificate --no-cookies --header "Cookie ...

  9. springboot中使用FeignClient调用http请求

    1. 在.pom文件中添加openfeign的依赖 <dependency> <groupId>org.springframework.cloud</groupId> ...

  10. Django(1)安装与基础使用

    一.Django介绍 Django介绍 Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的框架模式,即模型M,视图V和控制器C. Django官方网站 Django官方文 ...