【C++】做一个飞机空战小游戏(八)——生成敌方炮弹(rand()和srand()函数应用)

 [导读]本系列博文内容链接如下:

【C++】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值

【C++】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动
【C++】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动

【C++】做一个飞机空战小游戏(四)——给游戏添加背景音乐(多线程技巧应用)

【C++】做一个飞机空战小游戏(五)——getch()控制两个飞机图标移动(控制光标位置)

【C++】做一个飞机空战小游戏(六)——给两架飞机设置不同颜色(cout输出彩色字符、结构体使用技巧)

【C++】做一个飞机空战小游戏(七)——两组按键同时检测平滑移动(GetAsyncKeyState()函数应用)

【C++】做一个飞机空战小游戏(八)——生成敌方炮弹(rand()函数应用)

【C++】做一个飞机空战小游戏(九)——发射子弹的编程技巧

【C++】做一个飞机空战小游戏(十)——子弹击落炮弹、炮弹与飞机相撞 

前边7讲都是介绍飞机控制的方法,从今天开始介绍敌方炮弹生成的方法。炮弹生成所用到的rand()函数详细介绍见:【c++】rand()随机函数的应用(一)——rand()函数详解和实例_一只爬爬虫的博客-CSDN博客

目录

一、生成敌方炮弹的几个关键问题

(一)炮弹的数量

1、每轮炮弹数量(bombs_round)

2、每关总炮弹数量(bombs_stage)

3、最大同屏炮弹数量(end_bombs_round)

(二)炮弹出现的时间(rt)

(三)炮弹的起始位置

1、y坐标

2、x坐标

(四)炮弹移动速度(bomb_interval)

(五)炮弹与飞机相撞或被飞机子弹击落

二、构造结构体

(一)游戏结构体Game

(二)炮弹结构体Bomb

三、新增与炮弹相关的函数

(一)单个炮弹初始化函数

(二)所有炮弹初始化

(三)炮弹位置更新线程函数

(四)炮弹位置更新线程启动函数

四、更新后的程序代码

(一)主函数

(二)头文件control_plane.h

(三)库函数control_plane.cpp


一、生成敌方炮弹的几个关键问题

(一)炮弹的数量

1、每轮炮弹数量(bombs_round)

每轮炮弹数量,也就是屏幕当中出现的最多炮弹数量,也就是敌方同一波发射的最多炮弹数量,数量越多,难度也越大,这个数量可随关数的增加而增加。

2、每关总炮弹数量(bombs_stage)

每关发射的炮弹总数量不一样,关数越高,炮弹总数量也越多。

3、最大同屏炮弹数量(end_bombs_round)

最大单轮炮弹数量,也就是最后一关,敌方同一波发射炮弹数量。

(二)炮弹出现的时间(rt)

同一波炮弹出现的时间不能一样,否则所有炮弹呈现一排,游戏的体验感较差,所以,炮弹出现的时间也应该是随机的,也就是炮弹的y值是随机的。如下图所示,黄色方框为敌方炮弹。

 为了实现这个效果,炮弹设置了一个炮弹坠地(炮弹到达屏幕最下方)、被击落或者与飞机相撞后死亡复活时间(respawn time,缩写为rt),在复活期间,炮弹不出现在屏幕。这个复活时间是随机的,这个时间会自减1,当这个时间降为0的时候,炮弹复活,才从屏幕上方出现。

(三)炮弹的起始位置

1、y坐标

炮弹开始出现在屏幕的位置位于屏幕最上方,也就是y=0处,但因为炮弹有复活时间,炮弹的起始位置不能在y=0处,防止炮弹还未复活就被击落。所以,炮弹的起始位置设置在屏幕最下侧再往下一行,也就是b_b+6,b_b为飞机坐标的下边界,6为飞机图标的高度。这样,炮弹在复活期间就不会与飞机相撞,也不会被飞机发射的子弹击中。

所以,炮弹从死亡开始,到复活前,其位置为:x坐标随机,y=b_b+6,而且在复活期间,位置不发生移动。复活后x坐标不变,y=0,然后y值自加1。

2、x坐标

x坐标在死亡后复活前和复活后都是随机生成的,且坐标值一样。为了简化游戏难度,炮弹出现在屏幕中后,x坐标值不发生变化,仅有y值再增加,也就是炮弹是竖直下落的。

(四)炮弹移动速度(bomb_interval)

