HTML5_html5 튜토리얼 팁을 사용하여 간단하고 탄력 있는 공 게임 만들기

WBOY
풀어 주다: 2016-05-16 15:46:41
원래의
1865명이 탐색했습니다.

캔버스를 일주일 넘게 배우고 있는데 캔버스가 정말 재미있는 것 같아요. Canvas를 배우는 사람들은 아마도 나와 비슷한 생각을 가지고 있을 것이다. 그들은 게임을 쓰는 자세로 Canvas를 배운다. 따라서 운동학, 충돌 감지 및 몇 가지 간단한 알고리즘이 기본입니다. 게임을 한번도 만들어본 적이 없어서 배우기가 정말 어려웠습니다. 오늘은 캔버스를 사용하여 가장 간단한 중력 및 충돌 감지 기능을 사용하여 가장 간단한 탄력 있는 볼 게임을 작성하는 방법에 대해 이야기하겠습니다.

먼저 DEMO로 이동합니다. 탄력 있는 공 DEMO (캔버스의 빈 영역을 클릭하면 공의 속도가 달라집니다.)

【공 객체 생성】

첫 번째 단계는 공 개체를 만들고 공의 생성자를 작성하는 것입니다.

코드 복사
코드는 다음과 같습니다. 다음과 같습니다:

var Ball = function(x, y, r, color){
this.x = x;
this.y = y;
oldx. = x;
this.oldy = y;
this.vx = 0;
this.vy = 0;this.radius = r;
this.color = color;
}

공의 속성은 매우 간단합니다. xy는 공의 좌표이고, vx와 vy는 공의 초기 수평 속도와 초기 수직 속도입니다. radius는 공의 반경, color는 공의 색상(다른 공을 구별하기 위해), oldx 및 oldy는 이전 프레임에서 공의 위치를 ​​기록하고 공 간의 충돌 후 위치 수정에 사용됩니다. 나중에는 (실제로는 쓸모가 없음) 위에서는 위치보정을 직접 계산하는데, oldx를 이용해서 설정하면 굉장히 느슨해지겠지만, 기록을 하면 필연적으로 사용하게 된다.

공의 속성을 작성한 후 공 프로토타입에 공의 동작을 작성합니다.

코드 복사
코드는 다음과 같습니다:

Ball.prototype = {
Paint:function(){
ctx.save();
ctx.beginPath();
ctx .arc(this.x , this.y , this.radius , 0 , Math.PI*2);
ctx.fillStyle=this.color;
ctx.fill();
ctx .restore ();
this.moving = false;
},
run:function(t){
if(!this.candrod) {
this.paint();
return};
this.oldx = this.x;
this.oldy = this.y;


if(Math.abs(this.vx) < 0.01){
this.vx = 0;
}
else this.vx = this.vx>0? mocali*t : mocali*t;

this.vy = this.vy g * t;

this.x = t * this.vx * pxpm;
this.y = t * this.vy * pxpm;< /p>

if(this.y > canvas.height - ballRadius || this.y < ballRadius){
this.y = this.y < ballRadius : (canvas.height - ballRadius);
this.vy = -this.vy*collarg
}
if(this.x > canvas.width - ballRadius || this.x < ballRadius){
this.x = this .x < ballRadius ? ballRadius : (canvas.width - ballRadius);
this.derectionX = !this.derectionX;
this.vx = -this.vx*collarg;
}
this .paint();
},

}

공을 움직이는 방법은 두 가지뿐입니다. 첫 번째 방법은 직접 그리는 것이고, 두 번째 방법은 공의 움직임을 제어하는 ​​것입니다. t는 현재 프레임과 이전 프레임 사이의 시간 차이입니다. 공의 변위 증분을 얻기 위해 공 속도의 증분을 계산하는 데 사용되며, 이를 통해 공의 새로운 위치를 계산하고 공을 다시 그립니다. 새로운 위치가 얻어지면 공의 새로운 위치가 벽을 초과하는지 여부도 판단됩니다. 이를 초과하면 공이 리바운드될 수 있도록 속도가 수정됩니다.

두 번째 방법의 일부 상수 ballRadius =30, g = 9.8, mocali = 0.5, ball = [], collarg = 0.8, pxpm = canvas.width/20 의미는 분명합니다. ballradius는 공의 반경입니다. , g는 중력 가속도, mocali는 공기 저항에 의한 수평 감속도, ball은 작은 공 물체를 저장하는 데 사용되는 배열, 콜라겐은 탄성 계수입니다. pxpm은 픽셀과 미터 사이의 매핑으로 캔버스를 20미터 너비의 영역으로 처리합니다.

【충돌 감지】

공 객체를 생성한 후 공 간의 충돌 작성을 시작합니다.

