《用MATLAB玩轉游戲開發:從零開始打造你的數字樂園》基礎篇(2D圖形交互)-《打磚塊:向量反射與實時物理模擬》MATLAB教程

《用MATLAB玩轉游戲開發:從零開始打造你的數字樂園》基礎篇(2D圖形交互)-《打磚塊:向量反射與實時物理模擬》MATLAB教程 🎮

文章目錄

  • 《用MATLAB玩轉游戲開發:從零開始打造你的數字樂園》基礎篇(2D圖形交互)-《打磚塊:向量反射與實時物理模擬》MATLAB教程 🎮
    • 引言:從游戲到物理模擬
    • 1. 設計思路與游戲概述 🧠
      • 1.1 物理模型關鍵點 ??
    • 2. 核心原理詳解 🔍
      • 2.1 向量反射原理 📐
      • 2.2 碰撞檢測原理 🔄
      • 2.3 游戲循環結構 🔁
    • 3. 完整流程圖 📊
    • 4. 分步實現教程 🛠?
      • 4.1 初始化設置
      • 4.2 創建游戲對象
      • 4.3 游戲主循環
      • 4.4 碰撞檢測函數
    • 5. 完整可運行代碼 🏆
    • 6. 游戲操作說明 🎮
    • 7. 擴展思路 💡

在這里插入圖片描述

引言:從游戲到物理模擬

還記得小時候玩過的打磚塊游戲嗎?🎯 一個小球在屏幕上彈來彈去,擊碎各種磚塊,同時玩家控制一塊擋板防止小球掉落。這看似簡單的游戲背后,其實蘊含著豐富的物理和數學原理!今天,我們就用MATLAB來實現這個經典游戲,并深入探討其中的向量反射和實時物理模擬技術。

通過本教程,你將學到:

  • 向量運算在游戲物理中的應用
  • 實時碰撞檢測的實現方法
  • MATLAB動畫和交互式圖形編程
  • 游戲狀態管理和邏輯控制

準備好你的MATLAB環境(2016b版本),讓我們開始這場有趣的編程之旅吧!🚀

1. 設計思路與游戲概述 🧠

打磚塊游戲(Breakout/Arkanoid)是經典的街機游戲,包含以下核心元素:

  • 一個由玩家控制的擋板(paddle)
  • 一個運動的(ball)
  • 由磚塊組成的(bricks)
  • 邊界(walls)

游戲目標是用擋板反彈球,消除所有磚塊。每次球碰到磚塊,磚塊消失,玩家得分。

1.1 物理模型關鍵點 ??

  1. 碰撞檢測:判斷球與邊界、擋板、磚塊的接觸
  2. 反射計算:球碰到物體后的運動方向變化
  3. 實時渲染:游戲畫面的流暢更新
  4. 游戲邏輯:得分、生命、勝負判斷

2. 核心原理詳解 🔍

2.1 向量反射原理 📐

球碰到平面后的反射遵循"入射角=反射角"原則。數學上可以用向量運算表示:

給定:

  • 入射向量 v = [vx, vy]
  • 法向量 n = [nx, ny] (垂直于反射平面)

反射向量 r 的計算公式為:
r = v ? 2 ( v ? n ) n r = v - 2(v \cdot n)n r=v?2(v?n)n

在MATLAB中實現:

function reflectedVec = reflectVector(inVec, normalVec)% 歸一化法向量normalVec = normalVec / norm(normalVec);% 計算反射向量reflectedVec = inVec - 2 * dot(inVec, normalVec) * normalVec;
end

2.2 碰撞檢測原理 🔄

我們需要檢測球與以下物體的碰撞:

  1. 邊界:比較球心坐標與邊界位置
  2. 擋板:判斷球是否在擋板的矩形區域內
  3. 磚塊:類似擋板,但需要考慮磚塊是否已被消除

2.3 游戲循環結構 🔁

