移植2D物理引擎到LVGL

背景

在LVGL交流群,有网友提出想要移植物理引擎到LVGL,遂有了本文。阅读本文需要对IDF和LVGL有所了解
在这里插入图片描述

过程

2D物理引擎有很多,经过一番调研选择了Chipmunk2D

下载源码

此处省略一万字,Github访问可能会有些慢

添加文件

将源码中的src文件夹复制到,include/chipmunk/文件夹下,然后将chipmunk文件夹复制idf工程
在这里插入图片描述

完善lv_mem

lv_mem.h,lv_mem.c 文件里添加以下代码:

// lv_mem.h
void *lv_cp_malloc(size_t num,size_t size){
// lv_mem.c
void *lv_cp_malloc(size_t num,size_t size){size_t total_size = num * size;void* ptr = lv_malloc(total_size);  // 分配内存if (ptr != NULL) {lv_memset(ptr, 0, total_size);  // 初始化为零}return ptr;
}

配置Chipmunk2D

修改chipmunk.h,修改完成以后,物理引擎将共用LVGL的内存,总共8KB

// 添加头文件
#include "lvgl.h"
// 修改如下代码
#ifndef CP_BUFFER_BYTES#define CP_BUFFER_BYTES (8*1024) //默认32k,此处改为8k
#endif#ifndef cpcalloc/// Chipmunk calloc() alias.// #define cpcalloc calloc
#define cpcalloc lv_cp_malloc
#endif#ifndef cprealloc/// Chipmunk realloc() alias.// #define cprealloc realloc#define cprealloc lv_realloc
#endif#ifndef cpfree/// Chipmunk free() alias.// #define cpfree free#define cpfree lv_free
#endif

编写Demo

新建 chipmunk_demo文件夹如下:
在这里插入图片描述
并在component.mk文件中添加配置路径:

COMPONENT_SRCDIRS := . \chipmunk \chipmunk_demo

编写代码:
1.创建一个世界
2. 给这个世界添加重力
3. 创建四面墙围成框
4. 小框里面创建一个小球
5. 给墙和小球分别设置摩擦系数和弹性系数
6. 给小球随机设置一个初始速度
7. 启动定时器,定时调用 cpSpaceStep(space, 1.0/30.0);来推动时间前进
8. 定时读取并跟新小球的位置

根据物理学原理:小球按照抛物线运动,碰撞到四周时会反弹

物理引擎模拟重力

各个文件代码如下

// chipmunk_demo.h
#ifndef CHIP_MUNK_ESP_DEMO_H
#define CHIP_MUNK_ESP_DEMO_H
#include "lvgl.h"
#include "esp_log.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "chipmunk/chipmunk.h"
#include "chipmunk/chipmunk_structs.h"void start_chipmunk_esp_example();#endif
//chipmunk_demo.c
#include "chipmunk_demo.h"#include "lvgl.h"
#define WIDTH 480
#define HEIGHT 480
#define BALL_RADIUS 20
cpSpace *space;
cpBody *staticBody;
cpBody * ballBody;
lv_obj_t *ballObj;
const static double width = 480.0;
const static double height = 480.0;
void on_timer(lv_timer_t *t);void start_chipmunk_esp_example(){lv_obj_t * bg = lv_obj_create(lv_scr_act());lv_obj_set_size(bg,width,height);lv_obj_center(bg);lv_obj_set_style_pad_all(bg,0,LV_PART_MAIN);lv_obj_set_style_bg_color(bg,lv_color_hex(0x000000),LV_PART_MAIN);ballObj = lv_obj_create(bg);lv_obj_remove_style_all(ballObj);// 生成一个随机颜色lv_color_t random_color = lv_color_make(rand() % 256, rand() % 256, rand() % 256);// 将随机颜色应用到对象上lv_obj_set_style_bg_color(ballObj, random_color, LV_STATE_DEFAULT);lv_obj_set_style_bg_opa(ballObj,LV_OPA_100,LV_PART_MAIN);lv_obj_set_style_radius(ballObj,LV_RADIUS_CIRCLE,LV_PART_MAIN);lv_obj_set_size( ballObj,BALL_RADIUS*2,BALL_RADIUS*2);lv_obj_set_pos(ballObj,0,0);// 创建物理空间space = cpSpaceNew();cpSpaceSetGravity(space, cpv(0, 100));// 创建静态物体,即边界staticBody = cpSpaceGetStaticBody(space);cpShape *shape = cpSegmentShapeNew(staticBody, cpv(0,0), cpv(0, HEIGHT), 0.0f);cpShapeSetFriction(shape, 1.0);cpShapeSetElasticity(shape, 1.0);cpSpaceAddShape(space, shape);shape = cpSegmentShapeNew(staticBody, cpv(0, HEIGHT), cpv(WIDTH, HEIGHT), 0.0f);cpShapeSetFriction(shape, 1.0);cpShapeSetElasticity(shape, 1.0);cpSpaceAddShape(space, shape);shape = cpSegmentShapeNew(staticBody, cpv(WIDTH, HEIGHT), cpv(WIDTH, 0), 0.0f);// cpShapeSetFriction(shape, 1.0);cpShapeSetElasticity(shape, 1.0);cpSpaceAddShape(space, shape);shape = cpSegmentShapeNew(staticBody, cpv(WIDTH, 0), cpv(0, 0), 0.0f);cpShapeSetFriction(shape, 1.0);cpShapeSetElasticity(shape, 1.0);cpSpaceAddShape(space, shape);// // 创建1个小球cpFloat radius = 20.0;cpFloat x = cpflerp(radius * 2, WIDTH - radius * 2, (cpFloat)rand() / (cpFloat)RAND_MAX);cpFloat y = cpflerp(radius * 2, HEIGHT - radius * 2, (cpFloat)rand() / (cpFloat)RAND_MAX);ballBody = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForCircle(1.0f, 0.0f, radius, cpvzero)));cpBodySetPosition(ballBody, cpv(x, y));cpShape *ball_shape = cpSpaceAddShape(space, cpCircleShapeNew(ballBody, radius, cpvzero));cpShapeSetFriction(ball_shape, 0.7);cpShapeSetElasticity(ball_shape, 0.8);cpVect velocity = cpv((cpFloat)rand() / (cpFloat)RAND_MAX * 200 - 100, (cpFloat)rand() / (cpFloat)RAND_MAX * 200 - 100);cpBodySetVelocity(ballBody, velocity);lv_timer_t *timer = lv_timer_create(on_timer,30,NULL);lv_timer_set_repeat_count(timer,-1);}
void on_timer(lv_timer_t *t){cpSpaceStep(space, 1.0/30.0);printf("Ball Position: (%.2f, %.2f)\n", cpBodyGetPosition(ballBody).x, cpBodyGetPosition(ballBody).y);lv_obj_set_pos(ballObj, cpBodyGetPosition(ballBody).x-20, cpBodyGetPosition(ballBody).y-20);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/21029.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

针对软件性能问题,如何定位解决?解决思路总结

针对软件性能问题&#xff0c;我们可以按照以下步骤来定位和解决&#xff1a; 一、性能问题定位 响应时间分析&#xff1a; 响应时间是用户感知软件性能的重要指标之一。通过对系统的响应时间进行分析&#xff0c;可以定位到导致响应时间延长的关键路径。这些关键路径可能是数据…

前端3剑客(第1篇)-初识HTML

100编程书屋_孔夫子旧书网 当今主流的技术中&#xff0c;可以分为前端和后端两个门类。 前端&#xff1a;简单的理解就是和用户打交道 后端&#xff1a;主要用于组织数据 而前端就Web开发方向来说&#xff0c; 分为三门语言&#xff0c; HTML、CSS、JavaScript 语言作用HT…

【Mysql语句优化---Explain使用以及相关属性含义】

Explain使用以及相关属性含义 一.explain中的列 接下来我们将展示 explain 中每个列的信息。 1. id列 id列的编号是 select 的序列号&#xff0c;有几个 select 就有几个id&#xff0c;并且id的顺序是按 select 出现的顺序增长的。 id列越大执行优先级越高&#xff0c;id相…

罗德里格斯旋转公式证明-简洁

罗德里格斯旋转公式证明。 设旋转向量为 ( n , θ ) (n, \theta) (n,θ)&#xff0c;设其对应的旋转矩阵为 R R R&#xff0c; 如何证明&#xff1f; R c o s θ I n ∧ s i n θ ( 1 − c o s θ ) n n T Rcos\theta I n^{\wedge}sin\theta(1-cos\theta)nn^{T} RcosθI…

什么是线性代数(Linear algebra)?

什么是代数 代数的英文是Algebra&#xff0c;这个英文源自一个阿拉伯语“al jebr”&#xff0c;意思是 破碎部分的重新组合。这个意思促进了我代数的概念的理解。在代数中&#xff0c;我们会使用基本的算术&#xff08;加、减、乘、除&#xff09;&#xff0c;便是对于要处理的…

红队内网攻防渗透:内网渗透之windows内网权限提升技术:用户篇

红队内网攻防渗透 1. 内网权限提升技术1.1 内网安全-本地管理用户-权限提升1.2 本地管理用户-权限提升-服务启动(提权)1.3 本地管理用户-权限提升-远程控制(提权)1.4 本地管理用户-权限提升-进程注入(降权&提权)1.4.1 MSF-进程注入:1.4.1 CS-进程注入:1.5 本地管理用…

[leetcode 9回文数]三行解决回文数问题

9. 回文数 思路 将给定的整数x转换成字符串,再对字符串进行反转操作,最后比较两个字符串内容是否相等 java解法 class Solution {public boolean isPalindrome(int x) {String s String.valueOf(x);String reverse new StringBuffer(s).reverse().toString();return s.e…

RDD与Java实战:学生列表,先按性别降序,再按年龄降序排列

文章目录 Scala RDD 实现Java 实现实战总结 在本实战任务中&#xff0c;我们的目标是对学生列表进行排序&#xff0c;排序规则是先按性别降序排列&#xff0c;再按年龄降序排列。我们提供了两种实现方式&#xff1a;使用Scala的RDD&#xff08;弹性分布式数据集&#xff09;和…

Yocto - bitbake任务中clean和cleanall的区别

在 BitBake 中&#xff0c;clean 和 cleanall 命令都用于删除构建工件&#xff0c;但它们的范围和执行的清理程度不同。 1. clean 命令&#xff1a; 目的&#xff1a;clean命令用于删除与特定任务或配方相关的临时构建文件和工件。 范围&#xff1a;它只清除指定任务或配方生…

Python 二叉数的实例化及遍历

首先创建一个这样的二叉树&#xff0c;作为我们今天的实例。实例代码在下方。 #创建1个树类型 class TreeNode:def __init__(self,val,leftNone,rightNone):self.valvalself.leftleftself.rightright #实例化类 node1TreeNode(5) node2TreeNode(6) node3TreeNode(7) node4Tre…

Mybatis项目创建 + 规范

文章目录 一、相关概念Mybatis1.1 什么是Mybatis1.1 如何实现简化JDBC 二、如何创建 Mybatis 项目2.1 创建SpringBoot项目 加载依赖2.2 准备数据库 以及 对象的映射2.3 配置数据库连接池2.4 使用Mybatis操作数据库2.5 单元测试 三、其他3.1 数据库与Java对象的映射规则 ---- 结…

为什么GD32F303代码运行在flash比sram更快?

我们知道一般MCU的flash有等待周期&#xff0c;随主频提升需要插入flash读取的等待周期&#xff0c;以stm32f103为例&#xff0c;主频在72M时需要插入2个等待周期&#xff0c;故而代码效率无法达到最大时钟频率。 所以STM32F103将代码加载到sram运行速度更快。 但使用GD32F30…

复习kafka

Kafka 介绍 Kafka 是一种分布式的&#xff0c;基于发布/订阅的消息系统。它最初由 LinkedIn 开发&#xff0c;并于 2011 年开源。Kafka 的设计目标是提供一种高效、可靠的消息传输机制&#xff0c;能够处理大量的实时数据。 Kafka 基本概念 Producer&#xff1a;生产者&#xf…

Spring Boot 官方不再支持 Spring Boot 的 2.x 版本!新idea如何创建java8项目

idea现在只能创建最少jdk17 使用 IDEA 内置的 Spring Initializr 创建 Spring Boot 新项目时&#xff0c;没有 Java 8 的选项了&#xff0c;只剩下了 > 17 的版本 是因为 Spring Boot 官方不再支持 Spring Boot 的 2.x 版本了&#xff0c;之后全力维护 3.x&#xff1b;而 …

阿里云计算之运维概念学习笔记(一)

运维管理 运维管理&#xff08;Operation and Maintenance Management, 简称O&M管理&#xff09;是指通过科学的管理方法和技术手段&#xff0c;对IT系统和基础设施进行监控、维护、优化和保障&#xff0c;以确保系统的高可用性、稳定性、安全性和性能。运维管理涵盖了硬件…

ArcGIS属性域和子类型

01 属性域 道路的车道数值是小于10的。在编辑道路的此属性时&#xff0c;为了限制其值在10以内&#xff0c;可以使用属性域。当输入数据超过10时&#xff0c;就会限制输入。 限制输入这个功能是Pro特有的&#xff0c;在ArcMap中输入超出限制的值也是合法的&#xff0c;需要手动…

【NOIP提高组】进制转换

【NOIP提高组】进制转换 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 我们可以用这样的方式来表示一个十进制数&#xff1a;将每个阿拉伯数字乘以一个以该数字所处位置的&#xff08;值减1&#xff09;为指数&#xff0c;以 10 为底数的幂…

Mac硬件设备系统环境的升级/更新 macOS

Mac硬件设备上进行系统环境的升级/更新macOS 1.大版本(升级)判断(比如&#xff1a;我买的这台电脑设备最高支持Monterey) 点击进入对应的大版本描述说明页查看相关的兼容性描述&#xff0c;根据描述确定当前的电脑设备最高可采用哪个大版本系统(Sonoma/Ventura/Monterey/Big Su…

构建高效便捷的家政平台系统——打造优质家政服务的关键

随着人们生活节奏的加快和工作压力的增大&#xff0c;家政服务的需求日益增长。为了满足这一需求&#xff0c;家政平台系统应运而生。本文将探讨家政平台系统的整体架构&#xff0c;以实现高效便捷的家政服务&#xff0c;打造优质家政体验。 ### 1. 家政平台系统背景 随着现代…

18岁适合做什么编程:探索编程世界的无限可能

18岁适合做什么编程&#xff1a;探索编程世界的无限可能 在18岁的青春年华&#xff0c;选择学习编程不仅是对未来职业发展的明智投资&#xff0c;更是开启一个充满无限可能的创造世界。然而&#xff0c;面对琳琅满目的编程语言和技术&#xff0c;如何选择适合自己的编程领域成…