MegaBall2D

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск


Описание

Игра, где нужно попасть левым мячиком в правый. Присутствуют отскоки от стенок и гравитация. Радиус мячиков уменьшается с каждым уровнем. Если левый мячик уже никак не достигнет правого, то игра начинается заново.

Исполнитель: Грешников П.С.

Группа 13632/1 Кафедра Теоретической механики.

Файл: [[1]]

Математическая модель

Рассматриваем левый мячик как тело, брошенное под углом к горизонту.


Визуализация

Код программы

window.addEventListener("load",main,false); function main(){

var ctx = example_canvas.getContext("2d");
var h=example_canvas.height;
var w=example_canvas.width;
var lvl=1;
var r=40*10/(10+lvl);
var dt=0.05;
var fps=100;
var flag=false;
var x=250;
var y=h/2;
var x0=0;
var y0=0;
var x_k=250;
var y_k=800;
var vx=0;
var vy=0;
var padding ={x:0, y:0};
var defaultColor="black";
var TouchColor="red";
var XSL;
var YSL;
var start=false;
var imp=0;


setInterval(control,1000/fps);

function get_mouse_coords(e){ var m={}; // объявление пустого объекта var rect = example_canvas.getBoundingClientRect(); m.x=e.clientX-rect.left; m.y=e.clientY-rect.top; return m; }

example_canvas.onmousedown=function(e){ m=get_mouse_coords(e); var dx=m.x-x; var dy=m.y-y; padding.x=dx; padding.y=dy; if (Math.sqrt(dx*dx+dy*dy)<r) { x0=m.x; y0=m.y; flag = true; ctx.fillStyle=TouchColor; draw(); } }

	star();

example_canvas.onmouseup=function(e){ flag = false; ctx.fillStyle=defaultColor; draw(); m=get_mouse_coords(e); var dx=m.x-x; var dy=m.y-y; padding.x=dx; padding.y=dy; if (Math.sqrt(dx*dx+dy*dy)<r) { x_k=m.x; y_k=m.y; speed(); start=true; }

}

example_canvas.onmousemove = function(e){ if (flag) { m=get_mouse_coords(e); x=m.x-padding.x; y=m.y-padding.y; draw(); ctx.beginPath(); ctx.moveTo(Math.round(x),Math.round(y)); ctx.lineTo(Math.round(x0),Math.round(y0)); ctx.stroke(); } }

function phys(){

 if   (vy*vy<(y-YSL-2*r)) console.log('imp');

vy+=100*dt; x=x+vx*dt; y=y+vy*dt+100*dt*dt/2; if(x>=w-(r)) { vx=(-0.9)*Math.abs(vx); } else if(x<=(r)) vx=0.9*Math.abs(vx); if(y>=h-(r)){ vy=-0.9*Math.abs(vy); if (Math.abs(vy)<10){ vy=-150*dt; } } else if(y<=(r)) vy=0.9*Math.abs(vy);

if ((x >w/2-5-r)&&(x<w/2)&&(y>h*1/3-r)) { vx=-0.9*Math.abs(vx); } if ((x>w/2)&&(x<w/2+5+r)&&(y>h*1/3-r)){ vx=0.9*Math.abs(vx); } if ((x>w/2-5)&&(x<w/2+5)&&(y<h/3-r+5)&&(y>h/3-r)){ vy=-1000*Math.abs(vx); } }

function speed(){ vx=-(x_k-x0)*2; vy=-(y_k-y0)*2; }

function draw() { ctx.clearRect(0,0,w,h); ctx.beginPath(); ctx.arc(x,y,r,0,2*Math.PI); ctx.arc(XSL,YSL,r,0,2*Math.PI); ctx.moveTo(Math.round(x0),Math.round(y0)); ctx.lineTo(x,y); ctx.font = 'bold 30px sans-serif'; ctx.strokeText("CURRENT LEVEL:", 600, 100); ctx.strokeText(lvl, 900, 100);


ctx.fill(); ctx.beginPath(); ctx.moveTo(w/2-5,h); ctx.lineTo(w/2-5,h/3); ctx.moveTo(w/2+5,h/3); ctx.lineTo(w/2+5,h); ctx.moveTo(w/2+5,h/3); ctx.lineTo(w/2-5,h/3); ctx.stroke(); }


draw();

function control() { if (start) phys(); draw(); confront();

     imposible();

}

function star(){ XSL=Math.random()*(500-2*(r))+w/2+r; YSL=Math.random()*(h-2*(r))+r; }

function confront(){ if (((x-XSL)*(x-XSL)+(y-YSL)*(y-YSL)<=4*(r)*(r))&&(start)){ levelup(); } }

function levelup(){ x=250; y=h/2; vx=0; vy=0; lvl++;

   r=40*10/(10+lvl);

star(); start=false; }

 function restart(){

x=250; y=h/2; vx=0; vy=0; lvl=1;

   r=40*10/(10+lvl);

star(); start=false; }

function imposible() {

   if ((start)&&((vy*vy<(y-YSL-2*r))||((x<w/2)&&(vy*vy<(2*y/3+r))))) {
     imp++;
   }
   if (imp>40) {
     imp=0;
     restart();
   }

}

}