C/C++ 初级球球大作战练手

news2024/11/15 19:36:02

效果演示:

https://live.csdn.net/v/385490

游戏初始化

  • #include <stdbool.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    #include<graphics.h>
    #include <algorithm>
    #include<math.h>
    #include<mmsystem.h>
    #include <iostream>
    using namespace std;
    #pragma comment(lib,"winmm.lib")  
    //所需要的库引入
  • 需要准备的相关宏定义:
    #define WIN_WIDTH 1024 
    #define WIN_HEIGHT 640
    #define MAP_WIDTH  (WIN_WIDTH*5)
    #define MAP_HEIGHT (WIN_HEIGHT*5)
    #define FOOD_NUM 1000
    #define AI_NUM 500
  • 初始化显示终端:initgraph(1024,640)
    int main() {
    	initgraph(WIN_WIDTH, WIN_HEIGHT);//初始化界面
    	gameinit();
    
    	while (true) {
    		aimove();
    		gamedraw();
    		eatfood();
    		playercontroller(10);
    	}
    	/*getchar();*/
    	return 0;
    }
  • 根据main函数主体逻辑串联整个代码体系

游戏初始化操作

  • 游戏 初始化:在已经有的显示画面上进行布置球球的操作
  • 通过随机种子 :随机布置食物球球的位置  玩儿家的随机小球位置  自由移动的小球的位置
  • 前置定义:玩儿家,自由移动小球,食物小球
    struct ball
    {
    	int x;
    	int y;
    	int r;
    	bool flag;
    	DWORD color;
    }player,food[FOOD_NUM],ai[AI_NUM];

进入游戏的主题循环

  • 自由小球的移动设置
    void Chase(struct ball* chase,struct ball run)
    {
    	chase->x < run.x ? chase->x += 2 : chase->x -= 2;
    	chase->y < run.y ? chase->y += 2 : chase->y -= 2;
    }
    
    void aimove()
    {
    	for (int i = 0; i < AI_NUM; i++)
    	{
    		if (ai[i].flag)
    		{
    			Chase(&ai[i], player);
    		}
    	}
    }
    
  1. 通过循环遍历 ai 数组。
  2. 检查每个元素的 flag 是否为真(即激活状态)。
  3. 如果是真,调用 Chase 函数,将 ai[i](追击者的位置)和 player(目标的位置)作为参数传递给 Chase
  4. 如果 chase->x(追击者的横坐标)小于 run.x(目标的横坐标),则将 chase->x 增加 2。
  5. 否则(即 chase->x 不小于 run.x),将 chase->x 减少 2。
  6. 同理,对于纵坐标 y,如果 chase->y 小于 run.y,则 chase->y 增加 2;否则 chase->y 减少 2
  • 缺乏边界检查:可按照如下的案例变动:
    #include <limits.h> // 引入INT_MAX以确保不会除以零
    
    void Chase(struct ball* chase, struct ball run) {
        int dx = run.x - chase->x; // 计算目标和追击者之间的横坐标差
        int dy = run.y - chase->y; // 计算目标和追击者之间的纵坐标差
        
        // 确保不会除以零
        if (dx == 0 && dy == 0) {
            return;
        }
    
        // 限制移动速度
        int max_speed = 5; // 假设最大移动速度为5
        int speed = fmin(abs(dx), abs(dy)) * (dx < 0 ? -1 : 1); // 计算实际移动速度
        speed = fmin(speed, max_speed); // 限制速度不超过最大值
    
        // 更新追击者的位置
        if (dx < 0) {
            chase->x += speed;
        } else if (dx > 0) {
            chase->x -= speed;
        }
    
        if (dy < 0) {
            chase->y += speed;
        } else if (dy > 0) {
            chase->y -= speed;
        }
    
        // 确保移动后的位置不会超出边界
        int max_x = INT_MAX; // 假设横坐标的最大值
        int max_y = INT_MAX; // 假设纵坐标的最大值
        int min_x = INT_MIN; // 假设横坐标的最小值
        int min_y = INT_MIN; // 假设纵坐标的最大值
    
        chase->x = fmin(fmax(chase->x, min_x), max_x);
        chase->y = fmin(fmax(chase->y, min_y), max_y);
    }
    
    void aimove() {
        for (int i = 0; i < AI_NUM; i++) {
            if (ai[i].flag) {
                Chase(&ai[i], player);
                // 这里可以添加其他逻辑,例如检查玩家是否在AI的视野范围内
            }
        }
    }
    
    

