首页 > Sktech > 习作CF_给场景地图内容添加台词和信息
2017
12-20

习作CF_给场景地图内容添加台词和信息

习作CF_给场景地图内容添加台词和信息 - 第1张  | Processing编程艺术


地图上的某些角色或物品现在可以调查.
调查后会发生对话或显示信息.


文字内容保存的思路:
– 物品的判定保持原碰撞判定不变, 在判定附近添加热点, 主角进入后可以读取热点标识号.
– 给主角类添加保存物信息文字的容器, 用标识号查找物品的信息.
– 物品信息内容统一只有一段.
– 给NPC类添加保存对话文字的容器, 文字段数任意.
– NPC每次被对话后对话内容往下进展, 到底后重新循环.
– NPC有多个, 所以对话内容要在外部添加.

显示框的思路:
– 接受外部字符串和坐标信息, 在接收到的坐标处显示接收到的字符串.
– 显示框的大小随字符串内容自动调整.
– 显示框悬浮显示, 一段时间后自动消失.


– 问题:显示框显示方式较生硬, 切换地图后仍会显示, 且会随镜头移动漂移.
– 问题:东西乱加弄得太杂太长自己也不想看下去了…


– 修改:重写了上一例NPC的乱走逻辑, 使走动动作和自动面朝主角动作更流畅一点.


[W|S|A|D]:移动角色
[E]:调查
[Q]:退出程序


在2.0内制作, 用3.0以上运行可能会报错:


//- --- --- ---
//- public
//- --- --- ---
//-
EcMap pbTheCurrentMap=null;
EcProtagon pbTheKid=new EcProtagon();
//--
EcMap pbThisMapAA=new EcMap(800,400,311,pbTheKid);
EcMap pbThisMapAB=new EcMap(400,200,312,pbTheKid);
EcMap pbThisMapAC=new EcMap(400,1450,313,pbTheKid);
//--
EcTrangleObstacle pbThatDoorAAL=new EcTrangleObstacle(730, 350, 20, 20,'b');
EcTrangleObstacle pbThatDoorAAR=new EcTrangleObstacle(750, 350, 20, 20,'d');
EcTrangleObstacle pbThatDoorABL=new EcTrangleObstacle(30,150, 20, 20,'c');
EcTrangleObstacle pbThatDoorABR=new EcTrangleObstacle(50, 150, 20, 20,'a');
EcRectangleObstacle pbThatDoorBA=new EcRectangleObstacle(150, 100, 30, 10);
EcRectangleObstacle pbThatDoorBB=new EcRectangleObstacle(350-15, 1440, 30, 10);
EcRoundObstacle pbThatDoorCA= new EcRoundObstacle(350, 50, 25);
//--
EcRectangleObstacle pbThatSpotAA = new EcRectangleObstacle(210, 80+60, 50, 168-140);
EcRoundObstacle pbThatSpotAB = new EcRoundObstacle(0, 400,50);
EcRoundObstacle pbThatSpotAC = new EcRoundObstacle(400, 350,50);
//--
EcSomeKid pbThatKidAA = new EcSomeKid(300, 150, 40, 40, "porky",32);
EcSomeKid pbThatKidAB = new EcSomeKid(150, 150, 40, 40, "peaky",32);
EcOldMan pbThatManAC = new EcOldMan(350, 100, 40, 40, "leo",50);
//--
HcPopup pbThePopup = new HcPopup();
//--

void setup() {size(320, 240);noStroke();frameRate(32);textAlign(LEFT, TOP);ellipseMode(CENTER);
  frame.setTitle("CharaMap");
  //--
  fsPresetting();
  //-- 
  fsLoadMap(pbThisMapAA,-300,-200,650,357);
  pbTheKid.ccMoveCharactor(1f, 0);
  //--
}//+++

void draw(){background(0);
  //--
  if(pbTheCurrentMap!=null){
    pbTheCurrentMap.ccUpdate();
    spDrawMap(pbTheCurrentMap);
  }
  pbTheKid.ccUpdate();
  //--
  pbThePopup.ccUpdate();
}//+++

