Html5 brick breaking game, add props and speed pass mode (including source code)

breakout game

Made a Html5 version of Arkanoid, adding props and customs clearance timing system. Can run directly on the phone. The renderings are as follows
insert image description here

Source code download address

https://download.csdn.net/download/fujian87232/79892428

game code

index.html file

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<style>
			html,body{
      
      
				height:100%;
				margin: 0;
			}
		</style>
		<script src="pixi.min.js"></script>	

	</head>
	<body>
	</body>
	<script src="game.js"></script>

</html>

The imported game.js file, the main logic is here

var app = new PIXI.Application(494,800);
document.body.appendChild(app.view);

app.view.style.height = "100%";

var score = 0;
var level = 0;
var time = 0;
var lastBallNum = 10;
var gameType = 0;

var isBullet = false;

var blockLevelArr = 
[
[
    7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,0,0,7,7,7,7,7,0,0,7,7,
    7,7,0,0,2,2,2,2,2,0,0,7,7,
    7,7,0,0,8,8,8,8,8,0,0,7,7,
    7,3,3,3,3,3,3,3,3,3,3,3,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,
    0,7,7,7,0,0,0,0,0,7,7,7,0,
    6,6,6,7,0,0,0,0,0,7,6,6,6,
    6,6,6,6,8,8,8,8,8,6,6,6,6,
],
[
    7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,2,2,2,2,2,2,2,7,7,7,
    7,7,7,7,1,1,1,1,1,7,7,7,7,
    7,7,7,7,1,1,1,1,1,7,7,7,7,
    7,7,7,8,8,8,8,8,8,7,7,7,7,
    7,7,7,7,1,1,1,1,1,7,7,7,7,
],
[
    7,7,7,7,0,7,7,7,0,7,7,7,7,
    7,7,7,7,0,7,7,7,0,7,7,7,7,
    7,7,7,2,0,2,2,2,0,2,7,7,7,
    7,7,7,7,0,1,1,1,0,7,7,7,7,
    7,3,3,3,0,3,3,3,0,3,3,3,7,
    7,7,7,8,8,8,8,8,8,7,7,7,7,
    0,7,7,7,0,5,5,5,0,7,7,7,0,
    0,0,0,7,0,7,7,7,0,7,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,
],
[
    7,7,7,7,7,7,7,7,7,7,7,7,7,
    0,0,0,7,7,7,7,7,7,7,0,0,0,
    0,0,0,7,7,7,7,7,7,7,0,0,0,
    7,7,7,7,1,1,1,1,1,7,7,7,7,
    0,0,0,7,7,7,7,7,7,7,0,0,0,
    0,0,0,7,7,7,7,7,7,7,0,0,0,
    0,7,7,7,5,5,5,5,5,7,7,7,0,
    0,0,0,7,7,7,7,7,7,7,0,0,0,
    0,0,0,0,8,8,8,8,8,0,0,0,0,
],
[
    7,3,3,3,3,3,3,3,3,3,3,3,7,
    0,7,7,7,5,5,5,5,5,7,7,7,0,
    0,0,0,7,7,7,7,7,7,7,0,0,0,
    0,0,0,0,8,8,8,8,8,0,0,0,0,
    0,7,7,7,5,5,5,5,5,7,7,7,0,
    0,0,0,7,7,7,7,7,7,7,0,0,0,
    0,0,0,0,8,8,8,8,8,0,0,0,0,
    0,0,0,7,7,7,7,7,7,7,0,0,0,
    7,3,3,3,3,3,3,3,3,3,3,3,7,
],
[
    7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,2,2,2,2,2,2,2,7,7,7,
    0,7,7,7,5,5,5,5,5,7,7,7,0,
    0,0,0,7,7,7,7,7,7,7,0,0,0,
    0,0,0,0,7,7,7,7,7,0,0,0,0,
    7,7,0,0,7,7,7,7,7,0,0,7,7,
    7,7,0,0,2,2,2,2,2,0,0,7,7,
    7,7,0,0,1,1,1,1,1,0,0,7,7,
]

];

var bg = new PIXI.Sprite.fromImage("res/dazk/bg2.png");
app.stage.addChild(bg);

var gan = new PIXI.Sprite.fromImage("res/dazk/img_36.png");
app.stage.addChild(gan);
gan.anchor.x = 0.5;
gan.anchor.y = 0.5;
gan.x = 200;
gan.y = 700;

// ui
var uiBg = new PIXI.Sprite.fromImage("res/dazk/ui-2_02.png");
app.stage.addChild(uiBg);
uiBg.x = 20;

