首页 > Sktech > 习作AC_在场景地图里射击浮靶的喷气飞船
2017
09-01

习作AC_在场景地图里射击浮靶的喷气飞船

习作AC_在场景地图里射击浮靶的喷气飞船 - 第1张  | Processing编程艺术


由 nature of code 第九章GA的最终范例 Evolution EcoSystem 改编.
组织结构参考范例World类重写,子弹类参考范例Food类重写, 浮靶类参考范例Bloop类重写.
浮靶每秒产生一个,最大上限64个,被击中后显示血槽两秒.
飞船操作键位改到了[W][S][A][D].
(比较习惯以GBA游戏做参考分辨率设为320*240…适当调大可以降低难度)


[Q]键退出.
[J]键发射子弹.
[K]键启动力场.力场启动后对自机有减速效果,对力场判定内浮靶造成范围伤害.力场伤害较子弹小,力场击坠浮靶得分较子弹低.


– 问题:在地图边缘镜头还是抖动 <-飞船撞边不能全速移动,但镜头仍按全速反转,应该单独计算飞船的绝对速度.
– 问题:有时子弹的发射方向和飞船不平行
– 问题:子弹仍是点圆判定,速度慢了容易多判,半径小了容易漏弹,应该改成直线判定
– 问题:每帧耗时计算在 draw() 循环里面直接取两点 millis() 做减法能不能计算出?? 调大分辨率后卡顿明显,但差值并没有明显加大.(但范例的 Topic/Shaders/Landscape 里貌似也是用同样原理算的??)


//--
int pbLeRoller=0;
PVector pbTheOrigin;
//--
EcMap pbTheMap= new EcMap();
Spaceship ship = new Spaceship(pbTheMap);
EcCordinator pbTheCord= new EcCordinator(pbTheMap,ship,3);
//--


void setup() {
  size(320, 240);
  frameRate(32);
  pbTheOrigin=new PVector(width/2,height/2);
}//--


void draw() {background(0);pbLeRoller++;pbLeRoller&=0x1F;
  //--
  int lpMillisA=millis();
  //--
  fsCheckCamera();
  pbTheMap.ccUpdate();
  pbTheCord.ccUpdate();
  ship.ccRefresh();
  //--
  if(pbLeRoller==7){pbTheCord.ccNewDummy();}
  //--
  fill(0x77,0xEE,0x77);if(pbLeRoller<16){
  fnTextString("[W][S][A][D]to move ship...",2);
  fnTextString("[J]to fire beam [K] activate barrier...",3);}
  fnTextFloat("cameraX:",pbTheMap.cmPos.x,11);
  fnTextFloat("cameraY:",pbTheMap.cmPos.y,12);
  fnTextFloat("shipX:",ship.location.x,13);
  fnTextFloat("shipY:",ship.location.y,14);
  fnTextFloat("speed:",ship.velocity.mag(),26);
  fnTextInt("bullets:",pbTheCord.cmBulletList.cmPos.size(),28);
  fnTextInt("dummies:",pbTheCord.cmDummyList.size(),29);
  //--
  textAlign(RIGHT,TOP);text("Score:"+nf(pbTheCord.cmScore,6),width-5,2);textAlign(LEFT,TOP);
  //--
  if (keyPressed) {switch(key){
    case 'a':ship.turn(-0.15);ship.cmTurnPlus    = true;break;
    case 'd':ship.turn( 0.15);ship.cmTurnMinus   = true;break;
    case 'w':ship.thrust( 1);ship.thrusting     = true;break;
    case 's':ship.thrust(-1);ship.backThrusting = true;break;
    case 'k':case 'f':ship.cmBarrier = true;break;
   default:break;
  }}
  //--
  int lpMillisB=millis();
  fnTextInt("ms/f:",lpMillisB-lpMillisA,27);
  //--
}//+++


