zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Processing摸索前行(8)-弹珠游戏

游戏 Processing 前行
2023-09-27 14:27:33 时间

前面,我们摸索了Pressing线程已经对象封装,还做了雷达以及示波器,这一篇博文,我们利用processing来做一个小的游戏。这个游戏我们在很多手游上玩过,一个滑动的盘子,接住弹珠,弹珠每次弹跳可以击碎一个方块。
明白了需求,我们就来一步一步来实现吧。
一、会自动反弹的弹珠
首先我们要实现的是一个能够反弹的弹珠。代码如下:

PVector ballPosition, ballSpeed;
color ballColor;
void setup() {
 // noLoop();
 size(320,280);
  ballPosition = new PVector(this.width/2,this.height/2);
  ballSpeed = new PVector(4, 4); 
  ballColor=color(random(255),random(255),random(255));
}

void draw() {
  background(0);
  ellipse(ballPosition.x, ballPosition.y, 30, 30);
  fill(ballColor);
  ballPosition.add(ballSpeed);
  if(ballPosition.x<=15 || ballPosition.x>=(this.width-15))
  {
    ballSpeed.x*=-1;
      ballColor=color(random(255),random(255),random(255));
 
}
  if(ballPosition.y<=15 || ballPosition.y>=(this.height-15))
  {
    ballSpeed.y*=-1 ;
      ballColor=color(random(255),random(255),random(255));
 
}
}

我们在这里使用了向量来存储“”对值“,这里不用point来记录,那是因为point不能用来做运算。运行效果:
在这里插入图片描述
下面我们在屏幕上方放置一些方块,然后能够检测到碰撞,我们来看看代码:

PVector ballPosition, ballSpeed;
ArrayList<Block>  blocksArr;
color ballColor;
boolean   xbound=false;
boolean   ybound=false;
void setup() {
 size(320,280);
 
  ballPosition = new PVector(width/2,height/2);//random(this.width/2),random(this.height/2)
  ballSpeed = new PVector(4, 4); 
  ballColor=color(random(255),random(255),random(255));
  blocksArr=new ArrayList<Block>();
  initBlocks(5);
}

void draw() {
  background(0);

  for(Block block:blocksArr)
   if(block.displayStatus>0)
   {
    block.drawBlock();
    block.checkCollision(ballPosition);
    if(block.xb)
    {
      frameRate(10);
    xbound=block.xb;
    }
    if(block.yb)
    {
    ybound=block.yb;
    }


}
bounceBall();


}

void bounceBall()
{
  noStroke();
  fill(ballColor);
 
 
  ellipse(ballPosition.x, ballPosition.y, 10, 10);
  
  ballPosition.add(ballSpeed);
  
   //检测碰撞  
 if(!ybound &&!xbound)//当两个block碰撞检测量都为false则进入正常边界检测
 {
   //正常X边界检测
    if(ballPosition.x<=15 || ballPosition.x>=(this.width-5))
      xbound=true;
    else
      xbound=false;
   if(ballPosition.y<=15 || ballPosition.y>=(this.height-5))
      ybound=true;
   else
      ybound=false;
 }
    
  if(xbound)
  {
      ballSpeed.x*=-1;
      ballColor=color(random(255),random(255),random(255)); 
      xbound=!xbound;
   }
  if(ybound)
  {
      ballSpeed.y*=-1 ;
      ballColor=color(random(255),random(255),random(255));
      ybound=!ybound;
  }
  stroke(10,200,30);
}

void initBlocks(int layerCount)
{
  int bWidth=40;
  int bHeight=20;
  Block blk;
  for(int j=0;j<layerCount;j++)
  for(int i=0;i<this.width/40;i++)
  {
    blk=new Block(i*bWidth,j*bHeight);
    blocksArr.add(blk);
  }
  
}

class Block{



float xcoor;
  float ycoor;
  int bWidth=40;
  int bHeight=20;
  int displayStatus=5;
  boolean xb=false;
  boolean yb=false;
  Block(float x,float y)
  {
    xcoor=x;
    ycoor=y;  
  }
  

  void  drawBlock()
  {
    fill(180,100,100,displayStatus*50);
    rect(xcoor,ycoor,bWidth,bHeight);
    noFill();
  }

  void checkCollision(PVector ball)
  {
    float nearestValueX;
     float nearestValueY;


if(xcoor<ball.x && ball.x<xcoor+40 && ycoor<ball.y && ball.y<ycoor+20)

{
  nearestValueX=abs(ball.x-xcoor)>abs(ball.x-xcoor+40)?abs(ball.x-xcoor):abs(ball.x-xcoor+40);
  nearestValueY=abs(ycoor-ball.y)> abs(ball.y-ycoor+20)?abs(ycoor-ball.y):abs(ball.y-ycoor+20);
  
    if(nearestValueX<nearestValueY)
   { 
      xb=true;
 
     
   }
   else
    {
     yb=true;
 
    }

  displayStatus=0;


  
}
    
  }
  
}

以上代码利用了前面我们学习的类的封装将block封装为类了,检测方块与小球的碰撞也封装在其中了,这样做的目的就是减少一次对block的检测遍历,节约运算资源。这里的检测只是粗略的检测,喜欢钻研的小伙伴们可以将小球的半径也考虑在内效果会更好。
上述代码运行效果:
在这里插入图片描述

如果还有兴趣的话,按照同样的原理,可以增加一个接球的滑板,同样也自带一个检测碰撞函数,利用对xbound和ybound的操作来实现控制,贴在这里代码太长了。运行效果如下:
在这里插入图片描述
在这里插入图片描述
目前,这个小游戏玩起来基本没有什么问题,但是在processing运行的时候如果有其他的窗口优先于processing窗口处于激活状态,那么,游戏中的按键就不会响应。暂时还米有找到强制使processing窗体处于优先激活状态的语句。
加入了接球板的源代码:
完全版源代码