炮弹移动速度,由炮弹位置更新线程函数内的Sleep函数的参数决定,数值越大,位置更新的间隔越大,移动速度就越小,反之就越快。

(五)炮弹与飞机相撞或被飞机子弹击落

本文今天暂时没考虑,后边会实现这个功能。

二、构造结构体

(一)游戏结构体Game

//定义游戏结构体 
typedef struct{int stage;					//游戏当前关 	int bombs_round;			//敌方每轮发射炮弹数量 int bombs_stage;			//每关总计出现炮弹数量	bool complete;				//游戏通关 bool gameover;				//游戏结束int num_plane;				//飞机数量 int cur_num_bomb;			//当前已发射炮弹数量 int bomb_interval; 			//位置更新间隔 bool bomb_move;				//炮弹是否移动 
}Game;

(二)炮弹结构体Bomb

//定义敌方炮弹结构体 
typedef struct{Location location;	//炮弹位置 bool alive;			//炮弹是否存活 int color;			//炮弹颜色string icon;		//炮弹图标int rt;				//rt=respawn time复活时间 int hp;				//hp=hit point 生命值,此值<=0时,敌方炮弹死亡,敌方炮弹被飞机子弹击中hp会减少,坠地或与飞机相撞hp直接降为0 int dam;			//dam=damage 伤害值int type;			//炮弹类型 
}Bomb;

三、新增与炮弹相关的函数

(一)单个炮弹初始化函数

这个函数在单个炮弹死亡后调用。

//单个炮弹初始化函数 
Bomb init_bomb(Bomb bomb)
{bomb.location.x=rand()%r_b;	bomb.location.y=b_b+6;bomb.icon=icon_bomb;bomb.color=6;bomb.dam=1;bomb.hp=1;bomb.alive=false;bomb.rt=rand()%(eq_rt+1)+1;	//eq_rt为复活最长时间return bomb;			
}

此处,init_bomb函数的形参为结构体,形参传输函数计算后的结果,并不能直接返回给全局结构体,所以必须采用返回值的方法将初始化的值传递给结构体。

(二)所有炮弹初始化

这个函数在游戏启动或者游戏过关后调用。

//所有炮弹初始化函数 
void init_bombs(void)
{game.bomb_move=false;for(int i=0;i<game.bombs_round;i++){bomb[i]=init_bomb(bomb[i]);	}
}

(三)炮弹位置更新线程函数

这个函数在线程启动函数中启用。

//炮弹位置更新 线程 
void* thread_bomb(void* arg)
{while(1){Sleep(game.bomb_interval);game.bomb_move=true;for(int i=0;i<game.bombs_round;i++){			if(bomb[i].alive){bomb[i].location.y++;			}else{bomb[i].rt--;if(bomb[i].rt<=0){bomb[i].alive=true;bomb[i].location.y=0;}			}if(bomb[i].location.y>b_b+5){bomb[i].hp=0;									}if(bomb[i].hp<=0){bomb[i]=init_bomb(bomb[i]);				}}		}
}

(四)炮弹位置更新线程启动函数

这个函数在主函数中调用启动,然后一直运行。

//炮弹位置更新线程启动函数
void bomb_location_update()
{pthread_t tid; pthread_create(&tid, NULL, thread_bomb, NULL);
}

四、更新后的程序代码

(一)主函数

#include "control_plane.h"
using namespace std; Plane plane[eq_plane];
Game game;
Bomb bomb[eq_bombs_round];int main(int argc, char** argv) {	init();	//初始化					 bgmusic();//播放背景音乐getkey();bomb_location_update();	while(1)					//循环等待键盘指令 {if(plane[0].keycmd!=none_cmd ||plane[1].keycmd!=none_cmd ||game.bomb_move){game.bomb_move=false;system("cls");for(int i=0;i<game.num_plane;i++){show_plane(plane[i]);	//刷新飞机图标}for(int i=0;i<game.bombs_round;i++){if(bomb[i].alive){show_bomb(bomb[i]);}}}}return 0; 	
}

(二)头文件control_plane.h