void keyPressed(){switch(key){
  case 'j':case 'e':pbTheCord.cmBulletList.ccShoot(ship.location,ship.heading);break;
  case 'q':fsPover();break;
  default:break;
}}//+++


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


void fsCheckCamera(){
  PVector lpDist=PVector.sub(ship.cmAbsolutePos,pbTheOrigin);
  if(lpDist.mag()>32){
    lpDist.normalize();
    lpDist.mult(ship.velocity.mag());
    pbTheMap.cmPos.sub(lpDist);
  }
}//+++


void fnTextFloat(String pxTitle, float pxVal, int pxLine){boolean lpRight=pxLine>(height/16);
  text(pxTitle+nfc(pxVal,2),lpRight?width/2+16:16,16*(lpRight?pxLine-height/16:pxLine));
}//+++

void fnTextInt(String pxTitle, int pxVal, int pxLine){boolean lpRight=pxLine>(height/16);
  text(pxTitle+nf(pxVal,4),lpRight?width/2+16:16,16*(lpRight?pxLine-height/16:pxLine));
}//+++

void fnTextString(String pxTitle, int pxLine){boolean lpRight=pxLine>(height/16);
  text(pxTitle,lpRight?width/2+16:16,16*(lpRight?pxLine-height/16:pxLine));
}//+++


class EcMap{
  PVector cmPos;
  PVector cmDia;
  int cmColorSet;
  EcMap(){
    cmPos=new PVector(32,32);
    cmDia=new PVector(1400,1400);
    cmColorSet=0x77;
  }
  //--
  void ccUpdate(){
    fill(cmColorSet,cmColorSet);rect(cmPos.x,cmPos.y,cmDia.x,cmDia.y);
    float lpDiv=cmDia.x/8;
    fill(255-cmColorSet);
    for(int i=0;i<64;i++){
      text(nf(i,3),i%8*lpDiv+cmPos.x,i/8*lpDiv+cmPos.y);
    }
  }
  //--
}//+++


class Spaceship {
  //--
  EcMap cmMap;
  //--
  PVector cmAbsolutePos;
  //--
  PVector location,velocity,acceleration;
  float damping,topspeed,heading,r;
  boolean thrusting,backThrusting;
  //--
  boolean cmTurnMinus,cmTurnPlus;
  //--
  boolean cmBarrier;
  //--
  Spaceship(EcMap pxMap) {
    //--
    cmAbsolutePos = new PVector();
    location = new PVector(99,99);
    velocity = new PVector();
    acceleration = new PVector();
    cmMap=pxMap;
    damping=0.995;
    topspeed=8;
    heading=2;
    r=8;
    thrusting=false;
    backThrusting=false;
    cmTurnMinus=false;
    cmTurnPlus=false;
    cmBarrier=false;
    //--
  } 
  //--
  void ccRefresh(){update();display();}
  void update() { 
    damping=cmBarrier?0.950:0.995;
    velocity.add(acceleration);velocity.mult(damping);velocity.limit(topspeed);
    location.add(velocity);
    location.x=constrain(location.x,0,cmMap.cmDia.x);
    location.y=constrain(location.y,0,cmMap.cmDia.y);
    acceleration.mult(0);
  }
  //--
  void applyForce(PVector force) {PVector f = force.get();acceleration.add(f);}
  void turn(float a) {heading += a;thrust(a*0.3);}
  //--
  void thrust(float pxDirect) {
    float angle = heading - pxDirect*PI/2;
    PVector force = new PVector(cos(angle),sin(angle));
    force.mult(0.3);
    applyForce(force);
  }
  //--
  void display() { 
    //--
    cmAbsolutePos=PVector.add(location,cmMap.cmPos);
    //--
    pushMatrix();translate(cmAbsolutePos.x,cmAbsolutePos.y);rotate(heading);rectMode(CENTER);
    //--
    if(cmBarrier&&(frameCount%3==1)){fill(0xEE,0xEE);ellipse(0,0,128,128);};
    fill(thrusting?color(0x77,0x77,0xFF):color(0x33,0x11));rect(-r/2,r,r/2,2*r);rect(r/2,r,r/2,2*r);
    fill(backThrusting?color(0x77,0x77,0xFF):color(0x33,0x11));rect(-r*3/4,-r/2,r/4,r);rect(r*3/4,-r/2,r/4,r);
    fill(cmTurnMinus?color(0x77,0x77,0xFF):color(0x33,0x11));rect(-r,-r,10,r/4);rect( r,0,10,r/4);
    fill(cmTurnPlus?color(0x77,0x77,0xFF):color(0x33,0x11));rect( r,-r,10,4/4);rect(-r,0,10,r/4);
    //--
    fill(175);stroke(0);beginShape();
    vertex(-r,r);vertex(0,-2*r);vertex(r,r);
    endShape(CLOSE);
    rectMode(CORNER);noStroke();
    popMatrix();
    //--
    thrusting=false;backThrusting=false;
    cmTurnMinus=false;cmTurnPlus=false;
    cmBarrier=false;
  }
}//+++

