《Cocos Creator游戏实战》摘星星进阶版_cocos摘星星游戏改进跳转代码-程序员宅基地

技术标签: 摘星星进阶版  Cocos Creator  《Cocos Creator游戏实战》  

摘星星进阶版

添加开始按钮

实现按钮功能

显示"Game Over"

限制主角移动范围

让跳跃动作更加细腻

加入星星收集动画

编写动画脚本

加入触屏控制

添加游戏提示


Cocos Creator官方所发布的新手教程——快速上手:制作第一个游戏写得详细且通俗易懂,笔者出于学习的目的编写了关于摘星星进阶版的教程,希望对大家有所帮助。自知不能达到官方那样的水平,所以写得比较简单,还请大家不要见笑。

运行效果如下:

Cocos Creator版本号:2.0.10

注:大家可以先下载官方进阶版项目文件来获取资源。

注:笔者会按照官方提供的代码进行讲解,但个别地方可能会稍作修改,当然游戏设计和功能还是保持一致的。

公众号后台回复"摘星星",获取该教程完整项目下载地址:

添加开始按钮

只有玩家点击了开始按钮,游戏才会开始。

我们将textures文件夹下的按钮图片拖入层级管理器中,使其成为Canvas的子节点:

修改节点名称为BtnStart:

接着在属性检查器中修改节点Y坐标为-50,改变按钮在屏幕上的位置:

为体现按钮特性,我们在属性检查器中给这个节点加一个Button组件:

将该按钮组件的目标节点设置为BtnStart,直接将BtnStart节点拖入Target框中即可,这样Button组件就知道自己所应用的对象是谁了:

当玩家把鼠标(或手指)移动到按钮上或者点击按钮时,按钮的大小、颜色或者其他方面应当发生相应改变,这样可以让用户界面显得更加友好。要做到这样我们只需修改Button组件中的Transition即可(这里我们通过颜色变化作为响应方式):

大家可以看到一共有四种状态,分别是Normal(正常),Pressed(按下不放开)、Hover(悬停)和Disabled(禁用)。我们可以给各个状态设置相应的颜色:

四种状态的十六进制值分别为:#FFFFFF,#C9C9C9,#C9C4C4,#757575。大家可以在颜色修改界面中的Hex Color输出框中输入:

现在我们运行下游戏,发现当我们把鼠标悬停在按钮上,或者点击按钮时,按钮的颜色都会发生改变:

实现按钮功能

现在我们给按钮加上相应功能:玩家点击按钮后,游戏开始。

既然按钮被按下了游戏才开始,那也就是说在没按下之前星星先不生成,主角也静止不动。于是修改代码如下:

在Game.js的onLoad函数中注释掉或者删除生成星星的代码:

// Game.js
onLoad: function () {
    // 获取地平面的 y 轴坐标
    this.groundY = this.ground.y + this.ground.height/2;
        
    // 初始化计时器
    this.timer = 0;
    this.starDuration = 0;

    // is showing menu or running game
    this.enabled = false;

    // 生成一个新的星星
    // this.spawnNewStar();

    // 初始化计分
    this.score = 0;
},

然后在Player.js中注释掉或者让主角运动的代码:

// Player.js
onLoad: function() {
    this.enabled = false;

    // 初始化跳跃动作
    this.jumpAction = this.setJumpAction();
    // this.node.runAction(this.jumpAction);

    // 加速度方向开关
    this.accLeft = false;
    this.accRight = false;
    // 主角当前水平方向速度
    this.xSpeed = 0;

    // 初始化键盘输入监听
    cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
    cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);    
},

Game.js和Player.js中都加入了this.enabled = false;这行代码,目的是为了停止update以及其他计时器(Scheduler)。如果不加这行代码,会发现update方法一直在运行(可加入console.log()试验下)。

此时我们运行游戏,发现主角是静止的,星星也没有生成:

接着我们编写按钮的回调函数:

onStartGame: function () {
    // 初始化计分
    this.score = 0;
    this.scoreDisplay.string = 'Score: ' + this.score.toString();
    // set game state to running
    this.enabled = true;
    // set button and gameover text out of screen
    this.btnNode.x = 3000;
    // reset player position and move speed
    this.player.getComponent('Player').startMoveAt(cc.v2(0, this.groundY));
    // spawn star
    this.spawnNewStar();
},

按钮按下后,游戏开始。

  • 首先初始化计分(记得将onLoad方法中的相关代码删除)。
  • 通过this.enabled = true;这行代码来让update方法运行。
  • 按钮按下后我们将其移出屏幕,我们让按钮的x或y坐标大于画布尺寸即可。记得在properties中添加btnNode属性。
  • 调用Player.js脚本中的startMoveAt方法让主角开始运动。
  • 通过spawnNewStar方法生成星星。

以下是startMoveAt方法,这里不再赘述,相信大家可以理解:

// Player.js
startMoveAt: function (pos) {
    this.enabled = true;
    this.xSpeed = 0;
    this.node.setPosition(pos);
    this.node.runAction(this.setJumpAction());
},

之后我们在properties属性中添加btnNode属性:

// Game.js
btnNode: {
    default: null,
    type: cc.Node
},

并将BtnStart节点拖入相应的框中:

现在我们选择BtnStart节点,在按钮组件的Click Events选值框中输入1,此时下方就会显示一些需要设置的属性,一共有四个:

  1. 在Target属性中,我们需要拖入带有按钮回调函数脚本的节点,在这里是Canvas
  2. 在Component属性中选择Canvas所带的Game.js脚本组件
  3. 在Handler属性中选择按钮回调函数
  4. 可以在CustomEventData中传入任意字符串作为回调函数的参数值,这里没有用到,所以空着就行

填完之后显示如下:

此时运行游戏,点击Play按钮后,主角开始运动,星星也生成了:

显示"Game Over"

我们应该在游戏失败的时候显示"Game Over"字样,这样区分更加明显。

层级管理器中我们新建一个Label节点,命名为GameOver:

属性检查器中我们将该节点的各个属性设置如下:

"Game Over"文本应当只有在游戏失败时显示,所以刚开始应当让它不可见。我们将属性检查器下的勾给去掉就行:

此时层级管理器中的GameOver节点显示灰色,而且场景编辑器中也没有显示"Game Over":

现在将GameOver节点写进代码中。首先在properties中添加gameOverNode属性:

// Game.js
gameOverNode: {
    default: null,  
    type: cc.Node
},

然后在gameOver方法中,设置该节点可见:

// Game.js
gameOver: function () {
    this.gameOverNode.active = true;
    this.btnNode.x = 0;
    this.player.getComponent('Player').enabled = false;
    this.player.stopAllActions(); //停止 player 节点的跳跃动作
    // cc.director.loadScene('game');
}

在该方法中我们还要让按钮重新回到屏幕上以及停止主角的一切动作,还要去掉cc.director.loadScene('game')这行代码,否则游戏会立即重新载入。

此时我们运行游戏,发现游戏失败后显示"Game Over"字样:

但是如果我们点击Play按钮后,"Game Over"没有消失,而且还会再出现一个星星:

也就是说我们应该在用户点击了Play按钮后使"Game Over"文本不可见,并且要删除已存在的星星节点(该删除操作也可以放在gameOver方法中)。我们首先完成第一个:

// Game.js
onStartGame: function () {
    ...

    // "Game Over" not visible
    this.gameOverNode.active = false;

    ...
},

在编写删除星星的代码前,我们将生成星星的代码稍微修改下。目前我们是通过直接实例化一个Prefab来实现,而在进阶版中我们将使用对象池来更好的管理星星对象。

对象池就是一组可回收的节点对象,我们通过创建 cc.NodePool 的实例来初始化一种节点的对象池。通常当我们有多个 prefab 需要实例化时,应该为每个 prefab 创建一个 cc.NodePool 实例。 当我们需要创建节点时,向对象池申请一个节点,如果对象池里有空闲的可用节点,就会把节点返回给用户,用户通过 node.addChild 将这个新节点加入到场景节点树中。