#ifndef CONTROL_PLANE_H
#define CONTROL_PLANE
#include <iostream>
#include <ctime>
#include <string>
#include<stdlib.h>
#include<windows.h>
#include <pthread.h>//导入线程头文件库
#include <mmsystem.h> //导入声音头文件库
#pragma comment(lib,"winmm.lib")//导入声音的链接库
#define _CRT_SECURE_NO_WARNINGS 
using namespace std;#define t_b 0  	//图形显示区域上侧边界 
#define l_b 0	//图形显示区域左侧边界
#define r_b 100	//图形显示区域右侧边界
#define b_b 20	//图形显示区域下侧边界#define eq_plane 2	//飞机架数
#define eq_bombs_round 23	//eq=end quantity最终炮弹数量 
#define eq_rt 10	//复活最大时间//定义飞机造型 
const string icon_plane1[]={"    ■","■  ■  ■","■■■■■","■  ■  ■","    ■","  ■■■"};
const string icon_plane2[]={"    ■","■  ■  ■","■■■■■","    ■","  ■■■","■■■■■"};//定义炮弹造型
const string icon_bomb="■";//定义坐标结构体 
typedef struct{int x;int y;
} Location;//定义移动方向命令枚举类型 
typedef  enum {none_cmd,up_cmd,down_cmd,left_cmd,right_cmd} direction_cmd; //定义游戏结构体 
typedef struct{int stage;					//游戏当前关 	int bombs_round;			//敌方每轮发射炮弹数量 int bombs_stage;			//每关总计出现炮弹数量 bool clear;					//游戏过关 bool complete;				//游戏通关 bool gameover;				//游戏结束int num_plane;				//飞机数量 int cur_num_bomb;			//当前已发射炮弹数量 int bomb_interval; 			//位置更新间隔 bool bomb_move;				//炮弹是否移动 
}Game;//定义飞机结构体 
typedef struct{Location location;int color;int icon;direction_cmd keycmd;
}Plane;//定义敌方炮弹结构体 
typedef struct{Location location;	//炮弹位置 bool alive;			//炮弹是否存活 int color;			//炮弹颜色string icon;		//炮弹图标int rt;				//rt=respawn time复活时间 int hp;				//hp=hit point 生命值,此值<=0时,敌方炮弹死亡,敌方炮弹被飞机子弹击中hp会减少,坠地或与飞机相撞hp直接降为0 int dam;			//dam=damage 伤害值int type;			//炮弹类型 
}Bomb;extern Plane plane[eq_plane];
extern Game game;
extern Bomb bomb[eq_bombs_round];//声明刷新飞机位置函数
void show_plane(Plane plane);//获取键盘指令 
void key(void);//更新所有飞机坐标
void plane_location_update(void);//初始化函数 
void init(void);//播放背景音乐线程 
void* thread_bgmusic(void* arg);
void play_bgmusic();
void bgmusic();//获取按键指令线程
void* thread_key(void* arg);
void getkey();//输出彩色字符函数
template<typename T>	//T表示任何可以被cout输出的类型 
void ColorCout(T t, const int ForeColor = 7, const int BackColor = 0);void init_bombs(void);
Bomb init_(Bomb bomb);
void* thread_bomb(void* arg);
void bomb_location_update();
void show_bomb(Bomb bomb);#endif

(三)库函数control_plane.cpp

