Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
− |
| |
− |
| |
| == Описание == | | == Описание == |
| Игра, где нужно попасть левым мячиком в правый. Присутствуют отскоки от стенок и гравитация. Радиус мячиков уменьшается с каждым уровнем. Если левый мячик уже никак не достигнет правого, то игра начинается заново. | | Игра, где нужно попасть левым мячиком в правый. Присутствуют отскоки от стенок и гравитация. Радиус мячиков уменьшается с каждым уровнем. Если левый мячик уже никак не достигнет правого, то игра начинается заново. |
− |
| |
− | Исполнитель: [http://tm.spbstu.ru/%D0%93%D1%80%D0%B5%D1%88%D0%BD%D0%B8%D0%BA%D0%BE%D0%B2_%D0%9F%D0%B0%D0%B2%D0%B5%D0%BB Грешников П.С.]
| |
− |
| |
− | Группа 13632/1 Кафедра Теоретической механики.
| |
− |
| |
− | Файл: [[http://tm.spbstu.ru/htmlets/Greshnikov%20PS/KR_JS.docx]]
| |
− |
| |
| == Математическая модель == | | == Математическая модель == |
− |
| |
| Рассматриваем левый мячик как тело, брошенное под углом к горизонту. | | Рассматриваем левый мячик как тело, брошенное под углом к горизонту. |
| | | |
− | | + | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Greshnikov_PS/BB.html |width=1550 |height=600 |border=1 }} |
− | == Визуализация ==
| |
− | | |
− | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Greshnikov%20PS/BB.html |width=1050 |height=600 |border=1 }} | |
− | | |
− | == Код программы ==
| |
− | <div class="mw-collapsible mw-collapsed">
| |
− | <syntaxhighlight lang=javascript>
| |
− | 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();
| |
− | }
| |
− | }
| |
− | }
| |
− | </syntaxhighlight>
| |
− | <div>
| |