我们首先在onLoad方法中创建两个变量:

// Game.js
onLoad: function () {
    ...
    
    // store last star's x position
    this.currentStar = null;

    ...

    // initialize star and score pool
    this.starPool = new cc.NodePool('Star');
},

currentStar用于存储新生成的星星对象,currentStarX用于存储它的x坐标,而starPool就是对象池实例。

接着修改spawnNewStar方法:

// Game.js
spawnNewStar: function() {
    var newStar = null;
    // 使用给定的模板在场景中生成一个新节点
    if (this.starPool.size() > 0) {
        newStar = this.starPool.get(this); // this will be passed to Star's reuse method
    } else {
        newStar = cc.instantiate(this.starPrefab);
        // pass Game instance to star
        newStar.getComponent('Star').reuse(this);
    }
    // 为星星设置一个随机位置
    newStar.setPosition(this.getNewStarPosition());
    // 将新增的节点添加到 Canvas 节点下面
    this.node.addChild(newStar);

    // 重置计时器,根据消失时间范围随机取一个值
    this.starDuration = this.minStarDuration + Math.random() * (this.maxStarDuration - this.minStarDuration);
    this.timer = 0;

    this.currentStar = newStar;
},

我们通过调用size()来获取对象池大小。如果对象池中有星星对象,则调用get()获取一个;如果没有则实例化生成一个,并直接传入Game实例。接着设置星星的坐标并添加到Canvas上,重置计时器,并将新生成的星星对象赋值给currentStar变量。

大家可能已经注意到get()中传入了一个this,并且会对reuse()产生疑问(这哪来的?)。当我们在实例化对象池的时候,传入了'Star'(其实就是Star.js),这样的话当我们调用get方法时,就会自动调用Star.js中的reuse方法;而当调用put方法回收星星时,程序就会自动调用Star.js中的unuse方法。当然我们还得自己手动往Star.js中加入这两个函数先:

// Star.js
reuse(game) {
    this.game = game;
    this.enabled = true;
    this.node.opacity = 255;
},

unuse() {
    // 因为回收时不执行任何操作,所以该方法可以不写
},

星星生成的代码已经搞定,接下来编写回收代码:

// Game.js
despawnStar (star) {
    this.starPool.put(star);
    this.spawnNewStar();
},

该方法带一个参数star,也就是说我们调用的时候要传入星星对象所在的节点。在方法中我们调用put()来回收星星对象,同时生成一个新的星星。

现在我们在Star.js的onPicked方法中调用despawnStar():

// Star.js
onPicked: function() {
    // 调用 Game 脚本的得分方法
    this.game.gainScore();
    // 然后回收当前星星节点,并生成新的星星
    this.game.despawnStar(this.node);
},

上面是星星被主角收集,而在游戏结束时,我们还应当销毁当前存在于屏幕上的星星:

// Game.js
gameOver: function () {
    ...
    this.currentStar.destroy();
}

现在运行游戏,发现结束后星星会消失(节点被回收):

限制主角移动范围

现在我们给主角的活动范围加一个边界,禁止它跳到屏幕外边。要实现该功能,我们只需要往Player.js中添加一些代码即可:

// Player.js
update: function (dt) {
    ...

    // limit player position inside screen
    if ( this.node.x > this.node.parent.width/2) {
        this.node.x = this.node.parent.width/2;
        this.xSpeed = 0;
    } else if (this.node.x < -this.node.parent.width/2) {
        this.node.x = -this.node.parent.width/2;
        this.xSpeed = 0;
    }
},

通过比较主角节点的x坐标与屏幕一半大小来判断主角是否超出边界。若超出,则设置节点x坐标值为屏幕一半大小即可。

现在运行游戏,发现主角已无法跳出屏幕外:

让跳跃动作更加细腻

主角现在的跳跃动作还是非常平淡的,没有一种伸缩的感觉。按道理来讲,这种长得像果冻一样的主角,跳跃动作应该表现得像果冻一样才对。