//剩余砖块
var lastBlockNum = new PIXI.Text();
lastBlockNum.text = 100 + "";
app.stage.addChild(lastBlockNum);
lastBlockNum.x = 310;
lastBlockNum.y = 28;

//得分
var scoreTxt = new PIXI.Text();
scoreTxt.text = 0 + "";
app.stage.addChild(scoreTxt);
scoreTxt.x = 200;
scoreTxt.y = 28;

//倒计时
var timeTxt = new PIXI.Text();
timeTxt.text = 0 + "";
app.stage.addChild(timeTxt);
timeTxt.x = 60;
timeTxt.y = 740;

//剩余球数量
var lastBall = new PIXI.Sprite.fromImage("res/dazk/qiu_32.png");
app.stage.addChild(lastBall);
lastBall.x = 320;
lastBall.y = 745;

//剩余球
var lastBallTxt = new PIXI.Text();
lastBallTxt.text = " x " + lastBallNum;
app.stage.addChild(lastBallTxt);
lastBallTxt.x = 350;
lastBallTxt.y = 740;

//当前关卡
var currLevelTxt = new PIXI.Text();
currLevelTxt.text = level + " / " + blockLevelArr.length;
app.stage.addChild(currLevelTxt);
currLevelTxt.x = 85;
currLevelTxt.y = 28;

//提示:点击屏幕发射弹珠
var tip01Txt = new PIXI.Text("点击屏幕发射小球\n请以最快的速度通关");
app.stage.addChild(tip01Txt);
tip01Txt.x = 140;
tip01Txt.y = 560;
tip01Txt.visible = false;

//------------ ui -------------
var startUI = new PIXI.Sprite.fromImage("res/dazk/start/kaishi-img.png");
app.stage.addChild(startUI);

var startBtn = new PIXI.Sprite.fromImage("res/dazk/start/kaishi_79.png");
startUI.addChild(startBtn);
startBtn.x = 100;
startBtn.y = 440;
startBtn.interactive = true;
startBtn.on("click", startGame);
startBtn.on("touchstart", startGame);

bg.interactive = true;
bg.on("mousemove", move);
bg.on("touchmove", move);

function move(event){
    
    

    if(gameType == 0) {
    
    
        return;
    }

    var pos = event.data.getLocalPosition(app.stage);
    gan.x = pos.x;

    if(gan.x > 420) {
    
    
        gan.x = 420;
    }
    if(gan.x < 70) {
    
    
        gan.x = 70;
    }
}







var blockNum = 13;
var blockArr = [];

function startGame() {
    
    
    gameType = 1;
    nextLevel();
    startUI.visible = false;
    tip01Txt.visible = true;
}


//开始下一关
function nextLevel() {
    
    

    isBullet = false;
    lastBallNum += ballArr.length;
    lastBallTxt.text = " x " + lastBallNum;

    //清除所有球
    for(var i = ballArr.length - 1; i >= 0; i --) {
    
    
        var ball = ballArr[i];
        ball.remove();
        ballArr.splice(i, 1);
    }

    //清除所有子弹
    for(var i = bulletArr.length - 1; i >= 0; i --) {
    
    
        var bullet = bulletArr[i];
        bullet.remove();
        bulletArr.splice(i, 1);
    }

    var blockLevel = blockLevelArr[level];
    for(var i = 0; i < blockLevel.length; i++) {
    
    
    
        if(blockLevel[i] == 0) {
    
    
            continue;
        }
        var y = parseInt(i / blockNum) * 33 + 125;
        var x = i % blockNum * 33 + 50;
    
        var block = new Block();
        block.init(blockLevel[i], x, y);
        blockArr.push(block);
    
    }
    
    lastBlockNum.text = blockArr.length;

    level ++;

    currLevelTxt.text = level + " / " + blockLevelArr.length;
}



var ballArr = [];
function addBallClick() {
    
    
    if(lastBallNum <= 0) {
    
    
        return;
    }

    addBall();

    lastBallNum --;
    lastBallTxt.text = " x " + lastBallNum;
}

function addBall() {
    
    
    var ball = new Ball();
    ball.init();
    ballArr.push(ball);
}

var itemArr = [];
function addItem(x, y) {
    
    
    var item = new Item();
    var type = parseInt(Math.random() * 4) + 1;
    item.init(type, x, y);
    itemArr.push(item);
}

