【C语言】飞机大作战

 前言:

飞机大作战游戏是一种非常受欢迎的射击类游戏,玩家需要控制一架战斗机在屏幕上移动,击落敌机以获得分数。本游戏使用C语言编写,旨在帮助初学者了解游戏开发的基本概念和技巧。

在开始编写代码之前,我们需要先了解一下游戏的基本规则和功能:

  1. 游戏界面:游戏界面是一个矩形区域,玩家可以在这个区域内控制战斗机移动和射击。

  2. 战斗机:玩家控制的战斗机可以在游戏界面内自由移动,按下特定键可以发射子弹和开启技能击落敌机。

  3. 敌机:敌机会从屏幕的一侧出现,并沿着直线路径向另一侧移动。玩家需要击落敌机以获得分数。

  4. 分数:玩家每击落一架敌机,分数会增加。

  5. 游戏结束:当玩家飞机被敌机撞到到或者得分为0时,游戏结束。

接下来,我们将通过以下几个步骤来实现这个游戏:

  1. 初始化游戏界面和战斗机。

  2. 处理键盘输入,实现战斗机的移动和射击。

  3. 生成敌机,并控制其移动。

  4. 检测战斗机与敌机之间的碰撞,更新分数和技能充能值。

  5. 判断游戏是否结束。

通过学习这个游戏的开发过程,初学者将能够掌握C语言编程的基本技巧。

1. 打印菜单:

void menu()
{printf("--------------飞机大作战--------------\n");printf("|                                    |\n");printf("|             1.开始游戏             |\n");printf("|             0.退出游戏             |\n");printf("|             W/A/S/D移动            |\n");printf("|           空格射击 E/R技能         |\n");printf("|                                    |\n");printf("--------------------------------------\n");
}
int main()
{system("color b");int input = 0;menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("输入有误,请重新输入:\n");break;}return 0;
}

2. 写一个存放信息的数组

	int arr[Col][Row] = { 0 };

3. 写一个打印数组信息的函数

飞机大作战的要素无非就是路、围墙、玩家飞机、敌机、子弹这五个元素,要想在打印出这几个元素,我们只需在写一个函数在二维数组中存放这个五个元素的信息(用0-4代替),然后再写一个打印信息的函数分别出二维数组中对应的信息。

void DisPlay(int arr[Col][Row])
{gotoxy(0, 0);for(int i=0;i<Col;i++){for (int j = 0; j < Row; j++){if (arr[i][j] == 0){printf(" ");}if (arr[i][j] == 1){printf("█");}if (arr[i][j] == 2){printf("*");}if (arr[i][j] == 3){printf("$");}if (arr[i][j] == 4){printf("|");}}printf("\n");}printf("得分:%d ", score);printf("EnemySleep=%d ", EnemySleep);printf("skill1(20)=%d ", skill1);printf("skill2(5)=%d ", skill2);Sleep(20);
}

4. 写一个函数来初始化数组的信息

void InSet(int arr[Col][Row])
{//路--0//墙--1//玩家飞机--2//敌机--3//子弹--4
}

5. 初始化围墙

数组最边边的位置我们都让它等于1,这样就可以把游戏界面围起来了。

//墙--1
for (int i = 0; i < Col; i++)
{arr[i][0] = 1;arr[i][Row - 1] = 1;
}
for (int i = 0; i < Row; i++)
{arr[0][i] = 1;arr[Col - 1][i] = 1;
}

6. 初始化玩家飞机

玩家飞机刚开始应该出现在下侧的中央位置,所以将这个位置的坐标对应的值初始化为2。

//玩家飞机--2
arr[PlayerPlane_y][PlayerPlane_x] = 2;

7. 玩家操作飞机