標準游戲循環包含以下步驟:

  1. 初始化:創建游戲對象和變量
  2. 輸入處理:讀取玩家操作
  3. 狀態更新:計算物理和游戲邏輯
  4. 渲染:繪制游戲畫面
  5. 循環控制:控制幀率和退出條件

3. 完整流程圖 📊

開始
初始化游戲
繪制初始場景
游戲進行中?
處理玩家輸入
更新球位置
檢測碰撞
處理碰撞響應
更新游戲狀態
繪制新幀
顯示游戲結果
結束

4. 分步實現教程 🛠?

4.1 初始化設置

function breakoutGame()% 清除工作區和圖形窗口clc; clear; close all;% 游戲參數設置gameParams = struct(...'paddleWidth', 100, ...    % 擋板寬度'paddleHeight', 15, ...    % 擋板高度'ballRadius', 10, ...      % 球半徑'brickRows', 5, ...        % 磚塊行數'brickCols', 10, ...       % 磚塊列數'brickWidth', 60, ...      % 磚塊寬度'brickHeight', 20, ...     % 磚塊高度'brickOffsetTop', 50, ...  % 磚塊頂部偏移'brickPadding', 5, ...     % 磚塊間距'ballSpeed', 8, ...        % 球初始速度'lives', 3, ...            % 初始生命數'score', 0 ...             % 初始得分);% 創建圖形窗口fig = figure('Name', 'MATLAB打磚塊', ...'NumberTitle', 'off', ...'Position', [100, 100, 800, 600], ...'KeyPressFcn', @keyDown, ...'KeyReleaseFcn', @keyUp, ...'WindowButtonDownFcn', @mouseClick);% 創建坐標軸ax = axes('Parent', fig, ...'Position', [0.05, 0.05, 0.9, 0.9], ...'XLim', [0, 800], ...'YLim', [0, 600], ...'Color', [0.1, 0.1, 0.3], ...'XTick', [], ...'YTick', []);hold(ax, 'on');axis equal;

4.2 創建游戲對象

    % 創建擋板paddle = rectangle('Parent', ax, ...'Position', [350, 30, gameParams.paddleWidth, gameParams.paddleHeight], ...'FaceColor', [0.8, 0.2, 0.2], ...'EdgeColor', 'none', ...'Curvature', [0.2, 0.2]);% 創建球theta = rand * 2 * pi;  % 隨機初始角度ballVel = [gameParams.ballSpeed * cos(theta), gameParams.ballSpeed * sin(theta)];ball = rectangle('Parent', ax, ...'Position', [400, 200, gameParams.ballRadius*2, gameParams.ballRadius*2], ...'FaceColor', [0.9, 0.9, 0.1], ...'EdgeColor', 'none', ...'Curvature', [1, 1]);% 創建磚塊bricks = gobjects(gameParams.brickRows, gameParams.brickCols);brickColors = hsv(gameParams.brickRows);  % 每行不同顏色for r = 1:gameParams.brickRowsfor c = 1:gameParams.brickColsbrickX = (c-1) * (gameParams.brickWidth + gameParams.brickPadding);brickY = 550 - (r-1) * (gameParams.brickHeight + gameParams.brickPadding);bricks(r,c) = rectangle('Parent', ax, ...'Position', [brickX, brickY, gameParams.brickWidth, gameParams.brickHeight], ...'FaceColor', brickColors(r,:), ...'EdgeColor', 'w');endend% 創建文本顯示scoreText = text(ax, 20, 580, sprintf('得分: %d', gameParams.score), ...'Color', 'w', 'FontSize', 12);livesText = text(ax, 700, 580, sprintf('生命: %d', gameParams.lives), ...'Color', 'w', 'FontSize', 12);startText = text(ax, 400, 300, '點擊開始游戲', ...'Color', 'w', 'FontSize', 24, ...'HorizontalAlignment', 'center');

