首页 > 其他分享 >给娃写个游戏,庆祝嫦娥五号登月

给娃写个游戏,庆祝嫦娥五号登月

时间:2023-06-27 18:31:41浏览次数:38  
标签:surf 写个 五号 screen font pygame 登月 rect 255


年末航天有大事,嫦五揽月取岩石。

这几天,有被嫦娥五号刷屏吗?就在本周二晚11点11分,嫦娥五号的着陆器–上升器组合体成功登月,现已正式开展月面采样任务。嫦娥五号将为我国科学家带回约两千克月球岩石和土壤。时隔44年,人类终于能再次从月球带回“土特产”了!

给娃写个游戏,庆祝嫦娥五号登月_powerdesigner

嫦娥五号(图源:中国探月工程)

作为科技爱好者斜杠程序员爸爸,想不想写一个酷炫的月球着陆游戏,给娃秀一秀专业技能 让娃一起开心开心?

今天就来用Python写一个月球着陆仿真游戏吧!

太长不看提示:由“Python之父”吉多·范罗苏姆推荐的《父与子的编程之旅》。请滑至文末了解如何获取完整代码。

给娃写个游戏,庆祝嫦娥五号登月_游戏_02

给娃写个游戏,庆祝嫦娥五号登月_游戏_03

我们的飞船正准备登月。它携带定量的燃料,这些燃料会为反推发动机提供推力。

在游戏开始时,飞船离月球表面有一定的距离。月球的重力把它向下拉,我们必须使用反推发动机减缓降落速度,让飞船的纵向速度变为0,从而平缓着陆。

注意,必须小心地操作反推发动机。如果用力不足,飞船就会重重地摔在月面;如果用力过猛,则燃料会很快耗尽,飞船会向上飞入太空!

给娃写个游戏,庆祝嫦娥五号登月_游戏_02

给娃写个游戏,庆祝嫦娥五号登月_游戏_03

给娃写个游戏,庆祝嫦娥五号登月_powerdesigner_06

左下角的小灰条表示反推发动机的操作杆,用鼠标上下拖动即可控制推力。

燃料表(绿色)显示当前剩余的燃料。界面上方的文本给出动态变化的速度、加速度、高度和推力。

给娃写个游戏,庆祝嫦娥五号登月_游戏_02

给娃写个游戏,庆祝嫦娥五号登月_游戏_03

反推发动机的推力取决于消耗了多少燃料,有时推力会大于重力,有时则会小于重力。当发动机关闭时,推力为0,此时只剩下重力。

要得到飞船所受的净作用力,只需把推力和重力相加。由于二者的方向相反,因此可以用一个正数和一个负数来表示。一旦得到飞船所受的净作用力,就可以利用公式得出它的速度和位置。

我们的程序必须跟踪以下几点。

- 飞船相对于月面的高度,以及飞船的速度和加速度。

- 飞船的质量(随着燃料的消耗,质量会变化)。

- 反推发动机的推力。推力越大,燃料消耗得就越快。

- 飞船剩余多少燃料。当反推发动机消耗燃料时,飞船会变轻,但是如果燃料耗尽,就不再有推力了。

- 飞船所受的重力。这取决于月球的大小、飞船的质量、燃料的消耗情况等。

给娃写个游戏,庆祝嫦娥五号登月_游戏_02

给娃写个游戏,庆祝嫦娥五号登月_游戏_03

提示:本文假定你已经安装了Pygame模块。如果还没有安装,请滑至文末查看安装说明。

我们使用Pygame模块编写该游戏,用单次时钟“嘀嗒”作为时间单位。每“嘀嗒”一次,程序就要检查飞船当前所受的净作用力,并更新高度、速度、加速度和剩余燃料等信息,然后根据这些信息更新图片和文本。

 1  首先初始化游戏。创建Pygame窗口,加载图像,并为变量设置一些初始值。

import pygame, sys

pygame.init()
screen = pygame.display.set_mode([400,600])
screen.fill([0, 0, 0])
ship = pygame.image.load('lunarlander.png')
moon = pygame.image.load('moonsurface.png')
ground = 540

start = 90
clock = pygame.time.Clock()
ship_mass = 5000.0
fuel = 5000.0
velocity = -100.0
gravity = 10
height = 2000
thrust = 0
delta_v = 0
y_pos = 90
held_down = False

 2  为反推发动机定义Sprite类。

