吃鱼逻辑
最初是利用主角鱼和NPC之间的距离来判断NPC能否被吃掉
eatFish(){
for (let i = 0; i < this.Npcfishes.length; i++) {
let vx = this.fishX - this.Npcfishes[i].npcFishX;
let vy = this.fishY - this.Npcfishes[i].npcFishY;
if(distance >0 && (distance<this.Npcfishes[i].npcWidth)){
this.Npcfishes.splice(i,1)
}
}
}
但是由于他们的位置坐标在图片的左上角,因此会出现从用户视角看主角鱼已经碰到 NPC 但就是吃不掉的现象
于是采用了碰撞检测AABB 包围盒,就是采用一个长方体将物体包裹起来,进行两个物体的相交性检测时仅检测物体对应包围盒(包裹物体的长方体)的相交性
eatFish(){
for (let i = 0; i < this.Npcfishes.length; i++) {
let vx = this.fishX - this.Npcfishes[i].npcFishX;
let vy = this.fishY - this.Npcfishes[i].npcFishY;
if(this.isCollidingAABB(this.Npcfishes[i]) ){
this.Npcfishes.splice(i,1)
}
}
}
碰撞检测
isCollidingAABB(npc) {
return (
this.fishX <= npc.npcFishX + npc.npcWidth &&
this.fishX + this.fishSize >= npc.npcFishX &&
this.fishY <= npc.npcFishY + npc.npcWidth &&
this.fishY + this.fishSize >= npc.npcFishY
);
}
这样就可以实现只要主角鱼碰到NPC就可以吃掉NPC
从上面的代码可以看出NPC被吃掉之后消失是利用splice将其从数组当中删除了,但是删除掉数组的一个对象会导致页面的重现渲染,就会出现吃掉一个NPC之后其他NPC的图片出现变化
为了解决上面的问题,给NPC增加了透明度属性,当NPC被吃掉之后就会变透明,虽然没有将其从数组中删除,但是呈现给用户的就是NPC被吃掉了
eatFish(){
for (let i = 0; i < this.Npcfishes.length; i++) {
let vx = this.fishX - this.Npcfishes[i].npcFishX;
let vy = this.fishY - this.Npcfishes[i].npcFishY;
if(this.isCollidingAABB(this.Npcfishes[i]) ){
if(this.Npcfishes[i].npcOpacity!=0 && this.fishSize<=500{
this.fishSize+=this.Npcfishes[i].npcWidth/20
}
this.Npcfishes[i].npcOpacity=0;
}
}
}
游戏继续
当一组NPC被用户操控的主角鱼全部吃掉之后就会提示用户“You Win”,出现“continue”按钮,用户点击按钮之后就可以实现继续游戏的效果
通过定义的isContinue来判断什么时候对用户给出提示,isContinue最初设为false,当局内所有的NPC的透明度全部为0时候变为true
eatFish(){
for (let i = 0; i < this.Npcfishes.length; i++) {
let vx = this.fishX - this.Npcfishes[i].npcFishX;
let vy = this.fishY - this.Npcfishes[i].npcFishY;
//let distance = Math.sqrt(vx * vx + vy * vy)
if(this.isCollidingAABB(this.Npcfishes[i]) ){
if(this.Npcfishes[i].npcOpacity!=0 && this.fishSize<=500 && this.speed>=2){
this.fishSize+=this.Npcfishes[i].npcWidth/20
}
this.Npcfishes[i].npcOpacity=0;
this.opacitycnt=this.OpacityCnt()
if(this.opacitycnt==this.Npcfishes.length){
this.isContinue=true;
}
}
}
计数变透明的NPC
OpacityCnt(){
let transparentCount = 0;
for(let i=0;i<this.Npcfishes.length;i++){
if(this.Npcfishes[i].npcOpacity==0){
transparentCount++;
// console.log("opacitycnt:"+this.opacitycnt.toString())
}
}
return transparentCount
}
当isContinue为true时,即满足可以继续游戏的条件,游戏继续即会生成新的NPC
if(this.isContinue){
Text("You Win")
.fontSize(150)
.width(800)
.height(600)
.fontWeight(FontWeight.Bold)
.transition({
scale:{x:0,y:0},
opacity: 0,
rotate:{angle:-360}
})
.position({x:750,y:300})
Button("CONTINUE")
.width(400)
.height(150)
.fontSize(60)
.position({x:850,y:700})
.onClick(()=>{
this.isContinue=false
//floor是向下取整
//Math.floor(Math.random() * (max - min + 1)) + min;
this.RandomNpcY=Math.floor(Math.random()*this.screenHeight-200);
console.log(this.RandomNpcY.toString());
//this.RandomNpcSpeed=Math.random()*(this.NpcSpeedMax-this.NpcSpeedMin+1)+this.NpcSpeedMin;
this.Npcfishes=[
new NpcInfo(5,this.RandomNpcY,6,200,0,1),
new NpcInfo(8,(this.RandomNpcY+this.Domain*2)%(this.screenHeight-200),1,80,1,1),
new NpcInfo(10,(this.RandomNpcY+this.Domain*5)%(this.screenHeight-200),2,60,1,1),
new NpcInfo(2,(this.RandomNpcY+this.Domain*10)%(this.screenHeight-200),3,70,0,1),
new NpcInfo(9,(this.RandomNpcY+this.Domain*30)%(this.screenHeight-200),4,140,1,1),
new NpcInfo(5,(this.RandomNpcY+this.Domain*21)%(this.screenHeight-200),5,220,0,1),
]
})
}