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

1.实验内容

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
注:在华为ECS服务器(OpenOuler系统)和物理机(Windows/Linux系统)上使用VIM、PDB、IDLE、Pycharm等工具编程实现。

2,实验过程及结果

(一)实验内容

编写一个塔防游戏,类似于保卫萝卜以及明日方舟那种。

(二)选题理由

因为本人对塔防游戏情有独钟,所以自己想编写一个塔防游戏,但由于对python的学习空间剩余的还很大,所以在网上找了许多的参考资料并且学习参考了教学视频才勉强完成,虽然不太完美,但对于自己来说也是一个挑战自己的机会。

(三)实验过程

1.首先购买一个华为云服务器

这个步骤我在本专业的C语言课程中其实已提前完成,所以没有花掉我多少的时间

2.下载pygame

这个步骤我是通过在网上找找资料,然后根据热心网友的回答解决的,但是在这个步骤的实现的过程我遇见了一个挺大的麻烦,就是明明我已经下载了pygame我在pycharm上运行时却会显示说我没安装pygame,这个问题困扰我很久,但好在课代表热心能力有强,帮我解决了这个问题,原因是我的电脑里下列三个python

但是只有一个python是有pygame的,最终帮我换了一个编译环境后解决了问题。(真的感谢课代表,我自己弄不知道要多久)

3.配置远程桌面

这个步骤也是在课代表的提醒下弄得,课代表在群里说需要下载这个才可以在华为云服务器上运行,不然会报错

首先在linux系统

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

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

下载xterm和xauth,EularOS用如下命令

yum install xterm

yum install xauth
用vim编辑器打开(vi是vim的简写)网络设置,注意xming与putty之间是通过ssh协议通信的

vi /etc/ssh/sshd_config
设置X11Forwarding yes
在vim编辑器中按i进入编辑模式,按Esc退出编辑,按:输入wq退出vim
完成后退出putty

xming下载并安装好后,在菜单栏找到xlaunch,一直点下一步至完成即可。之后打开putty输入xterm即可看见窗口了。

设置X11Forwarding yes

下载xming

最后为了成功运行xterm花了不少时间,通过上网查找教程和群里的文件,最终自己独立完成,但运行成功出现自己的理想中的结果时,有点成就感

4.编写代码过程及思路

首先塔防游戏需要涉及地图

# map1=[(50,14),(86,14),(135,14),(175,14),(180,47),(180,92),(215,92),(260,92),\
#       (302,94),(305,135),(306,174),(344,174),(392,174),(430,180),(430,139),\
#       (430,90),(430,51),(475,52),(516,52),(560,52),(560,94),(560,131),(560,166),\
#       (560,205),(560,247),(560,273),(560,307),(513,305),(469,305),(432,305),\
#       (387,305),(349,305),(300,305),(250,305),(200,305)]
#用分段函数来表示路径,t从55开始
# def get_path(t):
#       if t<203 and t>50:
#             x=t
#             y=14
#             return [x,y]
#       elif t<286:
#             x=182
#             y=t-203+14
#             return [x,y]
#       elif t<403:
#             x=t-286+203
#             y=116
#             return [x,y]
#       elif t<487:
#             x=320
#             y=t-403+116
#             return [x,y]
#       elif t<633:
#             x=t-487+320
#             y=200
#             return [x,y]
#       elif t<770:
#             x=466
#             y=-(t-633)+200
#             return [x,y]
#       elif t<884:
#             x=t-770+466
#             y=63
#             return [x,y]
#       elif t<1277:
#             x=580
#             y=t-884+63
#             return [x,y]
#       elif t<1647:
#             x=-(t-1277)+580
#             y=330
#             return [x,y]
#       else:
#             pass#意思是不在路径上
def get_path(t):
      if t<203 and t>50:
            x=t
            y=34
            return [x,y]
      elif t<286:
            x=203
            y=t-203+34
            return [x,y]
      elif t<403:
            x=t-286+203
            y=116
            return [x,y]
      elif t<487:
            x=320
            y=t-403+116
            return [x,y]
      elif t<633:
            x=t-487+320
            y=200
            return [x,y]
      elif t<770:
            x=466
            y=-(t-633)+200
            return [x,y]
      elif t<884:
            x=t-770+466
            y=63
            return [x,y]
      elif t<1177:
            x=580
            y=t-884+63
            return [x,y]
      elif t<1647:
            x=-(t-1177)+580
            y=330
            return [x,y]
      else:
            return [40,40]#意思是不在路径上