要实现这样的功能也非常容易,我们只需要往Play.js的setJumpAction方法中再加入一些动作:

// Player.js
setJumpAction: function () {
    // 跳跃上升
    var jumpUp = cc.moveBy(this.jumpDuration, cc.v2(0, this.jumpHeight)).easing(cc.easeCubicActionOut());
    // 下落
    var jumpDown = cc.moveBy(this.jumpDuration, cc.v2(0, -this.jumpHeight)).easing(cc.easeCubicActionIn());
    // 形变
    var squash = cc.scaleTo(this.squashDuration, 1, 0.6);
    var stretch = cc.scaleTo(this.squashDuration, 1, 1.2);
    var scaleBack = cc.scaleTo(this.squashDuration, 1, 1);
    // 添加一个回调函数,用于在动作结束时调用我们定义的其他方法
    var callback = cc.callFunc(this.playJumpSound, this);
    // 不断重复,而且每次完成落地动作后调用回调来播放声音
    return cc.repeatForever(cc.sequence(squash, stretch, jumpUp, scaleBack, jumpDown, callback));
},

可以看到我们加入了squash(挤压),stretch(伸展)和scaleBack(复原)这三个动作,持续时间都为squashDuration,然后加入到了sequence中。记得在properties中添加相应属性:

// Player.js
properties: {
    // 主角跳跃高度
    jumpHeight: 0,
    // 主角跳跃持续时间
    jumpDuration: 0,
    // 辅助形变动作时间
    squashDuration: 0,
    ...
},

接着我们在属性检查器中修改squashDuration的值:

现在运行游戏,发现跳跃动作更细腻了,更像一个果冻了:

加入星星收集动画

为了让收集星星时的效果更佳华丽酷炫,我们可以在主角和星星碰撞时加入一小段动画。官方在项目中提供了几张用于动画制作的图片,大家可以先导入进来:

在创建动画前,我们先来了解下动画组件和动画剪辑这两个概念。前者作为组件可以被添加到节点上,它可以用来管理一个或多个动画剪辑,而动画剪辑其实就是动画的所播放的内容了。

我们先在层级管理器中新建一个空节点,并将其命名为animRoot:

接着在该节点下再创建一个Sprite精灵节点和一个Label节点,分别命名为pop和score。前者跟动画中的图片有关,后者跟文本有关,相当于有两个节点的动画要实现。

我们这里直接将score节点的文本颜色改#F8DD4D,内容改成+1并拖入字体文件:

现在可以往animRoot上添加一个动画组件了:

添加之后我们看到该组件一共有三个属性:Default Clip,Clips和Play On Load。

以下是官方对这三种属性的解释,非常清楚:

属性 功能说明
Default Clip 默认的动画剪辑,如果这一项设置了值,并且 Play On Load 也为true,那么动画会在加载完成后自动播放 Default Clip 的内容
Clips 列表类型,默认为空,在这里面添加的 AnimationClip 会反映到 动画编辑器 中,用户可以在 动画编辑器 里编辑 Clips 的内容 
Play On Load 布尔类型,是否在动画加载完成后自动播放 Default Clip 的内容

那我们这里只会用到一个动画剪辑,所以使用Default Clip就好(当Default Clip被放入动画剪辑时,Clips属性值自动会变为1)。而动画是在主角碰到星星后才会播放,所以Play On Load不勾选。

现在我们可以在资源管理器中新建一个动画剪辑,并命名为score_pop:

然后将该动画剪辑拖入到刚才动画组件的Default Clip属性中:

前期工作已经做好,可以开始编辑动画了!我们点击控制台旁边的动画编辑器标签页,显示编辑器界面:

按照提示点击左上角按钮开始编辑,由于不需要太高质量,我们这里把帧速率(每秒动画帧数)改为25:

关于该编辑器的介绍,大家可以直接去看官方文档,笔者这里不再赘述。

为方便理解,我们先来处理score节点的动画。点击编辑器中的score,然后在属性列表中添加position属性(位置)和opacity属性(透明度):

