当前位置: 首页 > news >正文

【QT5】<应用> 小游戏:贪吃蛇

文章目录

一、项目要求

二、需求分析

三、实现效果

四、代码


一、项目要求

【1】主要实现:游戏界面存在一条蛇🐍,使用键盘wsad或者↑↓←→键盘可以控制蛇的行走方向。同时界面中会随机出现食物,蛇可以吃食物,然后蛇的身体就会变长。吃完一个食物之后才会刷新另外一个食物。

【2】游戏结束:蛇碰壁。

【3】玩家分数:由蛇的存活时间以及长度综合计算。time为蛇存活的秒数,lent-len0表示蛇增加的节点数量。同时,玩家分数需要实时显示

【4】重新开始:点击相应的按钮。

【5】加速模式:双击键盘可以加速蛇的移动。例如按两下w键,蛇的速度变为原来的2倍。

【6】不同食物:食物有多种类别,不同的食物会导致蛇变长的长度不同。


二、需求分析

【1】针对主要实现:

  • 创建蛇(Snake)食物(Food)主要窗口(Widget)类。
  • Snake类:创建方法来实现蛇的移动(头插一个,尾删一个)、蛇的方向检测(根据键盘值)、蛇是否死亡(是否碰壁)以及在窗口中绘制蛇(通过传入painter)。
  • Food类:创建方法来实现食物的坐标生成和类型生成(利用随机数)、在窗口中绘制食物。用type整型变量来标志食物类型,当type=1时蛇吃掉后加1节,当type=2时蛇吃掉后加2节,以此类推。
  • Widget类:创建方法来实现整体的按键检测绘制图像计算玩家分数。为了让蛇不断移动,使用定时器(QTimer)来周期性触发槽函数,在槽函数中执行蛇吃食物、食物更新、画面更新等操作。
  • 按键控制:①↑↓←→键盘控制蛇的移动;②空格键控制游戏的开始/暂停(控制定时器开始/停止)。
  • 综合不同类的绘图:将主要逻辑的Widget类中实例化的painter对象作为形参传入Snake和Food类中,在它们各自的方法中进行各自的绘图操作。

【2】针对重新开始:

  • 在ui设计器中添加QPushButton,并添加相应的槽函数。
  • 槽函数中将分数、暂停标志、时间计数器等属性恢复初始值。
  • 槽函数中将已有的蛇、食物对象delete,再创建新的蛇、食物对象。
  • 槽函数中需要重新聚焦于gameWidget,否则点击按钮后需要再点击gameWidget才能检测键盘的输入。重新聚焦调用"ui->gameWidget->setFocus();"

【3】针对不同速度:

  • 在Snake类中创建属性speed,当speed为1时表示每次触发定时器槽函数执行蛇前进1格,当speed为2时表示每次触发定时器槽函数执行蛇前进2格。
  • 初始化speed为1,当用户手动按下两下↑后会加速,直到用户改变蛇的方向

【4】针对不同食物:

  • 在Food类中创建属性type,当type为1时表示食物类型为1(蛇吃后增加1节),当type为2时表示食物类型为2(蛇吃后增加2节),当type为3时表示食物类型为3(蛇吃后增加3节)。
  • 类型1设定为绿色的圆形
  • 类型2设定为深蓝色的椭圆
  • 类型3设定为浅蓝色的方形

三、实现效果


四、代码

【1】food.h:

#ifndef FOOD_H
#define FOOD_H#include <QWidget>
#include <QPainter>
#include <QRandomGenerator>/************************************************************ @类名:	Food* @摘要:	食物类* @作者:	柯同学* @注意:	三种食物类型:type值为几就加几节蛇身*********************************************************/
class Food : public QWidget
{Q_OBJECT
public:explicit Food(QWidget *parent = nullptr);int getX();         //返回食物横坐标int getY();         //返回食物纵坐标int getRadius();    //返回食物半径int getType();      //返回食物类型void generateFood();//生成食物的坐标和类型void paintFood(QPainter &painter);//绘制食物private:int foodX;  //食物横坐标int foodY;  //食物纵坐标int radius; //食物半径int type;   //食物类型:1类型为增加1节,2类型增加2节,3类型增加3节
};#endif // FOOD_H

【2】food.cpp:

#include "food.h"/************************************************************ @函数名:Food* @功  能:食物类的构造函数* @参  数:parent父对象* @返回值:无*********************************************************/
Food::Food(QWidget *parent): QWidget(parent), radius(15)
{//初始的食物也随机generateFood();
}/************************************************************ @函数名:getX* @功  能:返回食物的横坐标* @参  数:无* @返回值:食物的横坐标*********************************************************/
int Food::getX()
{return foodX;
}/************************************************************ @函数名:getY* @功  能:返回食物的纵坐标* @参  数:无* @返回值:食物的纵坐标*********************************************************/
int Food::getY()
{return foodY;
}/************************************************************ @函数名:getRadius* @功  能:返回食物的半径* @参  数:无* @返回值:食物的半径*********************************************************/
int Food::getRadius()
{return radius;
}/************************************************************ @函数名:getType* @功  能:返回食物的类型* @参  数:无* @返回值:食物的类型*********************************************************/
int Food::getType()
{return type;
}/************************************************************ @函数名:generateFood* @功  能:随机生成食物的坐标、类型* @参  数:无* @返回值:无*********************************************************/
void Food::generateFood()
{//随机生成坐标,距边界radius降低反应难度foodX = QRandomGenerator::global()->bounded(10 + radius, 580 - radius * 2);foodY = QRandomGenerator::global()->bounded(20 + radius, 570 - radius * 2);//随机生成类型[1,4)type = QRandomGenerator::global()->bounded(1, 4);
}/************************************************************ @函数名:paintFood* @功  能:根据食物类型的不同,绘制不同的食物类型。* @参  数:painter---画家对象* @返回值:无* @说  明:type=1---类型1:绿色的圆形*         type=2---类型2:深蓝色的椭圆形*         type=3---类型3:淡蓝色的矩形*********************************************************/
void Food::paintFood(QPainter &painter)
{QPen pen;QBrush brush;//根据type不同,绘制不同的食物switch (this->type){case 1:pen.setColor(QColor(43, 220, 112));brush.setColor(QColor(43, 220, 112));brush.setStyle(Qt::SolidPattern);painter.setPen(pen);painter.setBrush(brush);painter.drawEllipse(QRect(foodX, foodY, radius, radius));break;case 2:pen.setColor(QColor(0, 62, 146));brush.setColor(QColor(0, 62, 146));brush.setStyle(Qt::SolidPattern);painter.setPen(pen);painter.setBrush(brush);painter.drawEllipse(QRect(foodX, foodY, radius*2, radius));break;case 3:pen.setColor(QColor(29, 130, 154));brush.setColor(QColor(29, 130, 154));brush.setStyle(Qt::SolidPattern);painter.setPen(pen);painter.setBrush(brush);painter.drawRect(QRect(foodX, foodY, radius, radius));break;}
}

【3】snake.h:

#ifndef SNAKE_H
#define SNAKE_H#include <QWidget>
#include <QEvent>
#include <QPaintEvent>
#include <QPainter>//枚举蛇前进的方向
enum Direct{MOVE_UP,MOVE_DOWN,MOVE_LEFT,MOVE_RIGHT
};/************************************************************ @类名:	Snake* @摘要:	蛇类* @作者:	柯同学* @注意:	有两种速度:speed为1就每次timeout前进1格,以此类推。*         在原有方向的基础上,再次按原方向键能切换到二倍速模式,*         比如蛇在往上,再次按up键就两倍速,直到切换方向。*********************************************************/
class Snake : public QWidget
{Q_OBJECT
public:explicit Snake(QWidget *parent = nullptr);void paintSnake(QPainter &painter); //绘制蛇身void keyPress(QKeyEvent *event);    //键盘控制移动方向void autoMove();        //沿着方向自动移动void frontAddBody();     //根据方向增加首节点QRect getSnakeHead();   //获取蛇的首节点信息int getLength();        //返回蛇身节点个数bool isOver();          //返回蛇是否死亡,死亡为trueprivate:QList<QRect> body;  //蛇身int nodeWidth;      //节点宽度int nodeHeight;     //节点高度int moveDirect;     //移动方向int speed;          //移动速度:1表示默认速度,2表示两倍速度
};#endif // SNAKE_H

【4】snake.cpp:

#include "snake.h"/************************************************************ @函数名:Snake* @功  能:蛇的构造函数* @参  数:parent---父对象* @返回值:无* @说  明:初始化三节蛇身*********************************************************/
Snake::Snake(QWidget *parent): QWidget(parent), nodeWidth(20), nodeHeight(20), moveDirect(MOVE_LEFT), speed(1)
{//初始给定三节蛇身body.append(QRect(400, 300, nodeWidth, nodeHeight));body.append(QRect(400 + nodeWidth, 300, nodeWidth, nodeHeight));body.append(QRect(400 + nodeWidth * 2, 300, nodeWidth, nodeHeight));
}/************************************************************ @函数名:getLength* @功  能:获取蛇身的长度,即有几个节点* @参  数:无* @返回值:蛇身的长度*********************************************************/
int Snake::getLength()
{return body.length();
}/************************************************************ @函数名:isOver* @功  能:判定蛇是否碰墙死亡* @参  数:无* @返回值:true---蛇死亡,false---蛇没有死亡*********************************************************/
bool Snake::isOver()
{if (body[0].y() <= 20 || body[0].y() + nodeHeight >= 570 ||body[0].x() <= 10 || body[0].x() + nodeWidth >= 580) {return true;}return false;
}/************************************************************ @函数名:keyPress* @功  能:按键检测,控制蛇的前进方向* @参  数:event---按键的事件* @返回值:无* @说  明:在原有方向的基础上,再次按原方向键能切换到二倍速模式*********************************************************/
void Snake::keyPress(QKeyEvent *event)
{switch(event->key()) {case Qt::Key_Up://蛇往上if (MOVE_UP == moveDirect){speed = 2;}else if (moveDirect != MOVE_DOWN){moveDirect = MOVE_UP;speed = 1;}break;case Qt::Key_Down://蛇往下if (MOVE_DOWN == moveDirect){speed = 2;}else if (moveDirect != MOVE_UP){moveDirect = MOVE_DOWN;speed = 1;}break;case Qt::Key_Left://蛇往左if (MOVE_LEFT == moveDirect){speed = 2;}else if (moveDirect != MOVE_RIGHT){moveDirect = MOVE_LEFT;speed = 1;}break;case Qt::Key_Right://蛇往右if (MOVE_RIGHT == moveDirect){speed = 2;}else if (moveDirect != MOVE_LEFT){moveDirect = MOVE_RIGHT;speed = 1;}break;default:break;}
}/************************************************************ @函数名:autoMove* @功  能:根据speed属性,让蛇前进1格或2格* @参  数:无* @返回值:无* @说  明:蛇的前进做法:每次头插一个节点,删除最后的一个节点*********************************************************/
void Snake::autoMove()
{if (1 == speed){frontAddBody();body.removeLast();}else if (2 == speed){frontAddBody();frontAddBody();body.removeLast();body.removeLast();}
}/************************************************************ @函数名:frontAddBody* @功  能:根据前进方向,头插不同位置的节点* @参  数:无* @返回值:无* @说  明:由于碰壁就死亡了,无需越界判定*********************************************************/
void Snake::frontAddBody()
{switch (moveDirect){case MOVE_UP:body.insert(0, QRect(body[0].x(), body[0].y() - nodeHeight, nodeWidth, nodeHeight));break;case MOVE_DOWN:body.insert(0, QRect(body[0].x(), body[0].y() + nodeHeight, nodeWidth, nodeHeight));break;case MOVE_LEFT:body.insert(0, QRect(body[0].x() - nodeWidth, body[0].y(), nodeWidth, nodeHeight));break;case MOVE_RIGHT:body.insert(0, QRect(body[0].x() + nodeWidth, body[0].y(), nodeWidth, nodeHeight));break;}
}/************************************************************ @函数名:getSnakeHead* @功  能:返回首节点的拷贝,以防外界修改。* @参  数:无* @返回值:无*********************************************************/
QRect Snake::getSnakeHead()
{return body[0];
}/************************************************************ @函数名:paintSnake* @功  能:绘制蛇身,遍历QList* @参  数:painter---画家对象* @返回值:无*********************************************************/
void Snake::paintSnake(QPainter &painter)
{//设置painterQPen pen(QColor(64, 65, 66));QBrush brush(QColor(183, 1, 1));painter.setPen(pen);painter.setBrush(brush);//绘制蛇身for (int i = 0; i < body.length(); ++i) {painter.drawRect(body[i]);}
}

【5】widget.h:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "snake.h"
#include "food.h"
#include <QPainter>
#include <QTimer>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE/************************************************************ @类名:	Widget* @摘要:	主要界面类* @作者:	柯同学* @注意:	在该类中进行蛇吃食物、游戏结束等逻辑的实现*********************************************************/
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void paintEvent(QPaintEvent *event) override;   //绘图void keyPressEvent(QKeyEvent *event) override;  //按键检测void snakeEatFood();    //蛇吃食物,更新食物void computeScore();    //计算玩家分数private slots:void timeOut();         //定时器触发的槽函数void on_pushButton_clicked();//"重新开始"按钮的槽函数private:Ui::Widget *ui;Snake *snake;   //蛇Food *food;     //食物QTimer *timer;  //定时器,固定100ms触发bool isPause;   //开始或暂停的标志,true为暂停int timerCount; //定时器触发次数double score;   //玩家分数
};
#endif // WIDGET_H