코드 복사
코드는 다음과 같습니다.

함수 충돌(){
for(var i=0;i for(var j=0;j var b1 = 공[i],b2 = 공[j];
if(b1 !== b2){
var rc = Math.sqrt(Math.pow(b1.x - b2.x , 2) Math.pow(b1.y - b2.y , 2));
if(Math.ceil(rc) < (b1.radius b2.radius)){

//충돌 후 속도 증가분을 구합니다
var ax = ((b1.vx - b2.vx)*Math.pow((b1.x - b2.x) , 2) (b1.vy - b2.vy)*(b1.x - b2.x)*(b1.y - b2.y))/Math.pow(rc , 2)
var ay = ((b1.vy - b2.vy )*Math.pow((b1.y - b2.y) , 2) (b1.vx - b2.vx)*(b1.x - b2.x) (b1.y - b2.y))/Math. pow(rc, 2)

//공에 새로운 속도 부여
b1.vx = (b1.vx-ax)*collarg;
b1.vy = (b1.vy-ay)*collarg;
b2 .vx = (b2.vx ax)*collarg;
b2.vy = (b2.vy ay)*collarg;

//두 볼의 비스듬한 절단 위치를 구하고 강제로 비틀기
var clength = ((b1.radius b2.radius)-rc)/2;
var cx = clength * (b1 .x-b2 .x)/rc;
var cy = clength * (b1.y-b2.y)/rc;
b1.x = b1.x cx;
b1.y = b1 .y cy;
b2.x = b2.x-cx;
b2.y = b2.y-cy;
}
}
}
}
}


매 프레임마다 두 공의 중심 사이의 거리가 두 공의 반경의 합보다 작다면 두 공의 충돌 여부를 판단합니다. 공이 충돌했습니다. 그런 다음 두 공이 충돌한 후 속도의 변화를 계산합니다. ax와 ay는 속도의 변화입니다.
뒤에 있는 긴 공식은 다음과 같습니다.
2015512173816364.png (334×192)

구체적인 원리에 대해서는 다루지 않겠습니다. 원리를 알고 싶다면 작은 공 충돌의 알고리즘 설계를 클릭하세요. 다음 문단은 반복되는 충돌 감지로 인해 공이 정상적으로 튕겨 나가는 것을 방지하기 위한 것이므로, 두 공의 중심 사이의 거리를 계산한 후, 두 공의 경사 위치를 계산하고, 공의 위치를 ​​구한다. 두 개의 공이 수정되었습니다.

【모션 애니메이션】

마지막 단계:

코드 복사
코드는 다음과 같습니다.
< /p>

canvas.onclick = function(event){
event = event || window.event;
var x = event.clientX document.body.scrollLeft document.documentElement.scrollLeft - canvas.offsetLeft;
var y= event.clientY document.body.scrollTop document.documentElement.scrollTop - canvas.offsetTop;

balls.forEach(function(){
this.vx = (x - this.x)/20; //초기 속도 m/s
this.vy = (y - this.y) /20;
});
}

함수 애니메이션(){
ctx.save();
ctx.fillStyle = "rgba(255,255,255,0.2)";
ctx.fillRect(0,0,canvas.width,canvas .height)
ctx.restore();
// ctx.clearRect(0,0,canvas.width,canvas.height)

var t1 = new Date();
var t = (t1 - t0)/1000;
충돌();
balls.forEach(function(){
this.run (t);
});

t0 = t1;

if(창의 "requestAnimationFrame"){
requestAnimationFrame(animate);
}
else if(창의 "webkitRequestAnimationFrame"){
webkitRequestAnimationFrame(animate);
}
else if(창의 "msRequestAnimationFrame"){
msRequestAnimationFrame(animate);
}
else if(창의 "mozRequestAnimationFrame"){
mozRequestAnimationFrame(animate);
}
}
}

캔버스를 클릭하여 공에 초기 속도를 부여한 다음 애니메이션은 애니메이션의 각 프레임을 실행하는 데 사용되는 방법입니다. 위의 ctx.fillStyle = "rgba(255,255,255,0.2)"; ctx.fillRect(0,0,canvas.width,canvas.height) 는 공에 고스트 그림자를 추가하는 것입니다. 마음에 들지 않으면, ClearRect를 사용하여 직접 삭제하세요. 그런 다음 각 프레임의 시간 차이를 계산한 다음 작은 공 배열에서 작은 공 배열을 탐색하고 다시 그립니다. 그런 다음 충돌 감지를 위한 충돌 방법을 추가합니다. 애니메이션이 완성되었습니다.

이때 소스코드 주소는

로 작성되었습니다.

 https://github.com/whxaxes/canvas-test/blob/gh-pages/src/Other-demo/shotBall.html

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!