2016年10月1日 星期六

MCPE插件教學Part 4.4 - 算法分享

這裡的算法從網路上各個插件中擷取出來,方便進行運算,僅供參考用。




  • 飛行 + 前進算法

玩家的頭若低下,則實體會停留在原地,否則則會隨著玩家的頭方向前進/飛行。
主要用於飛行物,若去掉Y則也可以用做自動前進。


var p=((Entity.getPitch(Player.getEntity())+90)*Math.PI)/180;
var y=((Entity.getYaw(Player.getEntity())+90)*Math.PI)/180;

var xx=Math.sin(p)*Math.cos(y);
var yy=Math.sin(p)*Math.sin(y); 
var zz=Math.cos(p);


Entity.setVelX(nowRiding,1*xx);//這裡1都可以改掉,跟前進速度成正比。nowRiding為實體對象
Entity.setVelY(nowRiding,1*zz); //若不想飛行也可以去掉Y
Entity.setVelZ(nowRiding,1*yy);



  • 跑步算法
以前沒有跑步時需要,現在則是能讓玩家跑得更快用。

參考來源: http://www.minecraftforum.net/forums/minecraft-pocket-edition/mcpe-mods-tools/1986186-sprint-mod
var xSave = 0 ,ySave = 0 ,zSave = 0

;//玩家舊的座標,y可以不設定,總不會跑到飛起來吧。

var x = 0, y = 0 , z = 0;//玩家現在的座標

var power=0.7;//需要變動的只有此值,與跑步速度成正比。

function modTick()


x = Player.getX();

y = Player.getY();

z = Player.getZ();//不斷偵測玩家座標

if (!(x-xSave==0))//當前座標減舊座標若>0,代表玩家移動

Entity.setVelX(Player.getEntity(),(x-xSave)*power);//將玩家往X方向推,移動值互減若>0,則玩家正向移動;反之則負向移動。Z座標同理。

xSave = x;//更新舊座標。


if (!(z-zSave==0))//同X

Entity.setVelZ(Player.getEntity(), (z-zSave)*power);//同X

zSave = z;//同X




  • 生成礦物的算法
  • 以下的註解皆翻譯自原始文章。
    資料來源:http://www.minecraftforum.net/forums/minecraft-pocket-edition/mcpe-mods-tools/2560455-how-to-generate-ores-random-with-modpe-nearly
    
    var tick=0;
    var curX=0;
    var curY=0;
    var curZ=0;
    var cX=0;
    var cY=0;
    var cZ=0;
    var count=0;
    var changeBack=false;
    
    /*
    可以改動的值:
    ●新增的礦物 (22行),你也可以加入更多
    ●生成礦物的高度(186行和188行)
    ● 礦脈有多廣(190行)
    ●setTile2這個函數 (164行), 你想要的話,也可以改成什麼方塊不要被取代。
    ●多複製180行到229行的程式碼幾次,來生成更多礦物
    ●更改生成礦物的可能性(181行)
    */
    
    try{
    Block.defineBlock(220, "Copper Ore", [["copper_ore", 0]], 1, false, 0); //新增方塊,這裡的例子是銅礦
    }catch(error){
    print("Import the texture pack first!");
    }
    
    function modTick(){
    tick++;
    if(tick%100==0){ //每5秒就執行一次doTick()
    doTick();
    }
    }
    
    function doTick(){
    if(Player.getDimension()==DimensionId.NORMAL){ //讓礦物只在主世界生成
    curX=Math.floor(Player.getX());
    curZ=Math.floor(Player.getZ());
    for(var i=0; i<16; i++){
    if(curX<0){
    changeBack=true;
    curX=curX*(-1);
    }
    if(curX%16!=0){
    curX--;
    }
    if(changeBack){
    curX=curX*(-1);
    }
    changeBack=false;
    if(curZ<0){
    changeBack=true;
    curZ=curZ*(-1);
    }
    if(curZ%16!=0){
    curZ--;
    }
    if(changeBack){
    curZ=curZ*(-1);
    }
    changeBack=false;
    }
    curX++;
    curZ++;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curZ=curZ+16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curZ=curZ+16;
    spawnOres();
    curZ=curZ+16;
    spawnOres();
    curZ=curZ+16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curZ=curZ+16;
    spawnOres();
    curZ=curZ+16;
    spawnOres();
    curZ=curZ+16;
    spawnOres();
    curZ=curZ+16;
    spawnOres();
    curZ=curZ+16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curX=curX-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curZ=curZ-16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    curX=curX+16;
    spawnOres();
    }
    }
    
    setTile2(p1, p2, p3, p4, p5){ //這裡為生成礦物添加更多可能生成的區塊,這裡僅取代石頭
    if(Level.getTile(p1, p2, p3)==1){ //如果那個座標是石頭,就取代它
    Level.setTile(p1, p2, p3, p4, p5);
    }
    }
    
    function spawnOres(){ //生成礦物
    if(Level.getTile(curX, 1, curZ)!=57){
    Level.setTile(curX, 1, curZ, 57, 0);
    Level.setTile(curX, 0, curZ, 7, 0);
    Level.setTile(curX, 2, curZ, 7, 0);
    Level.setTile(curX+1, 1, curZ, 7, 0);
    Level.setTile(curX-1, 1, curZ, 7, 0);
    Level.setTile(curX, 1, curZ+1, 7, 0);
    Level.setTile(curX, 1, curZ-1, 7, 0);
    //開始生成礦物
    //從183行開始複製到229行,如果你想要更多礦物,可以多重複這步驟幾次
    if(Math.floor(Math.random()*20)>7){ //計算機率,有到才開始執行以下生成礦物的程式碼
    cX=curX;
    cZ=curZ;
    cX=cX+Math.floor(Math.random()*10)+2; //隨機的X座標
    cZ=cZ+Math.floor(Math.random()*10)+2; //隨機的Z座標
    cY=Math.floor(Math.random()*30)+10; //隨機的高度 (此範例是10到40) , 你可以自己設定,通常大於5比較好,免得破壞基岩
    if(Level.getBiomeName(curX, curZ)=="Ocean"){ //如果要在海裡生成礦物
    cY=Math.floor(Math.random()*25)+5; //隨機高度(此範例為5到30)
    }
    count=Math.floor(Math.random()*12)+3; //要生成多少個礦物(此範例為3到15)
    setTile2(cX, cY, cZ, 220, 0); //220就是我們剛剛新增的礦物ID
    for(var i=0; i<count; i++){
    if(Math.floor(Math.random()*3)+1==2){
    cX++;
    }else{
    if(Math.floor(Math.random()*3)+1==2){
    //什麼也不做
    }else{
    cX--;
    }
    }
    if(Math.floor(Math.random()*3)+1==2){
    cZ++;
    }else{
    if(Math.floor(Math.random()*3)+1==2){
    //什麼也不做
    }else{
    cZ--;
    }
    }
    if(Math.floor(Math.random()*3)+1==2){
    cY++;
    if(cY>50){
    cY--;
    }
    }else{
    if(Math.floor(Math.random()*3)+1==2){
    //什麼也不做
    }else{
    cY--;
    if(cY<5){
    cY++;
    }
    }
    }
    setTile2(cX, cY, cZ, 220, 0); //220就是我們剛剛新增的礦物ID
    }
    }
    //銅礦生成的程式碼結束
    //礦物生成的程式碼結束
    }
    //
    }