《用MATLAB玩转游戏开发》Flappy Bird:小鸟飞行大战MATLAB趣味实现
《用MATLAB玩转游戏开发:从零开始打造你的数字乐园》基础篇(2D图形交互)-Flappy Bird:小鸟飞行大战MATLAB趣味实现
文章目录
- 《用MATLAB玩转游戏开发:从零开始打造你的数字乐园》基础篇(2D图形交互)-Flappy Bird:小鸟飞行大战MATLAB趣味实现
- 1.设计思路与原理⚙️
- 2.完整流程图 📊
- 3.分步实现教程 🛠️
- 3.1. 初始化游戏环境
- 3.2. 创建游戏界面
- 3.3. 障碍物生成系统
- 3.4. 游戏主循环
- 3.5. 游戏逻辑实现
- 3.6. 用户输入处理
- 3.7. 游戏结束处理
- 3.8. 重新开始游戏
- 3.9. GIF保存功能
- 4.完整可运行代码 🎮
- 5.游戏操作说明 🎯
- 6.扩展建议 💡
大家好!今天我将带大家用MATLAB实现经典游戏Flappy Bird!这个项目不仅能巩固你的MATLAB编程技能,还能让你了解游戏开发的基本原理。让我们开始这段有趣的编程之旅吧!🚀
1.设计思路与原理⚙️
Flappy Bird的核心机制其实非常简单,主要包括以下几个部分:
- 小鸟物理系统:模拟重力和跳跃
- 障碍物生成:随机生成上下管道
- 碰撞检测:判断小鸟是否撞到管道或地面
- 分数计算:记录玩家通过的管道数量
- 游戏循环:控制游戏节奏和画面更新
我们将使用MATLAB的图形处理功能来实现这些机制,主要依赖figure
、patch
、timer
等对象。
2.完整流程图 📊
3.分步实现教程 🛠️
3.1. 初始化游戏环境
首先我们需要设置游戏窗口和基本参数:
function flappy_bird()% 清空工作区clc; clear; close all;% 游戏参数设置game.screenWidth = 400; % 屏幕宽度game.screenHeight = 600; % 屏幕高度game.gravity = 0.25; % 重力加速度game.jumpStrength = -5; % 跳跃力度game.pipeSpeed = 2; % 管道移动速度game.pipeGap = 150; % 管道间隙game.pipeWidth = 50; % 管道宽度game.birdSize = 20; % 小鸟大小game.groundHeight = 50; % 地面高度game.score = 0; % 初始分数game.gameOver = false; % 游戏状态标志
3.2. 创建游戏界面
接下来创建游戏图形界面和各种图形对象:
% 创建图形窗口fig = figure('Name', 'Flappy Bird - MATLAB', ...'NumberTitle', 'off', ...'Position', [100, 100, game.screenWidth, game.screenHeight], ...'Color', [0.7 0.9 1], ...'KeyPressFcn', @keyPress, ...'MenuBar', 'none', ...'ToolBar', 'none');% 创建坐标轴ax = axes('Parent', fig, ...'Position', [0 0 1 1], ...'XLim', [0 game.screenWidth], ...'YLim', [0 game.screenHeight], ...'Visible', 'off');hold(ax, 'on');% 创建小鸟bird.x = game.screenWidth / 4;bird.y = game.screenHeight / 2;bird.velocity = 0;bird.handle = rectangle('Position', [bird.x, bird.y, game.birdSize, game.birdSize], ...'FaceColor', [1 1 0], ...'EdgeColor', [0 0 0], ...'Curvature', [1 1]);% 创建地面ground.handle = patch([0, game.screenWidth, game.screenWidth, 0], ...[0, 0, game.groundHeight, game.groundHeight], ...[0.6 0.4 0.2], 'EdgeColor', 'none');% 创建分数显示scoreText = text(game.screenWidth/2, game.screenHeight-50, num2str(game.score), ...'FontSize', 30, 'Color', [1 1 1], ...'HorizontalAlignment', 'center', 'FontWeight', 'bold');
3.3. 障碍物生成系统
管道是游戏的主要障碍物,我们需要随机生成它们:
% 初始化管道pipes = [];function generatePipe()% 随机生成管道间隙的位置gapY = randi([game.groundHeight+50, game.screenHeight-50-game.pipeGap]);% 下管道bottomPipe = struct();bottomPipe.x = game.screenWidth;bottomPipe.height = gapY - game.pipeGap/2;bottomPipe.handle = patch([0, game.pipeWidth, game.pipeWidth, 0]+bottomPipe.x, ...[0, 0, bottomPipe.height, bottomPipe.height], ...[0 0.8 0], 'EdgeColor', 'none');% 上管道topPipe = struct();topPipe.x = game.screenWidth;topPipe.height = game.screenHeight - gapY - game.pipeGap/2;topPipe.y = gapY + game.pipeGap/2;topPipe.handle = patch([0, game.pipeWidth, game.pipeWidth, 0]+topPipe.x, ...[0, 0, topPipe.height, topPipe.height]+topPipe.y, ...[0 0.8 0], 'EdgeColor', 'none');% 添加到管道列表pipes = [pipes; struct('bottom', bottomPipe, 'top', topPipe, 'passed', false)];end
3.4. 游戏主循环
使用MATLAB的timer对象创建游戏循环:
% 创建游戏计时器gameTimer = timer('ExecutionMode', 'fixedRate', ...'Period', 0.02, ...'TimerFcn', @gameLoop);% 生成初始管道generatePipe();% 启动背景音乐try[y, Fs] = audioread('background_music.mp3');player = audioplayer(y, Fs);play(player);catchwarning('背景音乐文件未找到,游戏将继续但没有背景音乐');end% 开始游戏start(gameTimer);
3.5. 游戏逻辑实现
实现游戏的核心逻辑:
function gameLoop(~, ~)if game.gameOverreturn;end% 更新小鸟位置bird.velocity = bird.velocity + game.gravity;bird.y = bird.y + bird.velocity;set(bird.handle, 'Position', [bird.x, bird.y, game.birdSize, game.birdSize]);% 旋转小鸟(根据速度)rotationAngle = min(max(bird.velocity * 5, -30), 30);rotate(bird.handle, [0 0 1], rotationAngle, [bird.x, bird.y, 0]);% 移动管道for i = 1:length(pipes)pipes(i).bottom.x = pipes(i).bottom.x - game.pipeSpeed;pipes(i).top.x = pipes(i).top.x - game.pipeSpeed;% 更新管道图形set(pipes(i).bottom.handle, 'XData', [0, game.pipeWidth, game.pipeWidth, 0]+pipes(i).bottom.x);set(pipes(i).top.handle, 'XData', [0, game.pipeWidth, game.pipeWidth, 0]+pipes(i).top.x);% 检查是否通过管道if ~pipes(i).passed && pipes(i).bottom.x + game.pipeWidth < bird.xpipes(i).passed = true;game.score = game.score + 1;set(scoreText, 'String', num2str(game.score));endend% 移除屏幕外的管道if ~isempty(pipes) && pipes(1).bottom.x + game.pipeWidth < 0delete(pipes(1).bottom.handle);delete(pipes(1).top.handle);pipes(1) = [];end% 生成新管道if isempty(pipes) || pipes(end).bottom.x < game.screenWidth - 200generatePipe();end% 碰撞检测if bird.y < game.groundHeight || bird.y + game.birdSize > game.screenHeightgameOver();endfor i = 1:length(pipes)% 检测与下管道的碰撞if bird.x + game.birdSize > pipes(i).bottom.x && ...bird.x < pipes(i).bottom.x + game.pipeWidth && ...bird.y < pipes(i).bottom.heightgameOver();end% 检测与上管道的碰撞if bird.x + game.birdSize > pipes(i).top.x && ...bird.x < pipes(i).top.x + game.pipeWidth && ...bird.y + game.birdSize > pipes(i).top.ygameOver();endend% 强制刷新图形drawnow;end
3.6. 用户输入处理
实现键盘控制:
function keyPress(~, event)if strcmp(event.Key, 'space') && ~game.gameOverbird.velocity = game.jumpStrength;elseif strcmp(event.Key, 'r') && game.gameOverrestartGame();endend
3.7. 游戏结束处理
function gameOver()game.gameOver = true;stop(gameTimer);% 显示游戏结束文字text(game.screenWidth/2, game.screenHeight/2, '游戏结束!', ...'FontSize', 40, 'Color', [1 0 0], ...'HorizontalAlignment', 'center', 'FontWeight', 'bold');text(game.screenWidth/2, game.screenHeight/2-50, ['得分: ' num2str(game.score)], ...'FontSize', 30, 'Color', [1 1 1], ...'HorizontalAlignment', 'center', 'FontWeight', 'bold');text(game.screenWidth/2, game.screenHeight/2-100, '按R键重新开始', ...'FontSize', 20, 'Color', [1 1 1], ...'HorizontalAlignment', 'center');% 保存GIFsaveGif();end
3.8. 重新开始游戏
function restartGame()% 清除现有管道for i = 1:length(pipes)delete(pipes(i).bottom.handle);delete(pipes(i).top.handle);endpipes = [];% 重置小鸟bird.y = game.screenHeight / 2;bird.velocity = 0;set(bird.handle, 'Position', [bird.x, bird.y, game.birdSize, game.birdSize]);rotate(bird.handle, [0 0 1], 0, [bird.x, bird.y, 0]);% 重置分数game.score = 0;set(scoreText, 'String', '0');% 删除游戏结束文本delete(findall(gcf, 'Type', 'text', 'String', '游戏结束!'));delete(findall(gcf, 'Type', 'text', 'String', ['得分: ' num2str(game.score)]));delete(findall(gcf, 'Type', 'text', 'String', '按R键重新开始'));% 生成新管道generatePipe();% 重置游戏状态game.gameOver = false;% 重新开始计时器start(gameTimer);end
3.9. GIF保存功能
function saveGif()% 创建GIF文件名timestamp = datestr(now, 'yyyy-mm-dd_HH-MM-SS');gifFilename = ['flappy_bird_' timestamp '.gif'];% 获取当前图形窗口内容frame = getframe(fig);im = frame2im(frame);[imind, cm] = rgb2ind(im, 256);% 写入GIF文件imwrite(imind, cm, gifFilename, 'gif', 'Loopcount', inf, 'DelayTime', 0.1);disp(['游戏已保存为GIF: ' gifFilename]);end
end
4.完整可运行代码 🎮
将以下所有代码合并到一个.m文件中即可运行:
function flappy_bird()% 清空工作区clc; clear; close all;% 游戏参数设置game.screenWidth = 400; % 屏幕宽度game.screenHeight = 600; % 屏幕高度game.gravity = 0.25; % 重力加速度game.jumpStrength = -5; % 跳跃力度game.pipeSpeed = 2; % 管道移动速度game.pipeGap = 150; % 管道间隙game.pipeWidth = 50; % 管道宽度game.birdSize = 20; % 小鸟大小game.groundHeight = 50; % 地面高度game.score = 0; % 初始分数game.gameOver = false; % 游戏状态标志% 创建图形窗口fig = figure('Name', 'Flappy Bird - MATLAB', ...'NumberTitle', 'off', ...'Position', [100, 100, game.screenWidth, game.screenHeight], ...'Color', [0.7 0.9 1], ...'KeyPressFcn', @keyPress, ...'MenuBar', 'none', ...'ToolBar', 'none');% 创建坐标轴ax = axes('Parent', fig, ...'Position', [0 0 1 1], ...'XLim', [0 game.screenWidth], ...'YLim', [0 game.screenHeight], ...'Visible', 'off');hold(ax, 'on');% 创建小鸟bird.x = game.screenWidth / 4;bird.y = game.screenHeight / 2;bird.velocity = 0;bird.handle = rectangle('Position', [bird.x, bird.y, game.birdSize, game.birdSize], ...'FaceColor', [1 1 0], ...'EdgeColor', [0 0 0], ...'Curvature', [1 1]);% 创建地面ground.handle = patch([0, game.screenWidth, game.screenWidth, 0], ...[0, 0, game.groundHeight, game.groundHeight], ...[0.6 0.4 0.2], 'EdgeColor', 'none');% 创建分数显示scoreText = text(game.screenWidth/2, game.screenHeight-50, num2str(game.score), ...'FontSize', 30, 'Color', [1 1 1], ...'HorizontalAlignment', 'center', 'FontWeight', 'bold');% 初始化管道pipes = [];function generatePipe()% 随机生成管道间隙的位置gapY = randi([game.groundHeight+50, game.screenHeight-50-game.pipeGap]);% 下管道bottomPipe = struct();bottomPipe.x = game.screenWidth;bottomPipe.height = gapY - game.pipeGap/2;bottomPipe.handle = patch([0, game.pipeWidth, game.pipeWidth, 0]+bottomPipe.x, ...[0, 0, bottomPipe.height, bottomPipe.height], ...[0 0.8 0], 'EdgeColor', 'none');% 上管道topPipe = struct();topPipe.x = game.screenWidth;topPipe.height = game.screenHeight - gapY - game.pipeGap/2;topPipe.y = gapY + game.pipeGap/2;topPipe.handle = patch([0, game.pipeWidth, game.pipeWidth, 0]+topPipe.x, ...[0, 0, topPipe.height, topPipe.height]+topPipe.y, ...[0 0.8 0], 'EdgeColor', 'none');% 添加到管道列表pipes = [pipes; struct('bottom', bottomPipe, 'top', topPipe, 'passed', false)];end% 创建游戏计时器gameTimer = timer('ExecutionMode', 'fixedRate', ...'Period', 0.02, ...'TimerFcn', @gameLoop);% 生成初始管道generatePipe();% 启动背景音乐try[y, Fs] = audioread('background_music.mp3');player = audioplayer(y, Fs);play(player);catchwarning('背景音乐文件未找到,游戏将继续但没有背景音乐');end% 开始游戏start(gameTimer);function gameLoop(~, ~)if game.gameOverreturn;end% 更新小鸟位置bird.velocity = bird.velocity + game.gravity;bird.y = bird.y + bird.velocity;set(bird.handle, 'Position', [bird.x, bird.y, game.birdSize, game.birdSize]);% 旋转小鸟(根据速度)rotationAngle = min(max(bird.velocity * 5, -30), 30);rotate(bird.handle, [0 0 1], rotationAngle, [bird.x, bird.y, 0]);% 移动管道for i = 1:length(pipes)pipes(i).bottom.x = pipes(i).bottom.x - game.pipeSpeed;pipes(i).top.x = pipes(i).top.x - game.pipeSpeed;% 更新管道图形set(pipes(i).bottom.handle, 'XData', [0, game.pipeWidth, game.pipeWidth, 0]+pipes(i).bottom.x);set(pipes(i).top.handle, 'XData', [0, game.pipeWidth, game.pipeWidth, 0]+pipes(i).top.x);% 检查是否通过管道if ~pipes(i).passed && pipes(i).bottom.x + game.pipeWidth < bird.xpipes(i).passed = true;game.score = game.score + 1;set(scoreText, 'String', num2str(game.score));endend% 移除屏幕外的管道if ~isempty(pipes) && pipes(1).bottom.x + game.pipeWidth < 0delete(pipes(1).bottom.handle);delete(pipes(1).top.handle);pipes(1) = [];end% 生成新管道if isempty(pipes) || pipes(end).bottom.x < game.screenWidth - 200generatePipe();end% 碰撞检测if bird.y < game.groundHeight || bird.y + game.birdSize > game.screenHeightgameOver();endfor i = 1:length(pipes)% 检测与下管道的碰撞if bird.x + game.birdSize > pipes(i).bottom.x && ...bird.x < pipes(i).bottom.x + game.pipeWidth && ...bird.y < pipes(i).bottom.heightgameOver();end% 检测与上管道的碰撞if bird.x + game.birdSize > pipes(i).top.x && ...bird.x < pipes(i).top.x + game.pipeWidth && ...bird.y + game.birdSize > pipes(i).top.ygameOver();endend% 强制刷新图形drawnow;endfunction keyPress(~, event)if strcmp(event.Key, 'space') && ~game.gameOverbird.velocity = game.jumpStrength;elseif strcmp(event.Key, 'r') && game.gameOverrestartGame();endendfunction gameOver()game.gameOver = true;stop(gameTimer);% 显示游戏结束文字text(game.screenWidth/2, game.screenHeight/2, '游戏结束!', ...'FontSize', 40, 'Color', [1 0 0], ...'HorizontalAlignment', 'center', 'FontWeight', 'bold');text(game.screenWidth/2, game.screenHeight/2-50, ['得分: ' num2str(game.score)], ...'FontSize', 30, 'Color', [1 1 1], ...'HorizontalAlignment', 'center', 'FontWeight', 'bold');text(game.screenWidth/2, game.screenHeight/2-100, '按R键重新开始', ...'FontSize', 20, 'Color', [1 1 1], ...'HorizontalAlignment', 'center');% 保存GIFsaveGif();endfunction restartGame()% 清除现有管道for i = 1:length(pipes)delete(pipes(i).bottom.handle);delete(pipes(i).top.handle);endpipes = [];% 重置小鸟bird.y = game.screenHeight / 2;bird.velocity = 0;set(bird.handle, 'Position', [bird.x, bird.y, game.birdSize, game.birdSize]);rotate(bird.handle, [0 0 1], 0, [bird.x, bird.y, 0]);% 重置分数game.score = 0;set(scoreText, 'String', '0');% 删除游戏结束文本delete(findall(gcf, 'Type', 'text', 'String', '游戏结束!'));delete(findall(gcf, 'Type', 'text', 'String', ['得分: ' num2str(game.score)]));delete(findall(gcf, 'Type', 'text', 'String', '按R键重新开始'));% 生成新管道generatePipe();% 重置游戏状态game.gameOver = false;% 重新开始计时器start(gameTimer);endfunction saveGif()% 创建GIF文件名timestamp = datestr(now, 'yyyy-mm-dd_HH-MM-SS');gifFilename = ['flappy_bird_' timestamp '.gif'];% 获取当前图形窗口内容frame = getframe(fig);im = frame2im(frame);[imind, cm] = rgb2ind(im, 256);% 写入GIF文件imwrite(imind, cm, gifFilename, 'gif', 'Loopcount', inf, 'DelayTime', 0.1);disp(['游戏已保存为GIF: ' gifFilename]);end
end
5.游戏操作说明 🎯
- 空格键:让小鸟跳跃
- R键:游戏结束后重新开始
- 游戏会自动保存为GIF动画
6.扩展建议 💡
如果你想进一步改进这个游戏,可以考虑:
- 添加更多的视觉效果,如云朵、背景滚动等
- 实现难度递增机制(随着分数增加,管道移动速度加快)
- 添加音效(跳跃音效、碰撞音效等)
- 实现高分记录功能
希望你喜欢这个MATLAB版的Flappy Bird!通过这个项目,你不仅学会了游戏开发的基本原理,还巩固了MATLAB的图形编程技巧。快去挑战你的最高分吧!🏆
如果有任何问题或建议,欢迎在评论区留言讨论哦!😊
相关文章:
《用MATLAB玩转游戏开发》Flappy Bird:小鸟飞行大战MATLAB趣味实现
《用MATLAB玩转游戏开发:从零开始打造你的数字乐园》基础篇(2D图形交互)-Flappy Bird:小鸟飞行大战MATLAB趣味实现 文章目录 《用MATLAB玩转游戏开发:从零开始打造你的数字乐园》基础篇(2D图形交互…...
【C/C++】跟我一起学_C++同步机制效率对比与优化策略
文章目录 C同步机制效率对比与优化策略1 效率对比2 核心同步机制详解与适用场景3 性能优化建议4 场景对比表5 总结 C同步机制效率对比与优化策略 多线程编程中,同步机制的选择直接影响程序性能与资源利用率。 主流同步方式: 互斥锁原子操作读写锁条件变量无锁数据…...
linux 三剑客命令学习
grep Grep 是一个命令行工具,用于在文本文件中搜索打印匹配指定模式的行。它的名称来自于 “Global Regular Expression Print”(全局正则表达式打印),它最初是由 Unix 系统上的一种工具实现的。Grep 工具在 Linux 和其他类 Unix…...
【js基础笔记] - 包含es6 类的使用
文章目录 js基础js 预解析js变量提升 DOM相关知识节点选择器获取属性节点创建节点插入节点替换节点克隆节点获取节点属性获取元素尺寸获取元素偏移量标准的dom事件流阻止事件传播阻止默认行为事件委托 正则表达式js复杂类型元字符 - 基本元字符元字符 - 边界符元字符 - 限定符元…...
《Linux命令行大全(第2版)》PDF下载
内容简介 本书对Linux命令行进行详细的介绍,全书内容包括4个部分,第一部分由Shell的介绍开启命令行基础知识的学习之旅;第二部分讲述配置文件的编辑,如何通过命令行控制计算机;第三部分探讨常见的任务与必备工具&…...
补补表面粗糙度的相关知识(一)
表面粗糙度,或简称粗糙度,是指表面不光滑的特性。这个在机械加工行业内可以说是绝绝的必备知识之一,但往往也是最容易被忽略的,因为往往天天接触的反而不怎么关心,或者没有真正的去认真学习掌握。对于像我一样…...
Python实用工具:pdf转doc
该工具只能使用在英文目录下,且无法转换出图片,以及文本特殊格式。 下载依赖项 pip install PyPDF2 升级依赖项 pip install PyPDF2 --upgrade 查看库版本 python -c "import PyPDF2; print(PyPDF2.__version__)" 下载第二个依赖项 pip i…...
基于Dify实现对Excel的数据分析
在dify部署完成后,大家就可以基于此进行各种应用场景建设,目前dify支持聊天助手(包括对话工作流)、工作流、agent等模式的场景建设,我们在日常工作中经常会遇到各种各样的数据清洗、格式转换处理、数据统计成图等数据分…...
Win全兼容!五五 Excel Word 转 PDF 工具解决多场景转换难题
各位办公小能手们!今天给你们介绍一款超牛的工具——五五Excel Word批量转PDF工具V5.5版。这玩意儿专注搞批量格式转换,能把Excel(.xls/.xlsx)和Word(.doc/.docx)文档唰唰地变成PDF格式。 先说说它的核心功…...
java加强 -Collection集合
集合是一种容器,类似于数组,但集合的大小可变,开发中也非常常用。Collection代表单列集合,每个元素(数据)只包含1个值。Collection集合分为两类,List集合与set集合。 特点 List系列集合&#…...
BGP实验练习1
需求: 要求五台路由器的环回地址均可以相互访问 需求分析: 1.图中存在五个路由器 AR1、AR2、AR3、AR4、AR5,分属不同自治系统(AS),AR1 在 AS 100,AR2 - AR4 在 AS 200,AR5 在 AS …...
Nginx location静态文件映射配置
遇到问题? 以下这个Nginx的配置,愿意为访问https://abc.com会指向一个动态网站,访问https://abc.com/tongsongzj时会访问静态网站,但是配置之后(注意看后面那个location /tongsongzj/静态文件映射的配置)&…...
四、Hive DDL表定义、数据类型、SerDe 与分隔符核心
在理解了 Hive 数据库的基本操作后,本篇笔记将深入到数据存储的核心单元——表 (Table) 的定义和管理。掌握如何创建表、选择合适的数据类型、以及配置数据的读写方式 (特别是 SerDe 和分隔符),是高效使用 Hive 的关键。 一、创建表 (CREATE TABLE)&…...
每日脚本 5.11 - 进制转换和ascii字符
前置知识 python中各个进制的开头 二进制 : 0b 八进制 : 0o 十六进制 : 0x 进制转换函数 : bin() 转为2进制 oct() 转换为八进制的函数 hex() 转换为16进制的函数 ascii码和字符之间的转换 : chr(97) 码转为字符 …...
cookie和session的区别
一、基本概念 1. Cookie 定义:Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据(通常小于4KB),浏览器会在后续请求中自动携带该数据。作用:用于跟踪用户状态(如登录状态)、记…...
Kotlin Multiplatform--03:项目实战
Kotlin Multiplatform--03:项目实战 引言配置iOS开发环境配置项目环境运行程序 引言 本章将会带领读者进行项目实战,了解如何从零开始编译一个能同时在Android和iOS运行的App。开发环境一般来说需要使用Macbook,笔者没试过Windows是否能开发。…...
图形学、人机交互、VR/AR领域文献速读【持续更新中...】
(1)笔者在时间有限的情况下,想要多积累一些自身课题之外的新文献、新知识,所以开了这一篇文章。 (2)想通过将文献喂给大模型,并向大模型提问的方式来快速理解文献的重要信息(如基础i…...
opencascade.js stp vite 调试笔记
Hello, World! | OpenCascade.js cnpm install opencascade.js cnpm install vite-plugin-wasm --save-dev 当你不知道文件写哪的时候trae还是有点用的 ‘’‘ import { defineConfig } from vite; import wasm from vite-plugin-wasm; import rollupWasm from rollup/plugi…...
openharmony系统移植之gpu mesa3d适配
openharmony系统移植之gpu mesa3d适配 文章目录 openharmony系统移植之gpu mesa3d适配1. 环境说明2. gpu内核panfrost驱动2.1 使能panfrost驱动2.2 panfrost dts配置 3. buildroot下测试gpu驱动3.1 buildroot配置编译 4. ohos下mesa3d适配4.1 ohos下mesa3d编译调试4.1.2 编译4.…...
Java开发经验——阿里巴巴编码规范经验总结2
摘要 这篇文章是关于Java开发中阿里巴巴编码规范的经验总结。它强调了避免使用Apache BeanUtils进行属性复制,因为它效率低下且类型转换不安全。推荐使用Spring BeanUtils、Hutool BeanUtil、MapStruct或手动赋值等替代方案。文章还指出不应在视图模板中加入复杂逻…...
Linux中常见开发工具简单介绍
目录 apt/yum 介绍 常用命令 install remove list vim 介绍 常用模式 命令模式 插入模式 批量操作 底行模式 模式替换图 vim的配置文件 gcc/g 介绍 处理过程 预处理 编译 汇编 链接 库 静态库 动态库(共享库) make/Makefile …...
深入理解深度Q网络DQN:基于python从零实现
DQN是什么玩意儿? 深度Q网络(DQN)是深度强化学习领域里一个超厉害的算法。它把Q学习和深度神经网络巧妙地结合在了一起,专门用来搞定那些状态空间维度特别高、特别复杂的难题。它展示了用函数近似来学习价值函数的超能力…...
使用lldb看看Rust的HashMap
目录 前言 正文 读取桶的状态 获取键值对 键值对的指针地址 此时,读取数据 读取索引4的键值对 多添加几个键值对 使用i32作为键,&str作为值 使用i32作为键,String作为值 前言 前面使用ldb看了看不同的类型,这篇再使用…...
Vue3简易版购物车的实现。
文章目录 一、话不多说,直接上代码? 一、话不多说,直接上代码? <template><div><input type"text" placeholder"请输入内容" v-model"keywords"><button click"addGood…...
比亚迪全栈自研生态的底层逻辑
比亚迪全栈自研生态的底层逻辑:汽车工程师必须理解的闭环技术革命 引言:当技术壁垒成为护城河 2023年比亚迪销量突破302万辆的震撼数据背后,隐藏着一个更值得工程师深思的事实:其全栈自研体系覆盖了新能源汽车83%的核心零部件。这…...
[Java实战]Spring Boot 快速配置 HTTPS 并实现 HTTP 自动跳转(八)
[Java实战]Spring Boot 快速配置 HTTPS 并实现 HTTP 自动跳转(八) 引言 在当今网络安全威胁日益严峻的背景下,为 Web 应用启用 HTTPS 已成为基本要求。Spring Boot 提供了简单高效的方式集成 HTTPS 支持,无论是开发环境测试还是生产环境部署࿰…...
5.1.1 WPF中Command使用介绍
WPF 的命令系统是一种强大的输入处理机制,它比传统的事件处理更加灵活和可重用,特别适合 MVVM (Model, View, ViewModel)模式开发。 一、命令系统核心概念 1.命令系统基本元素: 命令(Command): 即ICommand类,使用最多的是RoutedCommand,也可以自己继承ICommand使用自定…...
设计模式简述(十九)桥梁模式
桥梁模式 描述基本组件使用 描述 桥梁模式是一种相对简单的模式,通常以组合替代继承的方式实现。 从设计原则来讲,可以说是单一职责的一种体现。 将原本在一个类中的功能,按更细的粒度拆分到不同的类中,然后各自独立发展。 基本…...
常用设计模式
一、什么是设计模式 设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的代码设计经验总结,旨在解决面向对象设计中反复出现的问题,提升代码的可重用性、可理解性和可靠性。以下从多个维度详细讲解ÿ…...
20242817-李臻-课下作业:Qt和Sqlite
实验内容 阅读附件内容,编译运行附件中第一章,第三章的例子。 实验过程 第一章 t1实践 #include <QApplication> #include <QWidget> #include <QPushButton> #include <QVBoxLayout>int main(int argc, char *argv[]) {QA…...
嵌入式机器学习平台Edge Impulse图像分类 – 快速入门
陈拓 2025/05/08-2025/05/11 1. 简介 官方网址 https://edgeimpulse.com/ 适用于任何边缘设备的人工智能: Gateways - 网关 Sensors & Cameras - 传感器和摄像头 Docker Containers - Docker容器 MCUs, NPUs, CPUs, GPUs 构建数据集、训练模型并优化库以…...
JavaWeb, Spring, Spring Boot
出现时间 JavaWeb - Spring - Spring Boot 一、JavaWeb 的发展历程 Servlet 和 JSP: Servlet:1997 年首次发布,用于处理 HTTP 请求和响应。 JSP:1999 年首次发布,用于动态生成 HTML 页面。 特点:提供了基…...
upload-labs靶场通关详解:第五关
一、分析源代码 $is_upload false; $msg null; if (isset($_POST[submit])) {if (file_exists(UPLOAD_PATH)) {$deny_ext array(".php",".php5",".php4",".php3",".php2",".html",".htm",".ph…...
【问题】Watt加速github访问速度:好用[特殊字符]
前言 GitHub 是全球知名的代码托管平台,主要用于软件开发,提供 Git 仓库托管、协作工具等功能,经常要用到,但是国内用户常因网络问题难以稳定访问 。 Watt Toolkit(原名 Steam)是由江苏蒸汽凡星科技有限公…...
GitHub打开缓慢甚至失败的解决办法
在C:\Windows\System32\drivers\etc的hosts中增加如下内容: 20.205.243.166 github.com 199.59.149.236 github.global.ssl.fastly.net185.199.109.153 http://assets-cdn.github.com 185.199.108.153 http://assets-cdn.github.com 185.199.110.153 http://asset…...
【25软考网工】第六章(3)数字签名和数字证书
博客主页:christine-rr-CSDN博客 专栏主页:软考中级网络工程师笔记 大家好,我是christine-rr !目前《软考中级网络工程师》专栏已经更新二十多篇文章了,每篇笔记都包含详细的知识点,希望能帮助到你!…...
Android Native 函数 Hook 技术介绍
版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 前言 Android Native 函数 Hook 技术是一种在应用运行时拦截或替换系统或自身函数行为的手段,常见实现包括 PLT Hook、Inline Hook。 PLT Hook 和…...
代码随想录算法训练营第60期第三十二天打卡
大家好,今天是我们贪心算法章节的第三阶段,前面我们讲过的几道题不知道大家理解的情况如何,还是那句话,贪心算法没有固定的套路与模板,一道题一个思路,我们要多思考这样慢慢地我就就可以水到渠成。今天我们…...
Problem C: 异常1
1.题目描述 检测年龄,其中若为负数或大于等于200岁皆为异常,请将下列代码补充完整。 // 你的代码将被嵌入这里 class Main{ public static void main(String[] args){ Person p1new Person("John",80); Person p2new Pers…...
Ollama部署使用以及模型微调和本地部署
ollama是一款开源的本地大语言模型管理工具,专注于简化大语言模型(LLM)的本地部署和使用。以下是关于 Ollama 应用的详细介绍: Ollama 的主要功能 本地化部署: Ollama 支持在本地运行模型,无需依赖外部云…...
汇编学习——iOS开发对arm64汇编的初步了解
汇编学习——iOS开发对arm64汇编的初步了解 文章目录 汇编学习——iOS开发对arm64汇编的初步了解前言栈 指令 寄存器寄存器指令运算指令寻址指令前变基 与 后变基 栈堆(Heap)内存机制三、栈(Stack)内存机制 3. 多级调用示例 例子A…...
前端代理问题
在前后端联调的时候,有一次因为前端项目代理配置有问题,导致请求接口对不上, transpileDependencies: true,devServer: {hot: true,port: 8081,proxy: {/api: {target: http://localhost:8080,changeOrigin: true,ws: true,pathRewrite: {^/a…...
E+H流量计通过Profibus DP主站转Modbus TCP网关与上位机轻松通讯
EH流量计通过Profibus DP主站转Modbus TCP网关与上位机轻松通讯 在现代工业自动化的广阔舞台上,Profibus DP与Modbus TCP这两种通信协议各领风骚,它们在不同的应用场景中发挥着举足轻重的作用。但工业生产的复杂性往往要求不同设备、系统之间能够顺畅沟…...
TCP/IP 模型每层的封装格式
TCP/IP 模型是一个四层网络架构,每一层在数据传输时都会对数据进行封装,添加相应的头部(和尾部)信息。以下是各层的封装格式及关键字段说明: 1. 应用层(Application Layer) 封装格式:…...
openjdk底层汇编指令调用(一)——汇编指令及指令编码基础
汇编指令 计算机在执行过程时只识别代表0或者1的电信号。因此为了让计算机能够执行则须向计算机输入一系列01构成的指令。 例如在x64平台下,0x53,二进制为01010011,表示将rbx寄存器中的值压栈。 但是,对于程序员而言,…...
5G-A来了!5G信号多个A带来哪些改变?
5G-A来了!5G信号多个A带来哪些改变? 随着科技不断进步,通信网络的迭代升级也在加速。自4G、5G的推出以来,我们见证了通信技术的飞跃式发展。最近,越来越多的用户发现自己手机屏幕右上角的5G标识已经变成了“5G-A”。那…...
探索虚拟化:云计算时代的资源优化之道
前言 如果您想知道云提供商如何在全球范围内运行无数应用程序,而每个应用程序都没有机架服务器,那么答案就在于虚拟化。 它是为云提供支持的核心技术之一,在幕后悄悄工作,使现代计算高效、可扩展且具有成本效益。 在本文中&#x…...
用户登录构件示例
目录 一、登录构件概述 二、构件内部结构 1. 构件组成元素(表格形式) 2. 组件连接件设计...
【软件测试】基于项目驱动的功能测试报告
目录 一、项目的介绍 1.1 项目背景 二、测试目标 2.1 用户服务模块 2.1.1 用户注册模块 2.1.1.1 测试点 2.1.1.2 边界值分析法(等价类+边界值) 2.1.1.2.1 有效等价类 2.1.1.2.2 无效等价类 2.1.1.2.3 边界值 2.1.1.2.4 测试用例设计 2.2 文章标签模块 2.3 文章模…...
【QT】UDP通讯本地调试
qt已经写好了udp通讯代码,现在要进行测试。 1、终端输入ipconfig查看本机网卡的ipv4地址 2、 用udpBind函数,绑定到此ip和自定义的端口号。 3、 打开网络调试助手,自动检测到本机的ip地址,输入任意一个和程序里不一样的端口号。 …...