然后再游戏中也是需要音乐的,不然会让游玩者感到枯燥,所以加入了背景音乐

然后找了几张防御物,小怪物,地图的图来呈现

首先在塔防游戏中,防御物是需要攻击怪物的,所以我们首先编写攻击物间的代码

import math
import random
import pygame
'''子弹类'''
class bullet1(pygame.sprite.Sprite):
    def __init__(self,pos_x,pos_y,angle):
        pygame.sprite.Sprite.__init__(self)
        #载入子弹的图片
        image0 = pygame.image.load('./resource/imgs/game/arrow1.png').convert_alpha()
        self.image1= pygame.transform.scale(image0,(24,24))
        #self.image=pygame.transform.rotate(self.image1,math.pi/3)
        #self.image=pygame.transform.rotate(self.image1,math.radians(45))
        self.image2 = pygame.transform.rotate(self.image1,45)
        self.image = pygame.transform.rotate(self.image2,-180*angle/math.pi)
        self.rect = self.image.get_rect()
        self.position = pos_x,pos_y
        self.begin_pos=pos_x,pos_y
        #self.begin_pos = self.position
        self.rect.left, self.rect.top = self.position
        # 与水平向左的直线所成的夹角, 顺时针为正
        self.angle = angle#子弹的射击角度
        self.speed=50#子弹的移动速度
        self.scope=400#子弹的射击范围
        self.attack_power=9#子弹的杀伤力
    '''不停移动'''
    def move(self):
        self.rect.left = self.rect.left - self.speed * math.cos(self.angle)
        self.rect.top=self.rect.top - self.speed * math.sin(self.angle)
        #self.rect.left, self.rect.top = self.position
    '''重置子弹的位置'''
    # def reset(self, position, angle=None):
    #   if angle is None:
    #       angle = random.random() * math.pi * 2
    #   self.position = position
    #   self.angle = angle
    #   self.rect = self.image.get_rect()