【6】widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>/************************************************************ @函数名:Widget* @功  能:主要窗口的构造函数* @参  数:parent---父对象* @返回值:无*********************************************************/
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), isPause(true), timerCount(0), score(0)
{ui->setupUi(this);//实例化蛇snake = new Snake(ui->gameWidget);//实例化食物food = new Food(ui->gameWidget);//设置定时器timer = new QTimer(this);connect(timer, SIGNAL(timeout()), this, SLOT(timeOut()));//设置聚焦对象ui->gameWidget->setFocus();
}/************************************************************ @函数名:~Widget* @功  能:主要窗口的析构函数* @参  数:无* @返回值:无* @说  明:由于QT的对象树机制,绑定好父对象后无需手动delete其他空间*********************************************************/
Widget::~Widget()
{delete ui;
}/************************************************************ @函数名:~Widget* @功  能:主要窗口的析构函数* @参  数:无* @返回值:无*********************************************************/
void Widget::paintEvent(QPaintEvent *event)
{Q_UNUSED(event)QPainter painter(this);//判定游戏是否结束,结束则显示提示if (snake->isOver()) {//蛇死亡,游戏结束timer->stop();isPause = true;QFont font("宋体", 30, QFont::ExtraBold,false);painter.setFont(font);QRect showArea(200, 250, 200, 100);painter.drawText(showArea, Qt::AlignHCenter | Qt::AlignVCenter, "游戏结束!");}//绘制蛇和食物snake->paintSnake(painter);food->paintFood(painter);//实时显示玩家分数ui->scoreLabel->setText("分数: " + QString::number(score));
}/************************************************************ @函数名:keyPressEvent* @功  能:重写的按键检测事件函数* @参  数:event---按键事件* @返回值:无* @说  明:以防游戏结束后还能控制,首先需要判定游戏是否结束*********************************************************/
void Widget::keyPressEvent(QKeyEvent *event)
{//游戏未结束才进行按键控制if (!(snake->isOver())) {//按键控制蛇移动snake->keyPress(event);//按键控制暂停if (event->key() == Qt::Key_Space) {if (isPause){isPause = false;timer->start(100);}else {isPause = true;timer->stop();}}}
}/************************************************************ @函数名:snakeEatFood* @功  能:蛇与食物接触,则给蛇加节点,给食物重新生成坐标和类型* @参  数:无* @返回值:无* @说  明:生成食物必须放在蛇加节点之后*********************************************************/
void Widget::snakeEatFood()
{//蛇与食物接触if (abs(snake->getSnakeHead().x() - food->getX()) <= food->getRadius() &&abs(snake->getSnakeHead().y() - food->getY()) <= food->getRadius()){//蛇吃不同类型食物加不同节int count = food->getType();while (count--){snake->frontAddBody();}//再次生成食物food->generateFood();}
}/************************************************************ @函数名:computeScore* @功  能:计算玩家分数* @参  数:无* @返回值:无* @说  明:分数由两部分构成:时间分数、长度分数。*         每坚持1秒,分数增加1分。*         每多一节身体,分数增加10分。*********************************************************/
void Widget::computeScore()
{double timeScore = (timerCount / 10.0) * 1;     //时间的分数,每秒1分int lenScore = (snake->getLength() - 3) * 10;   //长度的分数,增一节10分if (lenScore >= 0)this->score = timeScore + lenScore;
}/************************************************************ @函数名:timeOut* @功  能:定时器的槽函数* @参  数:无* @返回值:无*********************************************************/
void Widget::timeOut()
{//蛇自动移动,吃食物snake->autoMove();snakeEatFood();//计算玩家分数timerCount++;computeScore();//更新界面this->update();
}/****************************************************************** @函数名:on_pushButton_clicked* @功  能:"重新开始"按钮的槽函数* @参  数:无* @返回值:无* @说  明:需要重新聚焦于gameWidget,否则点击按钮后需要再点击gameWidget***************************************************************/
void Widget::on_pushButton_clicked()
{//清除相关属性timerCount = 0; //定时器计数清零score = 0;      //分数清零isPause = true; //恢复暂停//删除已有成员对象if (snake) {delete snake;}if (food) {delete food;}//创建新对象snake = new Snake(ui->gameWidget);food = new Food(ui->gameWidget);//更新界面this->update();ui->gameWidget->setFocus();//重新聚焦于游戏窗口
}

