课程:《Python程序设计》
班级:2133
20213310吴增辉《python程序设计》实验四python综合实践
姓名: 吴增辉
学号:20213310
实验教师:王志强老师
实验日期:2022年5月22日
必修/选修: 公选课
1.实验内容
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。编写躲闪游戏并使用华为云服务(ECS或者MindSpore均可)运行。
- 实验过程及结果
前期准备
思考许久,发现python这次大作业内容很难,所以选择了经常接触且可能比较容易上手的游戏进行编程,因此最终选择编写躲闪游戏。
实验过程
刚开始困难较大,一直在网上寻找教学视频和相关博客资料,还找了同学帮助学习了进行华为云服务运行。
游戏编程代码
import sys
import random
from math import *
pygame.init()#初始化设置
width = 400
height = 500
display = pygame.display.set_mode((width, height))#初始化用于显示的窗口并设置窗口尺寸
pygame.display.set_caption("Simple Dodge Ball Game")#设定窗口标题
clock = pygame.time.Clock()#创建一个Clock对象,用于操作时间
background = (255, 255, 255)#背景色为白色
playerColor = (50, 50, 50)#选择(50, 50, 50)对应的颜色
red = (203, 67, 53)#颜色设定
yellow = (241, 196, 15)
blue = (46, 134, 193)
green = (34, 153, 84)
purple = (136, 78, 160)
orange = (214, 137, 16)
colors = [red, yellow, blue, green, purple, orange]#创建colors列表
score = 0 #初始分值为0
class Ball: #class:类
def __init__(self, radius, speed):
#初始值设定,无实际意义
self.x = 0
self.y = 0
self.r = radius
self.color = 0
self.speed = speed
self.angle = 0
def createBall(self):
self.x = width / 2 - self.r #x坐标设定
self.y = height / 2 - self.r #y坐标设定
self.color = random.choice(colors) #从创建的colors列表中随机选取颜色
self.angle = random.randint(-180, 180) #在[-180,180]的范围内随机生成整数
def move(self):
#球每次移动后,都有一个新坐标
self.x += self.speed * cos(radians(self.angle))
self.y += self.speed * sin(radians(self.angle))
#判断球是否撞到墙,当撞到墙时换向移动
if self.x < self.r or self.x + self.r > width:
self.angle = 180 - self.angle
if self.y < self.r or self.y + self.r > height:
self.angle *= -1
def draw(self):
pygame.draw.ellipse(display, self.color, (self.x - self.r, self.y - self.r, self.r * 2, self.r * 2))#绘制矩形,将所需的圆限定在设定好的矩形中(理解为画个圆就行了)
def collision(self, radius):
pos = pygame.mouse.get_pos()#获取鼠标光标的位置
dist = ((pos[0] - self.x) ** 2 + (pos[1] - self.y) ** 2) ** 0.5 #利用公式计算距离
if dist <= self.r + radius:#此处代表碰撞(距离小于等于两个物体的半径和),碰撞后游戏结束
gameOver()
class Target: #再设定另一个类
def __init__(self): #初始化设定
self.x = 0
self.y = 0
self.w = 20
self.h = self.w
def generateNewCoord(self):
self.x = random.randint(self.w, width - self.w)#定义该函数的(x,y)
self.y = random.randint(self.h, height - self.h)
def draw(self):
color = random.choice(colors)#随机选择颜色
pygame.draw.rect(display, color, (self.x, self.y, self.w, self.h)) #绘制方形
def gameOver():
loop = True #判断循环是仍在进行的
font = pygame.font.SysFont("Agency FB", 100) #字体设置
text = font.render("Game Over!", True, (0, 0, 0)) #弹出黑色字体的“Game Over”
while loop:
for event in pygame.event.get():
# 获取游戏窗口状态
# 图像移动KEYDOWN键盘按下事件
# 通过key属性对应按键
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.key == pygame.K_r:
gameLoop()
display.fill(background)#背景填充
display.blit(text, (20, height / 2 - 100))#位置设定
displayScore() #显示分数
pygame.display.update() #更新显示界面
clock.tick() #计时
def checkCollision(target, d, objTarget): #检查碰撞
pos = pygame.mouse.get_pos() #鼠标位置
dist = ((pos[0] - target[0] - objTarget.w) ** 2 + (pos[1] - target[1] - objTarget.h) ** 2) ** 0.5 #计算距离
if dist <= d + objTarget.w: #距离小于等于二者半径和的时候,则认为碰撞发生了
return True
return False
def drawPlayerPointer(pos, r):
pygame.draw.ellipse(display, playerColor, (pos[0] - r, pos[1] - r, 2 * r, 2 * r))#画圆
def close():
pygame.quit()#游戏停止
sys.exit() #退出
def displayScore():
font = pygame.font.SysFont("Arial", 30)#设置字体
scoreText = font.render("Score: " + str(score), True, (0, 0, 0)) #计分
display.blit(scoreText, (10, 10)) #显示计分
def gameLoop():
global score #设定score为全局变量
score = 0 #初始值
loop = True #循环在进行
pRadius = 10 #设定半径
balls = [] #列表设定
for i in range(1):
newBall = Ball(pRadius + 2, 5) #设定新球的半径和速度
newBall.createBall() #产生新球
balls.append(newBall) #每产生一个新球,添加到balls列表中
target = Target() #运行前面定义的函数,前面的def只是定义,现在运行出来
target.generateNewCoord()
while loop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
#图像移动KEYDOWN键盘按下事件
#通过key属性对应按键
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.key == pygame.K_r:
gameLoop()
display.fill(background) #背景填充
for i in range(len(balls)): #所有的球让它们移动起来
balls[i].move()
for i in range(len(balls)):
balls[i].draw() #画出这些球
for i in range(len(balls)):
balls[i].collision(pRadius) #检测碰撞
playerPos = pygame.mouse.get_pos()
drawPlayerPointer((playerPos[0], playerPos[1]), pRadius)
collide = checkCollision((target.x, target.y), pRadius, target)
if collide:
score += 1 #当球和方片碰撞的时候,计分加一分
target.generateNewCoord()
elif score == 2 and len(balls) == 1: #碰撞两次但是界面里只有一个球的时候
newBall = Ball(pRadius + 2, 5) #产生新球
newBall.createBall()#下面这三行都是让前面def的函数运行
balls.append(newBall)
target.generateNewCoord()
elif score == 5 and len(balls) == 2: #碰撞了五次但是界面里只有两个球的时候
newBall = Ball(pRadius + 2, 6) #产生新球并且球的运行速度变快
newBall.createBall()
balls.append(newBall)
target.generateNewCoord()
elif score == 10 and len(balls) == 3: #与上面的都是类似的,意思就是当碰撞十次的时候,界面上应该添加新球了
newBall = Ball(pRadius + 2, 7)
newBall.createBall()
balls.append(newBall)
target.generateNewCoord()
elif score == 15 and len(balls) == 4:
newBall = Ball(pRadius + 2, 8)
newBall.createBall()
balls.append(newBall)
target.generateNewCoord()
elif score == 20 and len(balls) == 5:
newBall = Ball(pRadius + 2, 9)
newBall.createBall()
balls.append(newBall)
target.generateNewCoord()
target.draw() #绘制
displayScore() #显示分数
pygame.display.update() #界面更新
clock.tick(60) #计时
gameLoop() #执行游戏
3.运行结果截图
vscode运行
华为云服务器运行
4.实验遇到的问题及解决
问题1:网上参考代码到自己的vscode无法运行
解决1:运行的文件地址和路径要和参考代码里的一致。
问题2:编写代码很难,有很多语句不懂,经常报错
解决2:不断查找资料,询问同学;
5.实验体会及课堂总结
这次大作业整体来说很困难,大部分依赖网上搜索相关资料和教学视频才能一步一步编写代码,再进行相关注释。想要真正自主地编写一个完整代码并理解,道阻且长,可能还需要继续努力。大一下册这学期同时接触python和c语言这两个全新的课程,是一个挑战也是锻炼。我更加明白学习编程,要有耐心有毅力,要结合网上资料多自学,也要常常打打代码锻炼手感,这样才能越学越顺利,更进一层楼。
最后,谈谈课堂总结。王志强老师真的很温柔,每堂课都带着我们一行一行打代码,而不是粗略地念ppt,更加注重实践。但是,作为选修课,很多同学确实没有对python了解很深,大多是对python好奇热爱的初学入门者,所以建议能稍微放慢脚步,多讲一些基础的编程语句,或者能够把上课打的代码发在微信群里方便复习。能选修python,这一学期以来听课很高兴,学到了一些真正的东西,迎难而上的成就感是不可替代的,从来没想过自己能有毅力去理解编写一个小游戏,但这次大作业做到了。感谢python,感谢王志强老师,希望老师越上越好,一切顺利!