void keyPressed() {
  int lpSpotFlag=0;
  switch(key){
    case 'e':
      pbThePopup.ccPopup(pbTheKid.ccTellLine());
      break;
    //--
    case 'w':lpSpotFlag=pbTheKid.ccMoveCharactor(0, -1f);pbTheKid.cmHeading=2*PI;break;
    case 's':lpSpotFlag=pbTheKid.ccMoveCharactor(0, 1f);pbTheKid.cmHeading=PI;break;
    case 'a':lpSpotFlag=pbTheKid.ccMoveCharactor(-1f, 0);pbTheKid.cmHeading=PI*3/2;break;
    case 'd':lpSpotFlag=pbTheKid.ccMoveCharactor(1f, 0);pbTheKid.cmHeading=PI/2;break;
    //--
    case 'q':fsPover();
    default:break;
  }
  //--
  switch(lpSpotFlag){
    case 11:
      fsLoadMap(pbThisMapAB, 0, 0, 75, 160);pbTheKid.ccMoveCharactor(1f, 0);
      break;
    case 12:
      fsLoadMap(pbThisMapAA, 0, 0, 720, 360);pbTheKid.ccMoveCharactor(-1f, 0);
      break;
    case 21:
      fsLoadMap(pbThisMapAC, 200, 1500, 350, 1420);pbTheKid.ccMoveCharactor(0, -1f);
      break;
    case 22:
      fsLoadMap(pbThisMapAB, 0, 0, 165, 115);pbTheKid.ccMoveCharactor(0, 1f);
      break;
    case 31:
      fsLoadMap(pbThisMapAB, 0, 0, 380, 190);pbTheKid.ccMoveCharactor(0, 1f);
      break;
    default:break;
  }
  //--
}//+++

//< <<< <<< <<< <<< <<< Overrided


//* *** *** *** *** ***
//*
//* Operate
//*
//* *** *** *** *** ***
//- --- --- ---

void fsPover(){
  exit();
}//+++

//< <<< <<< <<< <<< <<< operate


//* *** *** *** *** ***
//*
//* Support
//*
//* *** *** *** *** ***
//- --- --- ---