class ThrottleClass(pygame.sprite.Sprite):
    def __init__(self, location = [0,0]):
        pygame.sprite.Sprite.__init__(self)
        image_surface = pygame.surface.Surface([30, 10])
        image_surface.fill([128,128,128])
        self.image = image_surface.convert()
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.centery = location

 3  计算飞船的高度、速度、加速度和燃料消耗量。

def calculate_velocity():
    global thrust, fuel, velocity, delta_v, height, y_pos
    delta_t = 1/fps #对应Pygame循环的一帧
    thrust = (500 - myThrottle.rect.centery) * 5.0 #将反推发动机精灵的y坐标转换为推力
    fuel -= thrust /(10 * fps) #根据推力减少燃料
    if fuel < 0: fuel = 0.0
    if fuel < 0.1: thrust = 0.0
    delta_v = delta_t * (-gravity + 200 * thrust / (ship_mass + fuel)) #物理公式
    velocity = velocity + delta_v
    delta_h = velocity * delta_t
    height = height + delta_h
    y_pos = ground - (height * (ground - start) / 2000) - 90 #将高度转换为Pygame的y坐标

 4  使用字体对象显示统计信息。

def display_stats():
    v_str = "velocity: %i m/s" % velocity
    h_str = "height: %.1f" % height
    t_str = "thrust: %i" % thrust
    a_str = "acceleration: %.1f" % (delta_v * fps)
    f_str = "fuel: %i" % fuel
    v_font = pygame.font.Font(None, 26)
    v_surf = v_font.render(v_str, 1, (255, 255, 255))
    screen.blit(v_surf, [10, 50])
    a_font = pygame.font.Font(None, 26)
    a_surf = a_font.render(a_str, 1, (255, 255, 255))
    screen.blit(a_surf, [10, 100])
    h_font = pygame.font.Font(None, 26)
    h_surf = h_font.render(h_str, 1, (255, 255, 255))
    screen.blit(h_surf, [10, 150])
    t_font = pygame.font.Font(None, 26)
    t_surf = t_font.render(t_str, 1, (255, 255, 255))
    screen.blit(t_surf, [10, 200])
    f_font = pygame.font.Font(None, 26)
    f_surf = f_font.render(f_str, 1, (255, 255, 255))
    screen.blit(f_surf, [60, 300])

 5  画出尾焰三角形,尾焰大小会随推力变化而变化。

def display_flames():
    flame_size = thrust / 15
    for i in range (2):
        startx = 252 - 10 + i * 19
        starty = y_pos + 83
        pygame.draw.polygon(screen, [255, 109, 14], [(startx, starty),
                                    (startx + 4, starty + flame_size),
                                    (startx + 8, starty)], 0)

 6  Pygame程序主事件循环,画出所有内容。

myThrottle = ThrottleClass([15, 500]) #创建反推发动机对象
running = True
while running:
    clock.tick(30)
    fps = clock.get_fps()
    if fps < 1: fps = 30
    if height > 0.01:
        calculate_velocity()
        screen.fill([0, 0, 0])
        display_stats()
        pygame.draw.rect(screen, [0, 0, 255], [80, 350, 24, 100], 2)
        fuelbar = 96 * fuel / 5000
        pygame.draw.rect(screen, [0,255,0],
               [84,448-fuelbar,18, fuelbar], 0) #燃料量
        pygame.draw.rect(screen, [255, 0, 0],
               [25, 300, 10, 200],0) #画出反推发动机滑块
        screen.blit(moon, [0, 500, 400, 100]) #画出月球
        pygame.draw.rect(screen, [60, 60, 60],
               [220, 535, 70, 5],0) #着陆点
        screen.blit(myThrottle.image, myThrottle.rect) #画出操纵杆
        display_flames()
        screen.blit(ship, [230, y_pos, 50, 90]) #画出飞船
        instruct1 = "Land softly without running out of fuel"
        instruct2 = "Good landing: < 15m/s Great landing: < 5m/s"
        inst1_font = pygame.font.Font(None, 24)
        inst1_surf = inst1_font.render(instruct1, 1, (255, 255, 255))
        screen.blit(inst1_surf, [50, 550])
        inst2_font = pygame.font.Font(None, 24)
        inst2_surf = inst1_font.render(instruct2, 1, (255, 255, 255))
        screen.blit(inst2_surf, [20, 575])
        pygame.display.flip()

 7  收尾部分:检查鼠标是否拖动反推发动机,更新反推发动机位置。