4.3 游戲主循環

    % 游戲狀態變量gameState = struct(...'isRunning', false, ...    % 游戲是否進行中'paddleDir', 0, ...        % 擋板移動方向 (-1:左, 0:停止, 1:右)'paddleSpeed', 15, ...     % 擋板移動速度'activeBricks', true(gameParams.brickRows, gameParams.brickCols) ... % 活躍磚塊);% 鍵盤控制回調函數function keyDown(~, event)switch event.Keycase 'leftarrow'gameState.paddleDir = -1;case 'rightarrow'gameState.paddleDir = 1;case 'escape'gameState.isRunning = false;endendfunction keyUp(~, event)switch event.Keycase {'leftarrow', 'rightarrow'}gameState.paddleDir = 0;endend% 鼠標點擊開始游戲function mouseClick(~, ~)if ~gameState.isRunninggameState.isRunning = true;delete(startText);startText = [];endend% 主游戲循環while ishandle(fig)if gameState.isRunning% 更新擋板位置paddlePos = get(paddle, 'Position');newX = paddlePos(1) + gameState.paddleSpeed * gameState.paddleDir;% 限制擋板不超出邊界newX = max(0, min(newX, 800 - gameParams.paddleWidth));set(paddle, 'Position', [newX, paddlePos(2), paddlePos(3), paddlePos(4)]);% 更新球位置ballPos = get(ball, 'Position');newBallX = ballPos(1) + ballVel(1);newBallY = ballPos(2) + ballVel(2);% 檢測碰撞[ballVel, gameParams, gameState] = checkCollisions(...[newBallX, newBallY], ballVel, gameParams, gameState, paddle, bricks);% 更新球位置set(ball, 'Position', [newBallX, newBallY, ballPos(3), ballPos(4)]);% 更新文本顯示set(scoreText, 'String', sprintf('得分: %d', gameParams.score));set(livesText, 'String', sprintf('生命: %d', gameParams.lives));% 檢查游戲結束條件if newBallY < 0  % 球落到底部gameParams.lives = gameParams.lives - 1;if gameParams.lives <= 0gameState.isRunning = false;text(ax, 400, 300, '游戲結束!', ...'Color', 'r', 'FontSize', 36, ...'HorizontalAlignment', 'center');else% 重置球位置set(ball, 'Position', [400, 200, gameParams.ballRadius*2, gameParams.ballRadius*2]);theta = rand * 2 * pi;ballVel = [gameParams.ballSpeed * cos(theta), gameParams.ballSpeed * sin(theta)];pause(1);endend% 檢查勝利條件if ~any(gameState.activeBricks(:))gameState.isRunning = false;text(ax, 400, 300, '恭喜通關!', ...'Color', 'g', 'FontSize', 36, ...'HorizontalAlignment', 'center');endend% 控制幀率pause(0.02);end

4.4 碰撞檢測函數