所谓动画,其实就是把不同时刻表现形式不同的各个帧给连接起来。那也就是说我们只要让position和opacity在特定的帧数下表现不同就行了。

先搞定position。在开始处(第0帧),我们给position插入一帧(Windows下点击右键,Mac下双指点击触控板):

然后再把那条红色移动到第15帧,并插入一帧:

第15帧的时候,position肯定要表现不同,我们这里让它的y值变大,也就是说播放动画的时候socre节点会上升。此时我们保持红色位置不变,在属性检查器中修改y坐标为92(当然也可以其他数字,这里只是按照官方来):

此时我们发现在动画编辑器中出现一条淡蓝的线,将表现不同的两个帧给连接了起来:

现在点击动画编辑器左上角的播放按钮,可以在场景编辑器中看到冉冉升起的+1文本。但是这种匀速升起有点平淡,我们可以高点花样。双击蓝色线条,会出现一个速率编辑器:

点击Custom标签,然后把右边的蓝色线条拖曳成下面这个妖娆的样子(先慢后快再慢):

点击左边保存按钮后,我们关掉它,然后再次点击播放按钮,可以看到+1文本的运动显得更加有趣了些。

同理我们处理下opacity属性,插入帧位置如下(15,19,20):

我们将第19帧和第20帧的透明度分别改为51和0(注意移动红色位置),不用改变化速率:

现在来处理下pop节点。给它加上opacity,scaleX,scaleY和cc.Sprite.spriteFrame这四个属性:

scaleX和scaleY用来改变大小,而cc.Sprite.spriteFrame就是用来放不同图片的。我们先来处理下opacity,scaleX和scaleY:

在opacity属性的第8帧和第10帧插入一帧,然后修改第10帧的透明度为0。在scaleX和scaleY的第0帧,第2帧和第5帧插入一帧,修改第2帧的Scale X或Scale Y值为1.5。

针对cc.Sprite.spriteFrame属性,我们并不用插入帧,而是可以直接将图片拖入到相应帧位置。首先将第一章图片拖入到第二帧的位置:

然后将第二张图片拖入第三帧,依次操作直到全部图片拖曳完毕:

大家现在可以点击播放按钮看下效果。

动画制作到此结束,我们点击左上角的编辑按钮来保存(或者可以使用ctrl/cmd + s组合键),这样pop和score节点的动画就都保存在score_pop动画剪辑中了:

编写动画脚本

每当主角吃到星星,该动画就会显示出来,所以我们应该将animRoot节点变成一个预制(相信大家已经知道怎么把节点变预制了)。接着再在Game.js的properties中添加一个animRootPrfab属性:

// Game.js
properties: {
    // 这个属性引用了星星预制资源
    starPrefab: {
        default: null,
        type: cc.Prefab
    },
    animRootPrefab: {
        default: null,
        type: cc.Prefab
    },
    // 星星产生后消失时间的随机范围
    maxStarDuration: 0,
    minStarDuration: 0,
    ...
},

同样我们要使用对象池来管理生成的预制,所以在onLoad方法中新建一个currentAnimRoot和scorePool变量:

// Game.js
onLoad: function () {
    // store last star's x position
    this.currentStar = null;
    this.currentAnimRoot = null;

    ...
 
    // initialize star and score pool
    this.starPool = new cc.NodePool('Star');
    this.scorePool = new cc.NodePool('ScoreAnim');
},

这里传入一个ScoreAnim脚本名,该脚本内容如下:

// ScoreAnim.js
cc.Class({
    extends: cc.Component,

    reuse(game) {
        this.game = game;
    },

    despawn() {
        this.game.despawnAnimRoot();
    }
});

将该脚本添加到animRoot节点上:

现在编写一个spawnAnimRoot方法用于生成动画预制:

// Game.js
spawnAnimRoot: function () {
    var fx;
    if (this.scorePool.size() > 0) {
        fx = this.scorePool.get(this);
    } else {
        fx = cc.instantiate(this.animRootPrefab);
        fx.getComponent('ScoreAnim').reuse(this);
    }
    return fx;
},

