MegaBall2D — различия между версиями
(→Описание) |
(→top) |
||
Строка 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(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
== Описание == | == Описание == | ||
Игра, где нужно попасть левым мячиком в правый. Присутствуют отскоки от стенок и гравитация. Радиус мячиков уменьшается с каждым уровнем. Если левый мячик уже никак не достигнет правого, то игра начинается заново. | Игра, где нужно попасть левым мячиком в правый. Присутствуют отскоки от стенок и гравитация. Радиус мячиков уменьшается с каждым уровнем. Если левый мячик уже никак не достигнет правого, то игра начинается заново. |
Версия 11:56, 31 мая 2019
Код программы
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(); }
} }
Описание
Игра, где нужно попасть левым мячиком в правый. Присутствуют отскоки от стенок и гравитация. Радиус мячиков уменьшается с каждым уровнем. Если левый мячик уже никак не достигнет правого, то игра начинается заново.
Исполнитель: Грешников П.С.
Группа 13632/1 Кафедра Теоретической механики.
Файл: [[1]]
Математическая модель
Рассматриваем левый мячик как тело, брошенное под углом к горизонту.
Визуализация