function [newVel, gameParams, gameState] = checkCollisions(ballPos, ballVel, gameParams, gameState, paddle, bricks)% 獲取球參數ballX = ballPos(1) + gameParams.ballRadius;ballY = ballPos(2) + gameParams.ballRadius;% 邊界碰撞檢測if ballX <= gameParams.ballRadius || ballX >= 800 - gameParams.ballRadiusballVel(1) = -ballVel(1);  % 水平反轉endif ballY >= 600 - gameParams.ballRadiusballVel(2) = -ballVel(2);  % 垂直反轉end% 擋板碰撞檢測paddlePos = get(paddle, 'Position');if ballY <= paddlePos(2) + paddlePos(4) + gameParams.ballRadius && ...ballY >= paddlePos(2) && ...ballX >= paddlePos(1) - gameParams.ballRadius && ...ballX <= paddlePos(1) + paddlePos(3) + gameParams.ballRadius% 計算碰撞點相對于擋板中心的位置 (-1到1)hitPos = (ballX - (paddlePos(1) + paddlePos(3)/2)) / (paddlePos(3)/2);% 根據碰撞點調整反射角度maxAngle = pi/3;  % 最大反射角度 (60度)angle = hitPos * maxAngle;% 計算新速度向量speed = norm(ballVel);ballVel = [speed * sin(angle), speed * cos(angle)];% 增加一點速度讓游戲更有挑戰性ballVel = ballVel * 1.02;end% 磚塊碰撞檢測for r = 1:gameParams.brickRowsfor c = 1:gameParams.brickColsif gameState.activeBricks(r,c)brickPos = get(bricks(r,c), 'Position');% 檢查球是否與磚塊相交if ballX + gameParams.ballRadius > brickPos(1) && ...ballX - gameParams.ballRadius < brickPos(1) + brickPos(3) && ...ballY + gameParams.ballRadius > brickPos(2) && ...ballY - gameParams.ballRadius < brickPos(2) + brickPos(4)% 確定碰撞邊 (簡化版)if ballY < brickPos(2) || ballY > brickPos(2) + brickPos(4)ballVel(2) = -ballVel(2);  % 上下碰撞elseballVel(1) = -ballVel(1);  % 左右碰撞end% 標記磚塊為不活躍并隱藏gameState.activeBricks(r,c) = false;set(bricks(r,c), 'Visible', 'off');% 增加分數gameParams.score = gameParams.score + 10;% 只需要處理一次碰撞break;endendendendnewVel = ballVel;
end

5. 完整可運行代碼 🏆

將以下所有代碼段按順序組合成一個.m文件即可運行:

