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.