#include <iostream>
#include "conio.h"
#include <string>
#include "control_plane.h"
#include<windows.h>
using namespace std;//彩色输出函数
template<typename T>	//T表示任何可以被cout输出的类型
void ColorCout(T t, const int ForeColor = 7, const int BackColor = 0)
{//	0 = 黑色	1 = 蓝色	 2 = 绿色	 3 = 浅绿色		 4 = 红色	 5 = 紫色	 6 = 黄色	 7 = 白色//	8 = 灰色	9 = 淡蓝色	10 = 淡绿色	11 = 淡浅绿色	12 = 淡红色	13 = 淡紫色	14 = 淡黄色	15 = 亮白色SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), ForeColor + BackColor * 0x10);cout << t;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}//隐藏光标函数
HANDLE han = GetStdHandle(-11);
void hide(){CONSOLE_CURSOR_INFO cursor;cursor.bVisible = 0;cursor.dwSize = 1;SetConsoleCursorInfo(han,&cursor);
}//初始化函数 
void init(void)
{plane[0].location={2*r_b/3,b_b};plane[1].location={r_b/3,b_b};plane[0].color=1;plane[1].color=2;plane[0].icon=1;plane[1].icon=2;srand(time(NULL));game.num_plane=2;game.bombs_round=3;game.bomb_move=false;game.bomb_interval=1000;init_bombs();system("cls");for(int i=0;i<game.num_plane;i++)//刷新飞机图标{		show_plane(plane[i]);	plane[i].keycmd=none_cmd;		}		
//	game.num_plane=2;	game.bombs_round=3;hide();//隐藏光标
}//********************************************************************************//以下三个函数为获得按键指令线程函数 
//********************************************************************************void* thread_key(void* arg)
{while(1){Sleep(60); 		//获取指令延时一定时间,起滤波作用,延缓获取指令的响应速度 key();			//获取按键指令plane_location_update() ;//获取完指令马上更新飞机坐标 }
}
void getkey()
{pthread_t tid; pthread_create(&tid, NULL, thread_key, NULL);
}//获取键盘指令函数
void key(void)
{direction_cmd c=none_cmd;direction_cmd d=none_cmd;	if (GetAsyncKeyState(VK_UP) & 0x8000)		c = up_cmd;if (GetAsyncKeyState(VK_DOWN) & 0x8000)		c = down_cmd;if (GetAsyncKeyState(VK_LEFT) & 0x8000)		c = left_cmd;if (GetAsyncKeyState(VK_RIGHT) & 0x8000)	c = right_cmd;if (GetAsyncKeyState('W') & 0x8000)	d = up_cmd;if (GetAsyncKeyState('S') & 0x8000)	d = down_cmd;if (GetAsyncKeyState('A') & 0x8000)	d = left_cmd;if (GetAsyncKeyState('D') & 0x8000)	d = right_cmd;plane[0].keycmd=c;plane[1].keycmd=d;
}void gotoxy(int x, int y) {COORD pos = { x,y };HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出设备句柄SetConsoleCursorPosition(hOut, pos);//两个参数分别指定哪个窗口,具体位置
}//飞机图标刷新函数 
void show_plane(Plane plane)		//预先定义字符定位显示函数,x是列坐标,y是行坐标,原点(x=0,y=0)位于屏幕左上角 
{int x,y;int i,j;int rows;x=plane.location.x;y=plane.location.y;switch(plane.icon){case 1://第一种造型 rows=sizeof(icon_plane1)/sizeof(icon_plane1[0]);for(i=0;i<rows;i++)				 {gotoxy(x,y+i);				ColorCout(icon_plane1[i],plane.color);}break;case 2://第二种造型 rows=sizeof(icon_plane2)/sizeof(icon_plane2[0]);for(i=0;i<rows;i++)				{gotoxy(x,y+i);				ColorCout(icon_plane2[i],plane.color);}break;				}
}//更新两个飞机的坐标 
void plane_location_update(void)
{ 	for(int i=0;i<2;i++){if(plane[i].keycmd!=none_cmd) {int x,y;x=plane[i].location.x;y=plane[i].location.y;switch(plane[i].keycmd){case up_cmd:y--;				//字符上移一行,行值y减1if(y<t_b)			//限定y值最小值为0{y=t_b;}break;case down_cmd:y++;				//字符下移一行,行值y加1if(y>b_b)			//限定y高度 {y=b_b;}break;case left_cmd:x--;				//字符左移一列,列值x减1if(x<l_b){x=l_b;			//限定x最小值为0; }break;case right_cmd:x++;				//字符右移一列,列值x加1if(x>r_b){x=r_b;			//限定x宽度}break;}plane[i].location.x=x;plane[i].location.y=y;plane[i].keycmd=none_cmd;	}} 		
}//单个炮弹初始化函数 
Bomb init_bomb(Bomb bomb)
{bomb.location.x=rand()%r_b;	bomb.location.y=b_b+6;bomb.icon=icon_bomb;bomb.color=6;bomb.dam=1;bomb.hp=1;bomb.alive=false;bomb.rt=rand()%(eq_rt+1)+1;	return bomb;			
}//所有炮弹初始化函数 
void init_bombs(void)
{game.bomb_move=false;for(int i=0;i<game.bombs_round;i++){bomb[i]=init_bomb(bomb[i]);	}
}//炮弹位置更新 线程 
void* thread_bomb(void* arg)
{while(1){Sleep(game.bomb_interval);game.bomb_move=true;for(int i=0;i<game.bombs_round;i++){			if(bomb[i].alive){bomb[i].location.y++;			}else{bomb[i].rt--;if(bomb[i].rt<=0){bomb[i].alive=true;bomb[i].location.y=0;}			}if(bomb[i].location.y>b_b+5){bomb[i].hp=0;									}if(bomb[i].hp<=0){bomb[i]=init_bomb(bomb[i]);				}}		}
}
//炮弹位置更新 
void bomb_location_update()
{pthread_t tid; pthread_create(&tid, NULL, thread_bomb, NULL);
}炮弹图标刷新函数
void show_bomb(Bomb bomb)		//预先定义字符定位显示函数,x是列坐标,y是行坐标,原点(x=0,y=0)位于屏幕左上角 
{int x,y;	x=bomb.location.x;y=bomb.location.y;gotoxy(x,y);ColorCout(bomb.icon,bomb.color);} //********************************************************************************//以下三个函数为播放背景音乐功能 
//********************************************************************************//播放一遍背景音乐 void play_bgmusic() {  mciSendString(TEXT("open hero.mp3 alias s1"),NULL,0,NULL);mciSendString(TEXT("play s1"),NULL,0,NULL);Sleep(153*1000);//153*1000意思是153秒,是整首音乐的时长 mciSendString(TEXT("close S1"),NULL,0,NULL); }//循环播放音乐线程函数 
void* thread_bgmusic(void* arg) //
{ while(1){  	play_bgmusic();}
} //创建音乐播放线程,开始循环播放音乐 
void bgmusic()
{pthread_t tid; pthread_create(&tid, NULL, thread_bgmusic, NULL);
}

(未完待续)

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

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

相关文章

solidwords(5)

我们打算从上面画出总体&#xff0c;再从上面、侧面切除 最后成品

blender 发射体粒子

发射体粒子的基础设置 选择需要添加粒子的物体&#xff0c;点击右侧粒子属性&#xff0c;在属性面板中&#xff0c;点击加号&#xff0c;物体表面会出现很多小点点&#xff0c;点击空格键&#xff0c;粒子会自动运动&#xff0c;像下雨一样&#xff1b; bender 粒子系统分为两…

抖音火山引擎推出免费域名DNS和公共DNS服务

抖音旗下的云计算服务火山引擎最近推出了"TrafficRoute DNS 套件"服务&#xff0c;其中包括两款产品&#xff0c;对软希网来说非常有用。 1.域名DNS&#xff1a; 这是一个用于网站域名的DNS服务&#xff0c;可以加速域名解析速度&#xff0c;从而提升网站的速度。如…

【3Ds Max】挤出命令的简单使用(实现二维变三维)

简介 在3ds Max中&#xff0c;"挤出"&#xff08;Extrude&#xff09;是一种常用的建模操作&#xff0c;用于在平面或曲面上创建立体几何形状。以下是使用3ds Max中的挤出命令的基本步骤&#xff1a; 创建基本几何形状&#xff1a; 在3ds Max中创建一个基本的几何形…

自动驾驶——车辆动力学模型

/*lat_controller.cpp*/ namespace apollo { namespace control {using apollo::common::ErrorCode;//故障码 using apollo::common::Status;//状态码 using apollo::common::TrajectoryPoint;//轨迹点 using apollo::common::VehicleStateProvider;//车辆状态信息 using Matri…

Kotlin实战之获取本地配置文件、远程Apollo配置失败问题排查

背景 Kotlin作为一门JVM脚本语言&#xff0c;收到很多Java开发者的青睐。 项目采用JavaKotlin混合编程。Spring Boot应用开发&#xff0c;不会发生变动的配置放在本地配置文件&#xff0c;可能会变化的配置放在远程Apollo Server。 问题 因为业务需要&#xff0c;需要增加一…

MybatisPlus整合p6spy组件SQL分析

目录 p6spy java为什么需要 如何使用 其他配置 p6spy p6spy是一个开源项目&#xff0c;通常使用它来跟踪数据库操作&#xff0c;查看程序运行过程中执行的sql语句。 p6spy将应用的数据源给劫持了&#xff0c;应用操作数据库其实在调用p6spy的数据源&#xff0c;p6spy劫持到…

mysql中的窗口函数

MySQL中的窗口函数&#xff08;Window Functions&#xff09;是一种用于在查询结果集内执行计算的功能。窗口函数可以在查询中进行分析和聚合操作&#xff0c;而无需将查询结果分组。它们可以用于计算排名、行号、累积值等各种分析操作。窗口函数通常与OVER子句一起使用&#x…

亿赛通电子文档安全管理系统任意文件上传漏洞复现

0x01 产品简介 亿赛通电子文档安全管理系统&#xff08;简称&#xff1a;CDG&#xff09;是一款电子文档安全加密软件&#xff0c;该系统利用驱动层透明加密技术&#xff0c;通过对电子文档的加密保护&#xff0c;防止内部员工泄密和外部人员非法窃取企业核心重要数据资产&…

AI 绘画Stable Diffusion 研究(十)sd图生图功能详解-精美二维码的制作

免责声明: 本案例所用安装包免费提供&#xff0c;无任何盈利目的。 大家好&#xff0c;我是风雨无阻。 为了让大家更直观的了解图生图功能&#xff0c;明白图生图功能到底是干嘛的&#xff0c;能做什么事情&#xff1f;今天我们继续介绍图生图的实用案例-精美二维码的制作。 对…

第 7 章 排序算法(3)(选择排序)

7.6选择排序 7.6.1基本介绍 选择式排序也属于内部排序法&#xff0c;是从欲排序的数据中&#xff0c;按指定的规则选出某一元素&#xff0c;再依规定交换位置后达到排序的目的。 7.6.2选择排序思想: 选择排序&#xff08;select sorting&#xff09;也是一种简单的排序方法…

stm32_ADC电源、通道、工作模式

0、ADC功能框图 1、ADC的电源 1.1、工作电源 VSSAVSS&#xff0c;VDDAVDD&#xff0c;简单来说&#xff0c;通常stm32是3.3V&#xff0c;ADC的工作电源也是3.3V&#xff1b; 1.2、参考电压 VREF和VREF-并不一定引出&#xff0c;取决于封装&#xff0c;如果没有引出则VREF连接到…

MyBatis入门配置及CURD实现

目录 一、MyBatis简介 1. 什么是 MyBatis ? 2. MyBatis的特性 3. 什么是持久层框架&#xff1f; 二、MyBatis环境配置 2.1 创建maven工程 2.2 导入相关pom依赖 2.3 导入jdbc配置文件 2.4 Mybatis相关插件安装 3.5 Mybatis-cfg.xml 核心配置 2.6 引入Log4j2日志文件…

Pycharm与Anaconda Python的开发环境搭建

目录 一&#xff1a;下载 二&#xff1a;安装python 三&#xff1a;设置Pycharm 一&#xff1a;下载 下载Anaconda&#xff1a; Anaconda | The World’s Most Popular Data Science Platform 安装好以后&#xff0c;设置一下环境变量&#xff1a; 打开命令行&#xff0c…

Maven高级

目录 一、分模块开发与设计 1. 分模块开发的意义 2. 分模块开发&#xff08;模块拆分&#xff09; &#xff08;1&#xff09;创建Maven模块 &#xff08;2&#xff09;书写模块代码 &#xff08;3&#xff09;通过maven指令安装模块到本地仓库&#xff08;install指令&…

记录:win10物理机ping不通虚拟机上的docker子网(已解决)

【说明】 windows10&#xff1a;已关闭防火墙 linux发行版本&#xff1a;centos7.9&#xff08;已禁用SElinux、已关闭防火墙&#xff09; 虚拟机软件&#xff1a;VMware Workstation 17 虚拟机网络模式&#xff1a;NAT模式 docker版本&#xff1a;20.4.5 docker网络模式…

一百六十一、Kettle——Linux上安装的kettle9.2开启carte服务(亲测、附流程截图)

一、目的 在Linux上安装好kettle9.2并且连接好各个数据库后&#xff0c;下面开启carte服务 二、实施步骤 &#xff08;一&#xff09;carte服务文件路径 kettle的Linux运行的carte服务文件是carte.sh &#xff08;二&#xff09;修改kettle安装路径下的pwd文件夹里的服务器…

华为将收取蜂窝物联网专利费,或将影响LPWAN市场发展

近日&#xff0c;华为正式公布了其4G和5G手机、Wi-Fi6设备和物联网产品的专利许可费率&#xff0c;其中包含了长距离通信技术蜂窝物联网。作为蜂窝物联网技术的先驱&#xff0c;华为是LTE Category NB (NB-IoT)、LTE Category M和其他4G物联网标准的主要贡献者。 在NB-IoT领域…

18-组件化开发 根组件

组件化开发 & 根组件: 1. 组件化:一个页面可以拆分成一个个组件&#xff0c;每个组件有着自己独立的结构、样式、行为. 好处:便于维护&#xff0c;利于复用->提升开发效率 组件分类: 普通组件 , 根组件 2. 根组件:整个应用最上层的组件&#xff0c;包裹所有普通小组件…

PHP酒店点菜管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 酒店点菜管理系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 代码下载 https://download.csdn.net/download/qq_41221322/88232051 论文 https://…