class EcCordinator{
  //--
  EcMap cmMap;
  Spaceship cmProtagon;
  //--
  ArrayList<EcDummy> cmDummyList;
  EcBulletList cmBulletList;
  //--
  int cmScore;
  //--
  EcCordinator(EcMap pxMap,Spaceship pxShip,int pxInitDummyAmount){
    //--
    cmMap=pxMap;
    cmProtagon=pxShip;
    //--
    cmDummyList=new ArrayList<EcDummy>();
    cmBulletList= new EcBulletList(cmMap);
    for(int i=0;i<pxInitDummyAmount;i++){cmDummyList.add(new EcDummy(cmMap));}
    cmScore=0;
  }
  //--
  void ccNewDummy(){if(cmDummyList.size()>63){return;}
    cmDummyList.add(new EcDummy(cmMap));
  }
  void ccUpdate(){
    cmBulletList.ccUpdate();
    for (int i = cmDummyList.size()-1; i >= 0; i--) {
      EcDummy lpDummy=cmDummyList.get(i);
      lpDummy.ccUpdate();
      lpDummy.ccCheckShots(cmBulletList,cmProtagon);
      if(lpDummy.ccIsDestroyed()){cmDummyList.remove(i);cmScore+=cmProtagon.cmBarrier?2:10;}
    }
  }
  //--
}//+++