【7】main.cpp: 系统自动生成的,没有改动。

#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

相关文章:

【QT5】<应用> 小游戏:贪吃蛇

文章目录 一、项目要求 二、需求分析 三、实现效果 四、代码 一、项目要求 【1】主要实现&#xff1a;游戏界面存在一条蛇&#x1f40d;&#xff0c;使用键盘wsad或者↑↓←→键盘可以控制蛇的行走方向。同时界面中会随机出现食物&#xff0c;蛇可以吃食物&#xff0c;然后…...

【Webpack】使用 Webpack 构建 Vue3+TS 项目

构建项目目录 tsc --init npm init -yshim.d.ts 文件是一个类型声明文件&#xff0c;用于告诉 TypeScript 编译器如何处理 Vue 的单文件组件&#xff08;SFC&#xff09;和其他自定义模块。为 Vue 的单文件组件和其他非 TypeScript 模块提供类型信息&#xff0c;以便在 TypeScr…...

数据防泄漏的六个步骤|数据防泄漏软件有哪些

在当前复杂多变的网络安全环境下&#xff0c;数据防泄漏软件成为了企业信息安全架构中不可或缺的一环。下面以安企神软件为例&#xff0c;告诉你怎么防止数据泄露&#xff0c;以及好用的防泄露软件。 1. 安企神软件 安企神软件是当前市场上备受推崇的企业级数据防泄漏解决方案…...

SpringCloud 网关Gateway配置并使用

目录 1 什么是网关&#xff1f; 2 Gateway的使用 2.1 在其pom文件中引入依赖 2.2 然后gateway配置文件中配置信息 2.3 启动网关微服务 3 网关处理流程 4 前端-网关-微服务-微服务间实现信息共享传递 1 什么是网关&#xff1f; 网关&#xff1a;就是网络的关口&#xff…...

MySQl基础----Linux下搭建mysql软件及登录和基本使用(附实操图超简单一看就会)

绪论​ 涓滴之水可磨损大石&#xff0c;不是由于他力量强大&#xff0c;而是由于昼夜不舍地滴坠。 只有勤奋不懈地努力&#xff0c;才能够获得那些技巧。 ——贝多芬。新开MySQL篇章&#xff0c;本章非常基础包括如何在Linux上搭建&#xff08;当然上面的SQL语句你在其他能执行…...

PostgreSQL17优化器改进(4)允许UNION(没有ALL)使用MergeAppend

PostgreSQL17优化器改进(4)允许UNION(没有ALL)使用MergeAppend UNION存在的问题 到PostgreSQL16.3版本为止&#xff0c;UNION执行计划通常不是最优的&#xff0c;优化器有两种处理方法&#xff1a; 优化器只考虑使用Append节点并通过使用Hash Aggregate&#xff0c;Append -…...

SSM 基于大数据技术的创业推荐系统-计算机毕业设计源码02979

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…...

基于WPF技术的换热站智能监控系统03--实现左侧加载动画

1、左侧布局规划 左侧分5行&#xff0c;每行的高度通过height属性来指定&#xff0c;1.2*表示占1.2倍的宽度 2、创建用户控件 在WPF中想要进行个性化处理&#xff0c;主要可以通过三个方面来实现&#xff1a;控件模板&#xff08;控件模板、数据模板、数据容器模板&#xff09…...

4D毫米波雷达技术及发展