void fsPresetting(){
  //-- ** presetting
  //-- ** ** door
  pbThatDoorAAL.cmOffColor=color(0xEE,0x55,0x55);pbThatDoorAAL.cmID=11;
  pbThatDoorAAR.cmOffColor=color(0xEE,0x55,0x55);pbThatDoorAAR.cmID=11;
  pbThatDoorABL.cmOffColor=color(0xEE,0x55,0x55);pbThatDoorABL.cmID=12;
  pbThatDoorABR.cmOffColor=color(0xEE,0x55,0x55);pbThatDoorABR.cmID=12;
  pbThatDoorBA.cmOffColor=color(0xEE,0x55,0x55);pbThatDoorBA.cmID=21;
  pbThatDoorBB.cmOffColor=color(0xEE,0x55,0x55);pbThatDoorBB.cmID=22;
  pbThatDoorCA.cmOffColor=color(0xEE,0x55,0x55,0x00);pbThatDoorCA.cmID=31;
  //-- ** ** spot
  pbThatSpotAA.cmOffColor=color(0xEE,0x55,0x55,0x00);pbThatSpotAA.cmID=4001;
  pbThatSpotAB.cmOffColor=color(0xEE,0x55,0x55,0x00);pbThatSpotAB.cmID=4002;
  pbThatSpotAC.cmOffColor=color(0xEE,0x55,0x55,0x00);pbThatSpotAC.cmID=4003;
  //-- ** ** NPC
  pbThatKidAA.ccAddLine("hey! how did you\n got me?? ");
  pbThatKidAA.ccAddLine(" ... ");
  pbThatKidAA.ccAddLine(" i knew it. \n so i did it.");
  pbThatKidAA.ccAddLine(" yes, i did it to my self.\n  and...");
  pbThatKidAA.ccAddLine(" youll never find your way back! ");
  pbThatKidAA.ccAddLine(" but...");
  pbThatKidAB.ccAddLine("my brother is got stuck");
  pbThatKidAB.ccAddLine("can you get him\n out of there?");
  pbThatKidAB.ccAddLine("i mean...");
  pbThatManAC.ccAddLine("what? ");
  pbThatManAC.ccAddLine("so what? ");
  pbThatManAC.ccAddLine("what do you want?");
  pbThatManAC.ccAddLine("Rock and Roll...? ");
  pbThatManAC.ccAddLine(" no, no, no\n  youve go the\n wrong guy.");
  pbThatManAC.ccAddLine(" ... ");
  pbThatManAC.ccAddLine(" ... ");
  pbThatManAC.ccAddLine(" ... ");
  pbThatManAC.ccAddLine("you aint got nothing\n to do, huh? ");
  pbThatManAC.ccAddLine("go home , kid. ");
  pbThatManAC.ccAddLine(" ... ");
  pbThatManAC.ccAddLine(" ... ");
  pbThatManAC.ccAddLine(" ... ");
  pbThatManAC.ccAddLine("fine, fine, fine.");
  pbThatManAC.ccAddLine("ll tell you what\n the kid who got the\n rockn roll \n is gone.");
  pbThatManAC.ccAddLine("you wont find him\n unless you find THE warp machine.");
  pbThatManAC.ccAddLine("thats all i know.");
  pbThatManAC.ccAddLine(" ... ");
  pbThatManAC.ccAddLine(" ...so ");
  //--
  //--
  //-- ** buildup
  pbThisMapAA.ccAddObstacle(new EcRectangleObstacle(0, 0, 800, 300));
  pbThisMapAA.ccAddObstacle(new EcTrangleObstacle(0, 280, 120, 120,'a'));
  pbThisMapAA.ccAddObstacle(new EcTrangleObstacle(680, 280, 120, 120,'b'));
  pbThisMapAA.ccAddObstacle(new EcRectangleObstacle(150, 295, 60, 27));
  pbThisMapAA.ccAddObstacle(new EcRectangleObstacle(450, 295, 60, 27));
  pbThisMapAA.ccAddObstacle(new EcRoundObstacle(350, 350, 50));
  pbThisMapAA.ccAddHotspot(pbThatDoorAAL);
  pbThisMapAA.ccAddHotspot(pbThatDoorAAR);
  pbThisMapAA.ccAddHotspot(pbThatSpotAB);//...room corner
  pbThisMapAA.ccAddHotspot(pbThatSpotAC);//...table
  //--
  pbThisMapAB.ccAddObstacle(new EcRectangleObstacle(0, 0, 400, 100));
  pbThisMapAB.ccAddObstacle(new EcTrangleObstacle(0, 100, 100, 100,'a'));
  pbThisMapAB.ccAddObstacle(new EcTrangleObstacle(300-2, 100-2, 100+2, 100+2,'b'));
  pbThisMapAB.ccAddObstacle(new EcRectangleObstacle(210, 80, 47, 60));
  pbThisMapAB.ccAddObstacle(new EcRectangleObstacle(230, 120, 43, 60));
  pbThisMapAB.ccAddObstacle(new EcRectangleObstacle(198, 168, 50, 35));
  pbThisMapAB.ccAddHotspot(pbThatDoorABL);
  pbThisMapAB.ccAddHotspot(pbThatDoorABR);
  pbThisMapAB.ccAddHotspot(pbThatDoorBA);
  pbThisMapAB.ccAddHotspot(pbThatSpotAA);//...a sick box
  pbThisMapAB.ccAddNPC(pbThatKidAA);
  pbThisMapAB.ccAddNPC(pbThatKidAB);
  //--
  pbThisMapAC.ccAddObstacle(new EcRectangleObstacle(0, 0, 300, 450));
  pbThisMapAC.ccAddObstacle(new EcRectangleObstacle(0, 450, 200, 600));
  pbThisMapAC.ccAddObstacle(new EcRectangleObstacle(0, 450+600, 300, 400));
  pbThisMapAC.ccAddObstacle(new EcRectangleObstacle(400, 0, 200, 1450));
  pbThisMapAC.ccAddObstacle(new EcRectangleObstacle(300,550, 100, 400));
  pbThisMapAC.ccAddObstacle(new EcRectangleObstacle(300,0, 100, 50));
  pbThisMapAC.ccAddHotspot(pbThatDoorBB);
  pbThisMapAC.ccAddHotspot(pbThatDoorCA);
  pbThisMapAC.ccAddNPC(pbThatManAC);
  //--
}//+++

void fsLoadMap(EcMap pxMap,int pxMapCameraX,int pxMapCameraY, int pxCharaStartX, int pxCharaStartY){
  pbTheCurrentMap=pxMap;
  pbTheKid.ccInit(pxMap,pxCharaStartX,pxCharaStartY);
  pxMap.ccRepos(-pxMapCameraX, -pxMapCameraY);
}//+++

//< <<< <<< <<< <<< <<< Support


//* *** *** *** *** ***
//*
//* drawMap
//*
//* *** *** *** *** ***
  
//- --- --- ---
//- gate
//- --- --- ---
void spDrawMap(EcMap pxMap){
  switch(pxMap.cmID){
    case 311:spDrawMapAA(pxMap.cmPos.x,pxMap.cmPos.y);break;
    case 312:spDrawMapAB(pxMap.cmPos.x,pxMap.cmPos.y);break;
    case 313:spDrawMapAC(pxMap.cmPos.x,pxMap.cmPos.y);break;
    default:break;
  }
}//+++
  
//- --- --- ---
//- indie
//- --- --- ---