function animate() {
    
    
    
    if(gameType == 0) {
    
    
        return;
    }

    for(var i = ballArr.length - 1; i >= 0; i --) {
    
    
        var ball = ballArr[i];
        ball.animate();

        if(ball.img.y > 800) {
    
    
            ball.remove();
            ballArr.splice(i, 1);

            if(ballArr.length == 0 && lastBallNum == 0) {
    
    
                over();
            }
        }
    }

    for(var i = itemArr.length - 1; i >= 0; i --) {
    
    
        var item = itemArr[i];
        item.animate(i);

        if(item.img.y > 800) {
    
    
            item.remove();
            itemArr.splice(i, 1);
        }
    }

    crash();

    time ++;
    timeTxt.text = "用时 : " + (time / 60).toFixed(2) + " s";

    addBullet();

    for(var i = bulletArr.length - 1; i >= 0; i --) {
    
    
        var bullet = bulletArr[i];
        bullet.animate();
        if(bullet.img.y < 110) {
    
    
            bullet.remove();
            bulletArr.splice(i, 1);
        }
    }

    if(ballArr.length == 0) {
    
    
        tip01Txt.visible = true;
    } else {
    
    
        tip01Txt.visible = false;
    }

}
app.ticker.add(animate);

//背景点击事件
bg.interactive = true;
bg.on("click", addBallClick);
bg.on("touchstart", addBallClick);


var bulletArr = [];
var bulletSubTime = 45;
//发射子弹
function addBullet() {
    
    
    if(isBullet == false) {
    
    
        return;
    }

    if(bulletSubTime == 0) {
    
    
        var bullet = new Bullet();
        bullet.init(gan.x + 30, gan.y - 20);
        bulletArr.push(bullet);
        
        var bullet = new Bullet();
        bullet.init(gan.x - 30, gan.y - 20);
        bulletArr.push(bullet);

        bulletSubTime = 45;
    }
    bulletSubTime --;
}

function addAllBullet() {
    
    

    for(var i = 0; i < 13; i ++) {
    
    
        var bullet = new Bullet();
        bullet.init(i * 32 + 50, 700);
        bulletArr.push(bullet);
    }
    
}

function crash() {
    
    

    //球与方块碰撞
    for(var i = 0; i < ballArr.length; i ++) {
    
    
        var ball = ballArr[i];
        for(var j = blockArr.length - 1; j >= 0; j --) {
    
    
            var block = blockArr[j];
            
            var isCrash = checkCrash(ball, block);
            if(isCrash == true) {
    
    

                //添加道具
                if(Math.random() * 100 > 90) {
    
    
                    addItem(block.img.x, block.img.y);
                }

                if(block.crash() == true) {
    
    
                    block.remove();
                    blockArr.splice(j, 1);
                    lastBlockNum.text = blockArr.length;
                    //更新得分等
                    score += 100;
                    scoreTxt.text = score;
                }
               
                ball.direction(block);

                //验证是否结束,切换关卡
                if(isOver() == true) {
    
    
                    return;
                }
                
            }
        }
    }

    //子弹与方块碰撞
    for(var i = 0; i < bulletArr.length; i ++) {
    
    
        var bullet = bulletArr[i];
        for(var j = blockArr.length - 1; j >= 0; j --) {
    
    
            var block = blockArr[j];
            
            var isCrash = checkCrash(bullet, block);
            if(isCrash == true) {
    
    

                //添加道具
                if(Math.random() * 100 > 90) {
    
    
                    addItem(block.img.x, block.img.y);
                }
                if(block.crash() == true) {
    
    
                    block.remove();
                    blockArr.splice(j, 1);
                    lastBlockNum.text = blockArr.length;
                    //更新得分等
                    score += 100;
                    scoreTxt.text = score;
                }
                

                bullet.remove();
                bulletArr.splice(i, 1);

                //验证是否结束,切换关卡
                if(isOver() == true) {
    
    
                    return;
                }

                break;
                
            }
        }
    }

}

function isOver() {
    
    

    if(blockArr.length == 0) {
    
    
        //检测是否存在下一关
        if(level <= blockLevelArr.length - 1) {
    
    
            nextLevel();
            return true;
        } else {
    
    

            over();
        }

    }
    return false;
}