进入游戏绘制

  • 本质:在有了结构体 相当于有了对象,根据结构体对象,使其在画面上显示
  •  
    
    
    IMAGE map(MAP_WIDTH, MAP_HEIGHT);
    POINT cameraPos;
    
    void CameraUpdate()
    {
    	
    	cameraPos.x = player.x - WIN_WIDTH / 2;
    	cameraPos.y = player.y - WIN_HEIGHT / 2;
    
    	if (cameraPos.x < 0) cameraPos.x = 0;
    	if (cameraPos.y < 0) cameraPos.y = 0;
    	if (cameraPos.x > MAP_WIDTH - WIN_WIDTH) cameraPos.x = MAP_WIDTH - WIN_WIDTH;
    	if (cameraPos.y > MAP_HEIGHT - WIN_HEIGHT) cameraPos.y = MAP_HEIGHT - WIN_HEIGHT;
    
    }
    
    
    void gamedraw() {
    
    	BeginBatchDraw();
    
    	SetWorkingImage(&map);//设置图像
    
    	setbkcolor(WHITE);//设置背景颜色
    
    	cleardevice();
    
    	//准备工作
    
    	//绘制图像
    	//1.食物圆
    	for (int i = 0; i< FOOD_NUM; i++) {
    		if (food[i].flag) {
    			setfillcolor(food[i].color);
    			solidcircle(food[i].x, food[i].y, food[i].r);
    		}
    	}
    
    	//2.ai圆
    	for (int i = 0; i < AI_NUM; i++)
    	{
    		if (ai[i].flag)
    		{
    			setfillcolor(ai[i].color);
    			solidcircle(ai[i].x, ai[i].y, ai[i].r);
    		}
    	}
    
    	//3.玩儿家圆
    	if (player.flag)
    	{
    		setfillcolor(player.color);
    		solidcircle(player.x, player.y, player.r);
    		settextcolor(BLACK);
    		setbkmode(TRANSPARENT);
    		// 确保文件编码支持中文,并且项目设置使用MBCS
    		outtextxy(player.x, player.y, "百年好合");
    
    	}
    
    	//显示页面
    	SetWorkingImage();
    	CameraUpdate();
    	putimage(0, 0, WIN_WIDTH, WIN_HEIGHT, &map, cameraPos.x, cameraPos.y);
    	EndBatchDraw();
    }
    
    
    
    

  • BeginBatchDraw();: 开始批处理绘图,这通常意味着接下来所有的绘图操作都将被累积起来,直到 EndBatchDraw 被调用时一次性渲染到屏幕上。

    SetWorkingImage(&map);: 设置当前工作图像为 map,这通常是游戏中的地图或者背景图像

  • setbkcolor(WHITE);: 设置背景颜色为白色。

  • cleardevice();: 清除设备,通常是清除屏幕,使其变为背景颜色。

  • 关注代码设计的核心逻辑  置于陌生的调用方法 了解能用即可

现在整个画面已经布局好 但是静态的  需要令其动起来