void spDrawMapAA(float pxX, float pxY){
  stroke(0xFF);noFill();{
    rect(pxX+150, pxY+295, 60, 27); //...chair
    rect(pxX+450, pxY+295, 60, 27);//...another chair
    ellipse(pxX+350, pxY+350, 50, 50);//...table
    quad(pxX+0, pxY+0, pxX+100, pxY+0,//...wall a
         pxX+100, pxY+300,pxX+0, pxY+400);
    quad(pxX+700, pxY+0, pxX+800, pxY+0,//...wall b
         pxX+800, pxY+400,  pxX+700, pxY+300 );
    quad(pxX+750, pxY+300, pxX+770, pxY+315,//...door
         pxX+770, pxY+370,  pxX+750, pxY+350 );
  }noStroke();
  fill(0xFF);
  text("chair",pxX+455,pxY+305);
  text("another\n chair",pxX+155,pxY+292);
  text("table",pxX+340,pxY+340);
  text("wall...should there be a window??",pxX+400,pxY+260);
  text("wall",pxX+50,pxY+300);
  text("wall...\n with a door",pxX+720,pxY+255);
}//+++

void spDrawMapAB(float pxX, float pxY){
  stroke(0xFF);noFill();{
    quad(pxX+0,pxY+0,pxX+100,pxY+0,//...wall a
         pxX+100,pxY+100,pxX+0,pxY+200);
    quad(pxX+300,pxY+0,pxX+400,pxY+0,//...wall b
         pxX+400,pxY+200,pxX+300,pxY+100);
    rect(pxX+210,pxY+80,47,60); //...box a
    rect(pxX+230,pxY+120,43,60); //...box b
    rect(pxX+198,pxY+168,50,35); //...box c
    rect(pxX+150,pxY+100,30,-50); //...door to room c
    quad(pxX+30,pxY+115,pxX+50,pxY+100,//...door to room a
         pxX+50,pxY+150,pxX+30,pxY+170);
  }noStroke();
  fill(0xFF);
  text("still...\n  a wall\n \n [back!!]",pxX+20,pxY+45);
  text("its a longway\n to the top \n if you wanna rock n roll!!",pxX+120,pxY+5);
  text("some\n box",pxX+215,pxY+85);
  text("box..",pxX+235,pxY+140);
  text("Dont\n ask!!",pxX+200,pxY+170);
  text("the\n wall\n youll\n never\n reach",pxX+305,pxY+35);
}//+++

void spDrawMapAC(float pxX, float pxY){
  stroke(0xFF);noFill();{
    //-- ** ...actually there is nothing in room c
  }noStroke();
  fill(0xFF);
  text("rock n...roll?",pxX+315,pxY+15);
}//+++
  

//< <<< <<< <<< <<< <<< drawMap


//* *** *** *** *** ***
//*
//* Class
//*
//* *** *** *** *** ***

//- --- --- ---
//- charactor and map
//- --- --- ---
  
class EcMap{
  //--
  EcProtagon cmProtagon;
  //--
  PVector cmPos, cmDia;
  ArrayList<EcObstacle> cmObsatcleList;
  ArrayList<EcObstacle> cmHotspotList;
  ArrayList<EcNPCharactor> cmNPCList;
  float cmCameraRange;
  //--
  int cmID;
  //--
  EcMap(int pxW,int pxH, int pxID, EcProtagon pxProtagon){
    cmPos=new PVector(0,0);
    cmDia=new PVector(pxW, pxH);
    cmObsatcleList=new ArrayList<EcObstacle>();
    cmHotspotList=new ArrayList<EcObstacle>();
    cmNPCList=new ArrayList<EcNPCharactor>();
    cmCameraRange=100;
    cmID=pxID;
    cmProtagon=pxProtagon;
  }
  //--
  void ccRepos(int pxX, int pxY){
    cmPos.x=(float)pxX;
    cmPos.y=(float)pxY;
  }
  //--
  void ccAddObstacle(EcObstacle pxObstacle){cmObsatcleList.add(pxObstacle);}
  void ccAddHotspot(EcObstacle pxSpot){cmHotspotList.add(pxSpot);}
  void ccAddNPC(EcNPCharactor pxCharactor){
    cmObsatcleList.add(pxCharactor);
    cmNPCList.add(pxCharactor);
  }
  //--
  void ccUpdate(){
    fill(0xEE,0xAA,0x33);rect(cmPos.x,cmPos.y,cmDia.x,cmDia.y);
    if(!cmObsatcleList.isEmpty()){for(EcObstacle itObstacle:cmObsatcleList){
      itObstacle.ccRepos((int)cmPos.x, (int)cmPos.y);
      itObstacle.ccUpdate();
    }}
    if(!cmHotspotList.isEmpty()){for(EcObstacle itObstacle:cmHotspotList){
      itObstacle.ccRepos((int)cmPos.x, (int)cmPos.y);
      itObstacle.ccUpdate();
    }}
    if(!cmNPCList.isEmpty()){for(EcNPCharactor itCharactor:cmNPCList){
      itCharactor.ccWander(cmProtagon.cmRelatePos);
    }}
  }
  //--
  void ccMoveCamera(float pxX, float pxY){
    float lpRangeX=cmCameraRange;
    float lpRangeY=cmCameraRange;
    float lpRangeW=width-(cmCameraRange*2);
    float lpRangeH=height-(cmCameraRange*2);
    if(pxX<=lpRangeX){cmPos.x+=(lpRangeX-pxX);}
    if(pxX>=(lpRangeX+lpRangeW)){cmPos.x-=(pxX-lpRangeX-lpRangeW);}
    if(pxY<=lpRangeY){cmPos.y+=(lpRangeY-pxY);}
    if(pxY>=(lpRangeY+lpRangeH)){cmPos.y-=(pxY-lpRangeY-lpRangeH);}
  }
  //--
  boolean ccIsInMovableRange(float pxX, float pxY){
    if(
        (pxX>cmPos.x)&&(pxX<cmPos.x+cmDia.x)&&(pxY>cmPos.y)&&(pxY<cmPos.y+cmDia.y)
      ){
        if(!cmObsatcleList.isEmpty()){for(EcObstacle itObstacle:cmObsatcleList){
          boolean lpRes=itObstacle.ccIsContaining((int)pxX, (int)pxY);
          if(lpRes){return false;}
        }}
        return true;
      }
    return false;
  }
  //--
  int ccTellEnvID(float pxX, float pxY){
    if(!cmHotspotList.isEmpty()){for(EcObstacle itObstacle:cmHotspotList){
      if(itObstacle.ccIsContaining((int)pxX, (int)pxY)){
        return itObstacle.cmID;
      }
    }}
    return 0;
  }
  //--
}//+++