文章目录 前言一、4D毫米波雷达是什么&#xff1f;二、毫米波雷达是什么&#xff1f;毫米波雷达的基本原理多普勒效应 前言 现阶段自动驾驶技术中&#xff0c;主要用到的传感器有摄像头、激光雷达和毫米波雷达。 摄像头的光谱从可见光到红外光谱&#xff0c;是最接近人眼的传感…...

请解释Java Web应用的开发流程,包括前后端分离和交互方式。请解释Java中的锁分离技术,并讨论其在提高并发性能方面的作用。

请解释Java Web应用的开发流程&#xff0c;包括前后端分离和交互方式。 Java Web应用的开发流程是一个涵盖多个阶段的过程&#xff0c;这些阶段从需求分析开始&#xff0c;经过设计、编码、测试&#xff0c;最终到部署和维护。在这个过程中&#xff0c;前后端分离成为现代Web应…...

selenium使用已经打开的浏览器

Selenium 本身不支持直接连接到一个已经打开的浏览器页面。Selenium 启动的浏览器实例是一个全新的会话&#xff0c;它与手动打开的浏览器页面是分开的。但是&#xff0c;有一些变通的方法可以实现类似的效果。 一种方法是通过附加代理连接到已经打开的浏览器。下面是如何实现…...

Redis: 深入解析高性能内存数据库的实现原理

一、Redis简介 Redis是一种基于内存的键值存储数据库&#xff0c;支持丰富的数据类型&#xff0c;如字符串、列表、集合、有序集合和哈希表。它不仅具有极高的性能&#xff0c;还支持数据持久化、主从复制和分布式架构&#xff0c;使其在各种应用场景中表现出色。 1.1 Redis的…...

使用 Python进行自动备份文件

文件备份对数据保护至关重要&#xff0c;让我们使用 shutil 模块创建一个简单的备份脚本 这段代码的作用就是将指定源目录中的所有文件备份到目标备份目录中&#xff0c;并在备份目录中创建带有时间戳的子目录&#xff0c;通过定期运行这段代码&#xff0c;可以实现自动备份文…...

02_01_SpringMVC初识

一、回顾MVC三层架构 1、什么是MVC三层 MVC是 模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;、控制器&#xff08;Controller&#xff09;的简写&#xff0c;是一种软件设计规范。主要作用是降低视图与业务逻辑之间的双向耦合&#xff0c;它不是一种…...

Python学习打卡:day04

day4 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day428、while 循环的嵌套应用29、while 循环案例 — 九九乘法表补充知识示例&#xff1a;九九乘法表 30、for 循环基本语法while 和 for 循环对比f…...

gitlab问题记录

You wont be able to pull or push project code via SSH until you add an SSH key to you 解决方案&#xff1a;https://blog.csdn.net/gufenchen/article/details/95663284...

OpenCV练习(1)签名修复

1.目的 在学校的学习过程中&#xff0c;需要递交许多材料&#xff0c;且每份材料上都需要对应负责人签名&#xff0c;有时候找别人要签名&#xff0c;然后自己粘贴的话&#xff0c;会出现签名模糊&#xff0c;背景不是纯白透明。为此以word中的“颜色校正”功能为参照&#xf…...

软设之系统测试之测试的基本概念及分类

测试的基本概念 尽早&#xff0c;不断地进行测试 程序员避免测试自己设计的程序 既要选择有效&#xff0c;合理的数据&#xff0c;也要选择无效&#xff0c;不合理的数据 修改后应进行回归测试 尚未发现的错误数量与该程序已发现错误其他成正比。 动态测试 黑盒测试(测试…...

Python学习打卡:day06

day6 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day648、函数综合案例49、数据容器入门50、列表的定义语法51、列表的下标索引1、列表的下标&#xff08;索引&#xff09;2、列表的下标&#xff08…...

支付宝 沙盒demo使用

简介&#xff1a;支付宝沙箱环境是一个为开发者提供的模拟测试环境&#xff0c;用于在应用上线前进行接口功能开发和联调。在这个环境中&#xff0c;开发者可以模拟开放接口&#xff0c;进行开发调试工作&#xff0c;以确保应用上线后能顺利运行。 1. 配置沙盒 1. 1 沙箱控制…...

