20212115朱时鸿 《python程序设计》实验四报告
阅读原文时间:2022年05月29日阅读:1

课程:《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的学习还只是冰山一角,但相信通过王老师这一学期的引领,我在以后的学习中一定会得心应手,若果以后还有王老师的课,我一定还会选的(真)。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章