class EcProtagon{
  EcMap cmMap;
  PVector cmRelatePos;
  //--
  float cmSpeed;
  float cmHeading;
  int cmFoot;
  float cmScale;
  //--
  StringDict cmBaseLine;
  //--
  int cmEnvID;
  //--
  EcProtagon(){
    cmMap=null;
    cmRelatePos=new PVector(0, 0);
    cmSpeed=3.3f;
    cmHeading=PI/2;cmScale=3;
    cmFoot=0;cmEnvID=0;
    cmBaseLine=new StringDict();
    cmBaseLine.set("0000", "just\n nothing.");
    cmBaseLine.set("4001", "i cant move any of em...");
    cmBaseLine.set("4002", "...looks like there\n is no other door.");
    cmBaseLine.set("4003", "a strange darkness \n is around this table.");
  }
  //--
  void ccInit(EcMap pxMap, int pxX, int pxY){
    cmMap=pxMap;
    cmRelatePos.x=(float)pxX;
    cmRelatePos.y=(float)pxY;
  }
  //--
  int ccTellAbsoX(){return (int)(cmRelatePos.x+cmMap.cmPos.x);}
  int ccTellAbsoY(){return (int)(cmRelatePos.y+cmMap.cmPos.y);}
  //--
  void ccUpdate(){
    if(cmMap==null){return;}
    int lpAbsoX=ccTellAbsoX();
    int lpAbsoY=ccTellAbsoY();
    //--
    fill(0xFF);stroke(0);pushMatrix();{
      translate(lpAbsoX, lpAbsoY);
      rotate(cmHeading);
      quad(-2*cmScale,-3*cmScale, 2*cmScale,-3*cmScale,
            4*cmScale, 3*cmScale,-4*cmScale, 3*cmScale);
      fill(cmFoot<3?0x33:0xCC);rect(cmScale,cmScale,cmScale,cmScale);
      fill(cmFoot<3?0xCC:0x33);rect(-2*cmScale,cmScale,cmScale,cmScale);
      //fill(0xff);text(nf(cmEnvID,2),3,3);//<<[DTFM]
    }popMatrix();noStroke();
    //--
  }
  //--
  int ccMoveCharactor(float pxX, float pxY){
    float lpNewPosX=cmRelatePos.x+pxX*cmSpeed;
    float lpNewPosY=cmRelatePos.y+pxY*cmSpeed;
    if(cmMap.ccIsInMovableRange(lpNewPosX+cmMap.cmPos.x,lpNewPosY+cmMap.cmPos.y)){
      cmFoot++;cmFoot&=0x07;
      cmRelatePos.x=lpNewPosX;
      cmRelatePos.y=lpNewPosY;
      cmMap.ccMoveCamera(lpNewPosX+cmMap.cmPos.x, lpNewPosY+cmMap.cmPos.y);
      cmEnvID=cmMap.ccTellEnvID(lpNewPosX+cmMap.cmPos.x, lpNewPosY+cmMap.cmPos.y);
      return cmEnvID;
    }
    return 0;
  }
  //--
  int ccTellEnvId(){return cmEnvID;}
  //--
  HcPopline ccTellEnvLine(){
    String lpKey=nf(cmEnvID,4);
    if(cmBaseLine.hasKey(lpKey)){
      HcPopline lpRes=new HcPopline();
      lpRes.ccSetup(cmBaseLine.get(lpKey), ccTellAbsoX(), ccTellAbsoY(), 0x11);
      return lpRes;
    }
    return null;
  }
  HcPopline ccTellNpcLine(){
    HcPopline lpRes=new HcPopline();
    for(EcNPCharactor itNPC:cmMap.cmNPCList){
      if(itNPC.ccTellDistanceBy(cmRelatePos)<40){
        itNPC.ccHeadTo(cmRelatePos);
        lpRes.ccSetup(itNPC.ccGetTalked(), itNPC.cmAbsoX, itNPC.cmAbsoY, 0xEE);
        return lpRes;
      }
    }
    return null;
  }
  //--
  HcPopline ccTellLine(){
    HcPopline lpRes=ccTellNpcLine();
    if(lpRes!=null){return lpRes;}
    lpRes=ccTellEnvLine();
    if(lpRes!=null){return lpRes;}
    lpRes=new HcPopline();
    lpRes.ccSetup("...?", ccTellAbsoX(), ccTellAbsoY(), 0x33);
    return lpRes;
  }
  //--
}//+++
  