function breakoutGame()% 清除工作區和圖形窗口clc; clear; close all;% 游戲參數設置gameParams = struct(...'paddleWidth', 100, ...    % 擋板寬度'paddleHeight', 15, ...    % 擋板高度'ballRadius', 10, ...      % 球半徑'brickRows', 5, ...        % 磚塊行數'brickCols', 10, ...       % 磚塊列數'brickWidth', 60, ...      % 磚塊寬度'brickHeight', 20, ...     % 磚塊高度'brickOffsetTop', 50, ...  % 磚塊頂部偏移'brickPadding', 5, ...     % 磚塊間距'ballSpeed', 8, ...        % 球初始速度'lives', 3, ...            % 初始生命數'score', 0 ...             % 初始得分);% 創建圖形窗口fig = figure('Name', 'MATLAB打磚塊', ...'NumberTitle', 'off', ...'Position', [100, 100, 800, 600], ...'KeyPressFcn', @keyDown, ...'KeyReleaseFcn', @keyUp, ...'WindowButtonDownFcn', @mouseClick);% 創建坐標軸ax = axes('Parent', fig, ...'Position', [0.05, 0.05, 0.9, 0.9], ...'XLim', [0, 800], ...'YLim', [0, 600], ...'Color', [0.1, 0.1, 0.3], ...'XTick', [], ...'YTick', []);hold(ax, 'on');axis equal;% 創建擋板paddle = rectangle('Parent', ax, ...'Position', [350, 30, gameParams.paddleWidth, gameParams.paddleHeight], ...'FaceColor', [0.8, 0.2, 0.2], ...'EdgeColor', 'none', ...'Curvature', [0.2, 0.2]);% 創建球theta = rand * 2 * pi;  % 隨機初始角度ballVel = [gameParams.ballSpeed * cos(theta), gameParams.ballSpeed * sin(theta)];ball = rectangle('Parent', ax, ...'Position', [400, 200, gameParams.ballRadius*2, gameParams.ballRadius*2], ...'FaceColor', [0.9, 0.9, 0.1], ...'EdgeColor', 'none', ...'Curvature', [1, 1]);% 創建磚塊bricks = gobjects(gameParams.brickRows, gameParams.brickCols);brickColors = hsv(gameParams.brickRows);  % 每行不同顏色for r = 1:gameParams.brickRowsfor c = 1:gameParams.brickColsbrickX = (c-1) * (gameParams.brickWidth + gameParams.brickPadding);brickY = 550 - (r-1) * (gameParams.brickHeight + gameParams.brickPadding);bricks(r,c) = rectangle('Parent', ax, ...'Position', [brickX, brickY, gameParams.brickWidth, gameParams.brickHeight], ...'FaceColor', brickColors(r,:), ...'EdgeColor', 'w');endend% 創建文本顯示scoreText = text(ax, 20, 580, sprintf('得分: %d', gameParams.score), ...'Color', 'w', 'FontSize', 12);livesText = text(ax, 700, 580, sprintf('生命: %d', gameParams.lives), ...'Color', 'w', 'FontSize', 12);startText = text(ax, 400, 300, '點擊開始游戲', ...'Color', 'w', 'FontSize', 24, ...'HorizontalAlignment', 'center');% 游戲狀態變量gameState = struct(...'isRunning', false, ...    % 游戲是否進行中'paddleDir', 0, ...        % 擋板移動方向 (-1:左, 0:停止, 1:右)'paddleSpeed', 15, ...     % 擋板移動速度'activeBricks', true(gameParams.brickRows, gameParams.brickCols) ... % 活躍磚塊);% 鍵盤控制回調函數function keyDown(~, event)switch event.Keycase 'leftarrow'gameState.paddleDir = -1;case 'rightarrow'gameState.paddleDir = 1;case 'escape'gameState.isRunning = false;endendfunction keyUp(~, event)switch event.Keycase {'leftarrow', 'rightarrow'}gameState.paddleDir = 0;endend% 鼠標點擊開始游戲function mouseClick(~, ~)if ~gameState.isRunninggameState.isRunning = true;delete(startText);startText = [];endend% 主游戲循環while ishandle(fig)if gameState.isRunning% 更新擋板位置paddlePos = get(paddle, 'Position');newX = paddlePos(1) + gameState.paddleSpeed * gameState.paddleDir;% 限制擋板不超出邊界newX = max(0, min(newX, 800 - gameParams.paddleWidth));set(paddle, 'Position', [newX, paddlePos(2), paddlePos(3), paddlePos(4)]);% 更新球位置ballPos = get(ball, 'Position');newBallX = ballPos(1) + ballVel(1);newBallY = ballPos(2) + ballVel(2);% 檢測碰撞[ballVel, gameParams, gameState] = checkCollisions(...[newBallX, newBallY], ballVel, gameParams, gameState, paddle, bricks);% 更新球位置set(ball, 'Position', [newBallX, newBallY, ballPos(3), ballPos(4)]);% 更新文本顯示set(scoreText, 'String', sprintf('得分: %d', gameParams.score));set(livesText, 'String', sprintf('生命: %d', gameParams.lives));% 檢查游戲結束條件if newBallY < 0  % 球落到底部gameParams.lives = gameParams.lives - 1;if gameParams.lives <= 0gameState.isRunning = false;text(ax, 400, 300, '游戲結束!', ...'Color', 'r', 'FontSize', 36, ...'HorizontalAlignment', 'center');else% 重置球位置set(ball, 'Position', [400, 200, gameParams.ballRadius*2, gameParams.ballRadius*2]);theta = rand * 2 * pi;ballVel = [gameParams.ballSpeed * cos(theta), gameParams.ballSpeed * sin(theta)];pause(1);endend% 檢查勝利條件if ~any(gameState.activeBricks(:))gameState.isRunning = false;text(ax, 400, 300, '恭喜通關!', ...'Color', 'g', 'FontSize', 36, ...'HorizontalAlignment', 'center');endend% 控制幀率pause(0.02);end% 碰撞檢測函數function [newVel, gameParams, gameState] = checkCollisions(ballPos, ballVel, gameParams, gameState, paddle, bricks)% 獲取球參數ballX = ballPos(1) + gameParams.ballRadius;ballY = ballPos(2) + gameParams.ballRadius;% 邊界碰撞檢測if ballX <= gameParams.ballRadius || ballX >= 800 - gameParams.ballRadiusballVel(1) = -ballVel(1);  % 水平反轉endif ballY >= 600 - gameParams.ballRadiusballVel(2) = -ballVel(2);  % 垂直反轉end% 擋板碰撞檢測paddlePos = get(paddle, 'Position');if ballY <= paddlePos(2) + paddlePos(4) + gameParams.ballRadius && ...ballY >= paddlePos(2) && ...ballX >= paddlePos(1) - gameParams.ballRadius && ...ballX <= paddlePos(1) + paddlePos(3) + gameParams.ballRadius% 計算碰撞點相對于擋板中心的位置 (-1到1)hitPos = (ballX - (paddlePos(1) + paddlePos(3)/2)) / (paddlePos(3)/2);% 根據碰撞點調整反射角度maxAngle = pi/3;  % 最大反射角度 (60度)angle = hitPos * maxAngle;% 計算新速度向量speed = norm(ballVel);ballVel = [speed * sin(angle), speed * cos(angle)];% 增加一點速度讓游戲更有挑戰性ballVel = ballVel * 1.02;end% 磚塊碰撞檢測for r = 1:gameParams.brickRowsfor c = 1:gameParams.brickColsif gameState.activeBricks(r,c)brickPos = get(bricks(r,c), 'Position');% 檢查球是否與磚塊相交if ballX + gameParams.ballRadius > brickPos(1) && ...ballX - gameParams.ballRadius < brickPos(1) + brickPos(3) && ...ballY + gameParams.ballRadius > brickPos(2) && ...ballY - gameParams.ballRadius < brickPos(2) + brickPos(4)% 確定碰撞邊 (簡化版)if ballY < brickPos(2) || ballY > brickPos(2) + brickPos(4)ballVel(2) = -ballVel(2);  % 上下碰撞elseballVel(1) = -ballVel(1);  % 左右碰撞end% 標記磚塊為不活躍并隱藏gameState.activeBricks(r,c) = false;set(bricks(r,c), 'Visible', 'off');% 增加分數gameParams.score = gameParams.score + 10;% 只需要處理一次碰撞break;endendendendnewVel = ballVel;end
end