可以看到我们同时将this传给ScoreAnim.js中的reuse方法,目的就是为了调用Game.js中的despawnAnimRoot(至于该方法有什么用,后面会讲解)。

每加一分,动画播放一次,所以我们会在gainScore方法中调用spawnAnimRoot方法:

// Game.js
gainScore: function (pos) {
    this.score += 1;
    // 更新 scoreDisplay Label 的文字
    this.scoreDisplay.string = 'Score: ' + this.score;
    // 播放特效
    this.currentAnimRoot = this.spawnAnimRoot();
    this.node.addChild(this.currentAnimRoot.node);
    this.currentAnimRoot.node.setPosition(pos);
    this.currentAnimRoot.getComponent(cc.Animation).play('score_pop');
    // 播放得分音效
    cc.audioEngine.playEffect(this.scoreAudio, false);
},

可以看到gainScore方法多了一个参数pos。每当主角碰到星星的时候,获取星星所在的位置,传给gainScore方法作为动画预制的坐标。这样动画就会在星星被吃掉的位置播放了。于是我们修改下Star.js中的onPicked方法:

// Star.js
onPicked: function() {
    var pos = this.node.getPosition();
    // 调用 Game 脚本的得分方法
    this.game.gainScore(pos);
    // 然后销毁当前星星节点
    this.game.despawnStar(this.node);
},

动画播放完之后肯定要回收,代码如下:

// Game.js
despawnAnimRoot () {
    this.scorePool.put(this.currentAnimRoot);
},

那问题来了,我们怎么知道动画什么时候会播放结束呢?其实在动画编辑器中我们可以为帧添加回调函数,所以我们在动画播放的最后一帧添加despawnAnimRoot方法即可。

首先打开动画编辑器,然后我们把红线移动到最后一帧,也就是第20帧:

然后在点击左上角的一个小箭头按钮给该帧添加一个回调函数:

此时可以发现最后一帧的上方会出现一个小块:

双击该小块,进入到回调函数编辑区域:

我们可以直接往输入框中输入方法名称,不过该方法必须来自animRoot节点上的脚本组件,也就是ScoreAnim.js,那么这里就填入despawn(我们已经在该方法中调用了Game.js中的despawnAnimRoot方法):

输入完毕点击保存。接着将animRoot节点拖入资源管理器使其成为一个预制,再将其拖入到Canvas的Game组件中:

运行游戏,动画正常播放:

加入触屏控制

目前该游戏只能通过键盘来控制主角移动,现在我们为移动设备加入触屏控制。非常简单,只需要监听触摸事件即可:

// Player.js
onLoad: function() {
    ...

    var touchReceiver = cc.Canvas.instance.node;
    touchReceiver.on('touchstart', this.onTouchStart, this);
    touchReceiver.on('touchend', this.onTouchEnd, this);
},

onDestroy () {
    // 取消键盘输入监听
    ...

    var touchReceiver = cc.Canvas.instance.node;
    touchReceiver.off('touchstart', this.onTouchStart, this);
    touchReceiver.off('touchend', this.onTouchEnd, this);
},  

然后在onTouchStart和onTouchEnd方法中编写相应逻辑代码:

// Player.js
onTouchStart (event) {
    var touchLoc = event.getLocation();
    if (touchLoc.x >= cc.winSize.width/2) {
        this.accLeft = false;
        this.accRight = true;
    } else {
        this.accLeft = true;
        this.accRight = false;
    }
},

onTouchEnd (event) {
    this.accLeft = false;
    this.accRight = false;
},

当手指点击屏幕右侧时,主角往右加速;点击左侧时,往左移动加速。

这里插个小曲,在基础版摘星星代码中,官方还没有用键盘上的左右箭头来控制。而在进阶版中添加了:

// Player.js
onKeyDown (event) {
    // set a flag when key pressed
    switch(event.keyCode) {
        case cc.macro.KEY.a:
        case cc.macro.KEY.left:
            this.accLeft = true;
            break;
        case cc.macro.KEY.d:
        case cc.macro.KEY.right:
            this.accRight = true;
            break;
    }
},

