当前位置: 首页 > 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 沙箱控制…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...