Interactive script making of cocos character and enemy behavior

Posted by pankirk on Fri, 11 Feb 2022 03:55:39 +0100

Make a cocos free game for your baby

Chapter 1 introduction of background and development framework
Chapter 2 Node tree and scene production
Chapter III UI, map and level text production
Chapter IV rocker, key and character animation
Chapter 5 enemy and AI production
Chapter VI interactive script making of role and enemy behavior
Chapter 7 game packaging, release and debugging

preface

The previous section introduces how to make maps, ai and characters. This section pushes the boat along the river to do their interaction. A private letter from a friend said when we can add the plot and art work. The key technology is, but the picture looks wrong. The pressure is high. If you have time, you can talk about it later. The little sister of the artist has gone to hold the baby and can only be androgynous
Sorry, I've been busy for some time, and the game project has been shelved for a long time.

1, Interaction between character and map

Mainly because we didn't use tiedmap to make maps, we had to die and find another way to fall into the stream. So we should do map blocking function, plot trigger, blood loss treatment, etc. The feeling of sour and cruel

(1) Implementation of barrier

1. Map object - move tangentially when you encounter it, which can be realized. Don't forget that there is another component called the physical engine, which must be used as a barrier
Now add the previous map prefab object to the physics engine.

Check the rigid Bullet type, and select Static fixed (after all, it's a wall, etc.)

Other defaults are OK
Of course, the first step is to remember to turn on the physics engine when loading the map

Insert code slice here

2. Role object:
(1) Collision bodies (also physical components) are added to components that may be in contact with key positions, such as the body, hands and feet
Note: the character consists of multiple physical contact points, such as weapons, hands and feet. If the JOIN physical components are not added, the physical lag is turned on and will not follow the action of the main node
For physical components of join class, please refer to: https://blog.csdn.net/qq_43287088/article/details/107948878
Of course, you can also use the simplest method. When making an animation action, you need to record position in addition to angle, which can cut corners.

(2) Perfect map trigger

Add code to doors, ladders, boxes, etc. to realize barrier and passage switching, load content, etc. Considering interactivity, load aijs JS and write the response code on it

Adjust the lower canvas JS JS loadMaoObj and main json

2, Role and AI interaction

The relevant codes are written in ajjs JS file, judged by reacttype

        switch(this.reacttype){
            case 'box':   break;
            case 'guid':  break;
            case 'dialog':break;
            case 'player':break;
            case 'enemy': break;
            case 'story': break;
            case 'loader':break;         
        }

1.load readout tab

//This is directly in ajjs Accumulate attributes in jstick (the menu has been loaded in jstick)
    loadEquipment:function(owner){
        switch(this.reacttype){
            case 'box':  break;
            //json-items:position = owner
            case 'guid':  break;
            case 'dialog':break;
            case 'player': //Character's equipment attributes
                //ui-tab 
                var eq = cc.find('Canvas').getChildByName('UI').getChildByName('itemScrollView').getChildByName('equipment');
                if(eq){
                    var eqs = eq.children;
                    if(eqs.length > 0){
                        for(var i=0;i<eqs.length;i++){
                          var ip = eqs[i].children[0]?eqs[i].children[0].getComponent('itemstab'):null;
                          if(!ip){return;}
                          this.feeldistance  = Math.round(this.feeldistance) + Math.round(ip.feeldistance);
                          this.actdistance = Math.round(this.actdistance) + Math.round(ip.actdistance);
                          this.movespeed = Math.round(this.movespeed) + Math.round(ip.movespeed);
                          this.hp = Math.round(this.hp) + Math.round(ip.hp);
                          this.lp = Math.round(this.lp) + Math.round(ip.lp);
                          this.mp = Math.round(this.mp) + Math.round(ip.mp);
                          this.at = Math.round(this.at) + Math.round(ip.at);
                          this.skill1 = ip.skill1?ip.skill1:this.skill1 ;//cd? Press the key to check whether it is active
                          this.skill2 = ip.skill2?ip.skill2:this.skill2 ;
                          this.skill3 = ip.skill3?ip.skill3:this.skill3 ;
                          this.skill4 = ip.skill4?ip.skill4:this.skill4 ;
                        //   this.skills.push( ip.skill1?ip.skill1:this.skill1 );
                        }
                    }
                }
            break;
            case 'enemy'://Enemy equipment attributes
                //json-items:position = owner
                if(TOOLS){
                    for(var i=0;i<TOOLS.length;i++){
                        if(TOOLS[i].owner == this.node.name){
                                          
                            if(TOOLS[i].type=='S'){ //Go down and put it in the empty skill column
                                if(this.skill1 ==''){this.skill1 = TOOLS[i].name;}
                                else if(this.skill2==''){this.skill2 = TOOLS[i].name;}
                                else if(this.skill3 ==''){this.skill3 = TOOLS[i].name;}
                                else if(this.skill4 ==''){this.skill4 = TOOLS[i].name;}
                                else{}//None of them are empty and will not be executed
                                var tmp = 'name:'+TOOLS[i].name+',eff:'+TOOLS[i].eff+',at:'+TOOLS[i].value;
                                this.skills.push(tmp);
                            }                            
                            else{//Consumables are also added to the attribute, which will be considered for later optimization
                                switch(TOOLS[i].eff){
                                    case 'fd':this.feeldistance  = Math.round(this.feeldistance) + Math.round(TOOLS[i].value);break;
                                    case 'ad':this.actdistance = Math.round(this.actdistance) + Math.round(TOOLS[i].value);break;
                                    case 'ms':this.movespeed = Math.round(this.movespeed) + Math.round(TOOLS[i].value);break;
                                    case 'hp':this.hp = Math.round(this.hp) + Math.round(TOOLS[i].value);break;
                                    case 'lp':this.lp = Math.round(this.lp) + Math.round(TOOLS[i].value);break;
                                    case 'mp':this.mp = Math.round(this.mp) + Math.round(TOOLS[i].vaue);break;
                                    case 'at': this.at = Math.round(this.at) + Math.round(TOOLS[i].value);break;
                                }   
                            }

                        }
                    }
                }
            break;
            case 'story':break;
            case 'loader': break;         
        }
     },

2. Skill CD realization

Here, you can directly use the random method to release skills. Of course, you can load the skills into the array and cycle the distance to use the skills with mp

    takeActions:function(e){
        var an = this.node.getComponent(cc.Animation);
        var anstatus = this.node.getComponent(cc.Animation).AnimationStatus;
        // if(an){an.play('att_ailhit');};
        var sk = this.sk?this.sk:[];
        if(sk.length>0){
            var r = Math.floor(Math.random()*sk.length+1); //Random cd FREE
            an.play(sk[r].name);
            //The strike operation of blood reduction is all on the collision
        }
        //check free

        //important level
    },

3. Injury and blood deduction

It is realized in physical collision. If it is a weapon + opponent, it will reduce blood

//2. Physical collision
    onBeginContact(contact, selfCollider, otherCollider) {
        // cc.log("onBeginContact");        // Collision trigger event
        switch(this.reacttype){
            case 'box':  
            //need key?
            break;
            case 'door':  
            //need key?
            
            break;
            case 'guid':
               if( otherCollider.node.group != 'players'){break;}
                var lv = this.node.getComponent('aijs').lv ;//get lv text
                // if(!lv){break;}
                this.node.getChildByName('RichText').active = true;    
            break;
            case 'dialog':break;
            case 'player':
                if(otherCollider.node.group == 'weapon' && otherCollider.node.parent.group == 'enemies'){
                    var pai = otherCollider.node.parent.parent.parent.getComponent('aijs')?otherCollider.node.parent.parent.parent.getComponent('aijs'):otherCollider.node.parent.parent.parent.parent.getComponent('aijs');
                    this.hp -= pai.at;    
                }
            break;
            case 'enemy':
                //1.action back: elastic coefficient
                //2.hp mp lp changing
                if(otherCollider.node.group == 'weapon' && otherCollider.node.parent.group == 'players'){
                    var player = cc.find('Canvas').getChildByName('mapNode').getChildByName('player');
                    var pai = player.getComponent('aijs')?player.getComponent('aijs'):player.getChildByName('body').getComponent('aijs');
                    this.hp -= pai.at;                    
                }
            break;
            case 'story':break;
            case 'loader'://load 
                var lv = this.node.getComponent('aijs').lv ;//get lv text
                cc.loadScene(lv); 
                break;         

        }
    },

4. Overthrow and destroy

     goDieAndDistroy:function(e){
         if(!this.node){return;}
        var an = this.node.getComponent(cc.Animation);
        an.play('dead');
        // this.schedule(function () {
            this.node.parent.destroy();
        //   }, 0.2, 1,3);
     },

5 . Finally, simple AI is implemented in the UPDATE method

update (dt) {
        if(!this.node){return;}
        if(this.hp == 0){ 
            this.goDieAndDistroy();
            if(this.reacttype=='player'){
                var cvs = cc.find('Canvas');
                cvs.getChildByName('mapNode').acitve = false;
                cvs.getChildByName('UI').active = false;  //g over
                cvs.getChildByName('RichText').active =true ;//Can animate
              }
        }//Execute once

        else{
        //Judging by distance
        switch(this.reacttype){
            case 'guid':  break;
            case 'dialog':break;
            case 'player':break;
            case 'enemy':
                var player = this.node.parent.getChildByName('player');
                var tx = this.node.x - player.position.x;
                var pdis = this.node.position.sub(player.position);//If there is a direction, judging < > 0 cannot judge the vector
                // if(this.actdistance < pdis.mag() < this.feeldistance){                      
                //       if(this.node.x > player.x){ this.node.scaleX = -1 * Math.abs(this.node.scaleX );}
                //       else{this.node.scaleX =   Math.abs(this.node.scaleX )}//turnaround
                //       if(tx < 0) {this.node.x += this.movespeed;} 
                //       else if(tx > 0){this.node.x -= this.movespeed;} // 1D X-axis operation
                         this.playAnimation('walk');
                // }
                if(this.actdistance >= pdis.mag()){
                    //take actions
                      this.takeActions();
                }
                if(pdis.mag() > this.feeldistance){
                    cc.tween(this.node).to(2,{position:this.initpos}); //Original position
                };
                //obstacle

                break;
            case 'story':break;
        }
    }
    },

3, AI and maps

1. Barrier

It is implemented by physical engine, so there is no need to do special code processing, and the principle is not repeated. Remember to check the non penetration and trigger methods

2. Route

In aijs JS update writing logic:
Execute patrol route without interruption
Enter the distance and execute the catch-up route
Execute the route back to the original position after leaving

summary

Let's stop here first, and then elaborate on beautifying the script, packaging and publishing.

Topics: Game Development cocos cocos2d cocos-creator