zoukankan      html  css  js  c++  java
  • cocos creator实战-(二)跳一跳

    一、游戏的分析(之前没有接触过小游戏,制作的思维还停留在大型ARPG游戏大家共同协作的想法里,但是小游戏讲究小而全,大部分时间是一个人独立开发,所以需要迫使自己养成看到小游戏先拆分细化的思想)

    二、一些必要的参数

    台阶参数
    1: 设置分辨率: 720x1280
    2: 台阶的原点:
    3: 配置好4个中心点,如果跳到就到4个中心点,否则就失败;
    4: 编写代码获得中心点的位置,来初始化Player;
    5: 斜率: 0.5560472, 与平行四边形相当;
    6: 块开始的世界坐标的位置: (180, 350)

    参数
    1: 监听事件,开启蓄积能量, 2秒缩放到0.5;
    2: 0.5秒内,scale变形到1;
    3: 0.5秒内, 旋转一周;
    4: 0.5秒内,跳跃到目的地;
    5: 能量蓄积: 加速度: power: 600, 初始化: 150;
    this.speed += dt * this.power;
    this.jumpDistance += this.speed * dt;

    6:带上拖尾:
    MotionStreak组件: 配置好图片;(引擎bug,父节点移动,带有拖尾的子节点显示效果就会有问题,待解决)
    7: ancher_offset: 100
    8: 生成地图: 200, 400的距离随机
    9: 地图滚动参数: y, 随着玩家滚动, x 取最左值和最右值(180, 580);
    10:开始位置(180, 350)

    三、实现的步骤

    1 调整好player,具有旋转和压缩两个动画
    2 实现跳跃,前置条件是有东西可跳,所以要先制作两个块
    3 制作块,设置块的原点,中心点,前后左右点(主要是做跳跃检测,使用小色块),currBlock nextBlock
    4 开始写game_scene.js脚本
      绑定player和block
      固定第一个block(坐标转换)
      添加第二个block (add_block方法)
    5 调整第一个块和player的位置
    6 实现player的跳跃方法player_jump,以及block的检测方法is_jump_on_block
    7 实现地图滚动方法move_map
    8 完善游戏代码

    四、代码

    game_scene.js
    //game_scene.js
    
    cc.Class({
        extends: cc.Component,
    
        properties: {
            // foo: {
            //     // ATTRIBUTES:
            //     default: null,        // The default value will be used only when the component attaching
            //                           // to a node for the first time
            //     type: cc.SpriteFrame, // optional, default is typeof default
            //     serializable: true,   // optional, default is true
            // },
            // bar: {
            //     get () {
            //         return this._bar;
            //     },
            //     set (value) {
            //         this._bar = value;
            //     }
            // },
            player: {
                type: cc.Node,
                default: null
            },
            block_prefabs: {
                type: cc.Prefab,
                default: []
            },
            block_root: {
                default: null,
                type: cc.Node
            },
            left_org: cc.v2(0, 0),
            map_root: {
                default: null,
                type: cc.Node
            },
            y_radio: 0.5560472,
            checkout: {
                type: cc.Node,
                default: null
            }
        },
    
        // LIFE-CYCLE CALLBACKS:
    
        // onLoad () {},
    
        start() {
            this.block_list = [];
    
            this.cur_block = cc.instantiate(this.block_prefabs[Math.floor(Math.random() * this.block_prefabs.length)]);
            this.block_root.addChild(this.cur_block);
            // 将第一个块的位置设置为初始位置
            this.cur_block.setPosition(this.block_root.convertToNodeSpaceAR(this.left_org));
    
            var w_pos = this.cur_block.getChildByName('mid').convertToWorldSpaceAR(cc.v2(0, 0));
            this.player.setPosition(this.map_root.convertToNodeSpaceAR(w_pos));
            this.next_block = this.cur_block;
            this.player_comp = this.player.getComponent("player");
    
            this.block_zOrder = -1;
            this.add_block();
        },
        add_block: function() {
            this.cur_block = this.next_block;
    
            this.next_block = cc.instantiate(this.block_prefabs[Math.floor(Math.random() * this.block_prefabs.length)]);
            this.block_root.addChild(this.next_block);
    
            this.next_block.zIndex = this.block_zOrder;
            this.block_zOrder--;
    
            var x_distance = 200 + Math.random() * 200;
            var y_distance = x_distance * this.y_radio;
    
            var next_pos = this.cur_block.getPosition();
            next_pos.x += x_distance * this.player_comp.direction;
            next_pos.y += y_distance;
            this.next_block.setPosition(next_pos);
    
            this.player_comp.set_next_block(this.next_block.getComponent("block"));
    
            // 删除block
            this.block_list.push(this.next_block);
            if (this.block_list.length >= 5) {
                for (var i = 0; i < 2; i++) {
                    var block = this.block_list.shift();
                    block.destroy();
                }
            }
        },
    
        // 地图滚动
        move_map(offset_x, offset_y) {
            var m1 = cc.moveBy(0.5, offset_x, offset_y);
            var end_func = cc.callFunc(function() {
                this.add_block();
            }.bind(this));
    
            var seq = cc.sequence([m1, end_func]);
            this.map_root.runAction(seq);
        },
        on_checkout_game: function() {
            this.checkout.active = true;
        },
        on_game_again: function() {
            cc.director.loadScene("game_scene");
        },
        // update (dt) {},
    });
    player.js
    // player.js
    var game_scene = require("game_scene");
    cc.Class({
        extends: cc.Component,
    
        properties: {
            // foo: {
            //     // ATTRIBUTES:
            //     default: null,        // The default value will be used only when the component attaching
            //                           // to a node for the first time
            //     type: cc.SpriteFrame, // optional, default is typeof default
            //     serializable: true,   // optional, default is true
            // },
            // bar: {
            //     get () {
            //         return this._bar;
            //     },
            //     set (value) {
            //         this._bar = value;
            //     }
            // },
            init_speed: 150,
            a_power: 600,
            y_radio: 0.5560472,
    
            game_manager: {
                type: game_scene,
                default: null
            },
        },
    
        // LIFE-CYCLE CALLBACKS:
    
        onLoad() {
            this.next_block = null;
            this.direction = 1;
        },
    
        start() {
            this.rot_node = this.node.getChildByName("rotate");
            this.anima_node = this.rot_node.getChildByName("anima");
    
            this.is_power_mode = false;
            this.speed = 0;
            this.x_distance = 0;
    
            this.anima_node.on(cc.Node.EventType.TOUCH_START, function(e) {
                this.is_power_mode = true;
                this.x_distance = 0;
                this.speed = this.init_speed;
    
                this.anima_node.stopAllActions();
                this.anima_node.runAction(cc.scaleTo(2, 1, 0.5));
            }.bind(this), this);
    
            this.anima_node.on(cc.Node.EventType.TOUCH_END, function(e) {
                this.is_power_mode = false;
                this.anima_node.stopAllActions();
                this.anima_node.runAction(cc.scaleTo(0.5, 1, 1));
    
                this.player_jump();
            }.bind(this), this);
    
            this.anima_node.on(cc.Node.EventType.TOUCH_CANCEL, function(e) {
                this.is_power_mode = false;
                this.anima_node.stopAllActions();
                this.anima_node.runAction(cc.scaleTo(0.5, 1, 1));
    
                this.player_jump();
            }.bind(this), this);
        },
    
        update(dt) {
            if (this.is_power_mode) {
                this.speed += (this.a_power * dt);
                this.x_distance += this.speed * dt;
            }
        },
    
        player_jump: function() {
            var x_distance = this.x_distance * this.direction;
            var y_distance = this.x_distance * this.y_radio;
    
            var target_pos = this.node.getPosition();
            target_pos.x += x_distance;
            target_pos.y += y_distance;
    
            // 跳跃时候旋转
            this.rot_node.runAction(cc.rotateBy(0.5, -360 * this.direction));
    
            var w_pos = this.node.parent.convertToWorldSpaceAR(target_pos);
            var is_game_over = false;
            if (this.next_block.is_jump_on_block(w_pos, this.direction)) {
                target_pos = this.node.parent.convertToNodeSpaceAR(w_pos);
            } else {
                is_game_over = true;
            }
    
            var j = cc.jumpTo(0.5, target_pos, 200, 1);
            this.direction = (Math.random() < 0.5) ? -1 : 1;
            var end_func = cc.callFunc(function() {
                if (is_game_over) {
                    this.game_manager.on_checkout_game();
                } else {
                    if (this.direction === -1) {
                        this.game_manager.move_map(580 - w_pos.x, -y_distance);
                    } else {
                        this.game_manager.move_map(180 - w_pos.x, -y_distance);
                    }
                }
            }.bind(this));
    
            var seq = cc.sequence(j, end_func);
            this.node.runAction(seq);
        },
        set_next_block(block) {
            this.next_block = block;
        },
    });
    block.js
    // block.js
    cc.Class({
        extends: cc.Component,
    
        properties: {
            // foo: {
            //     // ATTRIBUTES:
            //     default: null,        // The default value will be used only when the component attaching
            //                           // to a node for the first time
            //     type: cc.SpriteFrame, // optional, default is typeof default
            //     serializable: true,   // optional, default is true
            // },
            // bar: {
            //     get () {
            //         return this._bar;
            //     },
            //     set (value) {
            //         this._bar = value;
            //     }
            // },
    
        },
        start() {
            this.mid = this.node.getChildByName("mid");
            this.up = this.node.getChildByName("up");
            this.down = this.node.getChildByName("down");
    
            this.left = this.node.getChildByName("left");
            this.right = this.node.getChildByName("right");
        },
    
        // dir 1右跳 -1左跳
        is_jump_on_block(w_dst_pos, direction) {
            var mid_pos = this.mid.convertToWorldSpaceAR(cc.v2(0, 0));
            var dir = w_dst_pos.sub(mid_pos);
            var min_len = dir.mag();
            var min_pos = mid_pos;
    
            if (direction === 1) {
                var up_pos = this.up.convertToWorldSpaceAR(cc.v2(0, 0));
                dir = w_dst_pos.sub(up_pos);
                var len = dir.mag();
                if (min_len > len) {
                    min_len = len;
                    min_pos = up_pos;
                }
                var down_pos = this.down.convertToWorldSpaceAR(cc.v2(0, 0));
                dir = w_dst_pos.sub(down_pos);
                var len = dir.mag();
                if (min_len > len) {
                    min_len = len;
                    min_pos = down_pos;
                }
            } else {
                var left_pos = this.left.convertToWorldSpaceAR(cc.v2(0, 0));
                dir = w_dst_pos.sub(left_pos);
                var len = dir.mag();
                if (min_len > len) {
                    min_len = len;
                    min_pos = left_pos;
                }
                var right_pos = this.right.convertToWorldSpaceAR(cc.v2(0, 0));
                dir = w_dst_pos.sub(right_pos);
                var len = dir.mag();
                if (min_len > len) {
                    min_len = len;
                    min_pos = right_pos;
                }
            }
    
            // 找到跳跃位置距离参考点最近的那个点以及位置
            dir = w_dst_pos.sub(min_pos);
            if (dir.mag() < 100) {
                w_dst_pos.x = min_pos.x;
                w_dst_pos.y = min_pos.y;
                return true;
            }
            return false;
        },
    });
  • 相关阅读:
    4月21日Java作业
    5.14 Java作业
    第十周java作业
    4月30号作业
    第七周上机
    4.9Java
    通宵看剧有感
    error: pathspec 'xxxxxxxxx' did not match any file(s) known to git
    markdown格式测试
    博客申请通过啦
  • 原文地址:https://www.cnblogs.com/orxx/p/10649384.html
Copyright © 2011-2022 走看看