多年前写过一篇 Flash/Flex学习笔记(25):摩擦力与屏幕环绕,可惜的当时上传的flash,服务器后来无人维护,现在flash链接都失效了。本篇用pygame重新实现了一个:

原理是类似,但要注意的是:pygame中旋转的角度采用逆时针系统 ,即:逆时针方向旋转,角度为正,反之为负。所以在外理角度时,y轴方向的速度要取反。

素材图(2张):

飞船熄火

飞船点火

需求:按向上键点火,飞船启动,一直加速;无按键时,飞船熄火,速度慢慢降下来(设置摩擦系数);左右键控制转向;飞出屏幕时,从另一侧切回来。

代码:

 import os
import pygame
import sys
import math pygame.init() clock = pygame.time.Clock() SIZE = WIDTH, HEIGHT = 400, 400
GRAY = (200, 200, 200)
RED = (255, 0, 0)
screen = pygame.display.set_mode(SIZE)
pygame.display.set_caption("ship")
img_base_path = os.getcwd() + '/img/' class Ship(object):
def __init__(self, img_base_path, screen):
self.vx = 0
self.vy = 0
# 旋转角速度
self.vr = 0
# 推进力
self.thrust = 0
self.angle = 0
self.show_flame = False
self.scale = 1.0
# 是否显示辅助边框
self.show_rect = False self.img_src = pygame.image.load(img_base_path + 'ship.png')
self.img_flame_src = pygame.image.load(img_base_path + 'ship_flame.png') self.img = self.img_src
self.rect = self.img_src.get_rect() self.img_new = self.img
self.rect_new = self.img_new.get_rect() self.rect = self.rect.move((WIDTH - self.rect.width) * 0.5, (HEIGHT - self.rect.height) * 0.5) def draw(self, screen):
screen.blit(self.img_new, self.rect_new)
if self.show_rect:
pygame.draw.rect(screen, GRAY, ship.rect, 1)
pygame.draw.rect(screen, RED, ship.rect_new, 1) def move(self):
self.rect = self.rect.move(self.vx, self.vy)
self.rect_new = self.rect_new.move(self.vx, self.vy)
# 向左飞出边界
if self.rect_new.right < 0 and ship.vx < 0:
self.rect_new.left = WIDTH
self.rect.left = WIDTH
# 向右飞出边界
if self.rect_new.left > WIDTH and ship.vx > 0:
self.rect_new.right = 0
self.rect.right = 0
# 向下飞出边界
if self.rect_new.top > HEIGHT and ship.vy > 0:
self.rect_new.bottom = 0
self.rect.bottom = 0
# 向上飞出边界
if self.rect_new.bottom < 0 and ship.vy < 0:
self.rect_new.top = HEIGHT
self.rect.top = HEIGHT def rotate_zoom(self):
# rotozoom=旋转+缩放
self.img_new = pygame.transform.rotozoom(self.img, self.angle, self.scale)
self.rect_new = self.img_new.get_rect(center=self.rect.center)
if math.fabs(self.angle) == 360:
self.angle = 0 def set_flame(self, show_flame=False):
self.show_flame = show_flame
if self.show_flame:
self.img = self.img_flame_src
else:
self.img = self.img_src def get_speed(speed):
if speed > 0:
return math.ceil(speed)
if speed < 0:
return math.floor(speed)
return speed ship = Ship(img_base_path, screen)
ship.scale = 0.5
ship.show_rect = True
# 摩擦系数
friction = 0.995
while True:
clock.tick(60) for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYUP:
# KEYUP时,熄火,动力归0
ship.vr = 0
ship.thrust = 0
ship.set_flame(False)
elif event.type == pygame.KEYDOWN:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
ship.vr = 5
elif keys[pygame.K_RIGHT]:
ship.vr = -5
if keys[pygame.K_UP]:
# 按向上键时,点火,动力为0.3
ship.set_flame(True)
ship.thrust = 0.3
else:
ship.set_flame(False) # 将每一帧的底色先填充成白色
screen.fill((255, 255, 255)) pygame.draw.line(screen, GRAY, (0, HEIGHT / 2), (WIDTH, HEIGHT / 2), 1)
pygame.draw.line(screen, GRAY, (WIDTH / 2, 0), (WIDTH / 2, HEIGHT), 1) ship.angle += ship.vr
ax = math.cos(ship.angle * math.pi / 180) * ship.thrust
# 注:pygame中,角度是逆时针转的,所以垂直加速度要取反
ay = -1 * math.sin(ship.angle * math.pi / 180) * ship.thrust
ship.vx += ax
ship.vy += ay # 摩擦系数
if math.fabs(ship.vx) > 0.001:
ship.vx = ship.vx * friction
if math.fabs(ship.vy) > 0.001:
ship.vy = ship.vy * friction print("vx:", ship.vx) ship.rotate_zoom()
ship.move()
ship.draw(screen) # 更新画布
pygame.display.update()