//- --- --- ---
//- Obsatcle
//- --- --- ---

abstract class EcObstacle{
  int cmFollowX,cmFollowY;
  int cmAbsoX,cmAbsoY;
  int cmX,cmY,cmW,cmH;
  int cmOffColor,cmOnColor;
  boolean cmAct;
  //--
  int cmID;
  //--
  EcObstacle(){
    cmX=cmY=cmW=cmH=9;
    cmOffColor=color(0x55,0x55,0x55);
    cmOnColor=color(0xEE,0xEE,0x33);
    cmAct=false;
    cmFollowX=0;cmFollowY=0;
    cmAbsoX=cmFollowX+cmX;cmFollowY=cmFollowY+cmY;
    cmID=255;
  }
  //--
  void ccRepos(int pxX, int pxY){
    cmFollowX=pxX;
    cmFollowY=pxY;
  }
  void ccRefreshPos(){
    cmAbsoX=cmFollowX+cmX;
    cmAbsoY=cmFollowY+cmY;
  }
  //--
  abstract void ccUpdate();
  abstract boolean ccIsContaining(int pxX, int pxY);
}//+++

class EcRectangleObstacle extends EcObstacle{
  //--
  EcRectangleObstacle(int pxX, int pxY, int pxW, int pxH) {
    super();
    cmX=pxX;cmY=pxY;
    cmW=pxW;cmH=pxH;
  }
  //--
  @Override void ccUpdate(){
    ccRefreshPos();
    fill(cmAct?cmOnColor:cmOffColor);
    rect(cmAbsoX,cmAbsoY,cmW,cmH);
  }
  //--
  @Override boolean ccIsContaining(int pxX, int pxY){
    return (pxX>cmAbsoX)&&(pxX<cmAbsoX+cmW)&&(pxY>cmAbsoY)&&(pxY<cmAbsoY+cmH);
  }
  //--
  }//+++

class EcRoundObstacle extends EcObstacle{
  //--
  int cmR;
  //--
  EcRoundObstacle(int pxX, int pxY, int pxD){
    super();
    cmX=pxX;cmY=pxY;
    cmW=cmH=pxD;
    cmR=pxD/2;
  }
  //--
  @Override void ccUpdate(){
    ccRefreshPos();
    fill(cmAct?cmOnColor:cmOffColor);
    ellipse(cmAbsoX,cmAbsoY,cmW,cmH);
  }
  //--
  @Override boolean ccIsContaining(int pxX, int pxY){
    if(!((pxX>cmAbsoX-cmR)&&(pxX<cmAbsoX+cmR)&&(pxY>cmAbsoY-cmR)&&(pxY<cmAbsoY+cmR))){return false;}else{
      PVector lpCenter=new PVector(cmAbsoX,cmAbsoY);
      PVector lpTarget=new PVector(pxX,pxY);
      return ceil(PVector.dist(lpTarget,lpCenter))<cmR;
    }
  }
}//+++