else:
    display_final()
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
    elif event.type == pygame.MOUSEBUTTONDOWN:
        held_down = True
    elif event.type == pygame.MOUSEBUTTONUP:
        held_down = False
    elif event.type == pygame.MOUSEMOTION:
        if held_down:
            myThrottle.rect.centery = event.pos[1]
            if myThrottle.rect.centery < 300:
                myThrottle.rect.centery = 300
            if myThrottle.rect.centery > 500:
                myThrottle.rect.centery = 500
pygame.quit()

搞定!到底能不能像嫦娥五号一样成功登月呢?今晚就和娃一起试试吧!Happy landing!

给娃写个游戏,庆祝嫦娥五号登月_游戏_02


标签:surf,写个,五号,screen,font,pygame,登月,rect,255
From: https://blog.51cto.com/u_15767091/6564887

相关文章

  • React SSR - 写个 Demo 一学就会
    ReactSSR-写个Demo一学就会今天写个小Demo来从头实现一下react的SSR,帮助理解SSR是如何实现的,有什么细节。什么是SSRSSR即ServerSideRendering服务端渲染,是指将网页内容在服务器端中生成并发送到浏览器的技术。相比于客户端渲染(CSR),SSR一般用于以下场景:SEO......
  • 致敬神舟十五号
    最近,中国神舟十五号载人飞行为期半年的航天任务取得圆满成功,又掀起了一股航天热潮。某城市气象站以此为契机,举办了一系列航天主题活动。在气象站研学活动中心,一群小朋友正在参观国产气象设备博物馆。气象科技的发展在人类历史上具有重要的地位。为了向公众普及气象知识,传承气象文......
  • 用while循环+if判断写个会员卡充值和招生功能
    """需求1:会员卡充值金额只能输入数字和浮点数、不能输入负数充值100(包含100)金额提示:成功充值N元,恭喜你成为普通会员充值100.01(包含100.01)至200金额提......
  • 三月十五号结对
    合作对象:李佳岳昨天完成了数据表的建立和数据库连接今天完成了一部分dao包的编写和一些html页面,所写代码如下。其中substasion函数用于在一条线上给定两个参数,然后将他门......
  • 推荐一个程序员接单平台,认证就白嫖50块,写个功能就能技术入股
    一直以为自己出身寒门呀,原来寒门是指势力较低的世家。我不是寒门,再怎么也得是个庶民吧!鬼知道这个庶民是指有房有钱的人。古代没有房叫做氓,没有钱叫做流,简称就是流氓。不服......
  • 推荐一个程序员接单平台,认证就白嫖50块,写个功能就能技术入股
    一直以为自己出身寒门呀,原来寒门是指势力较低的世家。我不是寒门,再怎么也得是个庶民吧!鬼知道这个庶民是指有房有钱的人。古代没有房叫做氓,没有钱叫做流,简称就是流氓。不......
  • 100 行 shell 写个 Docker
    作者:vivo互联网运维团队-HouDengfeng本文主要介绍使用shell实现一个简易的Docker。一、目的在初接触Docker的时候,我们必须要了解的几个概念就是Cgroup、Namespace、RootF......
  • 100 行 shell 写个 Docker
    作者:vivo互联网运维团队-HouDengfeng本文主要介绍使用shell实现一个简易的Docker。一、目的在初接触Docker的时候,我们必须要了解的几个概念就是Cgroup、Namespace......
  • 自己动手用 shell 写个 docker【转】
    本文主要介绍使用shell实现一个简易的Docker。一、目的 在初接触Docker的时候,我们必须要了解的几个概念就是Cgroup、Namespace、RootFs,如果本身对虚拟化的发展没有深入......
  • 网站总被攻击?写个自动封禁 IP 的脚本 转载
     链接:https://blog.csdn.net/qq_38925100/article/details/123742463个人网站总被攻击?写个自动封禁IP的脚本给你!具体如下:1.在ngnix的conf目录下创建一个 blockip.co......