function over() {
    
    

    gameType = 0;

    var overUI = new PIXI.Sprite.fromImage("res/dazk/end/jieshu-bg_21.png");
    app.stage.addChild(overUI);
    overUI.x = 70;
    overUI.y = 200;

    //关卡
    var currLevelTxt = new PIXI.Text();
    currLevelTxt.text = level + " / " + blockLevelArr.length;
    overUI.addChild(currLevelTxt);
    currLevelTxt.x = 180;
    currLevelTxt.y = 140;

    //得分
    var scoreTxt = new PIXI.Text();
    scoreTxt.text = score + "";
    overUI.addChild(scoreTxt);
    scoreTxt.x = 200;
    scoreTxt.y = 203;

    //时间
    var timeTxt = new PIXI.Text();
    timeTxt.text = time + " s";
    overUI.addChild(timeTxt);
    timeTxt.x = 200;
    timeTxt.y = 266;

    //最佳时间
    var bestTimeTxt = new PIXI.Text();
    bestTimeTxt.text = "120.00 s";
    overUI.addChild(bestTimeTxt);
    bestTimeTxt.x = 190;
    bestTimeTxt.y = 328;

    var restartBtn = new PIXI.Sprite.fromImage("res/dazk/end/cxks_95.png");
    overUI.addChild(restartBtn);
    restartBtn.x = 140;
    restartBtn.y = 400;
    restartBtn.interactive = true;
    restartBtn.on("click", restart);
    restartBtn.on("touchstart", restart);

}

function restart() {
    
    
    window.location.reload();
}

function checkCrash(a1, a2) {
    
    
    var img1 = a1.img;
    var img2 = a2.img;
    var a = (img1.x - img2.x) * (img1.x - img2.x) + (img1.y - img2.y) * (img1.y - img2.y);
    if(a < (a1.r + a2.r) * (a1.r + a2.r)) {
    
    
        return true;
    }
    return false;
}


//道具效果 - 火球
function fireBall() {
    
    

    for(var i = ballArr.length - 1; i >= 0; i --) {
    
    
        var ball = ballArr[i];
        ball.fire();
    }
}




// ------------ 对象分界线 -------------
//小球
function Ball() {
    
    
    
    this.img = null;
    this.r = 10;
    this.speed = 5;
    this.angle = Math.random() * 100 + 220;

    this.speedX = 0;
    this.speedY = 0;

    this.isFire = false;

    this.init = function(type) {
    
    
        var url = "res/dazk/qiu_32.png";
        this.img = new PIXI.Sprite.fromImage(url);
        this.img.anchor.x = 0.5;
        this.img.anchor.y = 0.5;
        app.stage.addChild(this.img);

        this.img.x = gan.x;
        this.img.y = gan.y - 20;

        this.changeAngle();
    }

    this.fire = function() {
    
    
        this.isFire = true;
        this.img.texture = new PIXI.Texture.fromImage("res/dazk/qiu-2_77.png");
    }
    
    this.animate = function() {
    
    
        this.move();
    }

    this.changeAngle = function() {
    
    

        var a = this.angle / 180 * 3.14;
        this.speedX = Math.cos(a) * this.speed;
        this.speedY = Math.sin(a) * this.speed;

        this.speed += 0.01;
    }

    this.move = function() {
    
    
        this.img.x += this.speedX;
        this.img.y += this.speedY;

        if(this.img.y < 120) {
    
    
            this.angleV();
        }
        if(this.img.x > 465) {
    
    
            this.angleH();
        }
        if(this.img.x < 30) {
    
    
            this.angleH();
        }

        if(this.img.y > 680 && this.img.y < 700 && this.img.x > (gan.x - 55) && this.img.x < (gan.x + 55) && this.speedY > 0) {
    
    
            //计算角度
            this.angle = 360 - ((gan.x + 50) - this.img.x) * 1.8;
            if(this.angle > 320) {
    
    
                this.angle = 320;
            }
            if(this.angle < 220) {
    
    
                this.angle = 220;
            }
            this.changeAngle();
        }

    }

    this.angleV = function() {
    
    
        
        this.angle -= this.angle * 2;
        this.changeAngle();
    }

    this.angleH = function() {
    
    

        this.angle = 180 - this.angle; 
        this.changeAngle();
    }

    this.direction = function(a1) {
    
    
        if(this.isFire == true) {
    
    
            return;
        }
        var img1 = a1.img;
        //处理小球反弹方向
        if(this.img.y > img1.y && this.img.x < img1.x + a1.r && this.img.x > img1.x - a1.r) {
    
    
            this.angleV();
        } else if(this.img.x > img1.x && this.img.y < img1.y + a1.r && this.img.y > img1.y - a1.r) {
    
    
            this.angleH();
        } else if(this.img.x < img1.x && this.img.y < img1.y + a1.r && this.img.y > img1.y - a1.r) {
    
    
            this.angleH();
        } else if(this.img.y < img1.y && this.img.x < img1.x + a1.r && this.img.x > img1.x - a1.r) {
    
    
            this.angleV();
        }

    }

    this.remove = function() {
    
    
        app.stage.removeChild(this.img);
    }

}


