-
2026年美加墨世界杯,足球滚大小技巧《₩₩₩典𝔧𝚜㊇㊇㍚ℂ𝒞》亚足联共有8.5个参赛席位。世预赛亚洲区从第一阶段开始,共22队参赛,晋级的11支球队与亚足联旗下FIFA排名前25的25支球队,参加第二阶段的36强赛。36强赛一共分为9个小组,每组4支球队,采取主客场双循环赛制,总计踢6轮比赛,最终只有小组前两名才能出线,晋级第三阶段18强赛。小组第三和第四名则直接出局,提前宣告无缘2026年世界杯决赛圈。中国男足已经进入了36强赛,与韩国、泰国、新加坡分在同一个小组,目标当然就是拿到小组前两名,顺利进入18强赛。首轮,11月16日晚20点30分,国足做客挑战泰国,可以说“首战即决战”,至少要带走1分。第二轮,11月21日晚20点,国足主场迎战韩国。韩国拥有孙兴慜、金玟哉、李刚仁等欧洲豪门球星,不出意外的话将获小组第一。所以国足若能在深圳拿到1分,就已完成目标;若能爆冷赢球,那更是巨大惊喜,出线不成问题。第三轮和第四轮,国足将在明年3月21日和24日连战新加坡,而且是先客后主。新加坡是本组最弱对手,所以国足的目标只有一个,就是全取6分,少拿2分都是巨大损失。如果前4轮战罢,国足能先赢泰国、再平韩国、双杀新加坡,3胜1平积10分,那么很有可能提前两轮出线!因为泰国要两战韩国,基本上会全败,4轮1胜3负只有3分——当然,这是最理想的情况。第五轮,国足将在6月6日主场迎战泰国。如果不胜,很有可能无法出线。因为第六轮,国足将在6月11日做客挑战韩国,对手恐已提前晋级,但大概率不会放水。
-
我这里用的是Centos7.9====================================================================下载steamcmdyum install -y wget libxcb glibc.i686 libcurl.i686 #下载相关依赖工具sudo useradd -m steam #这里要给steam单独创建一个用户,直接root做的话后面运行帕鲁服务器的时候会报错,提示不能在root用户下执行sudo -u steam -s #切换到steam用户cd /home/steam #进入主文件夹wget https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz #下载steamcmdtar -zxvf steamcmd_linux.tar.gz #解压steamcmd./steamcmd #打开steamcmd#如果运行steamcmd报错/lib/ld-linux.so.2: bad ELF interpreter: No such file or directory,那么就是上面的glibc.i686没有安装,那么你需要执行下面命令进行安装yum install glibc.i686 (glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。由于 glibc 囊括了几乎所有的 UNIX 通行的标准,可以想见其内容包罗万象。而就像其他的 UNIX 系统一样,其内含的档案群分散于系统的树状目录结构中,像一个支架一般撑起整个操作系统。)=======================================================================================下载幻兽帕鲁服务器login anonymous #在刚刚运行的steamcmd里面输入该命令,然后回车app_update 2394010 validate #下载/更新幻兽帕鲁服务器,文件大概2.5G大小exit #下载好后退出,steamcmdcd /home/steam/Steam/steamapps/common/PalServer #切换到刚刚下载的幻兽帕鲁目录./PalServer.sh #运行幻兽帕鲁服务器延迟还不错===========================================================================修改世界参数(具体参数含义,我的其他帖子有可以参考下)cd /home/steam/Steam/steamapps/common/PalServer #在该路径下vi /DefaultPalWorldSettings.ini #这是默认配置模板,复制里面的全部内容,推荐用ssh工具连接到服务器,一般鼠标选中内容,鼠标右键有复制的选项。按住键盘shift+: 输入q 然后回车 #退出vi编辑器cd /home/steam/Steam/steamapps/common/PalServer/Pal/Saved/Config/LinuxServer #拿着刚才复制的内容来到该路径下vi PalWorldSettings.ini #编辑文件键盘按下 i 进入编辑模式,然后把刚刚复制的内容,粘贴进来键盘按下ESC退出编辑模式,然后键盘同时按shift+: 输入wq! 保存并退出cd /home/steam/Steam/steamapps/common/PalServer./PalServer.sh #重启帕鲁服务器,就生效了
-
学习目标:目录DEvOps的五要素DEvOps的生命周期
qingqingjiayuan6
发表于2022-08-08 17:12:25
2022-08-08 17:12:25
最后回复
吃完就睡,快乐加倍
2022-08-09 11:13:53
235 11 -
题目给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标。示例 1:输入:nums = [2,3,1,1,4]输出:true解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。示例 2:输入:nums = [3,2,1,0,4]输出:false解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。方法一:正向遍历,计算每个位置开始能到达的最高处class Solution {public: bool canJump(vector& nums) { int reach=0;//记录当前能到达的最远处 //i遍历数组,i要始终处于能到达的位置,如果reach已经大于nums边界已经可以退出循环 for(int i=0;i<=reach&&reach<nums.size();i++) { reach=max(reach,i+nums[i]);//当前位置的最远边界为当前位置能加最大步数和最远边界,二者取较大 } return reach+1>=nums.size();//边界是数组下标,从0开始,所以要加1 }};时间复杂度O(n)空间复杂度O(1)思路对于数组中的任意一个位置y,只要当前位置x加上x处可走的最大步数,二者之和大于y,则可以到达y一次遍历数组,维护当前的最远边界最后比较最远边界是否可以到达数组大小,如果是则返回true法二:逆向遍历数组,从末尾看能不能下降到0class Solution {public: bool canJump(vector& nums) { int left=nums.size()-1;//左边界 //从后往前遍历数组,如果i所指的位置加上当前数组值大于lef,则当前的左边界为i for(int i=nums.size()-2;i>=0;i--) { if(nums[i]+i>=left) left=i; } //最后判断左边界能否小于0,即从终点能否回到起点 return left<=0; }};法三:动态规划class Solution {public: bool canJump(vector& nums) { vector f(nums.size(),0); f[0]=nums[0]-1;//初始位置可以到达的最远距离就是0加上当前可以走的步数 //依次确定经过每一个位置的最远距离 for(int i=1;i<nums.size();i++) { f[i]=max(f[i-1],i+nums[i-1]); if(f[i]==i) return false;//表示不能往后走了,返回false } return true; }};时间复杂度O(n)空间复杂度O(n)思路f[i]表示当前位置可以到达的最远位置状态转移方程:f[i]=max(f[i-1],i+nums[i-1])当前位置可以到达的最远位置有两种情况,如果不到达当前位置则是前一个位置可以到达的最远位置即f[i-1],如果从当前位置出发则是i+nums[i],二者取最大值每次比较当前位置可以到达的最远位置是否与当前位置相同,如果相同则表示无法继续向后走,返回false如果for循环正常退出则表示可以走到末尾,返回true————————————————版权声明:本文为CSDN博主「Mirevas」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_45781228/article/details/126202831
-
目录目标效果设计开始步骤一步骤二步骤三步骤四步骤五今天我们来动手实现一款2048小游戏。这款游戏的精髓就玩家能够在于通过滑动屏幕合并相同数字,直到不能再合并为止。玩法可以说是非常的简单,但挑战性也是十足的。话不多说,让我们从0开始实现!目标效果大致要实现的效果如下:设计开始首先简单分析一下游戏的逻辑:输入移动方向,游戏内所有方块都朝指定方向移动同方向移动的方块,数字相同则合并,然后生成一个合并的方块合并后生成新的方块,无法生成新方块时游戏结束用一系列的颜色来区分不同分数的方块(可有可无,纯粹是为了美观)ok,游戏内再逻辑已经很清晰了。现在开始实现:步骤一新建一个文件夹用来放需要的游戏素材步骤二新建一个python程序,可以命名为2048,放在素材目录的同级文件夹下步骤三导入需要的依赖库:123import pygame as pyimport sys, random, time, redis, os,mathimport numpy as np依赖库中的redis是一个额外的数据库,用来存取游戏历史数据,需要的可以考虑安装,不需要的用excel表代替也可以。首先需要思考的是,游戏内的方块的移动本质上是坐标的变换,并且方块的坐标是固定的,也就是说,每次输入一个方向就按照一个移动函数将所有方块的坐标进行对应的转换。那么,如此以来,就需要建立一个坐标系用以标记方块的坐标。因为是4x4的游戏,那么就按照(1,1),(1,2),(1,3),...,(4,4)建立游戏坐标,然而相比直接移动坐标还是比较麻烦,一个简单的想法是,每个方块给一个唯一的标记,如我们需要实现4x4的游戏,就需要16个记号。而每一个标记就对应了唯一且固定的坐标。给出如下代码:123456789# 预加载移动逻辑def pre_move(): numberPos = {} for num in range(1, 17): row1, row2 = divmod(num, 4) row = row1 + np.sign(row2) column = [row2 if row2 != 0 else 4][0] numberPos['{}'.format([row, column])] = num return numberPos这里的numberPos实际上就是{‘{1,1}’:1,’{1,2}‘:2......}。当然如果想设计5x5或者6x6的只需要把循环里面的17和4改成25和5或36和6就行。ok,有了坐标接下来的问题好解决了。步骤四在新建的素材文件夹内放入一些图片方块(正方形)用来表示每个不同分数的方块。如下图所示:当然,不使用图片加载游戏也是可以的,如使用py.draw.rect()也能绘制图像,不过每次加载都绘制图像会占用游戏大量运算内存,并且使用图片可以自定义自己的游戏风格,修改上也非常便利。设置完成之后,定义一个游戏的初始化模块:12345678910111213141516171819# 主程序def game_start(): global screen, rate py.init() clock = py.time.Clock() screen_x = 500 # 请调到合适的大小 screen_y = math.ceil(screen_x * rate / rate2) screen = py.display.set_mode((screen_x, screen_y), depth=32) py.display.set_caption("终极2048") BackGround = [251, 248, 239] # 灰色 Icon = py.image.load('./素材/icon.png').convert_alpha() py.display.set_icon(Icon) screen.fill(color=BackGround) # 主界面下设计 width = math.floor(screen_x * rate) bgSecond = py.image.load('./素材/BG_02.png').convert_alpha() bgSecond = py.transform.smoothscale(bgSecond, (width, width)) bgSecondRect = bgSecond.get_rect() bgSecondRect.topleft = math.floor(screen_x * (1 - rate) / 2), math.floor(screen_y * (1 - rate2))游戏界面的大小请调节到合适的尺寸。接下来加载分数图片,以便游戏循环时随时可以调用。123456789101112131415161718192021222324252627282930313233343536373839404142# 预加载分数图def pre_load_image(background): imageList = {} imagePath = './素材/分数/' image_filenames = [i for i in os.listdir(imagePath)] width = math.floor(background.width * (1 - internalWidth) / 4) for name in image_filenames: image = py.transform.smoothscale(py.image.load(imagePath + name).convert_alpha(), (width, width)) imageList[name.replace('.png', '')] = image return imageList# 加载分数图像def draw_image(score_list, image_list, pos_list): for pos_num in score_list: score = score_list[pos_num] scoreSurf = BasicFont01.render('{}'.format(score), True, (0, 0, 0)) scoreRect = scoreSurf.get_rect() if score <= 4096: image = image_list['{}'.format(score)] else: image = image_list['4096'] imageRect = image.get_rect() imageRect.topleft = pos_list['{}'.format(pos_num)] scoreRect.center = imageRect.center screen.blit(image, imageRect) if score > 0: screen.blit(scoreSurf, scoreRect)# 图像位置列表,表示为(x,y)# 用于确定加载的分数图像的显示点位def image_pos_list(background): pre_x = background.topleft[0] pre_y = background.topleft[-1] internalLong = math.ceil(internalWidth / 5 * background.width) imageLong = math.floor((1 - internalWidth) / 4 * background.width) posList = dict(zip(list(range(1, 17)), [''] * 16)) for num in range(1, 17): row1, row2 = divmod(num, 4) row = row1 + np.sign(row2) column = [row2 if row2 != 0 else 4][0] image_x = pre_x + internalLong * column + imageLong * (column - 1) image_y = pre_y + internalLong * row + imageLong * (row - 1) posList['{}'.format(num)] = (image_x, image_y) return posList这里用了三个函数来加载游戏图片,分表表示:提取图片名保存到列表中,绘制游戏中的2,4,8等等数字在分数图片上。最后一个函数用于确定每个坐标在游戏界面的显示位置,并将其一一绑定。加载完成图像之后,就需要完成关键的移动逻辑,先上代码:12345678910111213141516171819202122232425262728293031323334353637383940414243# 移动逻辑def number_move(number_pos, move_input, score_list): values = list(number_pos.values()) keys = list(number_pos.keys()) numberPosReverse = dict(zip(values, keys)) newScoreList = score_list.copy() oldScoreList = {} while newScoreList != oldScoreList: oldScoreList = newScoreList.copy() for num in range(1, 17): pos = eval(numberPosReverse[num]) x, y = pos[0] + move_input[0], pos[1] + move_input[1] pos[0] = [x if 1 <= x <= 4 else pos[0]][0] pos[1] = [y if 1 <= y <= 4 else pos[1]][0] number = number_pos['{}'.format(pos)] oldNumberScore = newScoreList[num] nextNumberScore = newScoreList[number] syn = list(map(lambda x, y: abs(x) * abs(y), move_input, pos)) # 0值移动 if nextNumberScore == 0: newScoreList[number] = oldNumberScore newScoreList[num] = 0 # 无法移动 elif num == number: pass # 合并移动 elif oldNumberScore == nextNumberScore and num != number: newScoreList[number] = 2 * oldNumberScore newScoreList[num] = 0 # 边界移动 elif oldNumberScore != nextNumberScore and 1 in syn or 4 not in syn: pass # 非边界移动 elif oldNumberScore != nextNumberScore and 1 not in syn and 4 not in syn: x, y = pos[0] + move_input[0], pos[1] + move_input[1] next2NumberScore = newScoreList[number_pos['{}'.format([x, y])]] if next2NumberScore != nextNumberScore: pass elif next2NumberScore == nextNumberScore: newScoreList[number_pos['{}'.format([x, y])]] = 2 * next2NumberScore newScoreList[number] = oldNumberScore newScoreList[num] = 0 return newScoreList首先导入预先确定好的坐标,移动变量。根据前面分析的游戏逻辑,每次输入移动向量后游戏内的所有方块都需要移动,相同分数的方块需要一次性合并到一起,并且不能留空。详细分析一下就是:输入一个移动向量(x,y),如(+1,0)表示方块向右移动一格。对所有的原坐标进行计算并保留为移动后坐标,提取前后两次坐标对应的分数从1号标记开始循环判断:0值移动:如果移动后的分数为0,用旧坐标分数替代新坐标的分数,并删除旧坐标的分数无法移动:移动后的坐标与移动前的坐标相同,那么不做改变合并移动:新旧坐标对应的分数相同,那么新坐标分数x2,旧坐标分数删除边界移动:方块已经处于移动的边界,无法移动,不做修改非边界移动:新旧坐标对应的分数不同,且新坐标的下一个坐标对应的分数也不同,不做修改;新旧坐标对应的分数不同,且新坐标的下一个坐标对应的分数相同,修改循环整个逻辑,直到所有坐标对应的分数不再发生改变通过上述分析,移动逻辑函数实现了输入一个方向游戏内的分数动态发生变化。最后我们还需要一个游戏结束的函数:12345678910111213141516171819# 游戏结束def game_over(score,bg): ip = '127.0.0.1' password = None r = redis.Redis(host=ip, password=password, port=6379, db=2, decode_responses=True) r.hset('2048','{}'.format(time.localtime()),score) py.draw.rect(screen,bg,[0,0,screen.get_width(),screen.get_height()],0) BasicFont02 = py.font.SysFont('/素材/simkai.ttf', 40) overSurf = BasicFont01.render('Game Over', True, (0, 0, 0)) overRect = overSurf.get_rect() overRect.center = (math.floor(screen.get_width() / 2), math.floor(screen.get_height() / 2)) scoreSurf = BasicFont02.render('最终得分:', True, (0, 0, 0)) scoreRect = scoreSurf.get_rect() scoreRect.center = (math.floor(screen.get_width() / 2), math.floor(screen.get_height() * 0.6)) numberSurf = BasicFont02.render('{}'.format(score), True, (0, 0, 0)) numberRect = numberSurf.get_rect() numberRect.center = (math.floor(screen.get_width() / 2), math.floor(screen.get_height() * 0.7)) time.sleep(3) sys.exit()一个键盘控制代码,实现键盘控制游戏:123456789101112# 键盘控制函数def keyboard_ctrl(event): move_output = [0, 0] if event.key == py.K_UP: move_output = [-1, 0] elif event.key == py.K_DOWN: move_output = [1, 0] elif event.key == py.K_RIGHT: move_output = [0, 1] elif event.key == py.K_LEFT: move_output = [0, -1] return move_output一个新方块生成器,实现每次合并之后能在空白方块处随机生成2或4中的一个新分数,生成概率按照当前游戏中的2和4的数量为基础。123456789101112# 随机得分生成def random_score(score_list): values = list(score_list.values()) pro = [2] * (2 + values.count(2)) + [4] * (1 + values.count(4)) # 以当前分数图中2或4出现的频率为概率 blank = [[i if score_list[i] == 0 else 0][0] for i in range(1, 17)] blank = list(set(blank)) blank.remove(0) if not blank: return 'GameOver' # 游戏结束 else: score_list[random.choice(blank)] = random.choice(pro) return score_list一个得分统计器,每次游戏运行是统计当前得分和历史最高得分:123456789101112131415161718192021222324252627# 统计并记录当前得分def record_score(score_list, background): totalScore = 0 values = list(score_list.values()) for i in values: totalScore += i scoreSurf = BasicFont01.render('得分:{}'.format(totalScore), True, (0, 0, 0)) scoreRect = scoreSurf.get_rect() scoreRect.topleft = (math.floor(0.1 * screen.get_width()), math.floor(0.05 * screen.get_height())) scoreRect.width = math.floor((rate - 0.15) / 2 * screen.get_width()) scoreRect.height = math.floor((1 - rate2) / 3 * 2 * screen.get_height()) py.draw.rect(screen, background, [scoreRect.topleft[0], scoreRect.topleft[1], scoreRect.width, scoreRect.height], 0) screen.blit(scoreSurf, scoreRect) return totalScore# 绘制历史最高得分def draw_best(background): ip = '127.0.0.1' password = None r = redis.Redis(host=ip, password=password, port=6379, db=2, decode_responses=True) scores=[eval(i) for i in list(r.hgetall('2048').values())] best_scores=max(scores) scoreSurf=BasicFont01.render('最高得分:{}'.format(best_scores),True,(0,0,0)) scoreRect=scoreSurf.get_rect() scoreRect.width = math.floor((rate - 0.15) / 2 * screen.get_width()) scoreRect.height = math.floor((1 - rate2) / 3 * 2 * screen.get_height()) scoreRect.topright = (math.floor(0.9 * screen.get_width()), math.floor(0.05 * screen.get_height())) py.draw.rect(screen, background, [scoreRect.topleft[0], scoreRect.topleft[1], scoreRect.width, scoreRect.height], 0) screen.blit(scoreSurf, scoreRect)最后补充完整的游戏启动器:12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455# 主程序def game_start(): global screen, rate py.init() clock = py.time.Clock() screen_x = 500 # 请调到合适的大小 screen_y = math.ceil(screen_x * rate / rate2) screen = py.display.set_mode((screen_x, screen_y), depth=32) py.display.set_caption("终极2048") BackGround = [251, 248, 239] # 灰色 Icon = py.image.load('./素材/icon.png').convert_alpha() py.display.set_icon(Icon) screen.fill(color=BackGround) # 主界面下设计 width = math.floor(screen_x * rate) bgSecond = py.image.load('./素材/BG_02.png').convert_alpha() bgSecond = py.transform.smoothscale(bgSecond, (width, width)) bgSecondRect = bgSecond.get_rect() bgSecondRect.topleft = math.floor(screen_x * (1 - rate) / 2), math.floor(screen_y * (1 - rate2)) # 主界面上部分设计 # 预加载数据 draw_best(BackGround) posList = image_pos_list(bgSecondRect) imageList = pre_load_image(bgSecondRect) scoreList = dict(zip(list(range(1, 17)), [0] * 15 + [2])) # 分数表 numberPos = pre_move() scoreList = random_score(scoreList) totalScore=0 # 主循环 while True: screen.blit(bgSecond, bgSecondRect) # 刷新屏幕 if scoreList == 'GameOver': game_over(totalScore,BackGround) draw_image(scoreList, imageList, posList) # 绘制得分 totalScore = record_score(scoreList, BackGround) key = py.key.get_pressed() if key[py.K_ESCAPE]: exit() for event in py.event.get(): if event.type == py.QUIT: sys.exit() elif event.type == py.KEYDOWN: move_input = keyboard_ctrl(event) # 按下按键 scoreList = number_move(numberPos, move_input, scoreList) # 移动数字 scoreList = random_score(scoreList) # 在按下按键后生成新的数字 py.display.update() clock.tick(FPS)if __name__ == '__main__': py.font.init() BasicFont01 = py.font.Font('./素材/simkai.ttf', 30) screen = py.display.set_mode((500, 500)) rate = 0.95 # 游戏主界面下的宽度占整个游戏界面宽度的比例 rate2 = 0.7 # 游戏主界面下的高度占整个游戏界面高度的比例 internalWidth = 0.1 # 间隙比例 FPS = 50 # 游戏帧率 game_start()步骤五启动游戏运行之前别忘了启动redis服务器。运行效果图:(游戏界面设计的不够好。。。。,本来打算再加入一些小道具比如说:撤销,全屏合并等功能)
-
目录目标效果设计开始步骤一步骤二步骤三步骤四步骤五今天我们来动手实现一款2048小游戏。这款游戏的精髓就玩家能够在于通过滑动屏幕合并相同数字,直到不能再合并为止。玩法可以说是非常的简单,但挑战性也是十足的。话不多说,让我们从0开始实现!目标效果大致要实现的效果如下:设计开始首先简单分析一下游戏的逻辑:输入移动方向,游戏内所有方块都朝指定方向移动同方向移动的方块,数字相同则合并,然后生成一个合并的方块合并后生成新的方块,无法生成新方块时游戏结束用一系列的颜色来区分不同分数的方块(可有可无,纯粹是为了美观)ok,游戏内再逻辑已经很清晰了。现在开始实现:步骤一新建一个文件夹用来放需要的游戏素材步骤二新建一个python程序,可以命名为2048,放在素材目录的同级文件夹下步骤三导入需要的依赖库:123import pygame as pyimport sys, random, time, redis, os,mathimport numpy as np依赖库中的redis是一个额外的数据库,用来存取游戏历史数据,需要的可以考虑安装,不需要的用excel表代替也可以。首先需要思考的是,游戏内的方块的移动本质上是坐标的变换,并且方块的坐标是固定的,也就是说,每次输入一个方向就按照一个移动函数将所有方块的坐标进行对应的转换。那么,如此以来,就需要建立一个坐标系用以标记方块的坐标。因为是4x4的游戏,那么就按照(1,1),(1,2),(1,3),...,(4,4)建立游戏坐标,然而相比直接移动坐标还是比较麻烦,一个简单的想法是,每个方块给一个唯一的标记,如我们需要实现4x4的游戏,就需要16个记号。而每一个标记就对应了唯一且固定的坐标。给出如下代码:123456789# 预加载移动逻辑def pre_move(): numberPos = {} for num in range(1, 17): row1, row2 = divmod(num, 4) row = row1 + np.sign(row2) column = [row2 if row2 != 0 else 4][0] numberPos['{}'.format([row, column])] = num return numberPos这里的numberPos实际上就是{‘{1,1}’:1,’{1,2}‘:2......}。当然如果想设计5x5或者6x6的只需要把循环里面的17和4改成25和5或36和6就行。ok,有了坐标接下来的问题好解决了。步骤四在新建的素材文件夹内放入一些图片方块(正方形)用来表示每个不同分数的方块。如下图所示:当然,不使用图片加载游戏也是可以的,如使用py.draw.rect()也能绘制图像,不过每次加载都绘制图像会占用游戏大量运算内存,并且使用图片可以自定义自己的游戏风格,修改上也非常便利。设置完成之后,定义一个游戏的初始化模块:12345678910111213141516171819# 主程序def game_start(): global screen, rate py.init() clock = py.time.Clock() screen_x = 500 # 请调到合适的大小 screen_y = math.ceil(screen_x * rate / rate2) screen = py.display.set_mode((screen_x, screen_y), depth=32) py.display.set_caption("终极2048") BackGround = [251, 248, 239] # 灰色 Icon = py.image.load('./素材/icon.png').convert_alpha() py.display.set_icon(Icon) screen.fill(color=BackGround) # 主界面下设计 width = math.floor(screen_x * rate) bgSecond = py.image.load('./素材/BG_02.png').convert_alpha() bgSecond = py.transform.smoothscale(bgSecond, (width, width)) bgSecondRect = bgSecond.get_rect() bgSecondRect.topleft = math.floor(screen_x * (1 - rate) / 2), math.floor(screen_y * (1 - rate2))游戏界面的大小请调节到合适的尺寸。接下来加载分数图片,以便游戏循环时随时可以调用。123456789101112131415161718192021222324252627282930313233343536373839404142# 预加载分数图def pre_load_image(background): imageList = {} imagePath = './素材/分数/' image_filenames = [i for i in os.listdir(imagePath)] width = math.floor(background.width * (1 - internalWidth) / 4) for name in image_filenames: image = py.transform.smoothscale(py.image.load(imagePath + name).convert_alpha(), (width, width)) imageList[name.replace('.png', '')] = image return imageList# 加载分数图像def draw_image(score_list, image_list, pos_list): for pos_num in score_list: score = score_list[pos_num] scoreSurf = BasicFont01.render('{}'.format(score), True, (0, 0, 0)) scoreRect = scoreSurf.get_rect() if score <= 4096: image = image_list['{}'.format(score)] else: image = image_list['4096'] imageRect = image.get_rect() imageRect.topleft = pos_list['{}'.format(pos_num)] scoreRect.center = imageRect.center screen.blit(image, imageRect) if score > 0: screen.blit(scoreSurf, scoreRect)# 图像位置列表,表示为(x,y)# 用于确定加载的分数图像的显示点位def image_pos_list(background): pre_x = background.topleft[0] pre_y = background.topleft[-1] internalLong = math.ceil(internalWidth / 5 * background.width) imageLong = math.floor((1 - internalWidth) / 4 * background.width) posList = dict(zip(list(range(1, 17)), [''] * 16)) for num in range(1, 17): row1, row2 = divmod(num, 4) row = row1 + np.sign(row2) column = [row2 if row2 != 0 else 4][0] image_x = pre_x + internalLong * column + imageLong * (column - 1) image_y = pre_y + internalLong * row + imageLong * (row - 1) posList['{}'.format(num)] = (image_x, image_y) return posList这里用了三个函数来加载游戏图片,分表表示:提取图片名保存到列表中,绘制游戏中的2,4,8等等数字在分数图片上。最后一个函数用于确定每个坐标在游戏界面的显示位置,并将其一一绑定。加载完成图像之后,就需要完成关键的移动逻辑,先上代码:12345678910111213141516171819202122232425262728293031323334353637383940414243# 移动逻辑def number_move(number_pos, move_input, score_list): values = list(number_pos.values()) keys = list(number_pos.keys()) numberPosReverse = dict(zip(values, keys)) newScoreList = score_list.copy() oldScoreList = {} while newScoreList != oldScoreList: oldScoreList = newScoreList.copy() for num in range(1, 17): pos = eval(numberPosReverse[num]) x, y = pos[0] + move_input[0], pos[1] + move_input[1] pos[0] = [x if 1 <= x <= 4 else pos[0]][0] pos[1] = [y if 1 <= y <= 4 else pos[1]][0] number = number_pos['{}'.format(pos)] oldNumberScore = newScoreList[num] nextNumberScore = newScoreList[number] syn = list(map(lambda x, y: abs(x) * abs(y), move_input, pos)) # 0值移动 if nextNumberScore == 0: newScoreList[number] = oldNumberScore newScoreList[num] = 0 # 无法移动 elif num == number: pass # 合并移动 elif oldNumberScore == nextNumberScore and num != number: newScoreList[number] = 2 * oldNumberScore newScoreList[num] = 0 # 边界移动 elif oldNumberScore != nextNumberScore and 1 in syn or 4 not in syn: pass # 非边界移动 elif oldNumberScore != nextNumberScore and 1 not in syn and 4 not in syn: x, y = pos[0] + move_input[0], pos[1] + move_input[1] next2NumberScore = newScoreList[number_pos['{}'.format([x, y])]] if next2NumberScore != nextNumberScore: pass elif next2NumberScore == nextNumberScore: newScoreList[number_pos['{}'.format([x, y])]] = 2 * next2NumberScore newScoreList[number] = oldNumberScore newScoreList[num] = 0 return newScoreList首先导入预先确定好的坐标,移动变量。根据前面分析的游戏逻辑,每次输入移动向量后游戏内的所有方块都需要移动,相同分数的方块需要一次性合并到一起,并且不能留空。详细分析一下就是:输入一个移动向量(x,y),如(+1,0)表示方块向右移动一格。对所有的原坐标进行计算并保留为移动后坐标,提取前后两次坐标对应的分数从1号标记开始循环判断:0值移动:如果移动后的分数为0,用旧坐标分数替代新坐标的分数,并删除旧坐标的分数无法移动:移动后的坐标与移动前的坐标相同,那么不做改变合并移动:新旧坐标对应的分数相同,那么新坐标分数x2,旧坐标分数删除边界移动:方块已经处于移动的边界,无法移动,不做修改非边界移动:新旧坐标对应的分数不同,且新坐标的下一个坐标对应的分数也不同,不做修改;新旧坐标对应的分数不同,且新坐标的下一个坐标对应的分数相同,修改循环整个逻辑,直到所有坐标对应的分数不再发生改变通过上述分析,移动逻辑函数实现了输入一个方向游戏内的分数动态发生变化。最后我们还需要一个游戏结束的函数:12345678910111213141516171819# 游戏结束def game_over(score,bg): ip = '127.0.0.1' password = None r = redis.Redis(host=ip, password=password, port=6379, db=2, decode_responses=True) r.hset('2048','{}'.format(time.localtime()),score) py.draw.rect(screen,bg,[0,0,screen.get_width(),screen.get_height()],0) BasicFont02 = py.font.SysFont('/素材/simkai.ttf', 40) overSurf = BasicFont01.render('Game Over', True, (0, 0, 0)) overRect = overSurf.get_rect() overRect.center = (math.floor(screen.get_width() / 2), math.floor(screen.get_height() / 2)) scoreSurf = BasicFont02.render('最终得分:', True, (0, 0, 0)) scoreRect = scoreSurf.get_rect() scoreRect.center = (math.floor(screen.get_width() / 2), math.floor(screen.get_height() * 0.6)) numberSurf = BasicFont02.render('{}'.format(score), True, (0, 0, 0)) numberRect = numberSurf.get_rect() numberRect.center = (math.floor(screen.get_width() / 2), math.floor(screen.get_height() * 0.7)) time.sleep(3) sys.exit()一个键盘控制代码,实现键盘控制游戏:123456789101112# 键盘控制函数def keyboard_ctrl(event): move_output = [0, 0] if event.key == py.K_UP: move_output = [-1, 0] elif event.key == py.K_DOWN: move_output = [1, 0] elif event.key == py.K_RIGHT: move_output = [0, 1] elif event.key == py.K_LEFT: move_output = [0, -1] return move_output一个新方块生成器,实现每次合并之后能在空白方块处随机生成2或4中的一个新分数,生成概率按照当前游戏中的2和4的数量为基础。123456789101112# 随机得分生成def random_score(score_list): values = list(score_list.values()) pro = [2] * (2 + values.count(2)) + [4] * (1 + values.count(4)) # 以当前分数图中2或4出现的频率为概率 blank = [[i if score_list[i] == 0 else 0][0] for i in range(1, 17)] blank = list(set(blank)) blank.remove(0) if not blank: return 'GameOver' # 游戏结束 else: score_list[random.choice(blank)] = random.choice(pro) return score_list一个得分统计器,每次游戏运行是统计当前得分和历史最高得分:123456789101112131415161718192021222324252627# 统计并记录当前得分def record_score(score_list, background): totalScore = 0 values = list(score_list.values()) for i in values: totalScore += i scoreSurf = BasicFont01.render('得分:{}'.format(totalScore), True, (0, 0, 0)) scoreRect = scoreSurf.get_rect() scoreRect.topleft = (math.floor(0.1 * screen.get_width()), math.floor(0.05 * screen.get_height())) scoreRect.width = math.floor((rate - 0.15) / 2 * screen.get_width()) scoreRect.height = math.floor((1 - rate2) / 3 * 2 * screen.get_height()) py.draw.rect(screen, background, [scoreRect.topleft[0], scoreRect.topleft[1], scoreRect.width, scoreRect.height], 0) screen.blit(scoreSurf, scoreRect) return totalScore# 绘制历史最高得分def draw_best(background): ip = '127.0.0.1' password = None r = redis.Redis(host=ip, password=password, port=6379, db=2, decode_responses=True) scores=[eval(i) for i in list(r.hgetall('2048').values())] best_scores=max(scores) scoreSurf=BasicFont01.render('最高得分:{}'.format(best_scores),True,(0,0,0)) scoreRect=scoreSurf.get_rect() scoreRect.width = math.floor((rate - 0.15) / 2 * screen.get_width()) scoreRect.height = math.floor((1 - rate2) / 3 * 2 * screen.get_height()) scoreRect.topright = (math.floor(0.9 * screen.get_width()), math.floor(0.05 * screen.get_height())) py.draw.rect(screen, background, [scoreRect.topleft[0], scoreRect.topleft[1], scoreRect.width, scoreRect.height], 0) screen.blit(scoreSurf, scoreRect)最后补充完整的游戏启动器:12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455# 主程序def game_start(): global screen, rate py.init() clock = py.time.Clock() screen_x = 500 # 请调到合适的大小 screen_y = math.ceil(screen_x * rate / rate2) screen = py.display.set_mode((screen_x, screen_y), depth=32) py.display.set_caption("终极2048") BackGround = [251, 248, 239] # 灰色 Icon = py.image.load('./素材/icon.png').convert_alpha() py.display.set_icon(Icon) screen.fill(color=BackGround) # 主界面下设计 width = math.floor(screen_x * rate) bgSecond = py.image.load('./素材/BG_02.png').convert_alpha() bgSecond = py.transform.smoothscale(bgSecond, (width, width)) bgSecondRect = bgSecond.get_rect() bgSecondRect.topleft = math.floor(screen_x * (1 - rate) / 2), math.floor(screen_y * (1 - rate2)) # 主界面上部分设计 # 预加载数据 draw_best(BackGround) posList = image_pos_list(bgSecondRect) imageList = pre_load_image(bgSecondRect) scoreList = dict(zip(list(range(1, 17)), [0] * 15 + [2])) # 分数表 numberPos = pre_move() scoreList = random_score(scoreList) totalScore=0 # 主循环 while True: screen.blit(bgSecond, bgSecondRect) # 刷新屏幕 if scoreList == 'GameOver': game_over(totalScore,BackGround) draw_image(scoreList, imageList, posList) # 绘制得分 totalScore = record_score(scoreList, BackGround) key = py.key.get_pressed() if key[py.K_ESCAPE]: exit() for event in py.event.get(): if event.type == py.QUIT: sys.exit() elif event.type == py.KEYDOWN: move_input = keyboard_ctrl(event) # 按下按键 scoreList = number_move(numberPos, move_input, scoreList) # 移动数字 scoreList = random_score(scoreList) # 在按下按键后生成新的数字 py.display.update() clock.tick(FPS)if __name__ == '__main__': py.font.init() BasicFont01 = py.font.Font('./素材/simkai.ttf', 30) screen = py.display.set_mode((500, 500)) rate = 0.95 # 游戏主界面下的宽度占整个游戏界面宽度的比例 rate2 = 0.7 # 游戏主界面下的高度占整个游戏界面高度的比例 internalWidth = 0.1 # 间隙比例 FPS = 50 # 游戏帧率 game_start()步骤五启动游戏运行之前别忘了启动redis服务器。运行效果图:(游戏界面设计的不够好。。。。,本来打算再加入一些小道具比如说:撤销,全屏合并等功能)
-
元宇宙话题性极高,但是想要实现这样的下世代互联网愿景,需要借助整个生态系统的公司来实现。本文将介绍元宇宙是什么?如何建立?谁在建立?目前元宇宙可以在虚拟世界举办直播演唱会和玩游戏,但元宇宙支持者所看到的未来是真实的人类以数字化身(avatar)居住在在线世界所建立起的社会。虽然这个在线世界仍处于发展初期,但长远而言将深具潜力。用户(尤其是年轻用户)最终可能会在数字世界中赚取他们的大部分资金并加以支出、投资。CB Insights的产业分析师认为,十年之后元宇宙可能将有1兆美元的市场规模。巨大的商机自然引起了产业的兴趣。去年年底,Facebook将品牌更名为Meta,2021年Q4的财报会议中提到的元宇宙年成长率(YoY)达4倍。一时之间,媒体开始大肆报导元宇宙相关话题,新闻机构纷纷开始猜测,究竟元宇宙以及成熟的虚拟经济的出现(包括财产所有权、公司办公室、时尚季等等)是科技业的下一个战场?或者只是个炒作意味浓厚的噱头?元宇宙是一种愿景而不是一种具体的技术。因此对企业而言,这样的模糊性使得企业要想弄清楚如何加入元宇宙所代表的一系列新兴科技,但事实上却备受困难。因此,CB Insights整理了下列架构,将元宇宙拆解为多个技术层面,并介绍了致力于实践元宇宙的关键供货商。1、基础设施(网络及运算)建立元宇宙需要能够大数据流程、低延迟运算及处理用基础设施,在芯片和处理器、5G、云端基础设施和边缘基础设施等方面的新兴技术,将显示创造一个无缝且无延迟体验的元宇宙的重要性。芯片及处理器之进展将支持各种元宇宙应用所需密集运算和处理以元宇宙为核心的新型硬件(如VR头戴式装置和AR眼镜),用于支持与高拟真图形及AI有关的密集工作负载,并在较小的轻型装置上使用。高通公司(Qualcomm)的芯片是这一领域的佼佼者,高通声称骁龙芯片(Snapdragon)已应用于50多个AR/VR装置,诸如Meta的Oculus和HTC Vive等主流VR头戴式装置。近来,高通还宣布推出1亿美元的骁龙元宇宙基金,投资扩展现实(XR)领域。此外,英特尔声称,元宇宙需要的是将计算效率提高1000倍,包括5G和混合边缘云基础设施的进步。也就是说,还需要新的芯片来驱动这些关键的低延迟计算网络。2022年2月,英特尔便发布了支持高功率数据中心和5G网络的新芯片的细节。5G和低延迟网络支持高分辨率元宇宙程序5G无线技术提供联机装置所需的可靠、弹性且低延迟网络,造就高分辨率的元宇宙应用程序,诸如沉浸式世界及游戏。至2022年止,美国的龙头电信公司都能为消费者提供5G网络。一些公司正在尝试在游戏和AR/VR中使用5G。例如:2021年4月,Verizon与VR新创公司Dreamscape Immersive合作,在Verizon的5G网络上建立沉浸式学习和培训应用。三个月后,AT&T与Meta的Reality Labs合作,展示如何利用5G来产生更多的无缝AR体验。云端基础设施协助低运算装置支持元宇宙云端基础设施将使元宇宙公司能够存储和解析它们产生的大量数据,尤其是那些托管虚拟世界和体验的公司。2018年,Epic Games的游戏《要塞英雄Fortnite》每月产生5PB的数据(这相当于2.5T页的标准文本)。为了储存和理解这些数据,Fortnite几乎是完全在亚马逊网络服务(AWS)上运行,在AWS上利用云端运算来加总(aggregate)和分析难以处理的数据流。云端基础设施的进步也将帮助人们在缺乏足够运算能力(如高分辨率图形和人工智能)的装置上存取元宇宙,云端运算促成在远程服务器上处理体验,然后流向终端装置,如PC、VR头盔或手机。虽然这种与外部服务器的来回通讯可能会迟滞,但随着边缘计算和5G的相关发展也会减少延迟的情况发生。边缘基础设施协助元宇宙之实时、在地运算边缘计算主要用于需要实时响应的元宇宙应用,如AR/VR和游戏。边缘计算使得低功耗装置的数据能够在更接近其产生的地方处理。当涉及到需要实时处理信息时,就是边缘计算派上用场的时候,比如利用VR头戴式装置上的手部追踪传感器或在竞技游戏中处理指令。事实上,Stackpath和Zenlayer等边缘基础设施公司正式将游戏和VR列为主要关注领域。边缘处理与云端运算密切关联。云端基础设施处理的工作负载不需要最低延迟,例如在游戏中加载超出视野的物体。而边缘基础设施处理需要非常快速响应的加载,例如玩家的动作。有些公司开发了混合的产品,例如:Akamai为一些高知名度的游戏公司提供边缘–云端混合服务,包括机器砖块(Roblox)和独角兽Riot Games。2、存取/接口(硬件)这部分包括人们体验元宇宙的硬件装置。虽然手机、个人计算机和游戏机等连接装置也是这一类别,但主要还是以新兴技术为中心,旨在加强使用者在虚拟环境中的沉浸感。触觉技术(Haptics)赋予数字物体质地与重量触感这类新创公司正在开发将触觉带入虚拟世界的技术。新创公司如HaptX和Sense Glove,正在开发能够赋予虚拟物体触觉的手套。将微振动、用于抗力的气动系统(pneumatic system)和运动追踪结合,使人们可以感觉到数字物体的材质、硬度和重量。未来,触觉技术可能不再限于人的双手。苏格兰的Teslasuit公司正在开发完整的连体服,以便在虚拟环境中提供全身的触觉回馈和温度控制(climate control)。头戴式装置(VR)提供景深感知、眼球追踪、手部追踪这些公司正在开发目前认为是进入元宇宙应用主要入口的VR眼镜。VR眼镜为用户提供视觉和听觉内容,使他们沉浸在数字环境中。最受欢迎的VR头戴式装置之一是Meta公司的Oculus,消费者在2021年的假期季对其兴趣激增。新创公司也纷纷仿效。例如:Varjo利用光达(lidar)和计算机视觉技术,为其VR头戴式装置带来景深感知(depth perception)、眼球追踪和手部追踪。全像投影(Holographics) 应用于场景设计、表演、产品设计及医学这些公司使用光衍射技术(light diffraction)将3D物体投射到实体空间。这些全像技术将数字体验带入实体世界。虽然目前仍处于早期阶段,但可能应用于广泛的应用案例,从全像图主导的场景设计和表演到产品设计及医学。Base Hologram公司正利用这项技术让Whitney Houston和Buddy Holly等已辞世流行音乐人重现舞台,以色列的RealView Imaging公司则是产生病人内部器官的全像投影,以辅助手术前规划。全像投影技术在获得广泛成功之前,还有很长的路要走,但目前该领域耕耘的公司已经让我们了解到未来的展望。智能眼镜应用于元宇宙与维修相关公司正在开发具有AR功能的眼镜或隐形眼镜。虽然并非所有AR眼镜的应用都与元宇宙直接相关,譬如为帮助工程师修理冰箱而设计的AR工具就不带有共享体验,但这类的公司所做的一切正在为实体和虚拟世界之间搭建桥梁。随着AR(尤其是社交应用类)的普及,该技术将发展成更有效地融合虚拟和现实世界的工具,譬如在某活动上与某人在元宇宙里的数字化身互动,这些都进一步模糊了消费者在线和线下身份之间的界限。目前,中国的新创公司Nreal正在为日常消费者开发配有网络浏览和影像串流功能的AR眼镜。其他公司如Magic Leap则正在开发企业用的AR头戴式装置。3、虚拟化工具该领域的公司正在研究软件开发工具包、游戏引擎、3D扫描技术和其他开发者工具,以帮助3D内容设计人员构建元宇宙及体验。3D设计引擎应用于建立元宇宙视觉要素该领域公司提供游戏引擎和动画视觉效果等工具,使设计师可以用来构建元宇宙中的视觉元素。例如:Epic Games的Unreal Engine用来开发其内部游戏套件,如《火箭联盟Rocket League》和《要塞英雄Fortnite》,Unreal Engine同时也是其他工作室制作的大量高知名度游戏的核心。AR/VR开发者也会使用Unreal Engine及其竞争对手Unity,VR游戏工作室Survios和Sanzaru使用前者,而知名VR游戏Beat Saber则是用Unity设计的。3D建模和捕捉 (3D modeling & capture)用于产品仿真该领域的公司帮助品牌捕捉和建立实体产品或环境的3D呈现。这项技术在电商平台日趋兴盛,因其有望帮助消费者更了解产品。而这项技术也即将被想要快速将真实世界的产品建立成元宇宙版本的公司所采用。例如:透过Vntana,品牌商可以上传现有的设计文件或3D扫描文件并立即进行优化,以符合网络、社交媒体和游戏引擎的标准。这些产品可以上传到电商网站、社交媒体或AR中,用户可以存取产品的360°视图、转变颜色和纹理,并测试产品在现实世界中可能的外观。有些公司则利用扫描和3D捕捉将实体环境转为虚拟环境。例如:PreVu3D建立了工厂的虚拟模型。这些模型目前用来帮助重新设计布局以提高效率,但基础技术也可以用于建立元宇宙体验。AR软件开发工具包与AR开发者平台该领域的公司提供软件开发工具包(SDK)以优化AR app开发。该领域的新创公司大多仍处于早期阶段,这是因为AR还没有渗透到主流应用案例中。2021年,《Pokémon GO》的开发商Niantic宣布推出自家的AR开发者平台Lightship,希望突破纯AR游戏公司的身份。2021年9月,高通公司收购了位于奥地利的Wikitude,这是一家建立SDK以加快AR app设计的新创公司。此次收购很可能成为高通公司开发头戴式AR开发者套件的基础,该套件在收购后2个月推出。高通公司并不是这个领域唯一的大型科技公司。新创公司可能会面临来自Amazon Sumerian、Google ARCore和Meta Presence平台等科技巨头产品的竞争。数字化身(avatar)之订制化写实与超写实模式数字化身开发新创公司正在帮助个人、游戏和品牌设计订制化且写实的数字化身,让元宇宙用户在虚拟世界具体化且参与其中。Alter和Ready Player Me这样的新创公司允许用户以多种方式订制化,将自拍变成卡通式的数字分身。这些公司还希望他们的数字化身能够在整个元宇宙内互通,以便让使用者在穿越虚拟世界和体验时维持同一个身份。其他新创公司更专注于超写实(hyper-realistic)的数字化身,包括企业用途。例如:Pinscreen和Uneeq提供数字化身开发平台,其中包含自然语言处理(NLP)工具,是一种能够理解并以智能方式回复人类语言的AI,以便品牌和企业能够为客户服务创建虚拟助理数字化身。空间捕捉影片(Volumetric video)应用于建立表演艺术新媒体空间捕捉影片公司从多个角度捕捉现实世界的影像,以便在数字环境中以3D方式观看。空间捕捉影片对于将娱乐带入元宇宙来说十分关键。以色列的Tetavi公司正在使用空间捕捉影片建立媒体、游戏和其他基于VR的内容。Tetavi声称,目前正在与主要的艺术家和制作公司进行讨论,也就是说,未来很有可能利用其技术将音乐会、舞蹈表演等直播到虚拟舞台上。4、虚拟世界虚拟世界是人们在元宇宙中聚集和存在的地方,而这些世界因用户驱动的体验和经济而不同。中心化世界:以开发者入口网站吸引高投入用户提升元宇宙体验在一个中心化的虚拟世界中,一个公司对世界的规则、商品和体验拥有最终的决定权。除此之外,中心化世界通常是一个社会驱动的环境,人们可以聚集在一起并使用互动工具。举例来说,Roblox有自己的开发者入口网站,用户能够建立自定义的景观、物品、小游戏等。这样的自由是Roblox世界的关键价值主张。用户被赋权(empowered)以创造从深海潜水到大胆越狱的各种场景,因而有助于带动飞轮效应,使这样的价值成为元宇宙世界发展的核心。因为,高度投入的用户改善虚拟世界,并吸引到更多的用户,也就是说,用户为其他人改善体验。创造者也可以针对他们的服务收费。虽然中心化的虚拟世界会收取创作者收入的一定比例(Roblox大约1美元会收取27美分),但一些创作者已经获得巨大的成功。2006年,虚拟世界Second Life中的创作者Anshe Chung被认为是第一个通过在虚拟世界中建立的业务实现现实世界百万富翁地位的人。虽然Roblox和Second Life可以在传统的游戏机上访问,如Xbox、Playstation、PC和智慧手机,但像VRChat和Rec Room这样的新创公司正寻求通过超越剧本以创造更多的沉浸式虚拟世界,并纳入VR功能。去中心化世界:促进游戏和其他平台之间的互操作性去中心化的虚拟世界提供类似于虚拟世界的体验。然而,这些世界是以区块链技术建立的。Decentraland和The Sandbox是两个最受欢迎的去中心化世界。就像中心化世界,这些世界允许居民购买、出售和创造。然而,这些交易都是基于每个世界独特的加密货币。此外,世界内的物品或土地都是以非同构型代币(NFT)的形式进行交易。由于开发者不会将控制权让给另一个控制标准的单一实体,一些人认为区块链的去中心化将促进游戏和其他平台之间的互操作性。这最终将使资产的稀有性在各个世界被实现。未来,一个人可能会把他们的NFT游艇从一个去中心化的世界转移到另一个世界。去中心化世界也倾向于使用与中心化世界不同的商业模式,去中心化世界从销售虚拟土地、加密货币和其他数字资产中获得收入,而不是从内部世界创造者(in-world creator)产生的利润中抽取一定比例。一些去中心化的虚拟世界甚至让他们的居民通过分布式自治组织(DAO)的方式帮助治理。这些由区块链技术、可自动执行的(auto-enforceable)智能合约支持的设置通常依据与他们内部世界加密资产间之比例,授予用户投票权,允许他们对世界内的规则和条例有发言权。5、经济基础设施该层面包括使人们能够在元宇宙中购买、出售和存储商品和服务的技术。尽管人们对加密货币和NFT的兴趣激增,但进入这一领域的新创企业和公司可能只为元宇宙的一小部分服务,而且是去中心化的元宇宙。因此,传统的支付公司仍保持高度的相关性。毕竟,如果元宇宙只在去中心化的金融上运行,公司将失去为非加密货币持有者服务的巨大商机。支付:传统与加密货币并存于元宇宙交易传统的支付方式在元宇宙中不会被淘汰。随着虚拟世界经济的发展,客户会出于方便而希望使用他们典型的支付系统,供货商会急于从这些交易中分一杯羹。PayPal已经可以被用来购买Roblox、Minecraft和econd Life中的虚拟货币。同时,Minecraft世界内的货币Minecoin也接受多种支付方式,包括Visa、Google Pay、Apple Pay和Mastercard。加密货币交易所:去中心化、跨交易所之交易这些公司提供购买和销售加密货币的平台,包含原生加密货币和去中心化的数字世界。举例来说,The Sandbox的加密货币Sand,可以在Gemini、Crypto和Binance等交易所进行交易。同样,Decentraland原生的加密货币MANA可以在Coinbase、Kraken和其他交易所购买。加密货币钱包:去中心化世界的登入凭证为了登入像Cryptovoxels或Decentraland这样的世界,使用者需要有一个加密货币钱包。钱包的唯一ID也是其成了使用者的个人账户。只要他们能够存取钱包,就可以从多个装置登入去中心化的世界,并接收数字资产,如世界内的货币或虚拟土地的NFTs。例如,Sandbox允许用户用一些最流行的加密货币钱包注册,包括Venly、Bitski和Metamask。NFT:可用于元宇宙与非元宇宙世界这些新创公司透过平台开发支持去中心化世界的商业活动,用户可以购买和出售虚拟土地、数字化身服装到虚拟游艇的NFT。非同质化代币(NFT)并不完全是一个元宇宙的概念,人们完全可以在不参与元宇宙的情况下购买和出售推文、影片等的NFT。然而,NFT正在成为去中心化虚拟世界中经济活动的支柱,因为它们为基于元宇宙的财产提供所有权证明。元宇宙物品的NFT也可以在元宇宙外部NFT市场上市。例如Open Sea或Rarible这样的市场已经支持销售Decentraland和The Sandbox的虚拟房地产和物品。同样,新创公司DMarket也在开发专门针对去中心化世界和游戏的商品交易的NFT市场。6、体验本层面涵盖了未来将在元宇宙中提供的各种商品、服务和体验。请注意,这一层面将持续发展和变化,下列的特色类别说明了目前市场上比较受欢迎的元宇宙体验。这一类别包括AR/VR游戏公司以及开发去中心化多人游戏的公司。虽然元宇宙可以纳入传统游戏,但下面强调的类别反而讨论了可能影响元宇宙发展的新兴游戏趋势。AR/VR游戏:沉浸式游戏这类新创公司正在迎来下一波沉浸式AR/VR游戏的发展。大多数这类型的公司(如:Ramen VR、Survios和ForeVR Games)是以VR为重点的游戏工作室。其他公司(如迪斯尼支持的Illumix)正在开发可以将消费者的智慧手机摄像头变成一个游戏平台的AR游戏。Illumix广受好评的恐怖游戏《玩具熊的五夜后宫Five Nights At Freddy’s》让用户可以击退并收集躲在家中墙壁里被附身的机械偶。去中心化、区块链多人游戏这类新创主要开发基于区块链的多人游戏或帮助游戏公司开发基于区块链的游戏。去中心化游戏类似于去中心化的虚拟世界,但在玩家自由度方面比较受限。例如,Mythical Games的去中心化游戏Blankos,允许玩家建立小游戏和交易NFT物品。然而,玩家不能像在Roblox或Second Life中那样创造新的纹理、生物或物品。此外,游戏的规则也不是像Decentraland或The Sandbox那样由分布式自治组织决定的。虚拟演唱会:音乐会游戏化这类新创公司正在元宇宙中建立虚拟演唱会场所,同时也在使用新的沉浸式体验来增强现场演唱会。例如,2022年1月,AmazeVR为其VR音乐会平台吸引了1500万美元的B轮融资。这类公司可能发现了自己正面临来自虚拟世界和游戏公司的竞争,《要塞英雄Fortnite》的Travis Scott演唱会吸引了超过1200万观众参加。其他新创公司也正致力于使用AR技术来增强现场音乐会。Pixelynx是一家由Deadmau5等音乐家创立的公司,该公司利用AR技术将音乐会游戏化。歌迷们可以将手机对准舞台,体验新的视觉效果,参与小游戏,并收集虚拟物品和NFT。虚拟时尚:数字化身之数字服饰虚拟时尚公司是开发在元宇宙中所著服装的品牌。虚拟时尚新创公司仍处于早期发展阶段。Brand New Vision和DressX最近进行了种子轮融资,以支持其基于NFT的时尚项目。从这些新创公司购买服装的用户可以选择使用AR来展示他们的虚拟服装,其范围可以从相对普通的外套到精心设计的礼服,这在真实世界中很难制造。大型时尚品牌也在关注虚拟时尚并将之作为营销和建立新收入来源的一种方式。例如,Nike收购了虚拟运动鞋公司RTFKT,并与Roblox合作建立了 「Nikeland」,这是一个用户可以为他们的数字化身购买Nike服装的世界。同样,巴黎世家在《要塞英雄》中发布了虚拟时装品牌,2021年5月,一个数字Gucci包在Roblox的售价超过4000美元。虚拟房地产:可购买、转售、开发、出租虚拟房地产公司在去中心化的虚拟世界中购买、转售、开发和出租虚拟财产。前面提到的Anshe Chung就是这样赚钱的,通过购买虚拟房地产,用Second Life的创作者工具重新开发,然后出租给其他Second Life的居民。虚拟房地产公司Everyrealm是Republic Realm的衍生公司,它在The Sandbox中购买价值400万美元的房产的事情成为头条新闻。该公司的项目包括在这块土地上开发热带景观,这些景观带有独特的物品和NFT,如:巨型游艇(其中最大的一艘以65万美元售出)。虚拟工作:沉浸式工作空间这类公司正在开发沉浸式工作空间,员工可以就项目进行合作,在数字办公室中移动,并相互交流,就像他们在同一个房间一样。这一领域的公司很多在很大程度上依赖AR和VR技术。例如:Immersed和vSpatial正在开发VR办公空间,数字化身可以在共享白板上实时协作,建立具有多个仪表板(dashboard)的复杂工作站并进行会议等等,在现实生活中设置这些仪表板是不切实际的。其他新创公司正专注于特定的使用案例。例如,IrisVR正在为建筑师开发VR空间,以便在项目上进行合作,允许他们在一个共享的虚拟环境中对接和探索结构的3D渲染。其他公司,如Cosmos Video,则更加强工作时的社交面向。员工可以浏览其电玩方式呈现的办公室,不止可以举办视频会议、办公时间,也可以在小游戏中相互挑战。导游与VR画廊除了上述应用外,还有一些公司在开发独特的元宇宙体验。Smartguide正在开发一款AR应用,将一个人的手机变成博物馆的导游。同时,Spatial公司筹集了2500万美元的B轮融资,以从虚拟工作空间转向开发VR画廊,人们可以在那里展示NFT艺术。(来源:文:何思颖原文链接:https://www.iothome.com/archives/7611
-
参赛资格获取 华为云昵称: kle 微信名:蒋 凭证截图:微信对话框截屏
-
智慧教育方法探索:手机游戏辅助研究教学盛浩1,2, 阮利1, 许可1, 韩军1, 熊璋1, 高小鹏1, 吕卫锋1,21 北京航空航天大学计算机学院软件开发环境国家重点实验室,北京 1001912 北京航空航天大学大数据科学与脑机智能高精尖创新中心,北京 100191摘要智能物联与泛在接入技术改变着学习方式,传统的手机辅助教学模式只是将课堂教学中部分内容简单地移植到互联网终端,没有充分发挥移动智能终端的灵活性和趣味性。基于学习内容碎片化和移动通信技术创新,提出了面向辅助教学的泛在学习理论,充分利用碎片时间与移动学习的优势,使得碎片化学习成为可能。然后,论证了游戏辅助教学的可行性,包括协同学习网络、情境认知理论、泛在学习方式3个部分。进一步提出了以学习者为中心的游戏辅助教学模型,由游戏辅助教学策略、学习者和教学设计模型构成,更关注预期教学目标实现和学习粘性保持。最后,通过两门课程的手机辅助教学实验结果验证了泛在学习理论的可行性和有效性,并使得手机游戏辅助教学成为传统课堂教学的有益补充。关键词: 智慧教育 ; 泛在学习 ; 手机游戏 ; 辅助教学1 引言智能物联与泛在接入技术不断改变着人们的生活和工作方式,也对学习模式和内容提出了新的挑战,从而使得碎片时间的泛在学习成为可能。传统教学以老师课堂讲解、学生被动接收为主,没有发挥学生在课堂教学中的主体性[1];受课堂时间的限制,讲授知识与课堂讨论难以兼顾,课堂讨论内容停留在问题分析层面,缺乏深度和广度,无益于培养学生的创新意识和独立思考能力[2,3,4,5];师生交流匮乏,知识单向灌输,课堂气氛沉闷,导致教学效果一般[6,7,8,9]。随着移动互联网的发展,智能手机应用已经渗透到学生生活的各个方面。中国社会科学院发布的《青少年蓝皮书》[10]显示,小学生、初中生和高中生拥有自己手机的比例分别达 64.2%、71.3%和86.9%。由于智能手机更加轻便且适用于碎片化使用场景,因此,受到更多人的青睐[11]。由此可知,充分利用碎片时间将会是课堂教学的有力补充,并可将学生的兴趣与学习相结合,寓教于乐。网络娱乐类应用是青少年网民群体最主要的互联网应用,其中,网络游戏对青少年的吸引尤为明显。《中国青少年上网行为研究报告》[12]显示,在所有网络娱乐类应用中,青少年网民使用网络游戏与网民总体水平的差异最明显,约70%的青少年使用网络游戏。如果能把游戏融入教学中,则能激发学生的学习热情、活跃课堂气氛,同时吸引学生在课下主动学习,取得良好的教学效果。2 国内外相关研究工作2.1 计算机辅助教学计算机辅助教学(CAI,computer assisted instruction)指用计算机帮助或代替教师执行部分教学任务,传递教学信息,传授知识和训练技能,直接为学生服务的教学活动。相比于幻灯机、投影仪、实验仪器等设备,计算机辅助教学具有人机交互的特点,已成为重要的现代教学手段。传统的智能手机辅助教学方式主要分为两类:1) 资源浏览型,通过智能手机上网查找、下载学习资源,摆脱了物理空间和时间的限制,真正做到了将课堂学习延伸到日常的生活和工作中[13];2) 社交协作型,为学习搭建了交流协作的平台,方便学生和学生、学生和老师之间的沟通,是理想的移动学习方式。然而,传统的智能手机辅助教学方式无法为学习者提供个性化指导,也不能根据学习情况动态调整学习策略[14],在反馈学习效果和调动学生学习热情上的表现也不尽如人意。以北京航空航天大学“在线网络实验平台”为例,学生可以随时随地进行网络实验,并安排老师在线解答问题。相比于传统课堂教学进步了很多,但它仅仅是一个预约实验的平台,没有对学生远程实验的效果做出反馈,只能依靠学生自己发现问题;学生按照实验步骤进行实验,趣味性不高。智能手机APP的快速普及为解决上述问题提供了另一个方向,计算机辅助教学缺乏灵活性和趣味性的问题可以通过手机游戏辅助教学来弥补。国外高校在智能手机辅助教学上起步较早,项目类型多样。如美国麻省理工学院MobileELDIT项目,旨在开发移动版本的在线语言学习系统,将E-learning平台上的内容以泛在方式提供给移动用户[15];美国斯坦福大学的 Uniwap 移动学习项目,通过智能手机APP为学生提供学习西班牙语的环境,通过其可以学习新词、查阅词典、翻译句子以及接受在线教学指导和测试等[16];美国阿比利大学开展的“联结项目”(connected program)通过移动设备辅助校园生活、教学和学习,更加高效、便捷[17];挪威奥斯陆大学的KnowMobile 项目,通过问题式学习法远程帮助医学院校学生解决实习期间遇到的问题[18]。国内的移动学习主要集中于国内高校[18]。如复旦大学的“i 复旦”是网络教学平台的移动版本,用户可以进行课程的视频直播、回放,学习资源的获取以及学习过程的交流[19];南京大学的 Calumet项目提供课件浏览、网络信息智能检索、课件服务器访问、智能交互回答、即时测验以及其他辅助教学功能[17];西安交通大学的SkyClass移动学习系统具有直播与交互、课件录制、资源管理、课件点播四大功能模块[19];北京师范大学的学习元项目为学习者提供微型学习资源和服务,能根据学习者的个性化需求提供课程推荐[20]。移动学习方式给老师和学生带来了新颖的教学和学习体验,取得了良好的学习效果,但是教学中也存在一些问题,如一些学生倾向于把移动设备当作通信工具。要解决上述问题还需要教育者的不断探索、改进。2.2 游戏辅助教学游戏一直被视为一种良好的益智、娱乐方式,如数独、俄罗斯方块等。随着智能移动设备的普及,人们开始花费更多空闲时间在游戏上。同时,研究人员也开始挖掘游戏除了娱乐以外的功能,如果能将游戏用于教学,作为一种具有互动性、吸引力的沉浸式活动,那么,游戏可以成为一种允许学习者积极参与学习的方式。国外研究人员开发了一款以超级马里奥为背景的游戏,帮助学生学习平衡二叉树,以生动的场景直观地展示二叉树的搜索、节点的插入和删除等操作,让学生在享受算法有趣性的同时学习知识[21]。Coloring Map游戏被应用于教学中[22],帮助学生理解约束满足问题(CSP,constraint satisfaction problem)的基本概念和求解算法;学生通过玩游戏可以实际模拟搜索算法所使用的步骤,在不知不觉中熟悉约束传播、回溯等概念,极大地促进了CSP求解和相应算法的理论教学。最后,可以再次使用游戏来测试所学的算法知识并进行实验,检验学生对CSP的理解程度;Binary Apple Tree游戏被用于算法课的教学[23],以可视化方式展示二叉树深度、广度优先等便利方法,取得了良好的教学效果;华盛顿大学计算机科学与工程学系和生物化学系联合开发了一款实验性的蛋白质折叠游戏 Foldit[24],来帮助研究者发现新的蛋白质模型,目前,该游戏已经帮助研究人员成功解决了一些通过计算机模拟无法解决的蛋白质折叠问题;心理学家通过游戏研究直接求解旅行商问题[25]和顶点覆盖问题[26]的过程。3 结束语本文尝试将泛在学习理论引入辅助教学中,使学生充分利用碎片时间开展移动学习。同时,论证了游戏辅助教学的可行性,通过协同学习网络、情境认知和泛在学习,将课程游戏以课程实践的形式提供给学生使用,为同学们提供了利用碎片时间思考课堂问题的机会,提高了课程学习的趣味性,帮助学生更直观地理解问题,发掘求解问题的算法策略。更进一步地,验证了以学习者为中心的游戏辅助教学模型对于预期教学目标实现和学习粘性保持都有良好的效果。通过游戏可以方便地模拟、验证算法策略,理解算法策略存在的问题,从而改进策略或者提出一种新的策略。两门课程的手机辅助教学实验结果显示,这种教学方法可以帮助同学们更好地理解问题、改进求解策略甚至发现新策略,验证了泛在学习理论的可行性和有效性,证明了手机游戏辅助教学是传统课堂教学的有益补充,值得进一步探索和实践。The authors have declared that no competing interests exist.作者已声明无竞争性利益关系。4 原文链接http://www.infocomm-journal.com/wlw/article/2019/2096-3750/2096-3750-3-4-00091.shtml
-
AMD 在今年三月宣布了 FidelityFX Super Resolution 2.0(FSR 2.0)。FSR 不同于英伟达的 Deep Learning Super Sampling (DLSS),没有使用 AI 训练模型,而是采用传统图像处理算法,其优点是容易整合到游戏中,支持旧显卡,甚至包括竞争对手的旧显卡。DLSS 需要英伟达显卡上的专门硬件重构图像,它甚至能重建出比原生画质更高的像素数。FSR 依赖和受制于游戏的基本像素,难以真正挑战 DLSS。上周 FSR 2.0 的源代码已公布在 GitHub 上,采用 MIT 许可证。上周末 Mod 开发者发布了《赛博朋克 2077》的 FSR 2.0 版本,使用英伟达旧显卡的用户可用它取代 DLSS。(Solidot)转载于CSDN微信公众号
-
参赛资格获取华为云昵称:马生凭证截图:
-
参赛资格获取华为云昵称:特务兔凭证截图:
-
参赛资格获取华为云昵称:陈女士凭证截图:微信对话框截屏
-
参赛资格获取华为云昵称:yd_280481656微信名:石头剪刀布凭证截图:
推荐直播
-
HDC深度解读系列 - Serverless与MCP融合创新,构建AI应用全新智能中枢2025/08/20 周三 16:30-18:00
张昆鹏 HCDG北京核心组代表
HDC2025期间,华为云展示了Serverless与MCP融合创新的解决方案,本期访谈直播,由华为云开发者专家(HCDE)兼华为云开发者社区组织HCDG北京核心组代表张鹏先生主持,华为云PaaS服务产品部 Serverless总监Ewen为大家深度解读华为云Serverless与MCP如何融合构建AI应用全新智能中枢
回顾中 -
关于RISC-V生态发展的思考2025/09/02 周二 17:00-18:00
中国科学院计算技术研究所副所长包云岗教授
中科院包云岗老师将在本次直播中,探讨处理器生态的关键要素及其联系,分享过去几年推动RISC-V生态建设实践过程中的经验与教训。
回顾中 -
一键搞定华为云万级资源,3步轻松管理企业成本2025/09/09 周二 15:00-16:00
阿言 华为云交易产品经理
本直播重点介绍如何一键续费万级资源,3步轻松管理成本,帮助提升日常管理效率!
回顾中
热门标签