如果把背景变成黑色,辅助边框去掉,看上去更有漆黑宇宙的感觉:)

源代码地址: https://github.com/yjmyzz/pygame_tutorial/blob/master/move_02.py

pygame 笔记-10 摩擦力与屏幕环绕的更多相关文章

  1. JavaScript:学习笔记(10)——XMLHttpRequest对象

    JavaScript:学习笔记(10)——XMLHttpRequest对象 XHR对象 使用XMLHttpRequest (XHR)对象可以与服务器交互.您可以从URL获取数据,而无需让整个的页面刷新 ...

  2. Spring 源码学习笔记10——Spring AOP

    Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...

  3. 操作系统概念学习笔记 10 CPU调度

    操作系统概念学习笔记 10 CPU调度 多道程序操作系统的基础.通过在进程之间切换CPU.操作系统能够提高计算机的吞吐率. 对于单处理器系统.每次仅仅同意一个进程执行:不论什么其它进程必须等待,直到C ...

  4. thinkphp学习笔记10—看不懂的路由规则

    原文:thinkphp学习笔记10-看不懂的路由规则 路由这部分貌似在实际工作中没有怎么设计过,只是在用默认的设置,在手册里面看到部分,艰涩难懂. 1.路由定义 要使用路由功能需要支持PATH_INF ...

  5. 《C++ Primer Plus》学习笔记10

    <C++ Primer Plus>学习笔记10 <<<<<<<<<<<<<<<<<&l ...

  6. SQL反模式学习笔记10 取整错误

    目标:使用小数取代整数 反模式:使用Float类型 根据IEEE754标识,float类型使用二进制格式编码实数数据. 缺点:(1)舍入的必要性: 并不是所有的十进制中描述的信息都能使用二进制存储,处 ...

  7. 安装好ubuntu 18.10之后,屏幕一直在自动旋转,怎么办?

    sudo apt-get install okular dia gimp Gparted sudo add-apt-repository universesudo apt install gnome- ...

  8. JAVA自学笔记10

    JAVA自学笔记10 1.形式参数与返回值 1)类名作为形式参数(基本类型.引用类型) 作形参必须是类的对象 2)抽象类名作形参 需要该抽象类的子类对象,通过多态实现 3)接口名为形参 需要的是该接口 ...

  9. golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息

    golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放 ...

随机推荐

  1. 【BZOJ4764】弹飞大爷

    题解: 这个应该还是比较简单的 首先比较容易想到用lct来维护 我们可以建立一个特殊点 然后我们要处理环 其实只要判断它和不和这个特殊点联通就行了 那么当它不是环了我们怎么还原呢 只要对每个在根节点记 ...

  2. 关于sizeof与#pragma pack 以及网络上关于字节对齐的一点感想

    工作中面试中对于字节对齐基本上是必考一个知识点,而很多面试是网络上上原题.基本上背一背就可以写正确,而关于4字节对齐我相信很多人也只是一个基本地了解,对于一些题目就感觉有问题,而且很多blog后面仍然 ...

  3. Elasticsearch - Scroll

    Scroll Version:6.1 英文原文地址:Scroll 当一个搜索请求返回单页结果时,可以使用 scroll API 检索体积大量(甚至全部)结果,这和在传统数据库中使用游标的方式非常相似. ...

  4. angularjs 中通过 $location 进行路由跳转传参

    $location.path('/page1').search({id: $scope.id,name:$scope.name}); 带参数跳转页面,在新的页面通过$routeParams接收参数 $ ...

  5. 前端接口自动化测试工具-DOClever使用介绍(转载)

    DOClever 不仅集成了文档编写,团队协作,接口运行,mock 数据等功能,还有两个功能是让我们团队大大的提高工作效率的.一个是接口的自动化生成,可以根据接口数据自动生成文档信息,还有一个便是本文 ...

  6. P1434 [SHOI2002]滑雪 dfs

    题目描述 Michael喜欢滑雪.这并不奇怪,因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道在一个区域中最长 ...

  7. js(javaScript)的各种事件触发,以常见为主eg:onclick

    js的各种事件触发,以常见为主eg:onclick1.onclick,点击后触发事件 (1)<h1 onclick="this.innerHTML='谢谢!'">请点击 ...

  8. linux 学习笔记五 查看文件篇章

    1 diff -y  test.txt  test2.txt 输出源文件与目标文件的全部 分为左右两篮 如下 --------------------------------------------- ...

  9. 动画库NineOldAndroids

    动画库NineOldAndroids   NineOldAndroids组件是一个向下兼容的动画库,主要是使低于API 11的系统也能够使用View的属性动画.该动画库支持旋转.移动.透明渐变.缩放等 ...

  10. 2018-6-25-随笔-MVC

    向IIS中注册.net框架版本:安装的IIS因为是先安装了VS所以它里面的应用程序池的.net框架还是系统自带的框架,Win7是2.0,需要将VS的.net框架版本注册 注册方法:在开始菜单找到VS2 ...