//方块
function Block() {
    
    

    this.img = null;
    this.r = 16;
    this.hp = 1;
    this.type = 0;

    this.init = function(type, x, y) {
    
    
        this.type = type;

        var url = "res/dazk/zhuankuai-1_06.png";
        if(type == 1) {
    
    
            url = "res/dazk/zhuankuai-1_06.png";
        } else if(type == 2) {
    
    
            url = "res/dazk/zhuankuai-2_08.png";
        } else if(type == 3) {
    
    
            url = "res/dazk/zhuankuai-3_10.png";
        } else if(type == 4) {
    
    
            url = "res/dazk/zhuankuai-4_12.png";
        } else if(type == 5) {
    
    
            url = "res/dazk/zhuankuai-5_14.png";
        } else if(type == 6) {
    
    
            url = "res/dazk/zhuankuai-6_16.png";
        } else if(type == 7) {
    
    
            url = "res/dazk/zhuankuai-7_18.png";
        } else if(type == 8) {
    
    
            url = "res/dazk/zhuankuai-8-1_41.png";
            this.hp = 2;
        }

        this.img = new PIXI.Sprite.fromImage(url);
        this.img.anchor.x = 0.5;
        this.img.anchor.y = 0.5;
        app.stage.addChild(this.img);

        this.img.x = x;
        this.img.y = y;
    }

    this.crash = function() {
    
    
        this.hp --;
        if(this.type == 8) {
    
    
            this.img.texture = new PIXI.Texture.fromImage("res/dazk/zhuankuai-8-2_43.png");
        }
        if(this.hp == 0) {
    
    
            return true;
        }
        return false;
    }

    this.remove = function() {
    
    
        app.stage.removeChild(this.img);
    }

}

function Item() {
    
    

    this.img = null;
    this.type = 0;
    this.r = 15;

    this.init = function(type, x, y) {
    
    
        this.type = type;
        var url = "res/dazk/daoju-qiu1_32.png";
        if(type == 1) {
    
    
            url = "res/dazk/daoju-qiu1_32.png";
        } else if(type == 2) {
    
    
            url = "res/dazk/daoju-qiu2_60.png";
        } else if(type == 3) {
    
    
            url = "res/dazk/daoju-zidan1_66.png";
        } else if(type == 4) {
    
    
            url = "res/dazk/daoju-zidan2_69.png";
        } 

        this.img = new PIXI.Sprite.fromImage(url);
        this.img.anchor.x = 0.5;
        this.img.anchor.y = 0.5;
        this.img.x = x;
        this.img.y = y;
        app.stage.addChild(this.img);
    }

    this.animate = function(i) {
    
    
        this.move(i);
    }

    this.move = function(i) {
    
    
        this.img.y += 2;

        if(this.img.y > 680 && this.img.y < 700 && this.img.x > (gan.x - 55) && this.img.x < (gan.x + 55)) {
    
    
            this.effect();
            itemArr.splice(i, 1);
            this.remove();
        }
    }

    this.effect = function() {
    
    
        if(this.type == 1) {
    
    
            addBall();
            addBall();
            addBall();
            lastBallNum ++;
            lastBallTxt.text = " x " + lastBallNum;
        } else if(this.type == 2) {
    
    
            fireBall();
        } else if(this.type == 3) {
    
    
            isBullet = true;
        } else if(this.type == 4) {
    
    
            addAllBullet();
        }
    }

    this.remove = function() {
    
    
        app.stage.removeChild(this.img);
    }
}

function Bullet() {
    
    
    this.img = null;
    this.r = 6;

    this.init = function(x, y) {
    
    

        var url = "res/dazk/zidan_74.png";
        this.img = new PIXI.Sprite.fromImage(url);
        this.img.anchor.x = 0.5;
        this.img.anchor.y = 0.5;
        this.img.x = x;
        this.img.y = y;
        app.stage.addChild(this.img);

    }

    this.animate = function() {
    
    
        this.move();
    }

    this.move = function() {
    
    
        this.img.y -= 6;
    }

    this.remove = function() {
    
    
        this.img.parent.removeChild(this.img);
    }

}

Guess you like

Origin blog.csdn.net/fujian87232/article/details/122851712