class EcDummy{
  //--
  EcMap cmMap;
  //--
  PVector cmRelativePos;
  float cmNoiseX,cmNoiseY;
  float cmMaxSpeed;
  //--
  int cmExplodeTimer;
  int cmShowsHpGaugeTimer;
  //--
  float cmHP;
  float cmScale;
  //--
  EcDummy(EcMap pxMap){
    cmMap=pxMap;
    cmRelativePos=new PVector(random(cmMap.cmDia.x),random(cmMap.cmDia.x));
    cmNoiseX=random(999); 
    cmNoiseY=random(999);
    cmMaxSpeed=4;
    cmExplodeTimer=0;
    cmShowsHpGaugeTimer=0;
    cmHP=192;
    cmScale=2;
  }
  //--
  void ccUpdate(){
    float lpNoiseX=map(noise(cmNoiseX),0,1,-cmMaxSpeed,cmMaxSpeed);cmNoiseX+=0.01;
    float lpNoiseY=map(noise(cmNoiseY),0,1,-cmMaxSpeed,cmMaxSpeed);cmNoiseY+=0.01;
    PVector lpSpeed = new PVector(lpNoiseX,lpNoiseY);
    cmRelativePos.add(lpSpeed);
    cmRelativePos.x=constrain(cmRelativePos.x,0,cmMap.cmDia.x);
    cmRelativePos.y=constrain(cmRelativePos.y,0,cmMap.cmDia.y);
    float lpAbsoX=cmMap.cmPos.x+cmRelativePos.x;
    float lpAbsoY=cmMap.cmPos.y+cmRelativePos.y;
    //--
    cmExplodeTimer--;if(cmExplodeTimer<0){cmExplodeTimer=0;}
    cmShowsHpGaugeTimer--;if(cmShowsHpGaugeTimer<0){cmShowsHpGaugeTimer=0;}
    cmScale+=0.5;if(cmScale>10){cmScale=10;}
    //--
    pushMatrix();translate(lpAbsoX,lpAbsoY);rotate(lpSpeed.heading());rectMode(CENTER);
    stroke(0);fill(0xEE);rect(0,0,cmScale,cmScale*2);
    noStroke();fill(0x33);rect(0,-cmScale/2,cmScale/2,cmScale/2);
    rectMode(CORNER);
    if(cmExplodeTimer!=0){fill(0xEE,0x77,0x77,0xAA);ellipse(random(8),random(8),16,16);}
    popMatrix();
    //--
    if(cmShowsHpGaugeTimer!=0){
      fill(0x33);rect(lpAbsoX-10,lpAbsoY-10,20,4);
      fill(0x33,0xEE,0x33);rect(lpAbsoX-10,lpAbsoY-10,map(cmHP,0,200,1,20),4);
    }
    //--
  }
  //--
  void ccCheckShots(EcBulletList pxList,Spaceship pxShip){
    ArrayList<PVector> lpList=pxList.ccGetList();
    PVector lpProtagonPos=pxShip.location.get();
    for (int i = lpList.size()-1; i >= 0; i--) {
      PVector lpBullet = lpList.get(i);
      float lpDist = PVector.dist(cmRelativePos,lpBullet);
      if(lpDist<20){ccDamaged(16);}
    }
    float lpProtagonDist = PVector.dist(cmRelativePos,lpProtagonPos);
    if(lpProtagonDist<80 && pxShip.cmBarrier){ccDamaged(4);}
  }
  //--
  boolean ccIsDestroyed(){return cmHP<5;}
  //--
  void ccDamaged(int pxDamage){
    cmExplodeTimer=7;cmShowsHpGaugeTimer=32;
    cmHP-=pxDamage;
  }
}//+++



class EcBulletList{
  //--
  EcMap cmMap;
  ArrayList<PVector> cmPos;
  ArrayList<PVector> cmSpeed;
  //--
  EcBulletList(EcMap pxMap){
    cmPos = new ArrayList();
    cmSpeed = new ArrayList();
    cmMap=pxMap;
  }
  //--
  void ccUpdate(){for(int i=cmPos.size()-1;i>=0;i--){
    PVector lpPos=cmPos.get(i);
    PVector lpSpeed=cmSpeed.get(i);
    float lpHeading=lpSpeed.heading();
    float lpAbsX=cmMap.cmPos.x+lpPos.x;
    float lpAbsY=cmMap.cmPos.y+lpPos.y;
    lpPos.add(lpSpeed);
    //--
    pushMatrix();translate(lpAbsX,lpAbsY);rotate(lpHeading);
    fill(0xFF,0x77,0x77);ellipse(20,0,3,3);rect(0,-1,24,2);
    popMatrix();
    //--
    if(lpPos.x<0 || lpPos.x>cmMap.cmDia.x ||
       lpPos.y<0 || lpPos.y>cmMap.cmDia.y
    ){cmPos.remove(i);cmSpeed.remove(i);}
    //--
  }}
  //--
  ArrayList ccGetList(){return cmPos;}
  void ccShoot(PVector pxPos, float pxHeading){
    cmPos.add(pxPos.get());
    float lpHeading = pxHeading -PI/2;
    PVector lpSpeed = new PVector(cos(lpHeading),sin(lpHeading));
    //--
    lpSpeed.mult(16);
    cmSpeed.add(lpSpeed.get());
  }
  //--
}//+++

//EOF

 



最后编辑:
作者:constrain
nullpointerexception

留下一个回复

你的email不会被公开。