onKeyUp (event) {
    // unset a flag when key released
    switch(event.keyCode) {
        case cc.macro.KEY.a:
        case cc.macro.KEY.left:
            this.accLeft = false;
            break;
        case cc.macro.KEY.d:
        case cc.macro.KEY.right:
            this.accRight = false;
            break;
    }
},

很简单,无非就是多了个case判断。

添加游戏提示

添加游戏提示可以让游戏更加友好,否则玩家可能一开始不知道要怎么样往下进行。

我们在层级管理器中加入两个Label控件,分别命名为Instruction_Control和Instruction_Goal:

将前者的x和y坐标以及文本内容修改如下:

将后者的x和y坐标以及文本内容修改如下:

同时修改下score节点的y坐标值为270:

最后修改Player节点y坐标值为0,让它不要被开始按钮遮住:

运行截图如下:

好到这里就讲解结束啦,希望大家有所收获!

欢迎关注我的微信公众号,发现更多有趣内容:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/La_vie_est_belle/article/details/102652568

智能推荐

docker删除重装,以及极其重要的/etc/docker/key.json文件-程序员宅基地

文章浏览阅读8.9k次,点赞2次,收藏2次。先说以下我为何要删除docker的原因吧:因为我感觉Docker Hub有点慢,就配置了阿里云的镜像加速器,可是按阿里云的官方配置完后我怎么感觉它更慢了,对比昨天配置阿里的maven镜像仓库后快到起飞的速度,我认为是此次配置没有生效。多次确认新加入的/etc/docker/demon.json文件无误后又多次systemctl了未果,随即我怀疑阿里给出的以下方案中的“修改”的/etc/dock...

空间物理——概述_空间物理概论-程序员宅基地

文章浏览阅读1.9k次,点赞3次,收藏4次。文章目录空间物理的研究对象太阳风能量向地球传输的三种方式和所需要的时间太阳内部结构、太阳活动太阳内部结构太阳活动太阳风速度从太阳表面到地球轨道附近变化参考空间物理的研究对象大气层:10KM以上,分成平流层、中层、低热层、热层、逃逸层电离层:60-90KM以上,一直到1000KM左右,部分电离气体,中性成风碰撞的影响不可忽略地球磁层:完全电离的气体,1000KM以上,可忽略碰撞,有太阳风和..._空间物理概论

BQ4050学习笔记(二)-程序员宅基地

文章浏览阅读2.9k次,点赞5次,收藏25次。BQ4050学习笔记(二)永久失效:如果发⽣严重故障,该设备可以永久禁⽤电池组。永久故障检查(IFC 和 DFW 除外)可以通过设置Settings:Enabled PFA、 Settings:Enabled PF B、 Settings:Enabled PF C 和Settings:Enabled PF D 中的相应位单独启⽤或禁⽤。所有永久在设置ManufacturingStatus()[PF]之前,故障检查(IFC 和 DFW 除外)被禁⽤。当任何PFStatus()位置位时,器件进⼊ PER_bq4050

SpringCloudAlibaba-Nacos注册中心的使用_spring-cloud-alibaba 使用nacos 2.1版本-程序员宅基地

文章浏览阅读152次。第二步:填写配置文件参数,这里定义了一个名字为application-user-dev.yaml的配置,使用的是YAML格式。DataID : 非常重要,可以看做是配置的文件的名字,在程序中拉取配置文件的时候需要指定Data ID。如果不使用默认的public命名空间,那么需要指定namespace配置为要使用的命名空间的Id值。第一步:打开Nacos监控面板,进入配置列表,新增一个user服务的配置文件。进入配置列表 ,切换到新建立的命名空间,创建配置文件。修改Nacos,添加命名空间。_spring-cloud-alibaba 使用nacos 2.1版本

CVE-2023-21716 Microsoft Word远程代码执行漏洞Poc_cve-2023-21716复现-程序员宅基地

文章浏览阅读293次。受害者打开python代码生成的RTF文件,RTF解析器解析恶意代码,触发堆溢出,Microsoft Word会闪退,用户其它Word中未保存的内容会丢失。_cve-2023-21716复现

