MegaBall2D — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
(→Описание) |
|||
(не показаны 4 промежуточные версии 2 участников) | |||
Строка 4: | Строка 4: | ||
Игра, где нужно попасть левым мячиком в правый. Присутствуют отскоки от стенок и гравитация. Радиус мячиков уменьшается с каждым уровнем. Если левый мячик уже никак не достигнет правого, то игра начинается заново. | Игра, где нужно попасть левым мячиком в правый. Присутствуют отскоки от стенок и гравитация. Радиус мячиков уменьшается с каждым уровнем. Если левый мячик уже никак не достигнет правого, то игра начинается заново. | ||
− | Исполнитель: [http://%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 | + | Исполнитель: [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 Кафедра Теоретической механики. | Группа 13632/1 Кафедра Теоретической механики. | ||
− | Файл: [[http:// | + | Файл: [[http://tm.spbstu.ru/htmlets/Greshnikov%20PS/KR_JS.docx]] |
== Математическая модель == | == Математическая модель == | ||
Строка 21: | Строка 21: | ||
== Код программы == | == Код программы == | ||
<div class="mw-collapsible mw-collapsed"> | <div class="mw-collapsible mw-collapsed"> | ||
+ | <syntaxhighlight lang=javascript> | ||
window.addEventListener("load",main,false); | window.addEventListener("load",main,false); | ||
function main(){ | function main(){ | ||
Строка 46: | Строка 47: | ||
var start=false; | var start=false; | ||
var imp=0; | 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){ | example_canvas.onmousedown=function(e){ | ||
m=get_mouse_coords(e); | m=get_mouse_coords(e); | ||
Строка 73: | Строка 69: | ||
} | } | ||
} | } | ||
− | |||
star(); | star(); | ||
− | |||
example_canvas.onmouseup=function(e){ | example_canvas.onmouseup=function(e){ | ||
flag = false; | flag = false; | ||
Строка 91: | Строка 85: | ||
start=true; | start=true; | ||
} | } | ||
− | |||
} | } | ||
− | |||
example_canvas.onmousemove = function(e){ | example_canvas.onmousemove = function(e){ | ||
if (flag) { | if (flag) { | ||
Строка 106: | Строка 98: | ||
} | } | ||
} | } | ||
− | |||
function phys(){ | function phys(){ | ||
if (vy*vy<(y-YSL-2*r)) console.log('imp'); | if (vy*vy<(y-YSL-2*r)) console.log('imp'); | ||
Строка 221: | Строка 212: | ||
} | } | ||
} | } | ||
+ | </syntaxhighlight> | ||
+ | <div> |
Текущая версия на 15:18, 19 июня 2019
Описание[править]
Игра, где нужно попасть левым мячиком в правый. Присутствуют отскоки от стенок и гравитация. Радиус мячиков уменьшается с каждым уровнем. Если левый мячик уже никак не достигнет правого, то игра начинается заново.
Исполнитель: Грешников П.С.
Группа 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();
}
}
}