來看看我這個菜雞玩了一局的效果,屏幕前的你也可以試試看看能的多少分~
在這里插入圖片描述

6. 游戲操作說明 🎮

  • 左右箭頭鍵:移動擋板
  • ESC鍵:退出游戲
  • 鼠標點擊:開始游戲

7. 擴展思路 💡

如果你想進一步提升這個游戲,可以考慮:

  1. 增加音效:使用audioplayer添加碰撞音效
  2. 多種磚塊:不同顏色磚塊需要多次擊中才能消除
  3. 特殊道具:球碰到某些磚塊會掉落道具,如加長擋板、額外生命等
  4. 關卡設計:設計不同布局的磚塊排列
  5. 粒子效果:磚塊消除時添加爆炸效果

希望你喜歡這個MATLAB打磚塊游戲教程!通過這個項目,你不僅學會了向量反射的原理,還掌握了實時物理模擬和游戲開發的基本技巧。Happy coding! 🚀

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/79298.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/79298.shtml
英文地址,請注明出處:http://en.pswp.cn/web/79298.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redisson 看門狗機制

何為看門狗 看門狗機制的主要作用是自動續期鎖&#xff0c;確保在節點完成任務之前&#xff0c;鎖不會過期。具體來說&#xff0c;當一個節點獲取到鎖后&#xff0c;看門狗會定期檢查該鎖的過期時間&#xff0c;并在必要時延長鎖的過期時間&#xff0c;確保節點可以順利完成任…

[架構之美]linux常見故障問題解決方案(十九)

