|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
主要缺点就是:速度比较慢,没有C和C++快运算飞机类游戏中枪弹是必不成少的,他们数目良多且充溢着全部屏幕,这些随机大概有着必定AI的小物体,完成起来不是总那末简单,偶然候你不能不思索良多和效能有关的成绩。我们之前界说了GameObject,很年夜水平上就是为了便利的重用Sprite,由于我们有良多的枪弹,不成能没增添一个枪弹都是一个Sprite,我必要共享统一个Sprite。我们经由过程承继GameObject来完成。
上面剖析一下这个枪弹类:
它将承继自GameObject;
纪录枪弹的个数;
一个枪弹的形态数组,纪录各个枪弹的范例type,地位x,y,速率vx,vy,是不是存活alive等等。
初始化枪弹
一个绘制办法,将枪弹画到屏幕上。
一个碰撞检测办法。
好了先如许吧,以下是我们枪弹类的界说,注重这类头脑――重用Sprite,这很主要。(这里参考了tony的良多计划)
publicclassBulletsextendsGameObject{
privateint[][]bullets;//枪弹形态数组
privateintbulletstotal;//数组的length
privateRandomrnd;//随机数
publicstaticfinalintBULLET_TYPE_LEFT=0;//枪弹初始化的地位范例
publicstaticfinalintBULLET_TYPE_RIGHT=1;//分为高低摆布四种
publicstaticfinalintBULLET_TYPE_TOP=2;
publicstaticfinalintBULLET_TYPE_BOTTOM=3;
privateintwidth,height;//屏幕的高和宽,用于随机枪弹地位
publicBullets(Imageimg,intpicwidth,intpicheight,intbulletstotal,intwidth,intheight){
super(img,picwidth,picheight);
this.bulletstotal=bulletstotal;
bullets=newint[bulletstotal][6];
rnd=newRandom();
this.width=width;
this.height=height;
}
publicvoidinitBullets(){//初始化枪弹形态数组
for(inti=0;i<bullets.length;i++){
initBullet(i);
}
}
privatevoidinitBullet(inti){//初始化index号枪弹
bullets[i][0]=(rnd.nextInt()&0x7fffffff)%4;//type
bullets[i][5]=1;//alive1暗示存活,0暗示逝世往
switch(bullets[i][0]){
caseBULLET_TYPE_LEFT:
bullets[i][1]=-5;
bullets[i][2]=(rnd.nextInt()&0x7fffffff)%height;
bullets[i][3]=(rnd.nextInt()&0x7fffffff)%3+1;//vx
bullets[i][4]=(rnd.nextInt())%3;//vy
break;
caseBULLET_TYPE_RIGHT:
bullets[i][1]=width+5;
bullets[i][2]=(rnd.nextInt()&0x7fffffff)%height;
bullets[i][3]=((rnd.nextInt()&0x7fffffff)%3+1)*-1;//vx
bullets[i][4]=(rnd.nextInt())%3;//vy
break;
caseBULLET_TYPE_TOP:
bullets[i][1]=(rnd.nextInt()&0x7fffffff)%width;
bullets[i][2]=-5;
bullets[i][3]=(rnd.nextInt())%3;//vx
bullets[i][4]=(rnd.nextInt()&0x7fffffff)%3+1;//vy
break;
caseBULLET_TYPE_BOTTOM:
bullets[i][1]=(rnd.nextInt()&0x7fffffff)%width;
bullets[i][2]=height+5;
bullets[i][3]=(rnd.nextInt())%3;//vx
bullets[i][4]=((rnd.nextInt()&0x7fffffff)%3+1)*-1;//vy
break;
}
}
publicvoidupdata(inti){//依据速率更新i枪弹下一桢的地位,受阻反弹
bullets[i][1]+=bullets[i][3];
bullets[i][2]+=bullets[i][4];
if(bullets[i][1]<-5||bullets[i][1]>width+5){
bullets[i][3]*=-1;
}
if(bullets[i][2]<-5||bullets[i][2]>height+5){
bullets[i][4]*=-1;
}
}
privatevoidpaint(Graphicsg,inti){//绘画出第i个枪弹
updataspritepos(i);//更新地位
sprite.paint(g);//绘画Sprtie
}
publicvoidpaint(Graphicsg){//绘画全部枪弹组
for(inti=0;i<bullets.length;i++){
if(bullets[i][5]==0){//逝世往的枪弹不绘画
continue;
}
sprite.setPosition(bullets[i][1],bullets[i][2]);//更新地位
sprite.paint(g);
}
}
publicvoidrefreshBullets(Spriteplanesprite,booleanneedcollision){//革新字典数组的形态,并作碰撞处置
for(inti=0;i<bullets.length;i++){
if(bullets[i][5]==0){//逝世往的枪弹不更新
continue;
}
if(needcollision){//假如必要碰撞检测
if(isCollision(planesprite,i,10)){//假如碰撞,举行处置
//System.out.println("collision");
Navigate.mc.gameover=true;
Navigate.mc.explosion.sprite.setPosition(bullets[i][1]-16,
bullets[i][2]-16);
bullets[i][5]=0;//杀逝世碰撞的枪弹
continue;
}
}
updata(i);//更新形态
}
}
privatebooleanisCollision(Spritesprite,inti,intrange){
//判别是不是碰撞
//updataspritepos(i);
//returnsprite.collidesWith(this.sprite,true);
booleanresult=false;
intplaneXCenter=sprite.getX()+12;
intplaneYCenter=sprite.getY()+12;
intbulletXCenter=bullets[i][1]+3;
intbulletYCenter=bullets[i][2]+3;
if(Math.abs(planeXCenter-bulletXCenter)<range){
if(Math.abs(planeYCenter-bulletYCenter)<range){
result=true;
}
}
returnresult;
}
privatevoidupdataspritepos(inti){//将sprite更新到i字弹的地位
sprite.setPosition(bullets[i][1],bullets[i][2]);
}
/*nousenow
publicvoidresetDeadBullet(){
for(inti=0;i<bullets.length;i++){
if(bullets[i][5]==0){//deadbullet
initBullet(i);
}
}
}
*/
publicvoidkillbullets(Spriteplanesprite,intrange){杀逝世必定地区内的枪弹
for(inti=0;i<bullets.length;i++){
if(bullets[i][5]!=0){//alivebullets
if(isCollision(planesprite,i,range)){
bullets[i][5]=0;
initBullet(i);
}
}
}
}
}
枪弹怎样暗示?
起首我们用一个二维数组来纪录枪弹的信息:
bullets[i][0]暗示枪弹的范例,有上、下、左、右四种,分离暗示枪弹飞进屏幕前的四种地位;
bullets[i][1]暗示枪弹的x坐标;
bullets[i][2]暗示枪弹的y坐标
bullets[i][3]暗示枪弹的x偏向速率;
bullets[i][4]暗示枪弹的y偏向速率;
bullets[i][5]暗示枪弹的存活形态;
枪弹怎样初始化?
我们起首写了一个初始化单个枪弹的办法,然后便当数组挪用initBullet(i);来更新全部形态数组。
枪弹怎样绘制?
我们起首写了一个绘制单个枪弹的办法,然后便当数组挪用paint(g,i);来绘制全部形态数组。
枪弹怎样碰撞?
有良多种办法,个中sprite自己就供应了边框碰撞检测和基于像素的碰撞检测。前者不太合适我们的游戏,我们的飞机是不划定规矩物体,且航行游戏对碰撞对照敏感;尔后者的效力又得不到我们的信任,以是我们是用一种半径检测,把飞机近似的当作圆,拔取得当的半径,Math.abs(planeXCenter-bulletXCenter)<range则标明碰撞。
碰撞看似复杂,实际上是很庞大的成绩,值得光荣的是,二维碰撞比拟三维碰撞复杂很多。一个小技能是,宁肯让收缩检测半径变小也不要他变得年夜――遗漏检测,总比误检测要好很多。
枪弹更新?
我们使用refreshBullets举行更新,这是次要逻辑部分。这个办法卖力便当数组检测碰撞,假如碰撞就将处于碰撞地位的枪弹杀逝世,并作响应的处置,这里是停止游戏并爆炸飞机;不然更新枪弹的地位。
我们只是线性的遍历全部的数组,举行碰撞检测,以后是更新地位;可是如许做有一个条件,就是碰撞检测复杂并且处置部分也很复杂:在这个游戏中,碰撞检测只是枪弹群和飞机的检测,碰撞检测在游戏停止后就不实行了(经由过程把持booleanneedcollision);而处置更是复杂了一些――间接停止了游戏。假如不是云云,好比处置后并非复杂的停止游戏,我们就不能不计划的庞大一些。大概就不是将碰撞复杂的以飞机为中央了。我们必要计划好游戏事务,计划好碰撞体系。
假如碰撞自己对照庞大,大概枪弹数目,品种增添时,我们线性的遍历数组就不克不及老是对一切的枪弹都检测,大概屏幕必要分区,不处于一个地区的单元不检测。
总之当你想一想你的1934时,将不在是设想着枪弹,飞机甚么的,你要思索一个体系。
总结一会儿弹类的大众接口:
nBullets(Imageimg,intpicwidth,intpicheight,intbulletstotal,intwidth,intheight)机关函数
npublicvoidinitBullets()初始化枪弹数组
npublicvoidpaint(Graphicsg)paint枪弹数组
npublicvoidrefreshBullets(Spriteplanesprite,booleanneedcollision)更新枪弹数组形态,碰撞检测、处置等逻辑事情的综合
npublicvoidkillbullets(Spriteplanesprite,intrange)//稍后注释
到此为止,我们的游戏已初具范围了,下一步是到场效果类,嘿嘿有点意义了…
专门做了这个例子;而java的这个例子好像就是为了教学而写的,很多教学目的的例子是不考虑优化、性能的。 |
|