别再手动写Prompt了!Lovable原生AI编排引擎深度解析(附12个已验证行业工作流)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Lovable无代码AI应用构建指南 Lovable 是一款面向业务人员与开发者的低门槛 AI 应用构建平台&#xff0c;它通过可视化编排、预置模型组件和自然语言驱动逻辑&#xff0c;实现无需编写代码即可部署可运…...

从AWE Designer到独立声卡:awb二进制文件固化Flash的实战解析

1. 从AWE Designer到独立声卡的核心逻辑 第一次接触AWE Designer的朋友可能会疑惑&#xff1a;为什么要把算法从PC端搬到开发板&#xff1f;简单来说&#xff0c;这就好比把厨师做好的预制菜打包成罐头——让美味脱离厨房环境也能随时享用。AWE Designer原本需要依赖电脑实时运…...

从虚拟到物理:电子系统原型设计的工程化策略与实战解析

1. 原型设计全景&#xff1a;从概念到实物的工程化思维 在电子系统设计领域&#xff0c;尤其是面对航空航天、汽车电子、通信设备这类高复杂、高可靠性要求的项目时&#xff0c;“原型”这个词的分量远超一个简单的模型。它不是一个可有可无的步骤&#xff0c;而是连接创意与产…...

OpenClaw-Readwise:自动化同步阅读笔记到Obsidian的实践指南

1. 项目概述&#xff1a;一个连接阅读与笔记的自动化桥梁 如果你和我一样&#xff0c;是个重度阅读爱好者&#xff0c;同时又在使用 Readwise 和 Obsidian 这类工具来管理自己的知识库&#xff0c;那你一定遇到过这个痛点&#xff1a;在 Readwise 里高亮、标注的精彩内容&…...

LT8650S双通道同步降压稳压器设计与汽车电子应用

1. LT8650S双通道同步降压稳压器设计解析在汽车电子和工业设备领域&#xff0c;电源管理系统的设计往往面临严苛挑战。LT8650S作为一款42V输入、双通道4A输出的同步降压稳压器&#xff0c;其Silent Switcher 2架构和6.2μA超低静态电流特性&#xff0c;为工程师提供了高性价比的…...

Tome:基于MCP协议的无代码AI桌面助手,轻松连接本地与云端模型

1. 项目概述&#xff1a;Tome&#xff0c;一个为普通人打造的魔法AI桌面应用 如果你对大型语言模型&#xff08;LLM&#xff09;和AI助手感兴趣&#xff0c;但又觉得那些命令行工具、复杂的API配置和JSON文件让人望而却步&#xff0c;那么Tome的出现&#xff0c;可能就是为你准…...

LLM Workflow Engine:命令行AI工作流引擎的架构与实战

1. 项目概述&#xff1a;从命令行到工作流&#xff0c;一个LLM引擎的进化如果你和我一样&#xff0c;是个重度命令行用户&#xff0c;同时又对大型语言模型&#xff08;LLM&#xff09;的潜力着迷&#xff0c;那你肯定经历过这种纠结&#xff1a;想快速用GPT-4验证一个想法&…...

Quality Guardian MCP:为AI编程助手设计的实时代码质量聚合与基线管理工具

1. 项目概述&#xff1a;为AI编程助手打造的代码质量守门员如果你和我一样&#xff0c;日常重度依赖 Claude Code、Cursor 这类 AI 编程助手来写代码&#xff0c;那你肯定也遇到过这个头疼的问题&#xff1a;AI 助手确实能快速生成代码&#xff0c;但它对项目里已有的“技术债”…...

repo2txt:Git仓库转纯文本工具,为AI分析、代码归档与审查提供完整上下文

1. 项目概述&#xff1a;从代码仓库到纯文本的自动化提取最近在整理个人技术笔记和项目文档时&#xff0c;我遇到了一个挺普遍但有点烦人的问题&#xff1a;如何把一个完整的Git代码仓库&#xff0c;包括它的目录结构、所有源代码文件以及提交历史&#xff0c;以一种清晰、可读…...

最火 AI 生图模型 Nano Banana Pro 国内免费使用指南

最近在设计圈和 AI 圈&#xff0c;几乎无人不知 Nano Banana Pro。它是谷歌基于 Gemini 3 Pro 打造的最新图像模型&#xff0c;一上线就斩获 LMArena 生图和图像编辑榜单第一名。虽然 Nano Banana 2 的历史成绩更亮眼&#xff0c;但实测体验发现 Pro 版更好用、操作更顺手。 为…...