《光影营造》 游戏的单页文案 概念: 一款基于光影投射的3D益智解谜游戏。玩家通过旋转看似无序的抽象物体,使其在墙上投射出具有特定意义的、与中国古建筑相关的剪影。核心体验是在沉浸式的解谜过程中,感受东方建筑的结构之美与意境之韵,以一种全新的交互方式实现文化科普。 游戏玩法: 核心机制: 玩家在三维空间中自由旋转一个或多个物体。核心目标是调整物体的角度,直到其投影与关卡预设的古建元素剪影(如斗拱、榫卯、角楼轮廓等)完全重合。 关卡递进: 游戏关卡由易到难,从单个的建筑构件(如瓦当、窗棂),到复杂的组合结构(如斗拱),再到完整的建筑剪影(如佛塔、牌楼),可以系统性地展示中国古建筑的魅力。 科普互动: 每当成功解开一个谜题,屏幕上会浮现关于该建筑元素的精美图文或动态展示,介绍其历史、功能与文化内涵。 艺术风格: 视觉: 整体风格空灵、静谧,富有禅意。采用简约的3D场景,突出光影的核心地位。投影背景可模拟宣纸或斑驳古墙的质感。被旋转的物体在视觉上可能呈现为木头、铜、玉等富有中国元素的材质。 听觉: 背景音乐以古琴、箫等舒缓的古典乐器为主,可以直接去找个古风歌曲去掉人声部分?交互音效(如旋转物体、解谜成功)清脆、雅致,共同营造一个能让人静下心来思考和欣赏的沉浸式氛围。 界面(UI): UI设计极简,不需要我们太多功夫设计,功能图标可参考中国印章或窗棂的样式,字体设计带有书法韵味,与整体艺术风格保持高度统一。 创意亮点: 玩法的独特性: 将“光影寻物”这一成熟有趣的玩法,首次深度应用于“中国古建筑”这一垂直文化主题,形式新颖,令人耳目一新。 “形”与“意”的结合: 游戏过程本身就是一种“从无序到有序,从抽象到具象”的创造过程,这与建筑从零件到整体的“营造”理念不谋而合,让玩家在操作中直观地领悟建筑的形态哲学。 极强的文化传播潜力: 游戏不依赖复杂的语言,通过直观的视觉和互动,能够跨越文化背景,向所有玩家展示中华建筑文明的精巧与智慧。 为什么这个玩法非常适合? 符合参赛类别要求: 大赛的“数媒类作品创作”明确列出了 “古建科普游戏和交互设计” 以及 “艺术科技融合——AI+、VR+等数字技术应用”。这游戏正是一种典型的交互设计,并且其光影玩法本身就是艺术与技术的完美结合。 趣味性与教育性兼备: 这种玩法通过解谜吸引玩家,让玩家在“玩”的过程中,不知不觉地认识和学习中国古建筑的各种元素。它将枯燥的建筑知识转化为了直观、可操作的视觉挑战。 极强的创意和表现空间: 光与影的艺术形式本身就带有一种神秘和美感,非常适合展现中国古建筑的意境和精巧。 如何将游戏玩法与“中国古代建筑”主题结合? 这里的关键在于,让玩家最终拼出的“影子”成为中国古建筑的标志性元素。 谜题设计(影子): 部件剪影: 影子的目标可以是古建筑的标志性部件,比如一个精巧的 斗拱、一个复杂的 榫卯结构、一扇典雅的 花窗、屋顶上的一只 脊兽。 建筑轮廓: 影子的目标可以是一座著名建筑的剪影,比如 天坛祈年殿、故宫角楼、一座 佛塔 或是一个 牌楼 的轮廓,这些网上的3d建模十分多,甚至都不需要我们自己建模。 文字与符号: 影子甚至可以是中国古代与建筑相关的文字,比如“天人合一”的印章形态,或者是一个古老的“营造”字样。 旋转物体设计: 拆解的部件: 为了拼出一个完整的“斗拱”影子,玩家需要旋转的可能是几块看似毫无关联的木材,而这些木材恰好是构成这个斗拱的零件。这能让玩家在无形中理解其构造。 意象化的物体: 旋转的物体可以是抽象的,但其线条和组合方式中蕴含着中国古典美学元素。 关卡与场景设计: 游戏可以按照建筑类型(如宫殿、园林、民居、桥梁)、朝代或地域来划分章节。 每个章节的背景音乐、界面设计都可以融入对应主题的文化元素,营造出沉浸式的体验。 总而言之, 将这种光影寻踪的游戏机制应用于中国古建筑主题,是一个绝佳的创意。它不仅完美契合了比赛的要求,而且能够以一种新颖、有趣的方式,让更多人领略到中国古代建筑的结构之美和文化之韵,是弘扬传统文化的优秀载体。