然后还需要设计被攻击的怪物
import pygame
from maps import MAP
'''敌方类'''
class Monster1(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('./resource/imgs/game/monster.png')
       
        self.rect = self.image.get_rect()
        self.t=55#已经走过的时间
        self.index1=0#目前所在路径列表中的位置
        self.position = 60, 40
        self.rect.left, self.rect.top = self.position
        # 最大生命值
        self.max_life_value = 20
        # 当前生命值
        self.life_value = 20
        # 速度
        self.speed = 10
        # 击杀奖励
        self.reward = 70
        # 对大本营造成的伤害
        self.damage = 2
    def move(self):#移动怪物
        self.t+=self.speed
        self.rect.left,self.rect.top=MAP.get_path(self.t)[0]-20,MAP.get_path(self.t)[1]-20#修改位置
    def die(self):
         global monsters
         monsters = [monster for monster in monsters if monster.t>=1647]#列表中元素的删除方式
         print("monsters的类型是:",type(monsters))
         print(len(monsters))

然后需要设计塔

import pygame
from sprites import Bullet
import math
import random
'''炮塔类'''
class Tower1(pygame.sprite.Sprite):
    def __init__(self,pos_x,pos_y,shot_angle,cooling_time):
                #shot_angle是射击方向
        pygame.sprite.Sprite.__init__(self)
        #self.imgs = ['./resource/imgs/game/basic_tower.png', './resource/imgs/game/med_tower.png', './resource/imgs/game/heavy_tower.png']
        self.image = pygame.image.load('./resource/imgs/game/tower5.png')
        self.rect = self.image.get_rect()
        self.cooling_time=cooling_time
        self.cooling_now=cooling_time#箭塔的冷却时间
        self.shot_angle=shot_angle
        self.price=300#箭塔的价格
        self.position = pos_x,pos_y
        self.rect.left, self.rect.top = self.position
    '''射击'''
    def shot(self, position):#参数是子弹的位置和角度
        bullet = None
        #print(self.cooling_now)
        if self.cooling_now<=0:
            #angle = 2*math.pi*random.randint(0,360)/360#随机生成箭的射击方向
            #bullet=Bullet.bullet1(position[0],position[1],angle)
            #bullets.add(i.shot(i.position))
            self.cooling_now=self.cooling_time
            return 1
        else:
            self.cooling_now-=1
            return 0
    #   bullet = None
    #   if not self.is_cooling:
    #       bullet = Bullet.bullet1()#初始化一个子弹
    #       bullet.reset(position, angle)
    #       self.is_cooling = True#子弹重新进入冷却时间
    #   if self.is_cooling:
    #       self.coolTime -= 1
    #       if self.coolTime == 0:#冷却时间结束以后
    #           self.reset()
    #   return bullet
    '''重置'''
    #def reset(self):
    #   self.price = 500
    #   # 射箭的冷却时间
    #   self.coolTime = 30
    #   # 是否在冷却期
    #   self.is_cooling = False

至此,最重要的几个元素就设计完成了

 
然后完善来一下设计购买防置的金钱,自己家的生命值,怪物生命值等最大的框架
#随机生成怪物
import pygame
from sprites import Monster
from sprites import Tower
from sprites import Bullet
from maps import MAP
import random
import os
from pygame.locals import*
from sys import exit
from random import*
import math
'''参数设置'''
WIDTH = 650
HEIGHT = 450
blood_color=(255,0,0)
blood_width=4
my_money=1000
monster_time=8#怪物出现的频率
home_life_value=20#自己家的生命值
'''主函数'''
pygame.init()
pygame.mixer.init()
pygame.mixer.music.load("./resource/music/back_ground_music.mp3")
hit_sound = pygame.mixer.Sound("./resource/music/s_hit.ogg")
hit_sound.set_volume(0.1)
#pygame.mixer.music.load("F:\defend_10\\td1_29\\resource\\music\\back_ground_music.mp3")
#hit_sound = pygame.mixer.Sound("F:\defend_10\\td1_29\\resource\\music\\s_hit.ogg")#中箭的声音
screen = pygame.display.set_mode((WIDTH, HEIGHT))
bg=(255,0,0)
background=pygame.image.load('./resource/imgs/game/map.jpg').convert()#地图
background0=pygame.image.load('./resource/imgs/game/ground0.JPG').convert()#底色
pygame.display.set_caption("塔防游戏")
clock = pygame.time.Clock()
#用列表存储实例化以后的怪物,子弹,炮塔
monster=Monster.Monster1()
monsters =pygame.sprite.Group(monster)#建立怪物的精灵组
tower1=Tower.Tower1(200,200,2,3)
towers=pygame.sprite.Group(tower1)#建立一个箭塔精灵组
bullets=pygame.sprite.Group(Bullet.bullet1(200,200,3))#建立一个子弹的精灵组
font1 = pygame.font.SysFont('宋体', 30, True)
def cal_dis(x1,y1,x2,y2):
    distance=math.sqrt(pow(x1-x2,2)+pow(y1-y2,2))
    return distance
def monster_move():
    for i in monsters:
        i.move()
def draw_blood():
    for i in monsters:
        start=(i.rect.left+10,i.rect.top-3)
        end=(i.rect.left+(i.life_value/i.max_life_value)*20+10,i.rect.top-3)
        pygame.draw.line(screen,blood_color,start,end,blood_width)
#碰撞检测,检测是否射中了怪物
def sprite_collide():
    global monsters
    global bullets
    global attack_power
    global my_money
    global home_life_value
    attack_power=10#默认的箭的杀伤力
    dict1=pygame.sprite.groupcollide(monsters, bullets, False,True, collided=None)
    for i in bullets:
        attack_power=i.attack_power
        if i.rect.top<0 or i.rect.left<0 or i.rect.top>HEIGHT or i.rect.left>WIDTH:
            bullets.remove(i)
            #hit_sound.play()
        else:
            pass
    for i in dict1:
        i.life_value-=attack_power
        hit_sound.play()
    for i in monsters:
        if i.life_value<=0:
            monsters.remove(i)
            my_money+=i.reward#杀死一个怪物奖励一定的金钱
        elif i.rect.top>260 and i.rect.left<200:
            print("怪物到达了你家")
            home_life_value-=i.damage#对你家造成杀伤
            monsters.remove(i)
        else:
            pass
#在这里面画上当前金钱数,箭塔价格,城堡生命值
def draw_text():
    #screen.blit(surface1, [20, 20])
    #screen.blit(my_money,[400,400])
    screen.blit(font1.render(u'my money::%d' % my_money, True, [255, 0, 0]), [350, 400])
    screen.blit(font1.render(u'home life_value::%d' % home_life_value, True, [255, 0, 0]), [350, 430])
def move_bullet():
    global bullets
    for i in bullets:
        i.move()
        #判断子弹是否超出射程,如果超出范围就删除这个子弹
        if cal_dis(i.position[0],i.position[1],i.begin_pos[0],i.begin_pos[1])>i.scope:
            bullets.remove(i)
        else:
            pass
def shot_bullet():
    for i in towers:
        k=i.shot(i.position)
        if k:
            angle = 2 * math.pi *randint(0, 360) / 360  # 随机生成箭的射击方向
            bullets.add(Bullet.bullet1(i.rect.left,i.rect.top,angle))
        else:
            pass
while True:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            sys.exit()
        elif event.type == MOUSEMOTION:
            pos = pygame.mouse.get_pos()
            mouse_x = pos[0]
            mouse_y = pos[1]
        elif event.type==pygame.KEYDOWN:
            if event.key==pygame.K_d:
                #建立一个箭塔,在箭塔精灵组中添加一个箭塔
                if my_money>tower1.price:
                    towers.add(Tower.Tower1(mouse_x, mouse_y, math.pi, 7))
                    my_money -= tower1.price  # 建立一个箭塔消耗一定的金钱
                else:
                    print("金钱不够")
            else:
                pass
                #建立一个箭塔,在鼠标的当前位置
        else:
            pass
    if pygame.mixer.music.get_busy()==False:
        pygame.mixer.music.play()
    else:
        pass
    if randint(0,100)<monster_time:
        #产生一个怪物
        monsters.add(Monster.Monster1())
    else:
        pass
    monster_move()#移动精灵组
    shot_bullet()#射箭
    sprite_collide()
    move_bullet()
    monsters.update()
    towers.update()
    bullets.update()
    screen.blit(background0, (0, 0))
    screen.blit(background, (0, 0))
    draw_blood()
    draw_text()
    monsters.draw(screen)
    towers.draw(screen)
    bullets.draw(screen)
    clock.tick(4)
    pygame.display.update()
 
在ecs主机上运行
首先通过winscp上传文件代码

首先在本地运行

然后是在ecs上面运行

在这个上运行有点慢

(五)实验中所遇到的问题及解决方法

1.在下载pygame后在本地运行是却显示没有这个插件

解决方法:换了一个编译环境,发现有三个不同的python,但是只有一个pygame所以换了那个有pygame插件的python

2.最开始在华为云商运行时没有画面,且会报错

解决方案:通过课代表在群里的提醒后,下载了一个xming,完美解决了这个问题

3.一开始将代码上传后,但是会出错

解决方案:再请教同学后,知道了不能上传声音,不然会出错,然后将和声音有关的代码全部屏蔽了,成功上传

(六)实验的感悟

通过本次实验我明白了一个道理:没有最好只有更好,每次解决了一个问题后,总会有另一个问题冒出来,这也间接证明我在知识点上面的欠缺。

在问题的发现解决中,我自己的能力也得到了许多的提升,在这个过程挺感谢课代表的帮助,相信通过这次的作业,我以后在编写游戏以及对华为云的运用上面一定会更加的得心应手。

参考资料:B站教学视频

课代表以及多位热心同学的帮助

结课感想与体会

python是一门非常有潜力的高级语言,历经多年的发展,其在编程上发挥着越来越大的作用。在这学期中,通过选修python课上的基础知识学习,我对python也有了一定的认识。而且,在字符串上的处理,python相对于c语言也是给程序员极大的便利。而python不仅如此,它的库也很多,正因为它强大的库,让编程变得不再艰难。但是,我认为python虽然在许多方面相对于c语言比较方便,但也有其相对于弱一点的方面,比如说for循环等方面。虽然一学期下来,我对python的学习也仅仅只是它的基础方面,但python的强大,也是足足地吸引着我,希望自己能够在不断地学习中,将python学习的更加好。 python是一门非常有潜力的高级语言,历经多年的发展,其在编程上发挥着越来越大的作用。在这学期中,通过选修python课上的基础知识学习,我对python也有了一定的认识。

在学习python的第一节课上,其对我的最初的印象就是,相较于我学习过的c语言编程,它更加的简洁。所有的变量都不需要像c语言编程那样需要提前去定义,这样给了编程者很大的自由空间与方便。如x=2,即可同时完成变量的定义与赋值。对于简化程序的代码,起到了许多的作用。而且,在字符串上的处理,python相对于c语言也是给程序员极大的便利。在c语言中,只能用字符类的数组对字符串进行相应的操作,步骤也是相对于比较繁琐的,而在python中,当我们需要创建一个字符串的时候,只需要在创建字符串的时候用"s=”就可以了。而python不仅如此,它的库也很多,正因为它强大的库,让编程变得不再艰难。我们只需要调用库中的函数,而对于函数的具体实现,也没有特殊的需求。

但是,我认为python虽然在许多方面相对于c语言比较方便,但也有其相对于弱一点的方面,比如说for循环等方面。不过也依然不会影响到python的强大,而随着近几年来的发展,python的受欢迎度也越来越高,而它的运用的领域也是越来越多,比如人工智能和大数据等领域,python都是在其中扮演者重要的角色。虽然一学期下来,我对python的学习也仅仅只是它的基础方面,但python的强大,也是足足地吸引着我,希望自己能够在不断地学习中,将python学习的更加好。

在王老师的教导下,我觉得自己比起刚开始上课啥也不懂的小白可谓是强了不止一星半点,而且更为重要的是通过王老师得我教导,我对python的兴趣更加的浓厚了

真的挺感谢王老师,教科好而且有责任心,您的课我觉得也非常风趣幽默,上起来没有其他一些课的枯燥乏味,我知道python的学习还只是冰山一角,但相信通过王老师这一学期的引领,我在以后的学习中一定会得心应手,若果以后还有王老师的课,我一定还会选的(真)。

20212115朱时鸿 《python程序设计》实验四报告的更多相关文章

  1. 20212115朱时鸿实验一《python程序设计》实验报告

    ------------恢复内容开始------------ #学号20212115 <python程序设计>实验一报告 课程: <python程序设计> 班级:2121 姓名 ...

  2. 20212115朱时鸿-关于python技能树以及markdown编辑器的测评

    csdn的链接:https://blog.csdn.net/m0_68116569/article/details/124049366 计算机连接:https://gitee.com/zhu-shih ...

  3. 20184302 2019-2020-2 《Python程序设计》实验四报告

    20184302 2019-2020-2 <Python程序设计>实验四报告 课程:<Python程序设计> 班级: 1843 姓名: 李新锐 学号:184302 实验教师:王 ...

  4. 20192204 2019-2020-2 《Python程序设计》实验四报告

    20192204 2019-2020-2 <Python程序设计>实验四报告 课程:<Python程序设计> 班级: 1922 姓名: 李龙威 学号:20192204 实验教师 ...

  5. Python程序设计实验报告四:循环结构程序设计(设计型实验)

    安徽工程大学 Python程序设计 实验报告 班级   物流191   姓名  姚彩琴  学号3190505129 成绩 日期     2020.4.8     指导老师       修宇 [实验名称 ...

  6. Python程序设计实验报告一:熟悉IDLE和在线编程平台

    安徽工程大学 Python程序设计 实验报告 班级   物流191   姓名  崔攀  学号3190505136 成绩_____           日期     2020.3.8     指导老师  ...

  7. Python程序设计实验报告三:分支结构程序设计

    安徽工程大学 Python程序设计 实验报告 班级   物流191   姓名  姚彩琴  学号3190505129 成绩 日期     2020.4.5     指导老师       修宇 [实验目的 ...

  8. PYTHON程序设计实验

    Python程序设计实验报告一: 熟悉IDLE和在线编程平台 安徽工程大学 Python程序设计实验报告 班级 物流191 姓名 邹缕学号 3190505117成绩 ▁▁▁ 日期 2020.3.5 指 ...

  9. Python程序设计实验报告二:顺序结构程序设计(验证性实验)

      安徽工程大学 Python程序设计 实验报告 班级   物流191   姓名  崔攀  学号3190505136 成绩 日期     2020.3.22     指导老师       修宇 [实验 ...

随机推荐

  1. 伪元素的margin值挤压主体元素解决

    伪元素的margin值挤压主体元素解决 主体是两个p标签,需要再其左侧添加一个竖线,很常见的需求 目标 前提条件 1. 右侧的文字个数不固定 问题 1. 需要让before元素为`float:left ...

  2. Anaconda安装tensorflow和keras(gpu版,超详细)

    本人配置:window10+GTX 1650+tensorflow-gpu 1.14+keras-gpu 2.2.5+python 3.6,亲测可行 一.Anaconda安装 直接到清华镜像网站下载( ...

  3. 使用 ssm 实现登录日志记录

    使用 ssm 实现登录日志记录 学习总结 一.基础准备 1. 实现效果 2. 数据表 2.1 登陆日志信息表 2.3 员工表 二.代码实现 1. SysLogLogin 实体类 2. LogAspec ...

  4. rpm方式安装mysql

    一.系统标准化采样 1)查看centos系统版本 [root@fp-web-126 ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 ...

  5. 数据库纳管平台DBhouse的技术路线与实践

    为帮助开发者更好地了解和学习前沿数据库技术,腾讯云数据库特推出"DB · TALK"系列技术分享会,聚焦干货赋能创新,邀请数十位鹅厂资深数据库专家每月和您一起深入探讨云数据库的内核 ...

  6. Java基础语法02——流程控制

    流程控制:顺序结构.分支结构(if-else.switch-case).循环结构(for.while.do-while)

  7. 帝国CMS内容页模板过滤清理简介smalltext前后空格的方法!

    在内容模板你需要调用的地方使用如下代码输出简介即可过滤简介smalltext前后的空格了: <? $qian=array(" "," ","\t ...

  8. Java学习day33

    线程池: 背景:经常创建和销毁.使用量特别大的资源,比如并发情况下的线程,对性能影响很大 思路:提前创建好多个线程.实现重复利用. 好处:提高响应速度,减少了创建新线程的时间:降低资源消耗,重复利用线 ...

  9. vue 组件复用 - component

    vue 组件复用 - component vue 组件复用 就是对 component 标签的使用 先看图 下图看使用 结果: 可以看到 在箱包 这一项,我将banner 组件用了两次,我 每次 点击 ...

  10. 纯css 实现充电动画

    <template>   <div class="container">     <div class="header">& ...