class EcTrangleObstacle extends EcObstacle{
  //--
  char cmMode;
  /** *
   * @param pxMode_ab [a]north west point..[b]north east point..
   * [c]south east point..[d]south west point
   */
  EcTrangleObstacle(int pxX, int pxY, int pxW, int pxH, char pxMode_abcd){
    super();
    cmX=pxX;cmY=pxY;
    cmW=pxW;cmH=pxH;
    cmMode=pxMode_abcd;
  }
  //--
  @Override void ccUpdate(){
    ccRefreshPos();
    fill(cmAct?cmOnColor:cmOffColor);
    switch(cmMode){
      case 'a':triangle(cmAbsoX, cmAbsoY, cmAbsoX+cmW, cmAbsoY, cmAbsoX, cmAbsoY+cmH);break;
      case 'b':triangle(cmAbsoX, cmAbsoY, cmAbsoX+cmW, cmAbsoY, cmAbsoX+cmW, cmAbsoY+cmH);break;
      case 'c':triangle(cmAbsoX+cmW, cmAbsoY, cmAbsoX+cmW, cmAbsoY+cmH, cmAbsoX, cmAbsoY+cmH);break;
      case 'd':triangle(cmAbsoX, cmAbsoY, cmAbsoX+cmW, cmAbsoY+cmH, cmAbsoX, cmAbsoY+cmH);break;
      default:break;
    }
  }
  //--
  @Override boolean ccIsContaining(int pxX, int pxY){
    if(!((pxX>cmAbsoX)&&(pxX<cmAbsoX+cmW)&&(pxY>cmAbsoY)&&(pxY<cmAbsoY+cmH))){return false;}else{
      int lpDPointL=(pxX-cmAbsoX)*cmH/cmW+cmAbsoY;
      int lpDPointR=(cmAbsoX+cmW-pxX)*cmH/cmW+cmAbsoY;
      switch(cmMode){
        case 'a':return pxY<lpDPointR;
        case 'b':return pxY<lpDPointL;
        case 'c':return pxY>lpDPointR;
        case 'd':return pxY>lpDPointL;
        default:return false;
      }
    }
  }
  //--
}//+++

class EcNPCharactor extends EcRoundObstacle{
  String cmName;
  int cmClock,cmDirect;
  float cmScale;
  boolean cmDirectUD;
  //--
  int cmRangeX, cmRangeY;
  int cmRangeW, cmRangeH;
  //--
  int cmFoot,cmSpeed;
  float cmHeading;
  //--
  StringList cmLineList;
  int cmLineCounter;
  int cmDoMove;
  //--
  EcNPCharactor(int pxX, int pxY,int pxRangeW, int pxRangeH, String pxName, int pxScale) {
    super(pxX, pxY,pxScale);
    cmName=pxName;
    cmClock=ceil(random(1,62));
    cmSpeed=1;cmFoot=3;
    cmHeading=PI/2;
    cmRangeW=pxRangeW;
    cmRangeH=pxRangeH;
    cmRangeX=cmX-cmRangeW/2;
    cmRangeY=cmY-cmRangeH/2;
    cmScale=cmR/8;
    cmLineList= new StringList();
    cmLineCounter=0;cmDoMove=0;
    cmDirect=0;//[0]nop[1]up[2]right[3]down[4]left
  }
  //--
  void ccAddLine(String pxLine){cmLineList.append(pxLine);}
  //--
  String ccGetTalked(){
    int lpSize=cmLineList.size();
    if(lpSize==0){return null;}
    String lpRes=cmLineList.get(cmLineCounter);
    cmLineCounter++;if(cmLineCounter>=lpSize){cmLineCounter=0;}
    return lpRes;
  }
  //--
  float ccTellDistanceBy(PVector pxPos){
    if(pxPos!=null){
      PVector lpPos=new PVector(cmX,cmY);
      return PVector.dist(pxPos,lpPos);
    }
    return 0;
  }
  //--
  void ccHeadTo(PVector pxPos){
    PVector lpPos=new PVector(cmX,cmY);
    cmHeading=PVector.sub(pxPos,lpPos).heading()+PI/2;
  }
  //--
  void ccWander(PVector pxProtagonPos){
    cmClock++;cmClock&=0x1F;
    cmDoMove--;
    PVector lpPos=new PVector(cmX,cmY);
    if(PVector.dist(pxProtagonPos,lpPos)<((float)cmR*1.3f)){
      cmHeading=PVector.sub(pxProtagonPos,lpPos).heading()+PI/2;
      return;
    }
    if(cmDoMove>0){
      switch(cmDirect){
        case 1: cmY-=cmSpeed;cmHeading=2*PI;break;
        case 2: cmX+=cmSpeed;cmHeading=PI/2;break;
        case 3: cmY+=cmSpeed;cmHeading=PI;break;
        case 4: cmX-=cmSpeed;cmHeading=PI*3/2;break;
        default:break;
      }
      cmFoot++;cmFoot&=0x07;
      cmX=constrain(cmX, cmRangeX, cmRangeX+cmRangeW);
      cmY=constrain(cmY, cmRangeY, cmRangeY+cmRangeH);
    }else{
      if(cmClock==17||cmClock==30){
        if(random(1)<0.51){
          float lpRandom=random(1);
          if(lpRandom>0.01f && lpRandom<0.25f){cmDirect=1;}
          if(lpRandom>0.25f && lpRandom<0.50f){cmDirect=2;}
          if(lpRandom>0.50f && lpRandom<0.75f){cmDirect=3;}
          if(lpRandom>0.75f && lpRandom<0.99f){cmDirect=4;}
          cmDoMove=8;
        }
      }
    }
  }
  //--
}//+++

