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

[C/C++]天天酷跑游戏超详细教程-上篇

  •  个人主页:北·海
  •  🎐CSDN新晋作者
  •  🎉欢迎 👍点赞✍评论⭐收藏
  • ✨收录专栏:C/C++
  • 🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!🤗

天天酷跑,一款童年游戏,主要是进行跳跃操作,和躲避障碍物,该结主要实现背景图的连续播放,跳跃,与障碍物创建 


一.游戏的展示效果


 二.本节开发日志

   1.创建项目
    2.导入素材
    3.创建游戏界面
        实际的开发流程
         对于初学者,最好的开发方式,从用户界面入手

      选择图形库或者其他引擎
      天天酷跑,是基于easyx图形库的
      1)创建游戏窗口
      2)实现游戏背景
        a.3重背景不同的速度同时移动
        b.循环滚动背景的实现
      3)实现游戏背景
        a.加载背景资源
        b.渲染 (背景知识 : 坐标)
        遇到问题 : 背景图片的png格式图片出现黑色 使用putimagePNG2接口

        4)创建人物

        5)创建障碍物小乌龟

三.素材

在主页有放置

四.游戏实现

    1)创建C++项目将素材导入项目

#include <iostream>using namespace std;int main(){return 0;
}

 2)游戏初始化

对于新手而言,建议拿到游戏的时候,从游戏的背景图进行入手,由于在游戏边玩边从磁盘加载资源,这样会影响游戏的体验,这也就是为什么王者荣耀进去时候要加载的原因,都是在开始游戏之前先把资源加载到项目里面,我们就可以在游戏开始之前进行创建一个用于初始化的函数,用于专门加载这些资源

需要用到的头文件 : graphics.h,这个需要安装easyx图形库,可在该官网进行下载安装

需要用到的函数    :   loadimage用于将资源从磁盘加载进来

                                 putimagePNG2,自定义的接口用于解决png图片出现黑边,和将加载的图片渲染到屏幕上,在主页文章有介绍该接口

                                  initgraph : 用于创建游戏窗口

                                   sprintf函数,可以对字符串进行格式化,改每个图片的路径

IMAGE: 用于存放图片资源

  

 1.实现游戏窗口的创建与游戏背景的加载

#include <iostream>
#include <graphics.h>//窗口的大小,一般在开发中由项目经理规定,定义为宏不仅可以增强代码的可读性还可以增强代码的健壮性
#define WIN_WIDTH 1012
#define WIN_HEIGHT 396  
using namespace std;IMAGE imgBg[3];void init(){//创建游戏窗口initgraph(WIN_WIDTH, WIN_HEIGHT);//加载游戏背景char name[64];for (int i = 0; i < 3; i++) {//"res/bg001.png  res/bg002.pngsprintf_s(name, "res/bg%03d.png", i + 1);loadimage(&imgBgs[i], name);}}int main(){init();//用于初始化return 0;
}

 2.渲染游戏背景图,可以创建一个专门渲染图片的函数updataBg()

这边不太会搞视频展示图,所以就简单描述一下,背景图往左连绵不断的走,有三层,草坪,山,天空,既然能连绵不断,这个实现的方法拿图来解释

由于由三层,每层的y坐标都是不同的,y坐标可以测量出来,由于背景需要滚动,原理是移动当前背景图,使其向左移动,当图片的最右边达到游戏窗口的最左边时候,重新复原图片的位置,使图片的最左边到达窗口的最左边,进行循环,循环的时候,三层图片以不同的速度进行移动,所以创建一个数组bgSpeed,用于存放三个图片的速度,bgX数组用于存放当前的x值,由于游戏是个死循环,所以除了初始化,其余函数套在while(1)循环里

