多年前写过一篇 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. js压缩图片上传插件localResizeIMG

    示例 /** * 本地图片压缩后上传 */ $("#vfile").change(function(){ var _this = $(this); lrz(this.files[0 ...

  2. L1-006 连续因子 (20 分) 模拟

    一个正整数 N 的因子中可能存在若干连续的数字.例如 630 可以分解为 3×5×6×7,其中 5.6.7 就是 3 个连续的数字.给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的 ...

  3. P1156 垃圾陷阱 DP

    题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2 \le D \le 100)D(2≤D≤100)英尺. 卡门 ...

  4. 20165235Linux安装及学习

    (一)安装虚拟机 在安装虚拟机的过程中我遇到了许多问题,首先是因为没有将CPU虚拟化,解决方法是我首先通过打开BIOS界面打开security,virtualization,选择Enable.解决了无 ...

  5. win10安装Oracle11g,出现INS-13001环境不满足最低要求问题

    今天安装Oracle11g,出现INS-13001环境不满足最低要求问题: 解决方法 在安装时点击setup.exe之后,出现了:[INS-13001]环境不满足最低要求 这时,打开你的解压后的dat ...

  6. JDBC概述

    什么是持久化(persistence):持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用.大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固 ...

  7. wireshark抓包工具详细说明及操作使用

    https://blog.csdn.net/qq78069460/article/details/79153895

  8. 语音VLAN异常流量分析

    现象描述:有线网络里,接入层交换机上,凡是被划入语音vlan的端口,都会呈现出相同的流量表现,而且瞬间流量都很大,30 - 40 MB级别,对有线网络的稳定性有很大的影响. 设备型号: IP 电话:A ...

  9. BZOJ.2655.calc(DP/容斥 拉格朗日插值)

    BZOJ 洛谷 待补.刚刚政治会考完来把它补上了2333.考数学去了. DP: 首先把无序化成有序,选严格递增的数,最后乘个\(n!\). 然后容易想到令\(f_{i,j}\)表示到第\(i\)个数, ...

  10. LOJ.6053.简单的函数(Min_25筛)

    题目链接 Min_25筛见这里: https://www.cnblogs.com/cjyyb/p/9185093.html https://www.cnblogs.com/zhoushuyu/p/91 ...