[架構之美]linux下常見故障問題解決方案 一&#xff0c;文本文件忙 問題一&#xff1a;rootwh-VMware-Virtual-Platform:/home/hail# cp /root/containerd/bin/* /usr/bin/ cp: 無法創建普通文件 ‘/usr/bin/containerd’: 文本文件忙 在Linux系統中遇到“文本文件忙”錯誤時…

QT實現曲線圖縮放、拖拽以及框選放大

.h文件 protected: void saveAxisRange();void wheelEvent(QWheelEvent *event) override;void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;private:QPoint m_…

【Pandas】pandas DataFrame corr

Pandas2.2 DataFrame Computations descriptive stats 方法描述DataFrame.abs()用于返回 DataFrame 中每個元素的絕對值DataFrame.all([axis, bool_only, skipna])用于判斷 DataFrame 中是否所有元素在指定軸上都為 TrueDataFrame.any(*[, axis, bool_only, skipna])用于判斷…

青藏高原七大河流源區徑流深、蒸散發數據集(TPRED)

時間分辨率 月空間分辨率 1km - 10km共享方式 開放獲取數據大小 83.27 MB數據時間范圍 1998-07-01 — 2017-12-31元數據更新時間 2024-07-22 數據集摘要 通過構建耦合積雪、凍土、冰川等冰凍圈水文物理過程的WEB-DHM模型&#xff08;Water and Energy Budget-based Distribute…

window環境下,如何通過USB接口控制打印機

雖然說大多數情況下&#xff0c;我們可以非常便利的通過打印機驅動來控制打印機&#xff0c;但還是有一些特殊情況&#xff0c;導致無法通過打印機驅動來完成我們預想的任務&#xff0c;比如&#xff0c;打印機只是一個系統設備中的一部分&#xff0c;需要協調其它設備一起工作…

CDGP數據治理主觀題評分標準與得分策略

1.數據模型題目評分標準 1)準確理解題目中所描述的業務邏輯和需求得[1分] 2)正確使用模型設計方法,使用信息工程、信息建模集成定義、巴克符號、陳氏符號等其中一種得[1分] 3)正確設計實體和屬性,題目中涉及的實體數量為25-30個,10個以內得[2分],10-20個得[3分],25個…

工業設計破局密碼:3D 可視化技術點燃產業升級引擎

3D可視化是一種將數據、信息或抽象概念以三維圖形、模型和動畫的形式呈現出來的技術。3D可視化技術通過構建三維數字孿生體&#xff0c;將設計思維轉化為可交互的虛擬原型&#xff0c;不僅打破了傳統二維設計的空間局限&#xff0c;更在效率、精度與用戶體驗層面開創了全新維度…

Qt中在子線程中刷新UI的方法

Qt中在子線程中刷新UI的方法 在Qt中UI界面并不是線程安全的&#xff0c;意味著在子線程中不能隨意操作UI界面組件&#xff08;比如按鈕、標簽&#xff09;等&#xff0c;如果強行操作這些組件有可能會導致程序崩潰。那么在Qt中如何在子線程中刷新UI控件呢&#xff1f; 兩種方…

為了摸魚和吃瓜,我開發了一個網站

平時上班真的比較累&#xff0c;摸魚和吃瓜還要跳轉多個平臺的話&#xff0c;就累上加累了。 所以做了一個聚合了全網主流平臺熱搜的網站。 目前市面上確實有很多這種網站了&#xff0c;所以目前最主要有兩點和他們不同&#xff1a; 給熱搜列表增加了配圖&#xff0c;刷的時候…

操作系統學習筆記第2章 (竟成)

第 2 章 進程管理 【考綱內容】 1.進程與線程&#xff1a; (1) 進程 / 線程的基本概念&#xff1b; (2) 進程 / 線程的狀態與轉換&#xff1b; (3) 線程的實現&#xff1a;內核支持的線程&#xff1b;線程庫支持的線程&#xff1b; (4) 進程與線程的組織與控制&#xff1b; (5)…

77.評論日記