异步编程作业
using System; using System.Diagnostics; using System.Threading.Tasks; namespace BreakfastMakerSystem { public class Item<T> { public string Name { get; } // 物品名称 (公开只读) // 例如: "咖啡", "鸡蛋" public T Spec { get; } // 物品规格 (泛型,公开只读) // 例如: 对于咖啡, T是int, Spec是容量(ml); 对于土豆, T是string, Spec是描述。 public Item(string name, T spec) { Name = name; Spec = spec; } // 构造函数,用于初始化物品。 } public class BreakfastMaker { #region 委托与事件定义 public delegate Task CookingStep(); // 定义一个委托,用于封装所有无参数、返回Task的烹饪步骤。 // 委托就像一个方法的“模板”或“签名”,所有符合这个签名的方法都可以被它引用。 // 返回 Task 是为了适配异步方法。 public delegate void StepStartedHandler(string stepName); // 定义步骤开始事件的委托。 // 它规定了所有订阅 StepStarted 事件的方法必须接受一个 string 参数 (步骤名) 且无返回值。 public delegate void StepCompletedHandler(string stepName, TimeSpan duration); // 定义步骤完成事件的委托。 // 它规定了所有订阅 StepCompleted 事件的方法必须接受 string (步骤名) 和 TimeSpan (耗时) 两个参数。 public event StepStartedHandler StepStarted; // 步骤开始事件。 // 外部代码可以 "订阅" (+=) 这个事件,当事件被 "触发" 时,所有订阅的方法都会被调用。 // 这是一种典型的 "发布-订阅" 模式,实现了逻辑解耦。 public event StepCompletedHandler StepCompleted; // 步骤完成事件。 #endregion #region 异步制作方法 public async Task PourCoffeeAsync(Item<int> coffee) { Stopwatch stopwatch = new(); StepStarted?.Invoke("倒咖啡"); // 触发步骤开始事件,通知所有订阅者 await Task.Delay(500); // 使用 Task.Delay 模拟倒咖啡的耗时操作 (500毫秒) Console.WriteLine($"倒入 {coffee.Spec}ml {coffee.Name}"); stopwatch.Stop(); StepCompleted?.Invoke("倒咖啡", stopwatch.Elapsed); // 触发步骤完成事件,并传递耗时 } // 异步倒咖啡 public async Task FryEggsAsync(Item<int> eggs) { var stopwatch = Stopwatch.StartNew(); StepStarted?.Invoke("煎鸡蛋"); for (int i = 0; i < eggs.Spec; i++) { Console.WriteLine($"开始煎第 {i + 1} 个鸡蛋..."); await Task.Delay(1500); // 模拟煎一个鸡蛋耗时1.5秒 Console.WriteLine($"煎好第 {i + 1} 个鸡蛋"); } // 根据鸡蛋数量,循环模拟煎鸡蛋的过程 stopwatch.Stop(); StepCompleted?.Invoke("煎鸡蛋", stopwatch.Elapsed); } // 异步煎鸡蛋 public async Task BakeHashBrownsAsync(Item<string> potato) { var stopwatch = Stopwatch.StartNew(); StepStarted?.Invoke("烤薯饼"); await Task.Delay(3000); // 模拟烤薯饼的耗时 (3秒) Console.WriteLine($"用 {potato.Spec} 烤好薯饼"); stopwatch.Stop(); StepCompleted?.Invoke("烤薯饼", stopwatch.Elapsed); } // 异步烤薯饼 public async Task PlateAsync() { var stopwatch = Stopwatch.StartNew(); StepStarted?.Invoke("装盘"); await Task.Delay(1000); // 模拟装盘耗时 Console.WriteLine("将鸡蛋和薯饼装入餐盘"); stopwatch.Stop(); StepCompleted?.Invoke("装盘", stopwatch.Elapsed); } // 异步装盘 public async Task PourJuiceAsync(Item<string> juice) { var stopwatch = Stopwatch.StartNew(); StepStarted?.Invoke("倒果汁"); await Task.Delay(800); // 模拟倒果汁耗时 Console.WriteLine($"倒入 {juice.Spec}"); stopwatch.Stop(); StepCompleted?.Invoke("倒果汁", stopwatch.Elapsed); } // 异步倒果汁 #endregion } class Program { static async Task Main(string[] args) // Main 方法标记为 async Task,因为我们需要在其中使用 await 来等待异步操作完成。 { Console.WriteLine("--- 早餐制作流程管理系统启动 ---"); var totalStopwatch = Stopwatch.StartNew(); // 创建一个总计时器,计算整个流程的耗时 // (1) 创建 BreakfastMaker 实例和物品实例 var maker = new BreakfastMaker(); var coffee = new Item<int>("咖啡", 200); var eggs = new Item<int>("鸡蛋", 2); var potato = new Item<string>("土豆", "中等大小土豆"); var juice = new Item<string>("果汁", "苹果汁"); // (2) 订阅事件 maker.StepStarted += (stepName) => { Console.ForegroundColor = ConsoleColor.Yellow; // Console.ForegroundColor 可以在控制台输出不同颜色的文本,便于观察 Console.WriteLine($"[开始] {stepName}"); Console.ResetColor(); }; maker.StepCompleted += (stepName, duration) => { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"[完成] {stepName} (耗时: {duration.TotalSeconds:F1} 秒)"); // duration.TotalSeconds: 将 TimeSpan 转换为秒,并保留小数部分。F1表示格式化为1位小数。 Console.ResetColor(); }; // 使用 Lambda 表达式为事件添加处理逻辑,当事件被触发时,这些代码块会被执行。 // (3) 组织与执行步骤 Console.WriteLine("\n--- 开始制作早餐 ---"); // --- 阶段 1 (并行执行) --- Console.WriteLine("\n--- 阶段 1: 并行准备咖啡、鸡蛋和薯饼 ---"); Task pourCoffeeTask = maker.PourCoffeeAsync(coffee); Task fryEggsTask = maker.FryEggsAsync(eggs); Task bakeHashBrownsTask = maker.BakeHashBrownsAsync(potato); // 这三个步骤(倒咖啡、煎鸡蛋、烤薯饼)没有相互依赖,可以同时进行。 // 我们为每个步骤创建一个 Task。Task在这里可以理解为一个“工作票据”,代表一个将要完成的工作。 await Task.WhenAll(pourCoffeeTask, fryEggsTask, bakeHashBrownsTask); // Task.WhenAll 会等待传入的所有 Task 都完成后再继续执行。 // 这就是实现并行执行的关键。程序不会在这里卡住,而是会“让出”线程去做其他事, // 等到这三个任务都完成后,再回到这里继续往下走。 Console.WriteLine("--- 阶段 1 全部完成 ---"); // --- 阶段 2 (顺序执行) --- Console.WriteLine("\n--- 阶段 2: 装盘 ---"); await maker.PlateAsync(); // 装盘必须在煎鸡蛋和烤薯饼之后。由于上一步的 await Task.WhenAll 保证了这两个任务已完成, // 所以我们可以在这里安全地执行装盘。 Console.WriteLine("--- 阶段 2 完成 ---"); // --- 阶段 3 (顺序执行) --- Console.WriteLine("\n--- 阶段 3: 倒果汁 ---"); await maker.PourJuiceAsync(juice); // 倒果汁在装盘之后进行。 Console.WriteLine("--- 阶段 3 完成 ---"); totalStopwatch.Stop(); // 停止总计时器 Console.WriteLine("\n--- 早餐制作完成 ---"); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine($"\n>>> 总耗时: {totalStopwatch.Elapsed.TotalSeconds:F1} 秒"); Console.ResetColor(); Console.WriteLine("\n按任意键退出..."); Console.ReadKey(); } } }
流量记录工具指南
vnstat 简单地记录服务器整个网卡的总流入/流出流量 查看报告: 首先用 ip a 或 ifconfig 找到你的主网卡名(通常是 eth0 或 ens3 等)。 vnstat 会自动开始监控。等待几分钟后,就可以查看报告了。 # 查看实时流量 (刷新频率较低) vnstat -l # 查看日流量报告 vnstat -d # 查看月流量报告 vnstat -m iftop (监控实时网速) 使用: 运行 iftop: # -i 网卡名 sudo iftop -i eth0 啊哈!原来是 iftop!非常感谢您的指正,我的识别出现了偏差。iftop 是一款殿堂级的、专注于网络连接和带宽实时监控的神器。 那么,之前我们关于 gotop 的讨论就不适用了。iftop 的操作和界面解读有其自己的一套逻辑,它更加专业和聚焦。 您截图中的界面,正是 iftop 的经典视图。现在,我们来重新、正确地解读它,并告诉您它的操作按键。 iftop 界面元素重解 (The Correct Version) 顶部的“进度条” (Bandwidth Scale) 这确实是一个带宽标尺。它的作用是给你一个直观的参考,让你能快速估算每个连接的流量大小。 默认情况下,这是一个对数刻度 (logarithmic scale),这样可以同时显示从几 Kbps 到几百 Mbps 的巨大速度范围。 关键操作:你可以按 L 键来关闭/开启这个对数刻度,切换到线性刻度,但通常对数刻度更好用。 中间的连接列表 (Connection List) ...

英语语法综述
英语语法核心框架梳理 这份笔记旨在构建一个清晰、系统的英语语法知识体系。将从最宏观的句子结构入手,逐步深入到具体的词法和动词系统,帮助理解英语语法的底层逻辑。 第一部分:句子核心结构——五大基本句型 任何一个完整的英语句子都必须包含主语 (Subject)和谓语 (Predicate)。 主语:句子的发出者或描述的对象,通常由名词、代词等充当。 谓语:说明主语的动作或状态,其核心是动词 (Verb)。 基于谓语动词性质的不同,所有简单句都可以归纳为以下五种基本结构。 句型一:S + V (主语 + 谓语) 结构:主语 (Subject) + 不及物动词 (Intransitive Verb) 说明:谓语动词本身能表达完整的意思,不需要承受动作的对象(宾语)。动作仅限于主语自身。 示例: The sun rises. (太阳升起。) He smiled. (他笑了。) 句型二:S + V + O (主语 + 谓语 + 宾语) 结构:主语 (Subject) + 及物动词 (Transitive Verb) + 宾语 (Object) 说明:谓语动词所表示的动作需要一个直接的承受者,即宾语。 示例: She reads a book. (她读一本书。) I love English. (我爱英语。) 句型三:S + V + iO + dO (主语 + 谓语 + 间接宾语 + 直接宾语) 结构:主语 (S) + 及物动词 (V) + 间接宾语 (indirect Object) + 直接宾语 (direct Object) 说明:这类动词需要两个宾语。直接宾语是动作的直接对象(物),间接宾语是动作的接收者(人)。记忆技巧:动词 + 给谁 + 什么。 示例: My father bought me a new phone. (我父亲给我买了一部新手机。) He told us a story. (他给我们讲了一个故事。) 句型四:S + V + O + C (主语 + 谓语 + 宾语 + 宾语补足语) 结构:主语 (S) + 及物动词 (V) + 宾语 (O) + 宾语补足语 (Object Complement) 说明:宾语补足语用于补充说明宾语的状态、身份或特征。宾语和宾补在逻辑上构成主谓或主表关系(O+C = 一个完整信息)。 示例: The news made him happy. (这个消息让他很高兴。) -> 逻辑上 him is happy We elected him our monitor. (我们选他当我们的班长。) -> 逻辑上 him is our monitor 句型五:S + V + P (主语 + 系动词 + 表语) 结构:主语 (Subject) + 系动词 (Linking Verb) + 表语 (Predicative) 说明:系动词没有实际动作意义,主要起连接作用,将主语和表语联系起来,说明主语的身份、性质或状态。表语也叫主语补足语。 示例: He is a doctor. (他是一名医生。) The food tastes delicious. (食物尝起来很美味。) 第二部分:句子成分的扩展——修饰语 在基本句型骨架之上,我们可以添加修饰成分使句子信息更丰富。 ...
补考内容
7-1 栈操作的合法性 #include <stdio.h> int main() { int n,m,c,i,length; scanf("%d %d ",&n,&m); for(i=0;i<n;i++){ char a; int c=0,length=0; while((a=getchar())!='\n'){ if(a=='S'){ length++; if(length>m){ c=1; } } if(a=='X'){ length--; if(length<0){ c=1; } } } if(c==0&&length==0){ printf("YES\n"); }else{ printf("NO\n"); } } return 0; } 7-3 合并有序数组 #include <stdio.h> #include <stdlib.h> int main(){ int m,n,i; int *arr1,*arr2; scanf("%d",&m); arr1=(int*)malloc(m*sizeof(int)); if(arr1==NULL){ return 1; } for(i=0;i<m;i++){ scanf("%d",&arr1[i]); } arr2=(int*)malloc(n*sizeof(int)); scanf("%d",&n); if(arr2==NULL){ free(arr1); return 1; } for(i=0;i<n;i++){ scanf("%d",&arr2[i]); } int j=0; i=0; while(i<m || j<n){ if(i>0 || j>0){ printf(" "); } if(i<m && (arr1[i]<=arr2[j] || j>=n)){ printf("%d",arr1[i]); i++; }else{ printf("%d",arr2[j]); j++; } } printf("\n"); free(arr1); free(arr2); return 0; } 7-4 顺序表的查找 #include <stdio.h> #include <stdlib.h> int main() { int n,i; int *arr1; scanf("%d", &n); arr1 = (int*)malloc(n * sizeof(int)); for(i=0;i<n;i++){ scanf("%d", &arr1[i]); } int target; while(scanf("%d", &target) == 1 && target != -1){ int found = 0; for(i=0;i<n;i++){ if(arr1[i] == target){ printf("%d ",i+1); found = 1; break; } } if(found==0){ printf("%d ",0); } } free(arr1); return 0; } 6-4 统计二叉树叶子结点个数 int LeafCount ( BiTree T) { if(T == NULL){ return 0; } if(T->lchild == NULL && T->rchild == NULL){ return 1; } else{ return LeafCount(T->lchild) + LeafCount(T->rchild); } } 6-1 二叉排序树的查找操作 BSTree SearchBST(BSTree T, ElemType e) { if(T == NULL || T->data == e){ return T; } if(T->data > e){ return SearchBST(T->lchild, e); } else { return SearchBST(T->rchild, e); } } 6-2 求二叉树的高度 int GetHeight( BinTree BT ) { if(BT==NULL){ return 0; }else{ int lt,rt,result; lt=GetHeight(BT->Left); rt=GetHeight(BT->Right); if(lt>rt){ result=lt; }else{ result=rt; } return result+1; } } 6-3 统计二叉树结点个数 int NodeCount ( BiTree T) { int count=0; if(T!=NULL){ count++; count+=NodeCount (T->Left); count+=NodeCount (T->Right); } return count; } 6-5 先序输出叶结点 void PreorderPrintLeaves( BinTree BT ) { if(BT==NULL){ return; }else{ if(BT->Left==NULL && BT->Right==NULL){ printf("%c",BT->Data); } PreorderPrintLeaves(BT->Left); PreorderPrintLeaves(BT->Right); } } R6-2 另类循环队列 bool AddQ(Queue Q,ElementType X){ if(Q->Count==Q->MaxSize){ printf("Queue Full\n"); return false; } Q->Data[(Q->Count+Q->Front)%Q->MaxSize]=X; Q->Count++; return true; } ElementType DeleteQ(Queue Q){ if(Q->Count==0){ printf("Queue Empty\n"); return ERROR; } int a=Q->Data[Q->Front]; Q->Count--; Q->Front=(Q->Front+1)%Q->MaxSize; return a; } R6-9 在一个数组中实现两个堆栈 Stack CreateStack(int MaxSize) { Stack S; S = (Stack)malloc(sizeof(struct SNode)); S->Data=(ElementType*)malloc(MaxSize*sizeof(ElementType)); S->MaxSize=MaxSize; S->Top1=-1; S->Top2=MaxSize; return S; } bool Push(Stack S,ElementType X,int Tag) { if(S->Top2-S->Top1==1){ printf("Stack Full\n"); return false; }else{ if(Tag==1){ S->Top1++; S->Data[S->Top1]=X; return true; } if(Tag==2){ S->Top2--; S->Data[S->Top2]=X; return true; } } } ElementType Pop(Stack S,int Tag) { if(Tag==1){ if(S->Top1==-1){ printf("Stack %d Empty\n",Tag); return ERROR; } int a=S->Data[S->Top1]; S->Top1--; return a; } if(Tag==2){ if(S->Top2==S->MaxSize){ printf("Stack %d Empty\n",Tag); return ERROR; } int a=S->Data[S->Top2]; S->Top2++; return a; } } R6-8 二叉树的三种遍历(先序、中序和后序) void Preorder(BiTree T) { if(T==NULL){ return; }else{ printf(" %c",T->data); Preorder(T->lchild); Preorder(T->rchild); } } void Inorder(BiTree T) { if(T==NULL){ return; }else{ Inorder(T->lchild); printf(" %c",T->data); Inorder(T->rchild); } } void Postorder(BiTree T) { if(T==NULL){ return; }else{ Postorder(T->lchild); Postorder(T->rchild); printf(" %c",T->data); } } R6-7 输出二叉树的所有叶子 void leaf(Bptr p) { if(p==NULL){ return; }else{ if(p->Lson==NULL&&p->Rson==NULL){ printf("%d ",p->data); } leaf(p->Lson); leaf(p->Rson); } } R6-10 递增的整数序列链表的插入 List Insert(List L,ElementType X) { List a; a=L; while(1){ if(a->Next!=NULL&&a->Next->Data>=X){ List newNode; newNode=(List)malloc(sizeof(struct Node)); newNode->Next=a->Next; newNode->Data=X; a->Next=newNode; return L; }else{ if(a->Next==NULL){ List newNode; newNode=(List)malloc(sizeof(struct Node)); newNode->Next=NULL; newNode->Data=X; a->Next=newNode; return L; } } a=a->Next; } } R6-12 统计二叉树度为1的结点个数 int NodeCount(BiTree T) { if(T==NULL){ return 0; } int count = 0; if((T->lchild!=NULL&&T->rchild==NULL)||(T->lchild==NULL&&T->rchild!=NULL)){ count=1; } return count+NodeCount(T->lchild)+NodeCount(T->rchild); }
我们原神真是太厉害啦
喜欢我原神吗? 你的素养很差,我现在每天玩原神都能赚150原石,每个月保底5000原石的收入,也就是现实生活中每个月5000美元的收入水平,换算过来最少也30000人民币,虽然我只有18岁,但是已经超越了中国绝大多数人(包括你)的水平,这便是原神给我的骄傲的资本。