class EcSomeKid extends EcNPCharactor{
  //--
  //--
  EcSomeKid(int pxX, int pxY,int pxRangeX, int pxRangeY, String pxName, int pxScale) {
    super(pxX, pxY,pxRangeX,pxRangeY,pxName, pxScale);
  }
  //--
  @Override void ccUpdate(){
    ccRefreshPos();
    //--
    fill(0xCC);stroke(0);pushMatrix();{
      translate(cmAbsoX, cmAbsoY);
      rotate(cmHeading);
      quad(-2*cmScale,-3*cmScale, 2*cmScale,-3*cmScale,
            4*cmScale, 3*cmScale,-4*cmScale, 3*cmScale);
      fill(cmFoot<3?0x33:0xCC);rect(cmScale,cmScale,cmScale,cmScale);
      fill(cmFoot<3?0xCC:0x33);rect(-2*cmScale,cmScale,cmScale,cmScale);
    }popMatrix();noStroke();
  }
  //--
}//+++

class EcOldMan extends EcNPCharactor{
  //--
  EcOldMan(int pxX, int pxY,int pxRangeX, int pxRangeY, String pxName, int pxScale) {
    super(pxX, pxY,pxRangeX,pxRangeY,pxName, pxScale);
  }
  //--
  @Override void ccUpdate(){
    ccRefreshPos();
    //--
    fill(0x77);stroke(0);pushMatrix();{
      translate(cmAbsoX, cmAbsoY);
      rotate(cmHeading);
      quad(-2*cmScale,-3*cmScale, 2*cmScale,-3*cmScale,
            4*cmScale, 3*cmScale,-4*cmScale, 3*cmScale);
      fill(cmFoot<3?0x33:0xCC);rect(cmScale,cmScale,cmScale,cmScale);
      fill(cmFoot<3?0xCC:0x33);rect(-2*cmScale,cmScale,cmScale,cmScale);
    }popMatrix();noStroke();
  }
  //--
}//+++


//- --- --- ---
//- Holder
//- --- --- ---

class HcPopup{
  int cmX,cmY,cmW,cmH;
  int cmTime;
  String cmLastLine;
  int cmTheme;
  HcPopup(){
    cmX=cmY=cmH=0;
    cmW=32;
    cmTime=0;
    cmLastLine="...";
    cmTheme=0x11;
  }
  void ccUpdate(){if(cmTime==0){return;}
    cmTime-=(cmTime>0)?1:0;
    //--
    fill(cmTheme,0xAA);stroke(0x77);
    rect(cmX,cmY,cmW,cmH);noStroke();
    fill(0xFF-cmTheme);text(cmLastLine,cmX+4,cmY+4);
    //--
  }
  void ccPopup(HcPopline pxLine){
    cmTime=ceil(frameRate)*2;
    cmLastLine=pxLine.cmLine;
    cmW=ceil(textWidth(cmLastLine)*1.05f);
    int lpLine=1;char[] lpArray=cmLastLine.toCharArray();
    for(int i=0, s=lpArray.length;i<s;i++){if(lpArray[i]=='\n'){lpLine++;}}
    cmH=16*lpLine+4;
    cmX=pxLine.cmX-cmW/2;cmY=pxLine.cmY-cmH-16;
    cmTheme=pxLine.cmColor;
  }
}//+++

class HcPopline{
  String cmLine;
  int cmX, cmY;
  int cmColor;
  HcPopline(){
    cmX=0;cmY=0;cmLine=null;cmColor=0;
  }
  //--
  void ccSetup(String pxLine, int pxX, int pxY, int pxColor){
    cmX=pxX;cmY=pxY;
    cmLine=pxLine;cmColor=pxColor;
  }
}//+++


//EOF

 



最后编辑:
作者:constrain
nullpointerexception

留下一个回复

你的email不会被公开。