版权声明:本博客所有原创文章未经准许不得转载或保存转发,本人保留版权法律追诉权。 https://blog.csdn.net/haigear/article/details/85385428
前面,我们摸索了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窗体处于优先激活状态的语句。
加入了接球板的源代码:
完全版源代码