通过按下A/W/S/D键来控制飞机的移动,空格键来控制飞机发射子弹,要想实现这个功能我们需要用到getch()函数,这个函数用于从标准输入(通常是键盘)获取一个字符,而不需要用户按下回车键。这个函数在Windows操作系统下的conio.h头文件中定义,而在Unix/Linux系统下,通常使用termios.hunistd.h头文件中的函数来实现类似的功能。

char ch = getch();
if (ch == 'w' && arr[PlayerPlane_y - 1][PlayerPlane_x] == 0)
{arr[PlayerPlane_y][PlayerPlane_x] = 0;PlayerPlane_y--;arr[PlayerPlane_y][PlayerPlane_x] = 2;
}
if (ch == 'a' && arr[PlayerPlane_y][PlayerPlane_x - 1] == 0)
{arr[PlayerPlane_y][PlayerPlane_x] = 0;PlayerPlane_x--;arr[PlayerPlane_y][PlayerPlane_x] = 2;
}
if (ch == 's' && arr[PlayerPlane_y + 1][PlayerPlane_x] == 0)
{arr[PlayerPlane_y][PlayerPlane_x] = 0;PlayerPlane_y++;arr[PlayerPlane_y][PlayerPlane_x] = 2;
}
if (ch == 'd' && arr[PlayerPlane_y][PlayerPlane_x + 1] == 0)
{arr[PlayerPlane_y][PlayerPlane_x] = 0;PlayerPlane_x++;arr[PlayerPlane_y][PlayerPlane_x] = 2;
}
if (ch == ' ')
{Bullet_y = PlayerPlane_y - 1;Bullet_x = PlayerPlane_x;arr[Bullet_y][Bullet_x] = 4;
}
}

8. 子弹上移

子弹上移一格就调用一次DisPlay函数打印内容这样就实现了子弹上移的效果,这时需要用到到我们的while循环来循环子弹上移的函数和打印的函数,而子弹是由玩家按键产生的,所以这个while还需要循环上玩家操作飞机的函数,但是getch()会让while停止下来,玩家按键后才会继续,导致玩家按一次键盘按键,子弹才会上移一次,样就子弹就出现不了的这连续上移的效果了,所以我们需要在玩家操作的函数加上if(_kbhit())的判断语句函数,它会判断是否有按键按下来,如果没有就不执行getch()函数,继续循环。

_kbhit() 是一个C语言中的函数,用于检测键盘是否有按键被按下。它通常在Windows操作系统下的conio.h头文件中定义。该函数不接受任何参数,并返回一个整数值。如果键盘上有按键被按下,则返回非零值(通常是1),否则返回0。

while (1)
{//玩家操作PlayerPlay(arr);//打印棋盘DisPlay(arr);//子弹与敌机的操作BulletEnemy(arr);
}

在循环打印的时候它会框框打印根本就看不清游戏界面,所以在这里还需要使用到光标的知识 :

在C语言中,光标通常指的是控制台或终端中的文本输入位置指示器。它显示了用户当前输入或输出的位置。在编写C程序时,有时需要对光标的显示和位置进行控制,以便创建更复杂的用户界面或处理特定的输入输出需求。

在Windows操作系统下,可以使用conio.h头文件中提供的函数来控制光标。

因为它会在光标的位置输出信息,所以我们在每次打印前将光标的位置置为(0,0)就可以了。

但是光标还会在那框框的闪,非常的碍眼,所以我们还需要使用函数将光标隐藏。

