Qt QML實現彈球消磚塊小游戲

前言

彈球消磚塊游戲想必大家都玩過,很簡單的小游戲,通過移動擋板反彈下落的小球,然后撞擊磚塊將其消除。本文使用QML來簡單實現這個小游戲。
效果圖:

在這里插入圖片描述
在這里插入圖片描述

正文

代碼目錄結構如下:
在這里插入圖片描述
首先是小球部分,邏輯比較麻煩一點,需要檢查與磚塊的碰撞以及與擋板的碰撞,還要更新小球的軌跡位置,代碼如下:
Ball.qml

import QtQuick 2.12Rectangle {id: ballwidth: 15height: 15radius: width / 2color: "#FFFFFF"border.color: "#DDDDDD"border.width: 1// 引用游戲區域和擋板property var gameAreaproperty var paddle// 球的速度和方向property real speedX: 0property real speedY: 0property real baseSpeed: 3// 信號:球丟失signal ballLost()// 重置球的位置和狀態function reset() {x = gameArea.width / 2 - width / 2;y = gameArea.height / 2;speedX = 0;speedY = 0;}// 開始移動球function start() {if (speedX === 0 && speedY === 0) {// 隨機初始方向,但確保向下var angle = (Math.random() * Math.PI / 2) + Math.PI / 4; // 45-135度之間speedX = Math.cos(angle) * baseSpeed;speedY = Math.sin(angle) * baseSpeed;}}// 檢查與磚塊的碰撞function checkBrickCollision() {for (var i = 0; i < gameArea.bricksRepeater.count; i++) {var brick = gameArea.bricksRepeater.itemAt(i);if (brick && !brick.destroyed) {var brickPos = brick.mapToItem(gameArea, 0, 0);if (x + width > brickPos.x && x < brickPos.x + brick.width &&y + height > brickPos.y && y < brickPos.y + brick.height) {// 確定碰撞方向并反彈var centerX = x + width / 2;var centerY = y + height / 2;var brickCenterX = brickPos.x + brick.width / 2;var brickCenterY = brickPos.y + brick.height / 2;var dx = centerX - brickCenterX;var dy = centerY - brickCenterY;if (Math.abs(dx / brick.width) > Math.abs(dy / brick.height)) {// 水平碰撞speedX = -speedX;} else {// 垂直碰撞speedY = -speedY;}// 擊中磚塊,立即消除當前碰撞的磚塊brick.hit();return true;}}}return false;}// 檢查與擋板的碰撞function checkPaddleCollision() {if (y + height >= paddle.y && y <= paddle.y + paddle.height &&x + width >= paddle.x && x <= paddle.x + paddle.width) {// 根據擊中擋板的位置調整反彈角度var paddleCenter = paddle.x + paddle.width / 2;var ballCenter = x + width / 2;var relativePosition = (ballCenter - paddleCenter) / (paddle.width / 2);// 計算新的速度向量var angle = relativePosition * (Math.PI / 3); // 最大±60度var speed = Math.sqrt(speedX * speedX + speedY * speedY);speedX = Math.sin(angle) * speed;speedY = -Math.abs(Math.cos(angle) * speed); // 確保向上反彈// 稍微增加速度speedX *= 1.05;speedY *= 1.05;return true;}return false;}// 更新球的位置Timer {interval: 16 // 約60fpsrunning: gameArea.gameRunningrepeat: trueonTriggered: {// 移動球x += speedX;y += speedY;// 檢查墻壁碰撞if (x <= 0 || x + width >= gameArea.width) {speedX = -speedX;x = Math.max(0, Math.min(x, gameArea.width - width));}if (y <= 0) {speedY = -speedY;y = 0;}// 檢查是否掉落if (y + height >= gameArea.height - 20 && !checkPaddleCollision()) {ballLost();return;}// 檢查磚塊碰撞checkBrickCollision();// 檢查擋板碰撞checkPaddleCollision();}}
}

其次是磚塊 Brick.qml

import QtQuick 2.12Rectangle {id: brickradius: 3// 磚塊狀態property bool destroyed: falseproperty int colorIndex: 0// 磚塊顏色數組readonly property var colors: ["#FF5252", // 紅色"#FFAB40", // 橙色"#FFEB3B", // 黃色"#66BB6A", // 綠色"#42A5F5"  // 藍色]// 磚塊被銷毀的信號signal brickDestroyed()// 設置磚塊顏色color: colors[colorIndex % colors.length]border.color: Qt.darker(color, 1.2)border.width: 1visible: !destroyed// 磚塊被擊中function hit() {if (!destroyed) {destroyed = true;visible = false;brickDestroyed();}}
}