游戏运行  吃食物 根据按键动作

  • 吃食物:遇见食物的坐标自身的小球的半径扩大即可
  • double DisTance(struct ball b1, struct ball b2)
    {
    	return sqrt((double)(b1.x - b2.x) * (b1.x - b2.x) + (b1.y - b2.y) * (b1.y - b2.y));
    }
    
    void eatfood() {
    	//吃食物的逻辑  :  遇见食物就圆扩大
    	for (int i = 0; i < FOOD_NUM; i++)
    	{
    		if (food[i].flag && DisTance(player, food[i]) < player.r)
    		{
    			food[i].flag = false;
    			player.r += food[i].r / 4;
    		}
    	}
    }

    函数 DisTance

    DisTance 函数计算两个球体之间的欧几里得距离。这个函数对于游戏中的碰撞检测非常有用,比如判断玩家控制的球体是否接触到食物。函数的逻辑如下:

  • 接受两个 ball 类型的参数 b1 和 b2,代表两个球体的位置。
  • 返回两个球体之间的距离,使用欧几里得距离公式:(𝑥2−𝑥1)2+(𝑦2−𝑦1)2(x2​−x1​)2+(y2​−y1​)2​。

        函数 eatfood  函数处理玩家球体吃食物的逻辑。当玩家球体接触到食物时,球体会变大。函数的逻辑如下:

  • 遍历 food 数组,该数组包含多个食物元素。
  • 对于每个食物元素,检查它是否激活(food[i].flag 为 true)以及玩家球体与食物之间的距离是否小于玩家球体的半径(player.r)。
  • 如果条件满足,说明玩家球体已经吃到食物,将食物的 flag 设置为 false,表示食物已被吃掉。
  • 增加玩家球体的半径,增加的大小是食物半径的四分之一(food[i].r / 4)。这表示玩家球体在吃到食物后会变大。

游戏核心玩儿家运作

  • 实质:根据按键  玩家控制小球的移动
  • void playercontroller(int speed) {
    	//根据按键玩家控制移动
    	if (GetAsyncKeyState(VK_UP) && player.y - player.r >= 0)
    	{
    		player.y -= speed;
    	}
    	if (GetAsyncKeyState(VK_DOWN) && player.y + player.r < MAP_HEIGHT)
    	{
    		player.y += speed;
    	}
    	if (GetAsyncKeyState(VK_LEFT) && player.x - player.r >= 0)
    	{
    		player.x -= speed;
    	}
    	if (GetAsyncKeyState(VK_RIGHT) && player.x + player.r < MAP_WIDTH)
    	{
    		player.x += speed;
    	}
    }

    使用了 GetAsyncKeyState 函数来检测按键的状态

  • if (GetAsyncKeyState(VK_UP) && player.y - player.r >= 0): 这行代码检查 ‘上’ 箭头键是否被按下,并且玩家的当前位置的 y 坐标减去其半径是否大于或等于 0。如果这两个条件都为真,意味着玩家不在屏幕底部,可以向上移动。

  • player.y -= speed;: 如果 ‘上’ 箭头键被按下,并且玩家不在屏幕底部,玩家的 y 坐标会减去速度值,这样玩家就会在游戏世界中向上移动。

  • if (GetAsyncKeyState(VK_UP) && player.y - player.r >= 0): 这行代码检查 ‘上’ 箭头键是否被按下,并且玩家的当前位置的 y 坐标减去其半径是否大于或等于 0。如果这两个条件都为真,意味着玩家不在屏幕底部,可以向上移动。

  • player.y -= speed;: 如果 ‘上’ 箭头键被按下,并且玩家不在屏幕底部,玩家的 y 坐标会减去速度值,这样玩家就会在游戏世界中向上移动。。。。。。。。。。

补充:

`CameraUpdate` 函数是用于更新游戏相机位置的函数。相机在游戏中的作用是让玩家能够看到游戏世界的一部分,通常是一个窗口(视口)。这个函数确保相机的位置始终在游戏世界的可视区域内。
以下是 `CameraUpdate` 函数的原理和逻辑:
1. `cameraPos.x = player.x - WIN_WIDTH / 2;`:计算相机在 x 轴的位置。相机的 x 坐标是玩家的 x 坐标减去屏幕宽度的一半。这样,相机就会在玩家正中间的位置。
2. `cameraPos.y = player.y - WIN_HEIGHT / 2;`:计算相机在 y 轴的位置。相机的 y 坐标是玩家的 y 坐标减去屏幕高度的一半。这样,相机就会在玩家正中间的位置。
3. `if (cameraPos.x < 0) cameraPos.x = 0;`:如果相机的位置在 x 轴上小于 0,则将相机的位置设置为 0。这意味着相机不能移动到游戏世界的左侧边界之外。
4. `if (cameraPos.y < 0) cameraPos.y = 0;`:如果相机的位置在 y 轴上小于 0,则将相机的位置设置为 0。这意味着相机不能移动到游戏世界的顶部边界之外。
5. `if (cameraPos.x > MAP_WIDTH - WIN_WIDTH) cameraPos.x = MAP_WIDTH - WIN_WIDTH;`:如果相机的位置在 x 轴上大于游戏世界的宽度减去屏幕宽度,则将相机的位置设置为游戏世界的右侧边界。
6. `if (cameraPos.y > MAP_HEIGHT - WIN_HEIGHT) cameraPos.y = MAP_HEIGHT - WIN_HEIGHT;`:如果相机的位置在 y 轴上大于游戏世界的高度减去屏幕高度,则将相机的位置设置为游戏世界的底部边界。
通过这些逻辑,`CameraUpdate` 函数确保相机始终在游戏世界的可视区域内,无论玩家在游戏世界中如何移动。这对于保持玩家在屏幕上的中心位置并显示游戏世界的重要部分非常重要。

全部代码:

//#include "contains.h"
#include <stdbool.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<graphics.h>
#include <algorithm>
#include<math.h>
#include<mmsystem.h>
#include <iostream>
using namespace std;
#pragma comment(lib,"winmm.lib")


#define WIN_WIDTH 1024 
#define WIN_HEIGHT 640
#define MAP_WIDTH  (WIN_WIDTH*5)
#define MAP_HEIGHT (WIN_HEIGHT*5)
#define FOOD_NUM 1000
#define AI_NUM 500

struct ball
{
	int x;
	int y;
	int r;
	bool flag;
	DWORD color;
}player,food[FOOD_NUM],ai[AI_NUM];
/*结构体定*/

IMAGE map(MAP_WIDTH, MAP_HEIGHT);
POINT cameraPos;

void PlayBackgroundMusic() {
	// 使用相对路径打开音频文件,假设音频文件名为"example.mp3"
	if (mciSendString("open mus.mp3 alias BGM", NULL, 0, NULL) != 0) {
		std::cerr << "Failed to open the audio file." << std::endl;
		return;
	}

	// 播放音频并设置为循环播放
	if (mciSendString("play BGM repeat", NULL, 0, NULL) != 0) {
		std::cerr << "Failed to play the audio." << std::endl;
		mciSendString("close BGM", NULL, 0, NULL); // 如果播放失败,关闭文件
		return;
	}
}