void HideCursor()
{CONSOLE_CURSOR_INFO cursor_info = { 1,0 };  //第二个值为0,表示隐藏光标SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

9. 初始化敌机

在这里我们需要随机生成5架敌机出现在游戏界面上侧1-3格的位置,所以需要使用一个大小为5的数组接受随机数的值。

//敌机--3
for (int i = 0; i < Count; i++)
{Enemy_y[i] = rand() % 3 + 1;Enemy_x[i] = rand() % Row + 1;//防止敌机生成在围墙上if (Enemy_x[i] >= Row - 1)Enemy_x[i] -= 2;arr[Enemy_y[i]][Enemy_x[i]] = 3;
}

10. 敌机的下移

如果敌机也像子弹一样直接进去循环的话,那么敌机会移动得非常快,所以我们需要定义两个全局变量sleep和EnemySleep来控制敌机的移动速度,例如给EnemySleep赋值一个20,然后sleep赋值一个0,随后sleep在while循环中循环一次就加1,当sleep等于EnemySleep时我们才给敌机进行一次下移的操作,这样就相当于while每循环20次,敌机才下移一次。

在敌机下的过程中我们可能无法打中敌机,而使敌机下降到了最下侧,这时就得让敌机在触碰到围墙前一格消失,然后重新在上侧生成新的敌机。

在敌机下移的过程中可能会碰到玩家的飞机,这时游戏就得结束了,然后告诉玩家游戏结束。控制游戏结束需要用到system("pause")和exit()这两个函数。

system("pause")的作用是在Windows系统的命令行窗口中暂停程序的执行,等待用户按下任意键后继续执行。这通常用于调试程序时,以便查看程序运行过程中的输出结果。

exit(0);是C/C++语言中用于终止程序执行的语句。其中,参数0表示程序正常退出,非零值表示程序异常退出。在程序执行到该语句时,程序会立即停止运行,并返回给操作系统一个退出状态码。

//控制敌机的速度
if (sleep < EnemySleep)
{sleep++;
}
else if (sleep > EnemySleep)
{sleep = 0;
}
for (int i = 0; i < Count; i++)
{//敌机击中玩家飞机的处理if (PlayerPlane_y == Enemy_y[i] && PlayerPlane_x == Enemy_x[i] || score < 0){printf("  /\\_/\\  \n");printf(" ( o.o ) \n");printf("  > ^ < \n");printf("游戏失败!\n");printf("\a");system("pause");exit(0);}//敌机到达最底面的处理if (Enemy_y[i] >= Col - 2){score -= 100;arr[Enemy_y[i]][Enemy_x[i]] = 0;Enemy_y[i] = rand() % 3 + 1;Enemy_x[i] = rand() % Row + 1;if (Enemy_x[i] >= Row - 1)Enemy_x[i] -= 2;arr[Enemy_y[i]][Enemy_x[i]] = 3;}//敌机下移的处理if (sleep == EnemySleep){for (int j = 0; j < Count; j++){arr[Enemy_y[j]][Enemy_x[j]] = 0;sleep = 0;Enemy_y[j]++;arr[Enemy_y[j]][Enemy_x[j]] = 3;}}
}

 11. 游戏数值的设定

(1)敌机加速的分数阈值

  • 当玩家得分达到 2000 分时,敌机的移动速度增加 2
  • 当玩家得分再次增加 2000 分,即达到 4000 分时,敌机的移动速度再增加 2
  • 以此类推,每当玩家得分增加 2000 分,敌机的速度增加 2

(2)打爆一架敌机的得分

  • 打爆一架普通敌机,玩家得到 100 分。

(3)一架敌机到底部消失的失分

  • 如果一架敌机到达屏幕底部而未被击落,玩家失去 100 分。

12. 游戏的优化

为了使游戏更具可玩性,我们可以给玩家飞机加上一些技能,在这里的我设定了E/R是释放技能的指令,这个加在玩家操作飞机的函数哪里就可以了,这两个技能都是可发射范围更广的子弹,当然了这两个技能也不是无限释放的,是需要达到一定的值才能释放的,这里我们可以设定一个变量来存放一个技能的充能值,打爆一架敌机就给充能值加1,当这个值达到的我们所规定的满能值时才能接受释放技能的指令。

//技能指令
if (ch == 'r')
{if (skill1 == 20){for (int i = 1; i < Row - 1; i++){skill1 = 0;Bullet_y = PlayerPlane_y - 1;Bullet_x = i;arr[Bullet_y][Bullet_x] = 4;}}
}
if (ch == 'e')
{int left = PlayerPlane_x - 3;int right = PlayerPlane_x + 3;if (skill2 == 5){for (int i = left; i < right; i++){if (i > 0 && i < Row - 1){skill2 = 0;Bullet_y = PlayerPlane_y - 1;Bullet_x = i;arr[Bullet_y][Bullet_x] = 4;}}}
}

源码: 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<Windows.h>
#include<time.h>
#define Count 5
#define Col 40//列
#define Row 40//行
//玩家飞机坐标
int PlayerPlane_y = Col - 2;
int PlayerPlane_x = Row / 2 - 1;
//子弹坐标
int Bullet_y;
int Bullet_x;
//敌机坐标
int Enemy_y[Count] = { 0 };
int Enemy_x[Count] = { 0 };
//敌机的移动速度
int EnemySleep = 20;
int sleep = 0;
//分数
int score = 0;
//技能充能
int skill1 = 20;
int skill2 = 5;
void menu()
{printf("--------------飞机大作战--------------\n");printf("|                                    |\n");printf("|             1.开始游戏             |\n");printf("|             0.退出游戏             |\n");printf("|             W/A/S/D移动            |\n");printf("|           空格射击 E/R技能         |\n");printf("|                                    |\n");printf("--------------------------------------\n");
}//隐藏光标
void HideCursor()
{CONSOLE_CURSOR_INFO cursor_info = { 1,0 };  //第二个值为0,表示隐藏光标SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}// 光标移到(X, Y)位置
void gotoxy(int x, int y)
{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos;pos.X = x;pos.Y = y;SetConsoleCursorPosition(handle, pos);
}void DisPlay(int arr[Col][Row])
{gotoxy(0, 0);for(int i=0;i<Col;i++){for (int j = 0; j < Row; j++){if (arr[i][j] == 0){printf(" ");}if (arr[i][j] == 1){printf("█");}if (arr[i][j] == 2){printf("*");}if (arr[i][j] == 3){printf("$");}if (arr[i][j] == 4){printf("|");}}printf("\n");}printf("得分:%d ", score);printf("EnemySleep=%d ", EnemySleep);printf("skill1(20)=%d ", skill1);printf("skill2(5)=%d ", skill2);Sleep(20);
}void InSet(int arr[Col][Row])
{srand(time(NULL));//路--0//墙--1for (int i = 0; i < Col; i++){arr[i][0] = 1;arr[i][Row - 1] = 1;}for (int i = 0; i < Row; i++){arr[0][i] = 1;arr[Col - 1][i] = 1;}//玩家飞机--2arr[PlayerPlane_y][PlayerPlane_x] = 2;//敌机--3for (int i = 0; i < Count; i++){Enemy_y[i] = rand() % 3 + 1;Enemy_x[i] = rand() % Row + 1;if (Enemy_x[i] >= Row - 1)Enemy_x[i] -= 2;arr[Enemy_y[i]][Enemy_x[i]] = 3;}//子弹--4
}
void PlayerPlay(int arr[Col][Row])
{if (_kbhit())//判断是否有按键按下{char ch = getch();if (ch == 'w' && arr[PlayerPlane_y - 1][PlayerPlane_x] == 0){arr[PlayerPlane_y][PlayerPlane_x] = 0;PlayerPlane_y--;arr[PlayerPlane_y][PlayerPlane_x] = 2;}if (ch == 'a' && arr[PlayerPlane_y][PlayerPlane_x - 1] == 0){arr[PlayerPlane_y][PlayerPlane_x] = 0;PlayerPlane_x--;arr[PlayerPlane_y][PlayerPlane_x] = 2;}if (ch == 's' && arr[PlayerPlane_y + 1][PlayerPlane_x] == 0){arr[PlayerPlane_y][PlayerPlane_x] = 0;PlayerPlane_y++;arr[PlayerPlane_y][PlayerPlane_x] = 2;}if (ch == 'd' && arr[PlayerPlane_y][PlayerPlane_x + 1] == 0){arr[PlayerPlane_y][PlayerPlane_x] = 0;PlayerPlane_x++;arr[PlayerPlane_y][PlayerPlane_x] = 2;}if (ch == ' '){Bullet_y = PlayerPlane_y - 1;Bullet_x = PlayerPlane_x;arr[Bullet_y][Bullet_x] = 4;}if (ch == 'r'){if (skill1 == 20){for (int i = 1; i < Row - 1; i++){skill1 = 0;Bullet_y = PlayerPlane_y - 1;Bullet_x = i;arr[Bullet_y][Bullet_x] = 4;}}}if (ch == 'e'){int left = PlayerPlane_x - 3;int right = PlayerPlane_x + 3;if (skill2 == 5){for (int i = left; i < right; i++){if (i > 0 && i < Row - 1){skill2 = 0;Bullet_y = PlayerPlane_y - 1;Bullet_x = i;arr[Bullet_y][Bullet_x] = 4;}}}}}
}
void BulletEnemy(int arr[Col][Row])
{for (int i = 0; i < Col; i++){for (int j = 0; j < Row; j++){if (arr[i][j] == 4){for (int k = 0; k < Count; k++){//子弹击中敌机的处理if (i == Enemy_y[k] && j == Enemy_x[k]){if (skill1 < 20){skill1++;}if (skill2 < 5){skill2++;}score += 100;arr[Enemy_y[k]][Enemy_x[k]] = 0;Enemy_y[k] = rand() % 3 + 1;Enemy_x[k] = rand() % Row + 1;if (Enemy_x[k] >= Row - 1)Enemy_x[k] -= 2;arr[Enemy_y[k]][Enemy_x[k]] = 3;//每2000分敌机加速if (score % 2000 == 0 && EnemySleep > 4){EnemySleep -= 2;}}}//子弹的移动if (arr[i][j] == 4){arr[i][j] = 0;if (i > 1){arr[i - 1][j] = 4;}}}}}//敌机的移动if (sleep < EnemySleep){sleep++;}else if (sleep > EnemySleep){sleep = 0;}for (int i = 0; i < Count; i++){if (PlayerPlane_y == Enemy_y[i] && PlayerPlane_x == Enemy_x[i] || score < 0){printf("  /\\_/\\  \n");//敌机击中玩家飞机的处理printf(" ( o.o ) \n");printf("  > ^ < \n");printf("游戏失败!\n");printf("\a");system("pause");exit(0);}//敌机到达最底面的处理if (Enemy_y[i] >= Col - 2){score -= 100;arr[Enemy_y[i]][Enemy_x[i]] = 0;Enemy_y[i] = rand() % 3 + 1;Enemy_x[i] = rand() % Row + 1;if (Enemy_x[i] >= Row - 1)Enemy_x[i] -= 2;arr[Enemy_y[i]][Enemy_x[i]] = 3;}//敌机下移的处理if (sleep == EnemySleep){for (int j = 0; j < Count; j++){arr[Enemy_y[j]][Enemy_x[j]] = 0;sleep = 0;Enemy_y[j]++;arr[Enemy_y[j]][Enemy_x[j]] = 3;}}}}void game()
{//设置一个存放信息的数组int arr[Col][Row] = { 0 };//隐藏光标HideCursor();//放置信息InSet(arr);//打印游戏界面DisPlay(arr);//玩家移动while (1){//玩家操作PlayerPlay(arr);//打印棋盘DisPlay(arr);//子弹与敌机的操作BulletEnemy(arr);}
}
int main()
{system("color b");int input = 0;menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("输入有误,请重新输入:\n");break;}return 0;
}

最终效果

飞机大作战

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

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

相关文章

记录一些mac电脑重装mysql和pgsql的坑

为什么要重装,是想在mac电脑 创建data目录…同事误操作,导致电脑重启不了.然后重装系统后,.就连不上数据库了.mysql和pgsql两个都连不上.网上也查了很多资料.实在不行,.就重装了… 重装mysql. 1.官网下载 https://www.mysql.com/downloads/ 滑到最下面 选择 选择对应的芯片版本…

设计推特(Leetcode355)

例题&#xff1a; https://leetcode.cn/problems/design-twitter/ 分析&#xff1a; 推特其实类似于微博&#xff0c;在微博中可以发送文章。 求解这类题目&#xff0c;我们需要根据题目需求&#xff0c;利用面向对象的思想&#xff0c;先对需求做一个抽象&#xff0c;看看能…

代码随想录训练营第34天| 435. 无重叠区间、763.划分字母区间、56. 合并区间

35. 无重叠区间 题目链接&#xff1a;435. 无重叠区间 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals, (x1, x2) -> {if (x1[0] ! x2[0]) {return x1[0] - x2[0];} else {return …

字符串(算法竞赛)--Manacher(马拉车)算法

1、B站视频链接&#xff1a;F05 Manacher(马拉车)_哔哩哔哩_bilibili 题目链接&#xff1a;【模板】manacher - 洛谷 ​ #include <bits/stdc.h> using namespace std; const int N3e7; char a[N],s[N]; int d[N];//回文半径函数void get_d(char*s,int n){d[1]1;for(int…

领域驱动设计(Domain-Driven Design DDD)——通过重构找到深层次模型2

五、应用分析模式 深层模型和柔性设计并非唾手可得。想要取得进展&#xff0c;必须学习大量领域知识并进行充分的讨论&#xff0c;还需要经历大量的尝试和失败。在实际的研究领域问题实践时&#xff0c;有一些成熟的模式可以供我们借鉴和套用。这样我们可以从这个起点来重构和试…

vim恢复.swp [BJDCTF2020]Cookie is so stable1

打开题目 扫描目录得到 关于 .swp 文件 .swp 文件一般是 vim 编辑器在编辑文件时产生的&#xff0c;当用 vim 编辑器编辑文件时就会产生&#xff0c;正常退出时 .swp 文件被删除&#xff0c;但是如果直接叉掉&#xff08;非正常退出&#xff09;&#xff0c;那么 .swp 文件就会…

【android】SDK兼容低版本Lambda的一次尝试

背景信息 背景是最近我们提供的SDK给合作方接入&#xff0c;对方接入的时候编译报这个错误。 报错内容如下 Exception in thread "main" java.lang.IllegalStateException: Expected a load for Lorg/yeshen/hello/test/u9; to set up parameter 0 for org/yeshen…

spring-security 过滤器 (三)

spring-security过滤器 版本信息过滤器配置过滤器配置相关类图过滤器加载过程创建 HttpSecurity Bean 对象创建过滤器 过滤器作用ExceptionTranslationFilter 自定义过滤器 本章介绍 spring-security 过滤器配置类 HttpSecurity&#xff0c;过滤器加载过程&#xff0c;自定义过…

信息抽取(UIE):使用自然语言处理技术提升证券投资决策效率

一、引言 在当今快速变化的证券市场中&#xff0c;信息的价值不言而喻。作为一名资深项目经理&#xff0c;我曾领导一个关键项目&#xff0c;旨在通过先进的信息抽取技术&#xff0c;从海量的文本数据中提取关键事件&#xff0c;如企业并购、新产品发布以及政策环境的变动。这些…

Open CASCADE学习|几何数据结构

在几何引擎内一般把数据分成两类&#xff1a;几何信息与拓扑信息。二者可以完整地表达出实体模型&#xff0c;彼此相互独立、又互相关联。几何信息是指构成几何实体的各几何元素在欧式空间中的位置、大小、尺寸和形状信息。例如一条空间的直线&#xff0c;可以用两端点的位置矢…

[ffmpeg] 获取编译配置信息

背景 想使用 ffmpeg 的 n 卡编码器&#xff0c;发现 find_encode 失败&#xff0c;想看看是不是编译 ffmpeg 的时候有些功能没有打开。 如何获取编译配置信息 api const char* configuration avcodec_configuration(); printf("FFmpeg file configuration: %s\n"…

五种多目标优化算法(MOCS、MOFA、NSWOA、MOAHA、MOPSO)性能对比(提供MATLAB代码)

一、5种多目标优化算法简介 多目标优化算法是用于解决具有多个目标函数的优化问题的一类算法。其求解流程通常包括以下几个步骤&#xff1a; 1. 定义问题&#xff1a;首先需要明确问题的目标函数和约束条件。多目标优化问题通常涉及多个目标函数&#xff0c;这些目标函数可能…

【人脸朝向识别与分类预测】基于BP神经网络

课题名称&#xff1a;基于BP神经网络的人脸朝向识别分类 版本日期&#xff1a;2024-02-20 运行方式&#xff1a;直接运行BP0503.m文件 代码获取方式&#xff1a;私信博主或 QQ:491052175 模型描述&#xff1a; 采集到一组人脸朝向不同角度时的图像&#xff0c;图像来自不同…

17.材质和外观

1.图形学中的材质 在图形学中&#xff0c;材质&#xff08;Material&#xff09;是用来描述物体外观和表面特性的属性集合。它包含了控制光的反射、折射、吸收以及其他光学效果的信息&#xff0c;从而决定了物体在渲染过程中的外观。 渲染方程中那一项和材质有关&#xff1f; …

c#高级-正则表达式

正则表达式是由普通字符和元字符&#xff08;特殊符号&#xff09;组成的文字形式 应用场景 1.用于验证输入的邮箱是否合法。 2.用于验证输入的电话号码是否合法。 3.用于验证输入的身份证号码是否合法。等等 正则表达式常用的限定符总结&#xff1a; 几种常用的正则简写表达式…

[VNCTF2024]-Web:CheckIn解析

查看网页 一款很经典的游戏&#xff0c;而且是用js写的 在调试器里面我们可以看见&#xff0c;如果游戏通关的话&#xff0c;它会进行一系列操作&#xff0c;包括使用console.log(_0x3d9d[0]);输出_0x3d9d[0]到控制台&#xff0c;那我们就直接在点击在控制台求出它的值

架构面试题汇总(一)

目录 系统设计性能优化分布式系统安全性微服务架构数据库设计 系统设计 问题&#xff1a; 在设计高可用的电商系统时&#xff0c;你会考虑哪些关键因素来确保系统的可扩展性&#xff1f; 答案&#xff1a; 水平扩展与垂直扩展&#xff1a;设计系统时应考虑支持通过增加更多服…

C++ //练习 8.9 使用你为8.1.2节(第281页)第一个练习所编写的函数打印一个istringstream对象的内容。

C Primer&#xff08;第5版&#xff09; 练习 8.9 练习 8.9 使用你为8.1.2节&#xff08;第281页&#xff09;第一个练习所编写的函数打印一个istringstream对象的内容。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /*****…

独立版表情包小程序完整版源码前后端源码,附带系统搭建教程

搭建要求&#xff1a; 1.系统要求Nginx 1.18.0PHP-7.2mysql5.6&#xff0c;开启 ssl&#xff0c;php需要安装 sg11 扩展 2.设置伪静态 location / { index index.php index.html index.htm; if (!-e $request_filename) { rewrite ^/(.*)$ /index.php?s$1; } } location /a…

容器镜像详解

1. 镜像组成 一个标准的OCI容器镜像由index, manifest, config, image layers这几个部分组成。 以docker镜像为例&#xff0c;下载的镜像文件保存在/var/lib/docker/目录下面 image/overlay2子目录下面保存着镜像相关的一些元数据 在下面的介绍主要以nginx:latest镜像为例子…