if(pacworld[i][j]==true){
intsquare=1;
if(pacworld[i+1][j]==true)square++;
elseif(pacworld[i-1][j]==true)square++;
if(pacworld[i][j+1]==true)square++;
elseif(pacworld[i][j-1]==true)square++;:
if(/*(i==320&&j==171)||*/(i==200&&j==87)||(i==442&&j==87)||(i==420&&j==341)||(i==224&&j==341))
{
addObject(newPower_Pellet(),i,j);
coins++;
}
elseif(i>=283&&i<=358&&j>=172&&j<=221)coins=coins;
elseif(square>2)
{
addObject(newCoin(),i,j);
coins++;
}
}
}
}
c=coins;
}
4.2Animal类
在Animal类中定义了用于子类继承的抽象方法,如:
方向的移动、方向移动的提前量判断等,在该类中还设置了角色的场景移动传送方法,用于对游戏场景中部特殊的通道移动的定义。
对于Ghost而言,他们的移动的围要求比吃豆人更广提高难度,当他们从地图中央两侧的通道进入时,将会从另一侧出现。
这种突然出现在身边的Ghost往往能提高玩家的紧感,提升游戏性。
protectedvoidwarp(){
positionX=this.getX();
positionY=this.getY();
if(positionX==94)setLocation(550,213);
elseif(positionX==556)setLocation(104,213);
}
例如:
当Ghost从右侧通道走出游戏场景时将会从左侧的通道重新出现在玩家的面前(如图4-3、图4-4所示)。
图4-3
图4-4
在游戏中,总是会在一个方向上碰到无法继续前进的情况,这个时候就需要判断此时还能往哪个方向进行运动,时刻检查能否向四周运动,并根据这个方向来和键盘输入的方向键进行比较,来执行最终的动作方向。
CheckD:
用于检查你可以去往哪个方向
privatebooleancheckD(chars)
{
intx=0,y=0;
switch(s)
{
case'u':
y=-steps;break;
case'd':
y=steps;break;
case'l':
x=-steps;break;
case'r':
x=steps;break;
}
returnPacWorld.pacworld[getX()+x][getY()+y];
}
只有当判定可以往目标方向移动时,角色才可以进行移动
protectedvoidmove(chardirection)
{
intx=0,y=0;
if(direction=='u'&&checkD(direction)==true)y=-steps;
if(direction=='d'&&checkD(direction)==true)y=steps;
if(direction=='l'&&checkD(direction)==true)x=-steps;
if(direction=='r'&&checkD(direction)==true)x=steps;
this.setLocation(this.getX()+x,this.getY()+y);
}
4.3PacMan类
privateGreenfootImageMopen=newGreenfootImage("open.png");
privateGreenfootImageMclosed=newGreenfootImage("closed.png");
定义吃豆人运动的两种状态图:
开口和闭口,用于运动时变换显示。
privatevoidmovePic(){
if(mCounter>=mChange){
setImage(Mopen);
if(mCounter==2*mChange)mCounter=0;
}
elsesetImage(Mclosed);
}
在类中,还需要专门设置一个用于标记吃豆人运动时图片的变化显示的量:
privatechard='l';
定义初始运动向左,吃豆人的四个运动方向分别是:
上(Up:
u),下(Down:
d),左(Left:
l),右(Right:
r)。
如:
(键盘点击方向键向上后,改变吃豆人的运动方向向上)
if(Greenfoot.isKeyDown("up")){
setRotation(90);
d='u';
}
图4-5
在获得了键盘输入的方向后,改变吃豆人的运动(位置、方向),这里还会对可能移动的方向先进行判断(判定是否可以朝目标方向移动)。
(图4-5)
privatevoidcorner(charside){
for(inti=-7;i<=7;i++){
intx=0,y=0;
switch(side){
case'u':
y=-1;x=i;break;
case'd':
y=1;x=i;break;
case'l':
x=-1;y=i;break;
case'r':
x=1;y=i;break;
}
if(PacWorld.pacworld[getX()+x][getY()+y]==true)
setLocation(getX()+x,getY()+y);
}
}
吃豆人在吃豆子时需要调用eat函数:
当吃到小豆子时,移除当前接触到的小豆子并让分数加一;当吃到大豆子时,移除当前接触到的大豆子并让分数加五;当分数高于200且当前游戏中仍存有豆子时,怪物的速度提升(难度提升)。
privatevoideat(){
if(isTouching(Coin.class)){
removeTouching(Coin.class);
coinsCollected++;
points++;
}
if(isTouching(Power_Pellet.class)){
removeTouching(Power_Pellet.class);
run=true;
coinsCollected++;
points+=5;
}
if(coinsCollected==PacWorld.coins&&PacWorld.coins!
=0){
if(points>200*Ghost.speed)Ghost.speed++;
Greenfoot.setWorld(newPacWorld(l,points,Ghost.speed));
}
}
在游戏中,吃豆人难免会出现触碰到怪物而死亡的情况,这个时候就需要死亡函数——在出生点重生,生命减一,并执行一次判断:
当生命所剩为零时重置游戏。
执行这个死亡函数的前提条件是吃豆人触碰到四个怪物中的任意一个(if语句)。
privatevoiddie(){
if(isTouching(Inky.class)||isTouching(Pinky.class)||isTouching(Blinky.class)||isTouching(Clyde.class)){
l--;
setLocation(320,257);
if(l==0){
points=0;
Greenfoot.setWorld(newPacWorld(3,0,1));
}
}
}
4.4Ghost类
在吃豆人游戏中,怪物是一个非常重要的存在,要让一个怪物实现在场景中移动就需要一个用于定义怪物随机移动的函数。
使用random函数随机生成四个方向的移动,当怪物移动到一个方向的尽头时则执行下一个方向的运动判断。
protectedvoidrandomWalk(){
intsquare=1;
if(PacWorld.pacworld[this.getX()+1][this.getY()]==true)square++;
elseif(PacWorld.pacworld[this.getX()-1][this.getY()]==true)square++;
if(PacWorld.pacworld[this.getX()][this.getY()+1]==true)square++;
elseif(PacWorld.pacworld[this.getX()][this.getY()-1]==true)square++;
if(square>2){
do{
intr=(int)(int)(Math.random()*4);
switch(r){
case0:
d='u';o='d';break;
case1:
d='d';o='u';break;
case2:
d='l';o='r';break;
case3:
d='r';o='l';break;
}
bX=this.getX();
bY=this.getY();
move(d);
aX=this.getX();
aY=this.getY();
move(o);
}while(bX==aX&&bY==aY);
}
for(inti=0;iif(this.getX()==320&&this.getY()>171&&this.getY()<221)this.setLocation(320,171);
}
protectedvoidrun(){
if(run)runCount++;
if(isTouching(PacMan.class)&&run==true){
PacMan.points+=20;
setLocation(320,213);
this.start=true;
}
elseif(800countR++;
if(countR==50){
countR=0;
this.setImage(uPic);
}
elsethis.setImage(gPic);
}
elseif(runCount==1000){
runCount=0;
run=false;
}
}
设置怪物由出生点出发(图4-6):
图4-6
protectedvoidleave(){
lCount++;
if(lCount==100){
this.order--;
Count=0;
}
if(this.position==false&&this.order!
=1){
if(this.getY()==204)this.d='d';
elseif(this.getY()==221)this.d='u';
move(this.d);
}
elseif(this.position==false&&this.order==1){
if(this.getY()<213)move('d');
elseif(this.getY()>213)move('u');
elseif(this.getY()==213){
if(this.getX()<320)move('r');
elseif(this.getX()>320)move('l');
else{
this.position=true;
}
}
}
elseif(this.position==true){
if(this.getY()>171)move('u');
else{
this.start=false;
inta=(int)(Math.random()*2);
if(a==0)this.d='r';
elsethis.d='l';
}
}
}
吃豆人有着其运动的样式,而怪物也同样有着四个方向运动的图案变化(图4-7):
图4-7
protectedvoidchangePic(){
if(run==false){
switch(this.d){
case'u':
this.setImage(this.uPic);break;
case'd':
this.setImage(this.dPic);break;
case'r':
this.setImage(this.rPic);break;
case'l':
this.setImage(this.lPic);break;
}
}
elsethis