磚塊擊中后要銷毀。

接著是擋板 Paddle.qml, 擋板可以通過鍵盤左右鍵進行移動,也可以直接使用鼠標進行左右拖動,代碼如下:

import QtQuick 2.12Rectangle {id: paddlewidth: 120height: 20radius: 10color: "#2196F3"border.color: "#1976D2"border.width: 1Component.onCompleted: {// 初始化時設置擋板居中x = (gameArea.width - width) / 2}// 引用游戲區域property var gameArea// 移動速度property int speed: 15property bool movingLeft: falseproperty bool movingRight: false// 處理鍵盤按下事件function handleKeyPress(key) {if (key === Qt.Key_Left) {movingLeft = true;} else if (key === Qt.Key_Right) {movingRight = true;}}// 處理鍵盤釋放事件function handleKeyRelease(key) {if (key === Qt.Key_Left) {movingLeft = false;} else if (key === Qt.Key_Right) {movingRight = false;}}// 鼠標控制MouseArea {anchors.fill: parentdrag.target: parentdrag.axis: Drag.XAxisdrag.minimumX: 0drag.maximumX: gameArea.width - parent.width}// 定時器更新擋板位置Timer {interval: 16 // 約60fpsrunning: (movingLeft || movingRight) && gameArea.gameRunningrepeat: trueonTriggered: {if (movingLeft) {paddle.x = Math.max(0, paddle.x - speed);}if (movingRight) {paddle.x = Math.min(gameArea.width - paddle.width, paddle.x + speed);}}}
}

以上是核心控件的完整代碼。


本文Demo下載

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

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

相關文章

04_Linux驅動_05_pinctrl子系統

以下代碼都在pinctrl相關的驅動函數和設備樹中 pinctrl-rockchip.c驅動&#xff0c;對應的是那個&#xff08;那些&#xff09;設備樹呢&#xff1f; 答案&#xff1a;通過.compatible "rockchip,rk3568-pinctrl"連接到rk3568.dtsi根節點下的pinctrl節點 一&#…

Python的那些事第四十五篇:繼承自Nose的測試框架Nose2

Nose2:繼承自Nose的測試框架 摘要 本文深入探討了Nose2這一繼承自Nose的測試框架。在軟件開發過程中,測試是確保代碼質量和穩定性的重要環節,而測試框架為測試工作的開展提供了有力支持。Nose2作為Nose的繼承者,在保留Nose優勢的基礎上進行了諸多改進和擴展,為Python測試…

如何通過 Airbyte 將數據攝取到 Elasticsearch

作者&#xff1a;來自 Elastic Andre Luiz Airbyte 是一個數據集成工具&#xff0c;可自動化并可擴展地將信息從各種來源傳輸到不同的目的地。它使你能夠從 API、數據庫和其他系統提取數據&#xff0c;并將其加載到 Elasticsearch 等平臺&#xff0c;以實現高級搜索和高效分析。…

RBAC 模型的簡單實現

RBAC 模型基本介紹 RBAC&#xff08;Role-Based Access Control&#xff0c;基于角色的訪問控制&#xff09;是一種廣泛應用的權限管理模型。它的核心思想是通過角色來管理權限&#xff0c;而不是直接分配權限給用戶。用戶被賦予一個或多個角色&#xff0c;而每個角色擁有不同…

數據結構---堆棧和列

一、堆棧 1.棧堆&#xff1a;具有一定操作約束的線性表&#xff1b;&#xff08;只在一端做插入刪除&#xff09; 2.棧的順序存儲結構&#xff1a; 由一個一維數組和一個記錄棧頂元素位置的變量組成。定義方式如下&#xff1a; 3.入棧操作&#xff1a; 注意&#xff1a;&…

2023 年全國職業院校技能大賽(中職組)移動應用與開發賽項 賽題第十套

2023 年全國職業院校技能大賽&#xff08;中職組&#xff09;移動應用與開發賽項 賽題第十套&#xff09; 移動應用與開發賽項競賽模塊 A&#xff1a;移動應用界面設計任務 1 環保中心界面設計&#xff08;7.5 分&#xff09;任務 2&#xff1a;首頁界面設計&#xff08;7.5 分…

FPGA為何要盡量減少組合邏輯的使用

在FPGA設計中&#xff0c;組合邏輯的使用確實需要謹慎&#xff0c;尤其是要盡量減少它的復雜性。這并不是因為組合邏輯本身不好&#xff0c;而是因為它在實際應用中容易引發一系列問題&#xff0c;而這些問題往往與FPGA的設計哲學和硬件特性相沖突。讓我從幾個關鍵點來和你聊聊…

c語言筆記 字符串函數---strcmp,strncmp,strchr,strrchr

目錄 函數strcmp與strncmp 以下是錯誤的示范&#xff1a;兩個指針字符型的指針不能直接進行比較 函數strchr與函數strrchr 函數strchr與函數strrchr與strstr函數三者對比 背景&#xff1a;如果說我們要比較兩個字符串是否相等&#xff0c;使用strcmp或者strncmp函數。在c語言中…

合React寶寶體質的自定義節流hook

本文為開發開源項目的真實開發經歷&#xff0c;感興趣的可以來給我的項目點個star&#xff0c;謝謝啦~ 具體博文介紹&#xff1a; 開源&#xff5c;Documind協同文檔&#xff08;接入deepseek-r1、支持實時聊天&#xff09;Documind &#x1f680; 一個支持實時聊天和接入 - 掘…

【RTSP】客戶端(五)H264 265處理邏輯

H264處理邏輯 整體邏輯分析 實現邏輯 解析 RTP 包頭&#xff1a;首先檢查 RTP 頭部的有效負載類型&#xff08;payloadType&#xff09;是否匹配處理擴展頭&#xff1a;如果 RTP 包包含擴展頭&#xff0c;跳過擴展頭部分&#xff0c;獲取有效負載處理分片數據&#xff1a;H264…

IDEA集成git,項目的克隆,遠程倉庫中文件的添加刪除

目錄 一、克隆項目 二、使用IDEA完成文件的上傳和刪除 1.配置git 2.上傳 3.刪除&#xff08;通過git bash&#xff09; 一、克隆項目 點擊克隆&#xff0c;復制url &#xff0c;如下 打開你想要克隆到哪里&#xff0c;右擊&#xff0c;選擇 open Git Bash here 這一步之后…

神經網絡:定義與核心原理

神經網絡&#xff08;Artificial Neural Network, ANN&#xff09;是一種受生物神經系統啟發的計算模型&#xff0c;旨在通過模擬神經元之間的連接與信息傳遞機制&#xff0c;實現復雜的數據處理和模式識別功能。其本質是由大量簡單處理單元&#xff08;神經元&#xff09;構成…

將pdf或者word轉換成base64格式

廢話不多說直接上代碼&#xff1a; function fileToBase64(file) {return new Promise((resolve, reject) > {const reader new FileReader();reader.readAsDataURL(file);reader.onload function (event) {const base64Data event.target.result.split(,)[1];resolve(b…

Spring @Bean注解使用場景二

bean:最近在寫一篇讓Successfactors顧問都能搞明白的sso的邏輯的文章&#xff0c;所以一致在研究IAS的saml2.0的協議&#xff0c;希望用代碼去解釋SP、idp的一些概念&#xff0c;讓顧問了解SSO與saml的關系&#xff0c;在github找代碼的時候發現一些代碼的調用關系很難理解&…

ubuntu22.04 關于掛在設備為nfts文件格式無法創建軟連接的問題

最近遇到情況&#xff0c;解壓工程報錯&#xff0c;無法創建軟連接 但是盤內還有130G空間&#xff0c;明顯不是空間問題&#xff0c;查找之后發現是移動硬盤的文件格式是NTFS&#xff0c;在ubuntu上不好兼容&#xff0c;于是報錯。 開貼記錄解決方案。 1.確定文件格式 使用命…

docker后臺運行,便于后期用命令行進入它的終端

在 docker compose up --build -d 命令中&#xff0c;?**-d?&#xff08;或 --detach&#xff09;參數的作用是讓容器以后臺模式&#xff08;detached mode&#xff09;?**運行。以下是詳細解釋&#xff1a; ?**-d 參數的作用** ?后臺運行容器&#xff1a; 默認情況下&a…

網頁制作14-Javascipt時間特效の顯示動態日期

<!doctype html> <html> <head> <meta charset"utf-8"> <title>動態日期</title> </head><script>var today new Date();//獲取時間var ytoday.getFullYear();//截取年var mtoday.getMonth();//截取月份,返回0~11v…

【BP神經網絡】實戰

1.參考Python實戰&#xff1a;BP神經網絡_bp神經網絡實戰python-CSDN博客 2.實踐 &#xff08;1&#xff09;運行環境 anocanda Powershell Prompt&#xff08;anocanda3&#xff09; &#xff08;2&#xff09;創建虛擬環境&#xff0c;解決安裝包的版本問題 *打開終端&a…

深度學習多模態人臉情緒識別:從理論到實踐

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站。https://www.captainbed.cn/north 文章目錄 1. 引言2. 技術框架與流程圖3. 核心算法解析3.1 視覺特征提取&#xff08;CNN&#xff09;3.2…