[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函数变的简单明了,讲述了开发技巧,计时器的使用,改善休眠间隔的方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/111654.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion Web UI的原理与使用

Stable Diffusion是一套基于Diffusion扩散模型生成技术的图片生成方案&#xff0c;随着技术的不断发展以及工业界对这套工程细节的不断优化&#xff0c;使其终于能在个人电脑上运行&#xff0c;本文将从github下载开始讲一讲如何使用Stable Diffusion Web UI进行AI图像的生成。…

摄像头的调用和视频识别

CV_tutorial3 摄像头调用实时播放保存视频 运动目标识别帧差法背景减除法 摄像头调用 创建视频捕捉对象&#xff1a;cv2.VideoCapture() 参数为视频设备的索引号&#xff0c;就一个摄像投的话写0默认&#xff1b; 或者是指定要读取视频的路径。 实时播放 import cv2 import …

华硕笔记本摄像头倒置怎么办?华硕笔记本摄像头上下颠倒怎么调整

笔记本电脑相较于台式电脑&#xff0c;更易携带&#xff0c;解决了很大一部分人的使用需求。但是笔记本电脑也存在很多不足&#xff0c;比如华硕笔记本电脑就经常会出现摄像头倒置的错误&#xff0c;出现这种问题要如何修复呢&#xff1f;下面就来看看详细的调整方法。 华硕笔记…

十二、集合(2)

本章概要 添加元素组集合的打印列表 List 添加元素组 在 java.util 包中的 Arrays 和 Collections 类中都有很多实用的方法&#xff0c;可以在一个 Collection 中添加一组元素。 Arrays.asList() 方法接受一个数组或是逗号分隔的元素列表&#xff08;使用可变参数&#xff…

【STM32】学习笔记-江科大

【STM32】学习笔记-江科大 1、STM32F103C8T6的GPIO口输出 2、GPIO口输出 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口可配置为8种输入输出模式引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V输出模式下可控制端口输出高低电平&#…

【GPT,Flask】用Python Flask结合OpenAI的GPT API构建一个可自主搭建的内容生成应用网站

【背景】 自己构建模型并进行训练需要很高的知识,技能和资源门槛。如今,通过OpenAI提供的API,则可以快速通过GPT能力构建可以提供内容生成服务的在线网站。这套框架可以提供给用户,用户可以利用该框架在自己的环境(比如自己的公司内)构建内容生成服务。你也可以自己上线…

以“迅”防“汛”!5G视频快线筑牢防汛“安全堤”

近期&#xff0c;西安多地突发山洪泥石流灾害。防洪救灾刻不容缓&#xff0c;为进一步做好防汛工作&#xff0c;加强防洪调度监管&#xff0c;切实保障群众的生命财产安全&#xff0c;当地政府管理部门亟需拓展智能化技术&#xff0c;通过人防技防双保障提升防灾救灾应急处置能…

Python基础小讲堂之条件分支与循环

万丈高楼平地起&#xff0c;今天给大家讲讲python中的&#xff1a;条件分支与循环。在学条件分支与循环之前&#xff0c;先掌握一下python的基本操作符。算术操作符&#xff1a; - * / % ** //对于算数操作符的前四个加减乘除&#xff0c;大家都懂&#xff0c;在py…

趣解建造者模式之网红小王购车记

一、前言 本文章是关于设计模式中的建造者模式的&#xff0c;也称构建者模式/生成器模式&#xff0c;英文我们称之为Builder Pattern。在开展讲解之前&#xff0c;我们先把该模式的定义了解一下。 建造者模式的定义&#xff1a; 该模式可以实现产品的封装构造过程&#xff0c…

浅谈视频汇聚平台EasyCVR中AI中台的应用功能

AI中台是将人工智能技术如深度学习、计算机视觉、知识图谱、自然语言理解等模块化&#xff0c;集约硬件的计算能力、算法的训练能力、模型的部署能力、基础业务的展现能力等人工智能能力&#xff0c;结合中台的数据资源&#xff0c;封装成整体中台系统。 在EasyCVR视频共享融合…

【AI】数学基础——高数(积分部分)

高数&#xff08;函数&微分部分&#xff09; 文章目录 1.4 微积分1.4.1 基本思想1.4.2 定积分定义定义计算定积分定积分性质定理N-L公式泰勒公式麦克劳林公式 1.5 求极值1.5.1 无条件极值1.5.2 条件极值1.5.3 多条件极值1.5.4 凹函数与凸函数 1.4 微积分 用于求解速度、面积…

vue3+ts+tinynce富文本编辑器+htmlDocx+file-saver 配合实现word下载

vue3 请下载html-docx-js-typescript&#xff0c;否则会报错类型问题 //报告导出word import * as htmlDocx from "html-docx-js-typescript";//ts-ignore import { saveAs } from file-saver// 下载文件&#xff0c; const downloadFile (row)> {try {const co…

得物一面,场景题问得有点多!

题目来源&#xff1a;https://www.nowcoder.com/discuss/525371909735792640 前文 本期是【捞捞面经】系列文章的第 1 期&#xff0c;持续更新中…。 《捞捞面经》系列正式开始连载啦&#xff0c;据说看了这个系列的朋友都拿到了大厂offer~ 欢迎星标订阅&#xff0c;持续更新…

服务器端使用django websocket,客户端使用uniapp 请问服务端和客户端群组互发消息的代码怎么写的参考笔记

2023/8/29 19:21:11 服务器端使用django websocket,客户端使用uniapp 请问服务端和客户端群组互发消息的代码怎么写 2023/8/29 19:22:25 在服务器端使用Django WebSocket和客户端使用Uniapp的情况下&#xff0c;以下是代码示例来实现服务器端和客户端之间的群组互发消息。 …

Redis——》Pipeline

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

15-mongodb

一、 MongoDB 简介 1 什么是 MongoDB MongoDB 是一个基于分布式文件存储的数据库。由 C语言编写。在为 WEB 应用提供可扩展的高性能数据存储解决方案。 MongoDB 是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系…

ChatGPT⼊门到精通(4):ChatGPT 为何⽜逼

⼀、通⽤型AI 在我们原始的幻想⾥&#xff0c;AI是基于对海量数据的学习&#xff0c;锻炼出⼀个⽆所不知⽆所不能的模 型&#xff0c;并借助计算机的优势&#xff08;计算速度、并发可能&#xff09;等碾压⼈类。 但我们⽬前的AI&#xff0c;不管是AlphaGo还是图像识别算法&am…

生活类书单视频如何做?几个步骤轻松拿捏

生活类书单视频是一种很受欢迎的内容形式&#xff0c;它可以帮助观众了解各种生活类书籍&#xff0c;并提供一些有用的信息。在制作生活类书单视频时&#xff0c;我们需要注意几个步骤&#xff0c;以确保视频内容的质量和专业性。 首先&#xff0c;我们需要选择适合的书单背景。…

R语言绘图相关函数(含实例)

目录 plot:可用于创建多种类型的图形 dev.new():新建画板 hist&#xff1a;绘制直方图 dotchart&#xff1a;绘制点图的函数 pie:绘制饼图 pair&#xff1a;绘制散点图矩阵 boxplot&#xff1a;绘制箱线图 scatterplot3D&#xff1a; 绘制三维散点图 par&#xff1a;修…

Maven导入包

有些时候maven导入不进去包&#xff0c;这个时候可以去直接去maven仓库找到你需要的包 https://mvnrepository.com/ 在自己本地输入命令 &#xff08;这只是一个样例&#xff0c;请根据自己需要的包参考&#xff09; mvn install:install-file -Dfile"C:/Users//Downloa…