JavaScriptでブロック崩しゲーム作成|HTML5&Canvasで簡単実装
JavaScriptでブラウザ上で遊べるブロック崩しゲームを作成しました!
マウスやタッチ操作でバーを移動し、クリックまたはタップでゲームを開始できます。
コピペOKのソースコード付きなので、すぐに実装可能!
ぜひ、ブロック崩しの爽快感をブラウザで体験してみてください!
ソースコード
ソースコードは以下です。
<div id="blockmain"></div>
<script>
class TBlock{
init(){
this.racket={x:this.wh/2-30, y:this.wh-60, w:60, h:20};
//ボールは中心
this.ball={
x:this.racket.x + this.racket.w/2,
y:this.racket.y-6,
r:6,
rx:+(Math.random()*0.1-0.05), ry:-4,
speed:4,
stopping:true,
};
}
stageinit(){
for(let i=0;i<this.stages[this.stageno].length;i++){
this.stage[i]=[];
this.stage[i].x = this.stages[this.stageno][i].x;
this.stage[i].y = this.stages[this.stageno][i].y;
this.stage[i].w = this.stages[this.stageno][i].w;
this.stage[i].h = this.stages[this.stageno][i].h;
this.stage[i].hp= this.stages[this.stageno][i].hp;
}
this.stagehp=this.stageshp[this.stageno];
}
constructor(elm){
this.wh=600;
this.div=elm;
this.div.style.cssText="margin:0 auto;padding:0;max-width:100%;width:600px;height:600px;box-sizing:border-box;border:1px solid #000;";
this.can=document.createElement("canvas");
this.can.style.cssText="margin:0;padding:0;width:100%;height:100%;";
this.can.setAttribute("width" , this.wh+"px");
this.can.setAttribute("height", this.wh+"px");
this.ctx=this.can.getContext("2d",{willReadFrequently:true});
this.div.appendChild(this.can);
this.blockcolor=["none","blue", "green", "red", "orange", "yellow"];
this.init();
/*
横 5 50 10 ・・・ 50 10 50 5
縦 20 20 20 20 20 20 20 20
*/
this.stageno=0;
this.stageshp=[];
this.stage=[];
this.stages=[];
let ct;
ct=0;
this.stageshp[0]=0;
this.stages[0]=[];
for(let y=0;y<8;y++){
for(let x=0;x<8;x++){
this.stages[0][ct]=[];
this.stages[0][ct].x = 0+x*75;
this.stages[0][ct].y = 40+y*40;
this.stages[0][ct].w = 70;
this.stages[0][ct].h = 40;
this.stages[0][ct].hp = 1+Math.floor(Math.random()*3);
this.stageshp[0]+=this.stages[0][ct].hp;
ct++;
}
}
ct=0;
this.stageshp[1]=0;
this.stages[1]=[];
for(let y=0;y<9;y++){
for(let x=0;x<8;x++){
this.stages[1][ct]=[];
this.stages[1][ct].x = 0+x*75;
this.stages[1][ct].y = 40+y*40;
this.stages[1][ct].w = 70;
this.stages[1][ct].h = 40;
this.stages[1][ct].hp = 2+Math.floor(Math.random()*2);
this.stageshp[1]+=this.stages[1][ct].hp;
ct++;
}
}
ct=0;
this.stageshp[2]=0;
this.stages[2]=[];
for(let y=0;y<10;y++){
for(let x=0;x<8;x++){
this.stages[2][ct]=[];
this.stages[2][ct].x = 0+x*75;
this.stages[2][ct].y = 40+y*40;
this.stages[2][ct].w = 70;
this.stages[2][ct].h = 40;
this.stages[2][ct].hp = 2+Math.floor(Math.random()*2);
this.stageshp[2]+=this.stages[2][ct].hp;
ct++;
}
}
ct=0;
this.stageshp[3]=0;
this.stages[3]=[];
for(let y=0;y<10;y++){
for(let x=0;x<8;x++){
this.stages[3][ct]=[];
this.stages[3][ct].x = 0+x*75;
this.stages[3][ct].y = 40+y*40;
this.stages[3][ct].w = 70;
this.stages[3][ct].h = 40;
this.stages[3][ct].hp = 3+Math.floor(Math.random()*3);
this.stageshp[3]+=this.stages[3][ct].hp;
ct++;
}
}
ct=0;
this.stageshp[4]=0;
this.stages[4]=[];
for(let y=0;y<11;y++){
for(let x=0;x<8;x++){
this.stages[4][ct]=[];
this.stages[4][ct].x = 0+x*75;
this.stages[4][ct].y = 40+y*40;
this.stages[4][ct].w = 70;
this.stages[4][ct].h = 40;
this.stages[4][ct].hp = 4+Math.floor(Math.random()*2);
this.stageshp[4]+=this.stages[4][ct].hp;
ct++;
}
}
this.stageinit();
document.documentElement.addEventListener("mousemove",function(){
let newx=(event.clientX-this.can.getBoundingClientRect().left)*this.wh/this.styleWidth;
if(newx<0){newx=0;}
if(newx>(this.wh-this.racket.w)){newx=this.wh-this.racket.w;}
if(this.ball.stopping){
let subx=newx-this.racket.x;
this.ball.x+=subx;
}
this.racket.x=newx;
//console.log(newx);
}.bind(this));
document.documentElement.addEventListener("mousedown",function(){
this.ball.stopping=false;
}.bind(this));
document.documentElement.addEventListener("touchmove",function(){
let newx=(event.touches[0].pageX-this.can.getBoundingClientRect().left)*this.wh/this.styleWidth;
if(newx<0){newx=0;}
if(newx>(this.wh-this.racket.w)){newx=this.wh-this.racket.w;}
if(this.ball.stopping){
let subx=newx-this.racket.x;
this.ball.x+=subx;
}
this.racket.x=newx;
//console.log(newx);
}.bind(this));
//ウィンドウ リサイズ時
window.addEventListener('resize',function(){
this.resize();
}.bind(this));
this.resize();
setInterval(this.interval.bind(this),16);
}
interval(){
if(!this.ball.stopping){
let nx=this.ball.x+this.ball.rx;
let ny=this.ball.y+this.ball.ry;
if(nx<this.ball.r||nx>(this.wh-this.ball.r)){
this.ball.rx=-this.ball.rx;
}else if(ny<this.ball.r){
this.ball.ry=-this.ball.ry;
}else if(ny>this.wh){
this.init();
}else if(
(nx>=this.racket.x)&&(nx<=(this.racket.x+this.racket.w))&&
(ny>=this.racket.y)&&(ny<=(this.racket.y+this.racket.h))&&
(this.ball.ry>0)
){
let subx=(nx-this.racket.x-this.racket.w/2+this.ball.rx)/this.racket.w *2/3 +(Math.random()*0.06-0.03);
this.ball.rx=-Math.cos((subx+0.5)*Math.PI)*this.ball.speed;
this.ball.ry=-Math.sin((subx+0.5)*Math.PI)*this.ball.speed;
}else{
let collision=false;
for(let i=0;i<this.stage.length;i++){
if( (this.stage[i].hp>0)&&
(this.stage[i].x<=nx)&&
((this.stage[i].x+this.stage[i].w)>=nx)&&
(this.stage[i].y<=ny)&&
((this.stage[i].y+this.stage[i].h)>=ny)
){
collision=true;
this.stage[i].hp--;
this.ball.speed+=0.01;
if(Math.abs(this.ball.rx)<0.001){
this.ball.ry=-this.ball.ry;
}else if( (this.stage[i].x>=this.ball.x)&&((this.stage[i].x+this.stage[i].w)<=this.ball.x) ){
this.ball.ry=-this.ball.ry;
}else{
let y=0;
//y=(y2-y1)(x-x1)/(x2-x1)+y1
if(this.ball.rx>0){
y=(ny-this.ball.y)*(this.stage[i].x-this.ball.x)/(nx-this.ball.x)+this.ball.y;
}else{
y=(ny-this.ball.y)*((this.stage[i].x+this.stage[i].w)-this.ball.x)/(nx-this.ball.x)+this.ball.y;
}
if( (y<=this.stage[i].y) || (y>=(this.stage[i].y+this.stage[i].h)) ){
this.ball.ry=-this.ball.ry;
}else{
this.ball.rx=-this.ball.rx;
}
}
break;
}
}
if(collision){
this.stagehp--;
if(this.stagehp==0){
this.stageno++;
if(this.stageno==this.stages.length){this.stageno=0;}
this.init();
this.stageinit();
}
}else{
this.ball.x+=this.ball.rx;
this.ball.y+=this.ball.ry;
}
}
}
this.draw();
}
draw(){
//キャンバスのクリア
this.ctx.clearRect(0,0,this.wh,this.wh);
this.ctx.fillStyle="rgb(220,220,220)";
this.ctx.fillRect(0,0,this.wh,this.wh);
for(let i=0;i<this.stage.length;i++){
if(this.stage[i].hp>0){
this.ctx.fillStyle=this.blockcolor[this.stage[i].hp];
this.ctx.fillRect(
this.stage[i].x,
this.stage[i].y,
this.stage[i].w,
this.stage[i].h
);
this.ctx.lineWidth=2;
this.ctx.strokeStyle="black";
this.ctx.strokeRect(
this.stage[i].x,
this.stage[i].y,
this.stage[i].w,
this.stage[i].h
);
}
}
this.ctx.fillStyle="black";
this.ctx.fillRect(this.racket.x,this.racket.y,this.racket.w,this.racket.h);
this.ctx.fillStyle="black";
this.ctx.beginPath();
this.ctx.arc(this.ball.x, this.ball.y, this.ball.r, 0,Math.PI*2);
this.ctx.fill();
}
resize(){
let style=window.getComputedStyle(this.div);
this.div.style.height=style.width;
this.styleWidth=parseFloat(style.width);
}
}
window.addEventListener("load",function(){
block=new TBlock(document.querySelector("#blockmain"));
});
</script>