int bgSpeed[3] = {1,2,4};
int bgX[3];//背景图片的x坐标//渲染游戏背景
void updateBg() {putimagePNG2(bgX[0], 0, WIN_WIDTH,&imgBgs[0]);putimagePNG2(bgX[1], 119,WIN_WIDTH, &imgBgs[1]);putimagePNG2 (bgX[2], 330, WIN_WIDTH,&imgBgs[2]);}void init(){//for循环里,添加bgX[i] = 0 ;给变量进行初始化}
int main(){'''
init();while(1){
updateBg();
}
...
}

 3.由于上面渲染的渲染背景图还是静态的,没有移动,因为bgx并没有改变,此时需要一个专门改变游戏数据的函数,fly函数吧

void fly(){for(int i =  0 ;i<3;i++){bgX[i] -=bgSpeed[i];//使每层图片减去他对应的速度//做一个判断,当达到最左边时候,复位图片的位置if(bgX[i] <=-WIN_WIDTH){
bgX[i] = 0;}}
}

4.此时的背景图已经开始滚动了,但是还有个小bug,因为这个渲染时用循环putimage上去的,就相当于将图片打印到上面,这也会出现的情况是每层图片之间会一闪一闪的,解决这个问题的方法,是先将他们输出到缓存区,一并打印出来,用到的函数如下:

BeginBatchDraw()

EndBatchDraw();

 此时就解决了背景的第一个问题

背景图实现,程序的进度:

#include <iostream>
#include<graphics.h>
#include "tools.h"#define WIN_WIDTH 1012
#define WIN_HEIGHT 396using namespace std;/*
1.先做背景
*/IMAGE imgBgs[3];
int bgSpeed[3] = { 1,2,4 };
int bgX[3];void init() {//创建游戏窗口initgraph(WIN_WIDTH, WIN_HEIGHT);//加载背景图char name[64];for (int i = 0; i < 3; i++) {//"res/bg001.png  res/bg002.pngsprintf_s(name, "res/bg%03d.png", i + 1);loadimage(&imgBgs[i], name);bgX[i] = 0;}}void updataBg() {putimagePNG2(bgX[0], 0,WIN_WIDTH, &imgBgs[0]);putimagePNG2(bgX[1], 119,WIN_WIDTH, &imgBgs[1]);putimagePNG2(bgX[2], 330,WIN_WIDTH, &imgBgs[2]);
}void fly() {//背景图for (int i = 0; i < 3; i++) {bgX[i] -= bgSpeed[i];if (bgX[i] < -WIN_WIDTH) {bgX[i] = 0;}}
}
int main() {init();while (1) {BeginBatchDraw();updataBg();EndBatchDraw();fly();}system("pause");return 0;
}


3)创建玩家

1.由于图片在动,只需要将人物在原地就行,将人物放在最中间,由于要实现人物的运动,这个的原理是将人物的多组图片进行轮播,人物的x,y坐标可以通过数学进行算出来,此时我们先在初始化函数里加载图片,在初始化函数里计算出人物的x,y坐标,由于人物的轮播,可以传创建一个帧序列

//人物的背景图
IMAGE imgHero[12];
int heroX;
int heroY;
int heroIndex;//帧序号void init(){...
//加载人物的图片,仍然老套路,用到sprintf函数for (int i = 0; i < 12; i++) {sprintf(name, "res/hero%d.png", i + 1);loadimage(&imgHero[i], name);}//人物初始化heroX = WIN_WIDTH * 0.5 - imgHero[0].getwidth() * 0.5;heroY = 345 - imgHero[0].getheight();heroIndex = 0;}

由于帧序列要改变才能实现轮播,所以需要在数据层的fly函数,进行修改帧序列

void fly(){....//修改帧序列,
/*heroIndex++;//如果使用这种方法的话,当进行越界,我们需要的是从1-12进行循环,所以我们用取余数进行实现
*/heroIndex = (heroIndex+1)%12;}

数据也可也可以改变了,我们需要将人物的图片渲染在窗口中,在main函数中只需要一条代码

int main(){...//实现人物的奔跑
putimagePNG2(heroX, heroY, WIN_WIDTH , &imgHero[heroIndex]);
...
}

效果图

这样人物就可以原地跑起来了,解决了第二个问题

4)实现玩家的跳跃

1.人物的跳跃是当玩家按下按键后,人物的y坐标开始上升,当达到某个高度后,然后下落

先来实现用户点击函数keyEvent(),由于只需要改变y坐标,底层的数据变化实在fly函数里面,我们只需要获取到用户的点击之后,给个可以改变y值得信号即可

用到的_kbhit()函数和_getch()函数都必须包含头文件conio.h

问题 : 都是从键盘获取一个字符为什么不用scanf()而用_getch()

答:如果使用scanf函数, 当输入数据,必须按回车,才能将数据输入进去,此时不按回车的话,程序会等待用户按回车键,此时的程序就卡在这里等待了,而用_hbhit()函数,不用等待,直接按下就可以输入进去

void keyEvent(){//先接收用户得鼠标消息char ch =  0 ;if(_kbhit()){ch = _getch();if(ch ===' '){jump();}}
}

实现初始化顺便打开可跳跃得按钮 

//全局变量
bool heroJump;//跳跃状态
int jumpHeightMax;//跳跃得最大高度
int heroJumpOff;//跳跃得偏移量void init(){...
//对跳跃得数据进行初始化//跳跃初始化heroJump = false;jumpHeightMax = 345 - imgHero[0].getheight() - 120;heroJumpOff = -4;}void jump(){heroJump = true;}

在fly函数里改变底层数据

void fly() {...//实现跳跃if (heroJump) {if (heroY < jumpHeightMax) {heroJumpOff = 4;//+ (-4)等于向上走,+4等于向下走}heroY += heroJumpOff;if (heroY > 345 - imgHero[0].getheight()) {//达到地面heroJump = false;heroJumpOff = -4;}}
}

 此时的英雄就可以进行跳跃了

这样人物就可以跳跃起来了,就能跳跃障碍物了,解决了第三个问题,此时还面临一个小bug,就是在当跳跃的途中,这个人物还处于一个跑步的状态,影响了用户体验,解决这个问题,我们就可以在改变底层数据里改部分代码,如果处于起跳状态则不更新帧序列,否则不跳的时候更新帧序列,以下是改变之后的渲染代码:

//人物跳跃if (heroJump) {if (heroY < jumpHeightMax) {heroJumpOff = 4;}heroY += heroJumpOff;if (heroY > 345 - imgHero[0].getheight()) {heroJump = false;heroJumpOff = -4;}}else {//heroIndex++ 这种方式会越界heroIndex = (heroIndex + 1) % 12;}

这样就解决了这个小bug,以上实现了背景图的轮播,人物的动态化,和人物的起跳,主要学到了,将渲染层,数据层分开,其他小的功能进行分支化,将main函数写的简介,实现功能模块化,接下来就可以实现障碍物了

5)障碍物小乌龟的实现

1.障碍物有许多种,先实现一种,其他的在做优化,依旧是老套路,初始化里面加载资源,渲染层进行打印图片,fly里面改变数据

2.先将小乌龟设置为静态的,优化时候也可加个帧序列实现动态的

定义小乌龟的变量

//全局状态
//小乌龟
IMAGE imgTortoise;
//小乌龟存在开关
bool torToiseExist;
int torToiseX;
int torToiseY;

 将小乌龟进行初始化

//初始化小乌龟
void init(){...//小乌龟初始化loadimage(&imgTortoise, "res/t1.png");torToiseY = 345 + 5 - imgTortoise.getheight();torToiseExist = false;}

从底层数据方面对小乌龟进行创建与使其移动

编程技巧:在创建小乌龟时候,如果直接写

void fly(){
...//创建小乌龟static int frameCount = 0;static int enemyFre = 100;frameCount++;if (frameCount > enemyFre) {frameCount = 0;enemyFre = 100+ rand() % 50;//创建障碍物if (!torToiseExist) {torToiseExist = true;torToiseX = WIN_WIDTH;}}//使小乌龟的运动,运动应该于草坪的移动速度保持一致,才能显得静止在草坪上if (torToiseExist) {torToiseX -= bgSpeed[2];if (torToiseX < -imgTortoise.getwidth()) {torToiseExist = false;}}}

将小乌龟渲染出来

void updateEnemy() {//渲染小乌龟if (torToiseExist) {putimagePNG2(torToiseX, torToiseY,WIN_WIDTH, &imgTortoise);}
}

 将其函数在main函数中调用,和渲染人物一起渲染出来

 此时代码进度为:

#include <iostream>
#include<graphics.h>
#include <conio.h>
#include "tools.h"#define WIN_WIDTH 1012
#define WIN_HEIGHT 396using namespace std;/*
1.先做背景
2.创建玩家
3.实现玩家跳跃
*///背景
IMAGE imgBgs[3];
int bgSpeed[3] = { 1,2,4 };
int bgX[3];//人物
IMAGE imgHero[12];
int heroX;
int heroY;
int heroIndex;//帧序列//跳跃
bool heroJump;//跳跃状态
int jumpHeightMax;//跳跃的最大高度
int heroJumpOff;//小乌龟
IMAGE imgTortoise;
//小乌龟存在开关
bool torToiseExist;
int torToiseX;
int torToiseY;void init() {//创建游戏窗口initgraph(WIN_WIDTH, WIN_HEIGHT);//加载背景图char name[64];for (int i = 0; i < 3; i++) {//"res/bg001.png  res/bg002.pngsprintf_s(name, "res/bg%03d.png", i + 1);loadimage(&imgBgs[i], name);bgX[i] = 0;}//加载人物背景图for (int i = 0; i < 12; i++) {sprintf(name, "res/hero%d.png", i + 1);loadimage(&imgHero[i], name);}//人物的位置放在窗口的最中间,由于人物需要运动,用多组图片进行轮播,需要定义一个帧序列heroX = WIN_WIDTH * 0.5 - imgHero[0].getwidth() * 0.5;heroY = 345 - imgHero[0].getheight();heroIndex = 0;//跳跃heroJump = false;jumpHeightMax = 345 - imgHero[0].getheight() - 120;heroJumpOff = -4;//小乌龟初始化loadimage(&imgTortoise, "res/t1.png");torToiseY = 345 + 5 - imgTortoise.getheight();torToiseExist = false;}void updataBg() {putimagePNG2(bgX[0], 0, WIN_WIDTH, &imgBgs[0]);putimagePNG2(bgX[1], 119, WIN_WIDTH, &imgBgs[1]);putimagePNG2(bgX[2], 330, WIN_WIDTH, &imgBgs[2]);
}void updateEnemy() {//渲染小乌龟if (torToiseExist) {putimagePNG2(torToiseX, torToiseY,WIN_WIDTH, &imgTortoise);}
}void fly() {//背景图for (int i = 0; i < 3; i++) {bgX[i] -= bgSpeed[i];if (bgX[i] < -WIN_WIDTH) {bgX[i] = 0;}}//实现跳跃if (heroJump) {if (heroY < jumpHeightMax) {heroJumpOff = 4;//+ (-4)等于向上走,+4等于向下走}heroY += heroJumpOff;if (heroY > 345 - imgHero[0].getheight()) {//达到地面heroJump = false;heroJumpOff = -4;}}else {//改变人物帧序列heroIndex = (heroIndex + 1) % 12;}//创建小乌龟static int frameCount = 0;static int enemyFre = 100;frameCount++;if (frameCount > enemyFre) {frameCount = 0;enemyFre = 100+ rand() % 50;//创建障碍物if (!torToiseExist) {torToiseExist = true;torToiseX = WIN_WIDTH;}}//使小乌龟的运动,运动应该于草坪的移动速度保持一致,才能显得静止在草坪上if (torToiseExist) {torToiseX -= bgSpeed[2];if (torToiseX < -imgTortoise.getwidth()) {torToiseExist = false;}}}void jump() {//跳跃只需要改变y值即可,在底层数据管理函数实现,此时只需要给出可以改数据的信号即可heroJump = true;
}void keyEvent() {//获取玩家键盘事件char ch = 0;if (_kbhit()) {ch = _getch();if (ch == ' ') {jump();}}}
int main() {init();while (1) {keyEvent();BeginBatchDraw();//渲染背景updataBg();//渲染人物putimagePNG2(heroX, heroY, &imgHero[heroIndex]);//渲染障碍物updateEnemy();EndBatchDraw();fly();Sleep(30);}system("pause");return 0;
}

6)对代码进行优化

1.在main函数的最后用了一条函数sleep(30),会将程序休眠30毫秒,如果在此期间有用户的键盘输入,会降低游戏的体验性

2.在创建小乌龟时候,由于只演示了一种障碍物,而添加障碍物时候,应该建立一个专门创建障碍物的函数

先解决第一点

在tools.cpp里有getDalay,用于计算上一次调用到现在的间隔时间,在全局状态定义一个计时器timer,在定义一个刷新界面的变量update,如果update为真,则开始刷新界面,如果间隔大于30毫秒,则将刷新界面变量至于true状态,可以代替30ms的休眠间隔,增强体验感

int main() {init();while (true) {keyEvent();timer += getDelay();if (timer > 30) {timer = 0;update = true;}if (update) {update = false;BeginBatchDraw();updataBg();//实现人物的奔跑putimagePNG2(heroX, heroY, &imgHero[heroIndex]);//渲染障碍物updateEnemy();EndBatchDraw();fly();}}system("pause");return 0;
}

解决第二点,将创建小乌龟障碍物先封装为一个函数,在下一期进行改善为可随机创建多种障碍物

void creatObstacle() {//小乌龟初始化if (!torToiseExist) {torToiseExist = true;torToiseX = WIN_WIDTH;}}

在原来fly函数里面,用creatObstacle()代替上面函数体内的三条语句即可


 五.本节总结

总结 : 这结实现了背景轮播图的实现,人物的创建,障碍物的创建,动态的原理就是改变帧序列,开发技巧是将渲染层,数据层分开,其他功能封装为函数,围绕这两个函数展开,将main函数变的简单明了,讲述了开发技巧,计时器的使用,改善休眠间隔的方法

相关文章:

[C/C++]天天酷跑游戏超详细教程-上篇

个人主页&#xff1a;北海 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C/C&#x1f91d;希望作者的文章能对你有所帮助&#xff0c;有不足的地方请在评论区留言指正&#xff0c;大家一起学习交流&#xff01;&#x1f9…...

5G NR:RACH流程 -- Msg1之选择正确的PRACH时频资源

PRACH的时域资源是如何确定的 PRACH的时域资源主要由参数“prach-ConfigurationIndex”决定。拿着这个参数的取值去协议38211查表6.3.3.2-2/3/4&#xff0c;需要注意根据实际情况在这三张表中进行选择&#xff1a; FR1 FDD/SULFR1 TDDFR2 TDD Random access preambles can onl…...

在vue3项目中编辑的时候,解决对话框里边的数据和列表中的数据联动了。深复制

//分析原因是从列表中拿到的数据直接复制去修改就涉及到堆里变的内容是一样的&#xff0c;直接复制其实只是把引用地址赋值给变量了&#xff0c;解决方法是 浅复制和深复制。<!-- 审批流程管理 --> <template><div style"float: left; width: 250px;backgr…...

循环结构(个人学习笔记黑马学习)

while循环语句 在屏幕中打印0~9这十个数字 #include <iostream> using namespace std;int main() {int i 0;while (i < 10) {cout << i << endl;i;}system("pause");return 0; } 练习案例: 猜数字 案例描述:系统随机生成一个1到100之间的数字&…...

ceph中PGLog处理流程

正文 struct pg_log_entry_t {ObjectModDesc mod_desc; //用于保存本地回滚的一些信息&#xff0c;用于EC模式下的回滚操作bufferlist snaps; //克隆操作&#xff0c;用于记录当前对象的snap列表hobject_t soid; …...

macOS使用命令行连接Oracle(SQL*Plus)

Author: histonevonzohomail.com Date: 2023/08/25 文章目录 SQL\*Plus安装下载环境配置 SQL\*Plus远程连接数据库参考文献 原文地址&#xff1a;https://histonevon.top/archives/oracle-mac-sqlplus数据库安装&#xff1a;Docker安装Oracle数据库 (histonevon.top) SQL*Plus…...

Mac下使用Homebrew安装MySQL5.7

Mac下使用Homebrew安装MySQL5.7 1. 安装Homebrew & Oh-My-Zsh2. 查询软件信息3. 执行安装命令4. 开机启动5. 服务状态查询6. 初始化配置7. 登录测试7.1 终端登录7.2 客户端登录 参考 1. 安装Homebrew & Oh-My-Zsh mac下如何安装homebrew MacOS安装Homebrew与Oh-My-Zsh…...

centos安装Nginx配置Nginx

1. 查看操作系统有没有安装Nginx which nginx 2. 使用epel的方式进行安装&#xff08;方法二&#xff09; 先安装epel sudo yum install yum-utils 安装完成后&#xff0c;查看安装的epel包即可 sudo yum install epel 3 开始安装nginx 上面的两个方法不管选择哪个&…...

Linux环境下搭建使用缓存中间件Redis

缓存中间件Redis搭建与使用 前言正文1 提供安装环境2 下载安装3 修改启动配置4 启动服务5 使用6 关闭服务7 卸载 前言 redis服务将在linux系统中部署&#xff0c;本文前提是已经搭建一个linux系统&#xff0c;并配置好网络等。使用vmware搭建一个linux系统&#xff0c;可以参考…...

Oracle 本地客户端连接远程 Oracle 服务端并使用 c# 连接测试

这里写自定义目录标题 前言Oracle 客户端安装先决条件下载 Oracle 客户端Oracle 客户端环境变量配置 PL/SQLPL/SQL 下载PL/SQL 配置 配置远程连接tnsnames.ora 文件配置 使用 PL/SQL 连接远程数据库使用 C# 远程访问 Oracle 数据库结语 前言 最近有一个需要使用本地的 Oracle …...

java中上传文件先下载到本地再上传还有就是直接通过文件流url地址进行上传优缺点?

在Java中上传文件到SFTP服务器时&#xff0c;有两种常见的方法&#xff1a;先下载到本地再上传和直接使用文件流URL地址进行上传。每种方法都有其优点和缺点&#xff0c;下面是对它们的简要比较&#xff1a; 先下载到本地再上传&#xff1a; 优点&#xff1a; 可以在本地对文件…...

华为复合vlan(mux vlan)

一、概念&#xff1a; Multiplex vlan&#xff1a;实现网络资源控制的的机制。 / Principle vlan&#xff1a;port 可以和mux vlan内所有接口进行通信&#xff0c;限制128个 < /Separate vlan&#xff1a;隔离型从vlan&#xff0c;只能和…...

第62步 深度学习图像识别:多分类建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 上期我们基于TensorFlow环境做了图像识别的多分类任务建模。 本期以健康组、肺结核组、COVID-19组、细菌性&#xff08;病毒性&#xff09;肺炎组为数据集&#xff0c;基于Pytorch环境&#xff0c;构建SqueezeNet多分类模型&#xff0…...

GPT带我学-设计模式-适配器模式

1 什么是适配器设计模式 适配器设计模式是一种结构性设计模式&#xff0c;用于在不兼容的接口之间进行转换。它允许将一个类的接口转换成客户端所期望的接口。 适配器模式包含以下几个角色&#xff1a; 目标接口&#xff08;Target&#xff09;&#xff1a;定义客户端所期望…...

Pyecharts教程(七):使用pyecharts创建堆叠柱状图的示例

Pyecharts教程(七):使用pyecharts创建堆叠柱状图的示例 作者:安静到无声 个人主页 目录 Pyecharts教程(七):使用pyecharts创建堆叠柱状图的示例完整代码推荐专栏在数据可视化中,柱状图是一种常见的图表类型,它可以清晰地展示各类别之间的比较关系。然而,如果我们想要在同…...

C++中的强制转换的常用类型及应用场景详解

C中的强制转换的常用类型及应用场景详解 文章目录 C中的强制转换的常用类型及应用场景详解一、静态转换&#xff08;static_cast&#xff09;二、动态转换&#xff08;dynamic_cast&#xff09;三、常量转换&#xff08;const_cast&#xff09;四、重新解释转换&#xff08;rei…...

ubuntu调整时区

ubuntu在新装系统的时候&#xff0c;所用的时区不一定是8的时区&#xff0c;需要设置一下&#xff0c;否则执行cron等定时任务的时候&#xff0c;时间就会不对 查看当前系统的时区 date -R tzselect 选择时区&#xff0c;但是没用 ,作用可能就是 选择时区 设置时区&#xff1a;…...

mybatis:动态sql【2】+转义符+缓存

目录 一、动态sql 1.set、if 2.foreach 二、转义符 三、缓存cache 1. 一级缓存 2. 二级缓存 一、动态sql 1.set、if 在update语句中使用set标签&#xff0c;动态更新set后的sql语句&#xff0c;&#xff0c;if作为判断条件。 <update id"updateStuent" pa…...

2021年09月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:抓牛 农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式: 1、从X移动到X-1或X+1,每次移动花费一分钟 2、从X移动到2*X,每次移动花费一分钟 假设牛没有意识到农夫的…...

Ansible学习笔记1

公司的服务器越来越多&#xff0c;维护一些简单的事情都会变得很繁琐。用Shell脚本来管理少量服务器效率还行&#xff0c;服务器多了&#xff0c;Shell脚本无法实现高效率运维。这种情况下&#xff0c;我们需要引入自动化运维工具&#xff0c;对多台服务器实现高效运维。 配置服…...

解决centos离线安装cmake找不到OpenSSL问题

安装方法&#xff1a;见另外一篇文章 https://blog.csdn.net/zhongxj183/article/details/118488629 按照文章下载了离线gcc 和OpenSSL&#xff0c;以及在cmake官网下载了最新版 cmake-3.27.4.tar.gz 顺利安装gcc 和OpenSSL 但执行编译cmake时&#xff0c;报错找不到OpenSSL…...

Java 中数据结构ArrayList的用法

Java ArrayList ArrayList 类是一个可以动态修改的数组&#xff0c;与普通数组的区别就是它是没有固定大小的限制&#xff0c;我们可以添加或删除元素。 方法集合样例代码 import java.util.*;public class list_set_iterator {public static void main(String[] args) {Lis…...

UDP 多播(组播)

前言&#xff08;了解分类的IP地址&#xff09; 1.组播&#xff08;多播&#xff09; 单播地址标识单个IP接口&#xff0c;广播地址标识某个子网的所有IP接口&#xff0c;多播地址标识一组IP接口。单播和广播是寻址方案的两个极端&#xff08;要么单个要么全部&#xff09;&am…...

分布式环境集成JWT(Java Web Token)

目录 一&#xff0c;说明&#xff1a;二&#xff0c;Token、Session和Cookie比较三&#xff0c;Spring Boot项目集成JWT1&#xff0c;引入依赖2&#xff0c;Token工具类3&#xff0c;定义拦截器4&#xff0c;注册拦截器5&#xff0c;编写登录代码6&#xff0c;测试 四&#xff…...

Python实战之数据表提取和下载自动化

在网络爬虫领域&#xff0c;动态渲染类型页面的数据提取和下载自动化是一个常见的挑战。本文将介绍如何利用Pyppeteer库完成这一任务&#xff0c;帮助您轻松地提取动态渲染页面中的数据表并实现下载自动化。 一、环境准备 首先&#xff0c;确保您已经安装了Python环境。接下来…...

Midjourney学习(三)6个高级应用

使用Remix Mode在原图片的基础上进行二次创作 通过prompt得到大图之后&#xff0c;点击Make Variations按钮&#xff0c;输入Remix Prompt&#xff0c;即可得到意想不到的效果&#xff01; 局部内容重绘 通过局部重绘可以实现对画面内容更加精细化的控制&#xff0c;同样也是需…...

C语言:指针类型的意义

1.指针的类型决定了解引用时访问几个字节 2.指针的类型决定了指针1、-1跳过几个字节 一、指针的类型决定指针解引用时访问几个字节 例如 int 型指针解引用时访问4个字节 char 型指针解引用时访问1个字节 详解代码如下&#xff1a; int b 0x11223344&#xff08;十六进制&…...

如何将 PDF 转换为 Word:前 5 个应用程序

必须将 PDF 转换为 Word 才能对其进行编辑和自定义。所以这里有 5 种很棒的方法 PDF 文件被广泛使用&#xff0c;因为它非常稳定且难以更改。这在处理法律合同、财务文件和推荐信等重要文件时尤其重要。但是&#xff0c;有时您可能需要编辑 PDF 文件。最好的方法是使用应用程序…...

AP5192 DC-DC降压恒流LED汽车头灯摩托车电动车大灯电源驱动

AP5192是一款PWM工作模式,高效率、外围简单、 内置功率MOS管&#xff0c;适用于4.5-100V输入的高精度 降压LED恒流驱动芯片。最大电流1.5A。 AP5192可实现线性调光和PWM调光&#xff0c;线性调光 脚有效电压范围0.55-2.6V. AP5192 工作频率可以通过RT 外部电阻编程 来设定&…...

Python Opencv实践 - Canny边缘检测

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_GRAYSCALE) print(img.shape)#图像Canny边缘检测 #cv.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradien…...

Python编程练习与解答 练习119:低于和高于平均水平

编写一个程序&#xff0c;从用户处读取数字&#xff0c;直到用户输入空行。程序应该显示用户输入的所有值的平均值。然后所有程序应该显示所有平均值的值&#xff0c;然后显示所有平均值&#xff08;若有&#xff09;&#xff0c;最后显示所有高于平均值的值。再每个值列表之前…...

vue中的nextTick的作用

vue里面&#xff0c;常用的事件onMounted里&#xff0c;总喜欢用一个nextTick&#xff1a; onMounted(() > {nextTick(() > {init();}); });这个东西有啥用呢&#xff1f;我总搞不懂。 今天我忽然有点明白了。这是一个跟前面语句有关的方法。意思是&#xff0c;等前面的…...

如何通过四个步骤清理网络防火墙规则

组织必须确保适当的安全策略到位&#xff0c;以保护其投资并优化其安全有效性。然而&#xff0c;随着网络的扩展和复杂性的增加&#xff0c;网络运营团队面临着管理来自多个供应商的大量防火墙和网络设备的挑战。他们必须解决分散的基础设施、职能孤岛、人员配置问题、分散的管…...

打开谷歌浏览器远程调试功能

谷歌浏览器远程调试功能 首先我们来启动Chrome的远程调试端口。你需要找到Chrome的安装位置&#xff0c;在Chrome的地址栏输入chrome://version就能找到Chrome的安装路径 开启远程控制命令 文件路径/chrome.exe --remote-debugging-port9222开启后的样子(注意要关闭其他谷歌浏…...

ChatGPT时代的我的博客

好久没有在CSDN写原创文章了。 ChatGPT出来之后&#xff0c;肯定对CSDN这样的平台有很大的冲击性。 我平时在CSDN写的文章&#xff0c;大多是翻译和一些平时编程遇到的代码问题。小部分是一些自己的经验和总结。 这些文章会被ChatGPT&#xff0c;或者更通用的说&#xff0c;…...

同步有关的思考。

同步通常标志着系统处于不稳定状态&#xff0c;所以同步过程分析和控制是非常重要的。 高速同步过程&#xff1a;高速同步的前提是同步源数据稳定可靠且同步过程不会破坏同步源数据的稳定性&#xff0c;数据接收方资源需要有足够裕量且能维持在就绪状态&#xff0c;双方连接链…...

Flutter Web 项目网络请求报 XMLHttpRequest error 解决方案

使用http库进行简单的网络请求时&#xff0c;运行在Chrome浏览器上&#xff0c;网络请求一直报错 XMLHttpRequest error&#xff0c;而在iOS 模拟器上运行则正常&#xff0c;后面在postman上发送请求&#xff0c;也是正常的。这就是很尴尬了&#xff01;&#xff01;&#xff0…...

Python面试:什么是GIL

1. GIL (Global Interpreter lock)可以避免多个线程同时执行字节码。 import threadinglock threading.Lock()n [0]def foo():with lock:n[0] n[0] 1n[0] n[0] 1threads [] for i in range(5000):t threading.Thread(targetfoo)threads.append(t)for t in threads:t.s…...

idea --Git Commit Template插件

Git Commit Template是一款免费的IntelliJ IDEA插件&#xff0c;用于提供Git提交模板。该插件可以帮助开发者编写规范的Git提交信息&#xff0c;提高代码管理效率。 首先安装插件&#xff1a; 使用Git Commit Template插件: 注&#xff1a;long description和Breaking changes…...

使用Python脚本添加新的相关节点到arxml文件中的指定位置

使用Python脚本添加新的相关节点到arxml文件中的指定位置 1 背景 随着汽车软件开发的复杂度越来越高,链路越来越长,很多手动配置的工具链所需要的时间就会被拉长,显然这对于项目的开发进度有了一定影响,根据需求自动化生成arxml文件其实很有必要。同时越来越多的测试开始…...

iOS开发Swift-闭包

1.闭包表达式语法 { (参数) -> return 类型 in//内容 }let names ["C", "A", "E", "B", "D"] func back(_ s1: String, s2: String) -> Bool {return s1 > s2 //(B > A, C > B) }//闭包后&#xff1a; va…...

从零开始学JAVA——常用类

常用类 课后习题一&#xff1a;课后练习二&#xff1a;课后练习三&#xff1a;课后练习四课后练习五&#xff1a; 课后习题一&#xff1a; 将字符串“2016-02-22”转换为对应的java.sql.Date类的对象 SimpDateFormat sdf new SimpDateFormate(“yyyy-MM-DD”); 解析 java.ut…...

LeetCode 面试题 02.04. 分割链表

文章目录 一、题目二、C# 题解 一、题目 给你一个链表的头节点 head 和一个特定值 x&#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你不需要 保留 每个分区中各节点的初始相对位置。 点击此处跳转题目。 示例 1&#…...

基于大语言模型知识问答应用落地实践 – 知识库构建(下)

上篇介绍了构建知识库的大体流程和一些优化经验细节&#xff0c;但并没有结合一个具体的场景给出更细节的实战经验以及相关的一些 benchmark 等&#xff0c;所以本文将会切入到一个具体场景进行讨论。 目标场景&#xff1a;对于 PubMed 医疗学术数据中的 1w 篇文章进行知识库构…...

Hive UDF自定义函数上线速记

0. 编写hive udf函数jar包 略 1. 永久函数上线 1.1 提交jar包至hdfs 使用命令or浏览器上传jar到hdfs,命令的话格式如下 hdfs dfs -put [Linux目录] [hdfs目录] 示例: hdfs dfs -put /home/mo/abc.jar /tmp1.2 将 JAR 文件添加到 Hive 中 注意hdfs路径前面要加上hdfs://na…...

【nacos】【sentinel】【gateway】docker-compose安装及web项目部署

docker安装 【centos】【docker】安装启动 docker-compose安装 【docker-compose】安装使用 配置文件 version: 2 networks: #自定义网络myapp&#xff0c;为了只有这些服务可以在该网络内相互访问myapp:driver: bridge services: #将容器抽象成服务nacos: #注册中心image…...

用idea查看sqlite数据库idea sqlite

1、安装Database Navigator插件 2、导入数据库并查看 3、删除数据库连接 在此做个笔记...

流媒体服务器与视频服务器有什么区别?

流媒体服务器与视频服务器有什么区别&#xff1f; 流媒体服务器用在远程教育&#xff0c;视频点播、网络电台、网络视频等方面。 直播过程中就需要使用流媒体服务器&#xff0c;一个完整的直播过程&#xff0c;包括采集、处理、编码、封包、推流、传输、转码、分发、解码、播放…...

03-基础例程3

基础例程3 01、外部中断 ESP32的外部中断有上升沿、下降沿、低电平、高电平触发模式。 实验目的 使用外部中断功能实现按键控制LED的亮灭 按键按下为0。【即下降沿】 * 接线说明&#xff1a;按键模块-->ESP32 IO* (K1-K4)-->(14,27,26,25)* * …...

Vue结合ElementUi修改<el-table>表格的背景颜色和表头样式

本项目在开发过程中vueelementui &#xff0c; 页面中使用了table表格的样式&#xff0c; 需要对原先的样式进行修改&#xff0c;以下是简单的修改样式内容&#xff1a;项目中某个 html中引用的table表格内容,定义了div的class : device_err :<div class"device_err&q…...