房間要經常搞衛生&#xff0c;不然會很多灰&#xff0c;很多頭發&#xff0c;很多垃圾。 當然&#xff0c;即使一直搞衛生&#xff0c;在一些看不到的角落也是會慢慢囤積垃圾。 想要把那些角落也打掃干凈&#xff0c;沒別的辦法&#xff0c;只有把那個角落上所有的東西都移開&a…

語音合成之十二 TTS聲學編解碼器的演進

TTS聲學編解碼器的演進 1 引言&#xff1a;聲碼器/聲學編解碼器在現代TTS中的關鍵作用2 奠定基石&#xff1a;從早期聲碼器到神經合成的曙光3. HiFi-GAN: 革新高效高保真波形生成4. 新的疆域&#xff1a;面向富語義TTS的先進聲學編解碼器5. XCodec2.0: 統一聲學與語義信息6.BiC…

大學之大:悉尼科技大學2025.5.10

悉尼科技大學&#xff1a;從技術先驅到全球創新樞紐的百年征程 一、歷史沿革&#xff1a;從技工培訓到世界百強名校的蛻變 1. 工業革命的技術火種&#xff08;1843-1945&#xff09; 悉尼科技大學的歷史可追溯至1843年成立的悉尼機械學院&#xff08;Sydney Mechanics’ Scho…

安裝阿里云的yum源并且下載軟件(CentOS7版本)

目錄 1. 進入root模式: 2. 進入yum.repos.d文件下 3.備份 4. 安裝阿里云的yum源 5. 安裝dnf 6. 安裝epel-release 7. 清除緩存,并新建緩存 8. 安裝智能拼音軟件包 8.1安裝 8.2 進入應用程序 -- 系統工具 -- 設置 8.3重啟后就可以打中文啦~ (需要重新啟動才能)…

Discriminative and domain invariant subspace alignment for visual tasks

用于視覺任務的判別性和域不變子空間對齊 作者&#xff1a;Samaneh Rezaei&#xff0c;Jafar Tahmoresnezhad 文章于2018年12月4日收到&#xff0c;2019年5月24日被接受&#xff0c;2019年6月3日在線發表于Iran Journal of Computer Science期刊&#xff0c;DOI: 10.1007/s42…

用jsp簡單實現C語言標準化測試系統

C語言標準化測試系統 在Web編程技術的學習過程中&#xff0c;我們小組為了深入理解相關技術原理&#xff0c;提升實踐能力&#xff0c;開發了一個基于動態Web工程框架的C語言標準化考試系統。現在&#xff0c;就來和大家分享一下我們的項目經歷。 一、實驗目的剖析 這個項目…

QMK鍵盤固件自定義指南 - 打造你的專屬鍵盤體驗

QMK鍵盤固件自定義指南 - 打造你的專屬鍵盤體驗 &#x1f680; 前言 在機械鍵盤的世界里&#xff0c;QMK固件讓你的鍵盤不再只是簡單的輸入設備&#xff0c;而是可以按照你的意愿定制的強大工具。本文將深入淺出地介紹如何自定義QMK鍵盤的行為&#xff0c;從基礎概念到高級應…

5.9培訓

文件上傳 先找文件上傳的地方&#xff0c;打開代理鏈接BP&#xff0c;它需要一個xls文件 我們創建一個sqzr.xls bp攔截了之后&#xff0c;我們修改請求&#xff0c;把后綴改成php&#xff0c;發送請求 找到我們的靜態資源所在的位置 訪問http://192.168.1.100:81/static/upload…

【FAQ】HarmonyOS SDK 閉源開放能力 — PDF Kit

1.問題描述&#xff1a; 預覽PDF文件&#xff0c;文檔上所描述的loadDocument接口&#xff0c;可以返回文件的狀態&#xff0c;并無法實現PDF的預覽&#xff0c;是否有能預覽PDF相關接口&#xff1f; 解決方案&#xff1a; 1、執行loadDocument進行加載PDF文件后&#xff0c…