c语言程序设计让a变成A,c语言程序设计a期末模拟试题.docx-程序员宅基地

文章浏览阅读451次。文件排版存档编号:[UYTR-OUPT28-KBNTL98-UYNN208]文件排版存档编号:[UYTR-OUPT28-KBNTL98-UYNN208]C语言程序设计A期末模拟试题C语言程序设计A期末模拟试题一一、单项选择题(每小题2分,共20分)由C++目标文件连接而成的可执行文件的缺省扩展名为( )。A. cpp B. exe C. obj D. li..._c语言如何将a转换成a

随便推点

利用beef和msf实现session远程命令_msf如何切换一个session-程序员宅基地

文章浏览阅读534次。笔记beef启动 beef 的方法msfbeef工具目录 /usr/share/beef-xss配置文件 config.yaml启动 beef 的方法1.beef-xss2./usr/share/beef-xss/beef(使用前需要修改默认的用户名称和密码)Web 管理界面 http://127.0.0.1:3000/ui/panelShellcode http://127.0.0.1:3000/hook.js测试页面 http://127.0.0.1:3000/demos/butch_msf如何切换一个session

python判断丑数_丑数问题及变种小结-程序员宅基地

文章浏览阅读503次。丑数问题及变种小结声明1 判断丑数因子只包含2,3,5的数称为丑数(Ugly Number),习惯上把1当作第一个丑数面试lintcode 517 ugly numbersegmentfault剑指offer 面试题34 丑数数组解法:参考剑指offer,将待判断目标依次连续整除2,3,5,若是最后获得1,证实该数为丑数;优化/*** 依次整除2,3,5判断(2,3,5顺序判断时间最优)* htt..._编写python来证明一个数是丑数

python自动化测试实战 —— WebDriver API的使用_python webdriver api-程序员宅基地

文章浏览阅读1.9k次,点赞30次,收藏11次。Selenium 简介: WebDriver是Selenium Tool套件中最重要的组件。Selenium 2.0之后已经将Selenium和WebDriver进行合并,作为一个更简单、简洁、有利于维护的API提供给测试人员使用。 它提供了一套标准的接口,可以用多种编程语言调用,并且和浏览器进行交互。 WebDriver可以对浏览器进行控制,包括输入URL,点击按钮,填写表单,滚动页面,甚至是执行JavaScript代码。同时,它也能够获取网页中的信息,如文本,标签,属_python webdriver api

Nodejs crypto模块公钥加密私钥解密探索_crypto.publicencrypt-程序员宅基地

文章浏览阅读1w次。1.什么是公钥加密私钥解密 简单一点来说一般加密解密都用的是同一个秘钥或者根本不用,而这里采用的是加密用一个秘钥,解密用另一个秘钥且能解密成功.这就属于不对称加密解密算法的一种了.2.公钥秘钥的生成 由于这种加密方案,公钥秘钥是成对的,所以需要一些工具生成 利用 openssl 生成公钥私钥 生成公钥: openssl genrsa -out rsa_private_key...._crypto.publicencrypt

Maven简明教程(5)---依赖关系(实例篇)_依赖关系怎么写-程序员宅基地

文章浏览阅读1.7k次。[工欲善其事,必先利其器]上文中,我们简单介绍了依赖关系的基本理论与配置方式。但是由于这个知识点在我们日后的开发过程中会经常使用到,因此,我们在本篇中通过演示实例来说明依赖关系,请各位看官一定跟着步骤,亲自尝试一番。仔细观察通过这种方式对我们程序架构造成的影响。特别的,这里以一份已经调试完成的工程为例,因此,与前文说的工程命名不一致,敬请谅解。准备工作:a.操作系统:win7 x6_依赖关系怎么写

2017多校联合第五场1006/hdu6090Rikka with Graph(思维公式)-程序员宅基地

文章浏览阅读343次。Rikka with GraphTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 592 Accepted Submission(s): 353Problem DescriptionAs we know,