void gameinit() {

	PlayBackgroundMusic();

	//bgm

	//随机种子
	srand((unsigned)time(NULL));
	
	//角色
	player.x = rand() % MAP_WIDTH;
	player.y = rand() % MAP_HEIGHT;
	player.r = 15;
	player.flag = true;
	player.color = RGB(rand() % 256, rand() % 256, rand() % 256);

	//食物
	for (int i = 0; i < FOOD_NUM; i++)
	{
		food[i].x = rand() % MAP_WIDTH;
		food[i].y = rand() % MAP_HEIGHT;
		food[i].r = rand() % 5 + 1;
		food[i].flag = true;
		food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
	}


	//自由移动者
	for (int i = 0; i < AI_NUM; i++)
	{
		ai[i].x = rand() % MAP_WIDTH;
		ai[i].y = rand() % MAP_HEIGHT;
		ai[i].r = rand() % 15 + 1;
		ai[i].flag = true;
		ai[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
	}
}


void Chase(struct ball* chase,struct ball run)
{
	chase->x < run.x ? chase->x += 2 : chase->x -= 2;
	chase->y < run.y ? chase->y += 2 : chase->y -= 2;
}

void aimove()
{
	for (int i = 0; i < AI_NUM; i++)
	{
		if (ai[i].flag)
		{
			Chase(&ai[i], player);
		}
	}
}

void CameraUpdate()
{
	
	cameraPos.x = player.x - WIN_WIDTH / 2;
	cameraPos.y = player.y - WIN_HEIGHT / 2;

	if (cameraPos.x < 0) cameraPos.x = 0;
	if (cameraPos.y < 0) cameraPos.y = 0;
	if (cameraPos.x > MAP_WIDTH - WIN_WIDTH) cameraPos.x = MAP_WIDTH - WIN_WIDTH;
	if (cameraPos.y > MAP_HEIGHT - WIN_HEIGHT) cameraPos.y = MAP_HEIGHT - WIN_HEIGHT;

}

void gamedraw() {

	BeginBatchDraw();

	SetWorkingImage(&map);//设置图像

	setbkcolor(WHITE);//设置背景颜色

	cleardevice();

	//准备工作

	//绘制图像
	//1.食物圆
	for (int i = 0; i< FOOD_NUM; i++) {
		if (food[i].flag) {
			setfillcolor(food[i].color);
			solidcircle(food[i].x, food[i].y, food[i].r);
		}
	}

	//2.ai圆
	for (int i = 0; i < AI_NUM; i++)
	{
		if (ai[i].flag)
		{
			setfillcolor(ai[i].color);
			solidcircle(ai[i].x, ai[i].y, ai[i].r);
		}
	}

	//3.玩儿家圆
	if (player.flag)
	{
		setfillcolor(player.color);
		solidcircle(player.x, player.y, player.r);
		settextcolor(BLACK);
		setbkmode(TRANSPARENT);
		// 确保文件编码支持中文,并且项目设置使用MBCS
		outtextxy(player.x, player.y, "百年好合");

	}

	//显示页面
	SetWorkingImage();
	CameraUpdate();
	putimage(0, 0, WIN_WIDTH, WIN_HEIGHT, &map, cameraPos.x, cameraPos.y);
	EndBatchDraw();
}

double DisTance(struct ball b1, struct ball b2)
{
	return sqrt((double)(b1.x - b2.x) * (b1.x - b2.x) + (b1.y - b2.y) * (b1.y - b2.y));
}

void eatfood() {
	//吃食物的逻辑  :  遇见食物就圆扩大
	for (int i = 0; i < FOOD_NUM; i++)
	{
		if (food[i].flag && DisTance(player, food[i]) < player.r)
		{
			food[i].flag = false;
			player.r += food[i].r / 4;
		}
	}
}

void playercontroller(int speed) {
	//根据按键玩家控制移动
	if (GetAsyncKeyState(VK_UP) && player.y - player.r >= 0)
	{
		player.y -= speed;
	}
	if (GetAsyncKeyState(VK_DOWN) && player.y + player.r < MAP_HEIGHT)
	{
		player.y += speed;
	}
	if (GetAsyncKeyState(VK_LEFT) && player.x - player.r >= 0)
	{
		player.x -= speed;
	}
	if (GetAsyncKeyState(VK_RIGHT) && player.x + player.r < MAP_WIDTH)
	{
		player.x += speed;
	}
}

int main() {
	initgraph(WIN_WIDTH, WIN_HEIGHT);//初始化界面
	gameinit();

	while (true) {
		aimove();
		gamedraw();
		eatfood();
		playercontroller(10);
	}
	/*getchar();*/
	return 0;
}

总结:至此简单实现的游戏完结,主要在于理清思路,拿此训练思维,孰能生巧。至于高级低级全看个人,随之成长日趋强键。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

飞天使-k8s知识点31-rancher的正确打开方式

文章目录 安装之前优化一下内核参数以及系统内核版本 rancher安装主要是使用以下命令nginx的配置为解决办法 安装之前优化一下内核参数以及系统内核版本 内核版本 4.17 cat > /etc/modules-load.d/iptables.conf <<EOF ip_tables iptable_filter EOF 然后重启服务器…

燃气电力瓶装气行业入户安检小程序开发

我们开发的小区业主入户安检小程序&#xff0c;旨在满足燃气、电力以及其他需要入户安检的行业需求。该程序支持自定义安检项目&#xff0c;实现线下实地安检与线上数据保存的完美结合。在安检过程中&#xff0c;我们可以拍照或录像&#xff0c;以确保安检的透明性和可追溯性&a…

亚马逊是如何铺设多个IP账号实现销量大卖的?

一、针对亚马逊平台机制&#xff0c;如何转变思路&#xff1f; 众所周知&#xff0c;一个亚马逊卖家只能够开一个账号&#xff0c;一家店铺&#xff0c;这是亚马逊平台明确规定的。平台如此严格限定&#xff0c;为的就是保护卖家&#xff0c;防止卖家重复铺货销售相同的产品&a…

Python | Leetcode Python题解之第75题颜色分类

题目&#xff1a; 题解&#xff1a; class Solution:def sortColors(self, nums: List[int]) -> None:n len(nums)p0, p2 0, n - 1i 0while i < p2:while i < p2 and nums[i] 2:nums[i], nums[p2] nums[p2], nums[i]p2 - 1if nums[i] 0:nums[i], nums[p0] num…

wePWNise:一款功能强大的红队Office宏VBA代码生成工具

关于wePWNise wePWNise是一款功能强大的Office宏VBA代码生成工具&#xff0c;该工具基于纯Python开发&#xff0c;可以帮助广大研究人员生成用于Office宏或模版的VBA代码&#xff0c;并以此来测试目标Office环境、应用程序控制和防护机制的安全性。 wePWNise的设计理念将自动化…

LNMT部署jpress

LNMT部署jpress 环境要求&#xff1a; MySQL版本5.6/5.7 tomcat版本9.0.65 源码安装MySQL5.7版 //源码安装MySQL5.7版1关闭防火墙 2创建mysql用户 3上传mysql5.7包&#xff08;https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.30-linux-glibc2.12-x86_64.tar.g…

向量数据库:PGVector

一、PGVector 介绍 PGVector 是一个基于 PostgreSQL 的扩展插件&#xff0c;为用户提供了一套强大的向量存储和查询的功能&#xff1a; 精确和近似最近邻搜索单精度&#xff08;Single-precision&#xff09;、半精度&#xff08;Half-precision&#xff09;、二进制&#xff…

使用动态种子的DGA:DNS流量中的意外行为

Akamai研究人员最近在域名系统&#xff08;DNS&#xff09;流量数据中观察到&#xff1a;使用动态种子的域名生成算法&#xff08;Domain Generation Algorithm&#xff0c;DGA&#xff09;的实际行为&#xff0c;与对算法进行逆向工程推测的预期行为之间存在一些差异。也就是说…

【最大公约 调和级数 并集查找】2709. 最大公约数遍历

涉及知识点 最大公约 调和级数 并集查找&#xff08;并差集) 质数、最大公约数、菲蜀定理 LeetCode 2709. 最大公约数遍历 给你一个下标从 0 开始的整数数组 nums &#xff0c;你可以在一些下标之间遍历。对于两个下标 i 和 j&#xff08;i ! j&#xff09;&#xff0c;当且…

tsconfig 备忘清单

前言 ❝ Nealyang/blog0 使用 ts 已多年&#xff0c;但是貌似对于 tsconfig 总是记忆不清&#xff0c;每次都是 cv 历史项目&#xff0c;所以写了这篇备忘录&#xff0c;希望能帮助到大家。 本文总结整理自 Matt Pocock 的一篇文章3&#xff0c;加以个人理解&#xff0c;并做了…

SpringBoot 使用Outlook邮箱发送邮件

目录 一、开启Outlook设置 二、依赖 三、配置文件 四、代码调用 一、开启Outlook设置 开启设置如图&#xff1a; 二、依赖 <!-- 邮箱依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mai…

【SpringBoot整合系列】SpringBoot整合RabbitMQ-消息可靠性

目录 确保消息的可靠性RabbitMQ 消息发送可靠性分析解决方案开启事务机制发送方确认机制单条消息处理消息批量处理 失败重试自带重试机制业务重试 RabbitMQ 消息消费可靠性如何保证消息在队列RabbitMQ 的消息消费&#xff0c;整体上来说有两种不同的思路&#xff1a;确保消费成…

C++音视频开发面试题

下面是音视频开发面试题精选&#xff1a; 1、纹理抗锯齿有哪些算法&#xff1f;各有哪些利弊&#xff1f;2、使用 OpenGL PBO 为什么能提高效率&#xff1f;3、iOS 如何使用分段转码&#xff0c;如何设置分片大小&#xff1f;4、VideoToolbox 中是不是不存在平面格式&#xff…

C#调用电脑摄像头拍照

1.打开VS2019&#xff0c;新建一个Form窗体&#xff0c;工具->NuGet包管理工具->管理解决方案的NuGet包&#xff0c;在浏览里搜索AForge.Controls、AForge.Video.DirectShow&#xff0c;安装AForge.Controls和AForge.Video.DirectShow 2.安装AForge组件完成后&#xff0c…

AI 绘画神器 Fooocus 本地部署指南:简介、硬件要求、部署步骤、界面介绍

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里&#xff0c;订阅后可阅读专栏内所有文章。 大家好&#xff0c;我是水滴~~ 随着人工智能技术的飞速发展&#xff0c;AI 绘画逐渐成为创意领域的新宠。Fooocus 作为一款免费开源的 AI 绘画工具&am…

mysql等保测评2.0命令-三级

版本 Win默认安装位置 C:\Program Files\MySQL\MySQL Server 8.0\bin 版本&#xff1a;select version() from dual; 身份鉴别 a应对登录的用户进行身份标识和鉴别&#xff0c;身份标识具有唯一性&#xff0c;身份鉴别信息具有复杂度要求并定期更换&#xff1b; 1、SELEC…

html--瀑布效果

<!doctype html> <html> <head> <meta charset"utf-8"> <title>瀑布效果</title><style> body {background: #222;color: white;overflow:hidden; }#container {box-shadow: inset 0 1px 0 #444, 0 -1px 0 #000;height: 1…

Windows远程桌面实现之十四:实现AirPlay接收端,让苹果设备(iOS,iPad等)屏幕镜像到PC端

by fanxiushu 2024-05-04 转载或引用请注明原始作者。 这个课题已经持续了好几年&#xff0c;已经可以说是很长时间了。 实现的程序是 xdisp_virt&#xff0c; 可以去github下载使用:GitHub - fanxiushu/xdisp_virt: xfsredir file system 一开始是基于测试镜像驱动的目的随便开…

【FX110】2024外汇市场中交易量最大的货币对是哪个?

作为最大、最流动的金融市场之一&#xff0c;外汇市场每天的交易量高达几万亿美元&#xff0c;涉及到数百种货币。不同货币对的交易活跃程度并不一样&#xff0c;交易者需要根据货币对各自的特点去进行交易。 全年外汇市场中涉及美元的外汇交易超过50%&#xff01; 实际上&…

对象复制工具Orika,快速实现两个java对象的属性赋值

一、maven依赖引入orika <dependency><groupId>ma.glasnost.orika</groupId><artifactId>orika-core</artifactId><version>1.5.4</version></dependency>二、Orika工具类 import io.swagger.annotations.ApiModel; import io…