Форум программистов, компьютерный форум, киберфорум
JavaScript: HTML5 Canvas
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
403 / 19 / 5
Регистрация: 17.01.2017
Сообщений: 572

Как сделать столкновение объектов?

24.03.2024, 21:02. Показов 6333. Ответов 70
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте мне нужно сделать столкновение объектов через функцию. Вот пример варианта, что нужно получить.
Название: GameCollision.gif
Просмотров: 615

Размер: 63.7 Кб
Я для этого специально написала функцию hitTest. Выше пример это обычный вариант где сравниваются по оси координат столкновения граней.

Через hitTest у меня фиксируется только столкновение когда объект находиться внутри. Пример на gif-анимации.
Название: GameHitTest.gif
Просмотров: 618

Размер: 88.7 Кб

Как проверять грани и запускать hitTest?

В прошлый раз мне не ответили поэтому я код изменила и сделала более легкую версию.

Здесь используются функции

- Transform
- setTransform. Все это важно для проверки столкновения.

Вот код, чтобы протестировать достаточно скопировать, сохранить в html файл и загрузить в браузере. Никакие библиотеки дополнительно подключать не нужно.
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Пример hitTest </title>
<script>
window.onload = function()
{
var canvas = document.getElementById("drawingCanvas");
var context = canvas.getContext("2d");
 
var BB=canvas.getBoundingClientRect();
var offsetX=BB.left;
var offsetY=BB.top;
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
 
var dragok = false;
var startX;
var startY;
var _activeInstructions = [];
 
var shapeW = 50, hitW = 100;
 
 
 
   localToLocal = function(hit1,x, y, target, pt) {
        var tx1,ty1,pt1;
        tx1 = 1*hit1.x+0*hit1.y+0;
        ty1 = 0*hit1.x+1*hit1.y+0;
 
        
        pt1 = {};
        pt1.x = x*1+y*0+tx1;
        pt1.y = x*0+y*1+ty1;
        
      
     
        return globalToLocal(target,pt1.x, pt1.y, pt);
    };
 
 
 
 
 
globalToLocal = function(hit1,x, y, pt) {
  
      
      var mtx1 = {a:1,b:0,c:0,d:1,tx:-150,ty:-150};
      
     
      var pt1 = {};
      pt1.x = x*1+y*0+mtx1.tx;
      pt1.y = x*0+y*1+mtx1.ty;
      
      
      return pt1;
       
}
 
 
 
Shape = function(x,y,w,h,color,color1,lineWidth1)
{
   
    this.x1 = x;
    this.y1 = y;
    this.w = w;
    this.h = h;
    this.color = color;
    this.color1 = color1;
    this.lineWidth = lineWidth1;
    this.exec = function(ctx)
    {
      ctx.lineWidth =  this.lineWidth;
      ctx.beginPath(); 
     
      
      ctx.rect(this.x1, this.y1, this.w, this.h);
      ctx.fillStyle = this.color;
      ctx.fill();
      
     
      ctx.strokeStyle = this.color1;
      ctx.stroke();
        
    }
    
   this.hitTest = function(ctx, x, y) {
     
      ctx.setTransform(1, 0, 0, 1, -x, -y);
      this.exec(ctx);
      
      var hit = this._testHit(ctx);
      
       
      ctx.setTransform(1, 0, 0, 1, 0, 0);
      ctx.clearRect(0, 0, 2, 2);
      return hit;
      
    };
   this.set = function(props) {
        
        for (var n in props) { 
        this[n] = props[n]; 
        }
        return this;
    };
    
  this._testHit = function(ctx) {
        try {
          
            var hit = ctx.getImageData(0, 0, 1, 1).data[3] > 1;
            
        } catch (e) {
            
        }
        
        return hit;
    };
    
    
 
    this.updateContext = function(ctx) {
        var o = this;
          var a1 = 1;
          var b1 = 0;
          var c1 = 0;
          var d1 = 1;
          
          var tx1 = a1*o.x+c1*o.y+0;
          var ty1 = b1*o.x+d1*o.y+0;
          
          var mtx = {a:1,b:0,c:0,d:1,tx:tx1,ty:ty1};
        
        var tx = mtx.tx,
            ty = mtx.ty;
       
        
        ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, tx, ty);
     
    }
}
 
Rectangle = function(x,y,w,h,color)
{
  this.x1 = x;
  this.y1 = y;
  this.w = w;
  this.h = h;
  this.color = color;
  this.exec = function(ctx)
  {
  
    ctx.beginPath(); 
    ctx.rect(0, 0, this.w, this.h);
    ctx.fillStyle = "#906";
    ctx.fill();
   
  }
  this.set = function(props) {
      
        for (var n in props) { this[n] = props[n]; }
        return this;
  };
  
  
  
  
  this.updateContext = function(ctx) {
        var o = this;
 
       
        
        
        var a1 = 1;
          var b1 = 0;
          var c1 = 0;
          var d1 = 1;
          
          var tx1 = a1*o.x+c1*o.y+0;
          var ty1 = b1*o.x+d1*o.y+0;
          
           
       var mtx = {a:1,b:0,c:0,d:1,tx:tx1,ty:ty1};
       var tx = mtx.tx,
            ty = mtx.ty;
        ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, tx, ty);
        ctx.globalAlpha *= 1;
    }
} 
 
 
 
function clear() {
  context.clearRect(0, 0, WIDTH, HEIGHT);
}
 
 
 
 
   setInterval(() => {
              (
                function() {
                  clear();
                  draw();
                }).call(this);
   }, 33);
var shape1,rect1; 
 
 
function init() {
  clear();
  
  shape1 = new Shape(0,0,hitW,hitW,"#ddd","blue",1);
  shape1.set({x:150, y:150});
  
  
 
  
  rect1 = new Rectangle(0,0,50,50,"#906");
  rect1.set({x:10, y:170});
  
   
   
   
 canvas.addEventListener("mousedown", (e) => {
      e.preventDefault();
      e.stopPropagation();
      
      var mx=parseInt(e.clientX-offsetX);
      var my=parseInt(e.clientY-offsetY);
      dragok=false;
      
      
      if(mx>rect1.x && mx<rect1.x+rect1.w && my>rect1.y && my<rect1.y+rect1.h){
          
         
          dragok=true;
          
     }
      
      
       startX=mx;
       startY=my;
      
      
  });
  canvas.addEventListener("mouseup", (e) => {
     e.preventDefault();
     e.stopPropagation();
 
 
     dragok = false;
      
  });
  
  canvas.addEventListener("mousemove", (e) => {
     
   if (dragok){
       e.preventDefault();
      e.stopPropagation();
 
    
      var mx=parseInt(e.clientX-offsetX);
      var my=parseInt(e.clientY-offsetY);
 
     
      var dx=mx-startX;
      var dy=my-startY;
      
     
      
      
      rect1.x+=dx;
      rect1.y+=dy;
      
      
       var pt = localToLocal(rect1,rect1.x-shape1.x,rect1.y-shape1.y,shape1);
                  if (shape1.hitTest(context,pt.x, pt.y)) {
                      shape1.color1 = "green";
                      shape1.lineWidth = 7;
                    } else {
                      shape1.color1 = "blue";
                      shape1.lineWidth = 1;
                   }
      startX=mx;
      startY=my;
      
      
    }
     
      
  });
   
   
  
 draw();
  
 
}
function draw()
{
  context.save();
  shape1.updateContext(context);
  shape1.exec(context);
  context.restore();
  
  context.save();
  rect1.updateContext(context);
  rect1.exec(context);
  context.restore();
}
init();
}
</script>
</head>
<body>
 
<canvas id="drawingCanvas" width="500" height="500"></canvas>
</body>
</html>
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.03.2024, 21:02
Ответы с готовыми решениями:

Непростое столкновение объектов на Canvas
Здравствуйте, уважаемые форумчане. Познаю работу с canvas. Нужно написать скрипт, реализующий перемещение круга мышкой из А в Б,...

Как определить столкновение объектов
Как сделать столкновение объектов. Когда зеленый объект прикасается слева или справа красный объект или когда верхняя часть зеленого...

Столкновение объектов
Есть проблемка, запутался ,помогите,пожалуйста.Не реагирует на столкновение,заранее большое спасибо &lt;html&gt; ...

70
403 / 19 / 5
Регистрация: 17.01.2017
Сообщений: 572
07.06.2024, 20:23  [ТС]
Студворк — интернет-сервис помощи студентам
8Observer8, Изучила новую библиотеку Pixi JS и создала пример столкновение объектов, где при сильном ударе сфера разбивается. Пример гифки.

Прежде чем удалось сделать это, я изучила основы, то что пригодиться конкретно в моем примере. Все это я добавила в архив, который прикреплен к посту. Вот список.
1. Добавление картинки
2. Рисование окружности
3. Рисование квадрата
4. Добавление масок, чтобы создать эффект осколков.
5. Рисование линии moveTo и LineTo, чтобы создать стены.
6. Создание картинок циклом. Чтобы при сильном ударе создать несколько сфер и наложить на них маски.
7. Работа с мышкой перетаскивание объекта.
8. Установка точки регистрации, у объекта. По умолчанию верхний левый угол, при использовании свойства rotation объект будет крутиться вокруг этого угла, также при захвате мышкой будет происходить смещение. Левый угол окажется у курсора.
Чтобы избежать этого нужно установить точку регистрации у объекта делается это так "obj.anchor.x = 0.5; obj.anchor.y = 0.5;" Посмотреть пример можно в папке 3_ОbjectRegistrationPoint, там происходит вращение вокруг центра, чтобы вернуть параметры по умолчанию, нужно закомментировать строчки "obj.anchor.x = 0.5; obj.anchor.y = 0.5;".
9. Пример удар окружности об стену 8_CircleCollision.
10. ФИНАЛ: удар сферы об стену. При сильном ударе сфера рассыпется на мелкие осколки папка FINAL_collisionball.
Все примеры находятся отдельно в папках.

Исходники:
https://disk.yandex.ru/d/S_eN9akd81yadQ
1
9953 / 2954 / 497
Регистрация: 05.10.2013
Сообщений: 8,075
Записей в блоге: 242
08.06.2024, 13:08
Katerina1993, исходники надо всегда прикреплять к сообщению, если смысл сообщения в том, чтобы поделиться своими достижениями, потому что вы можете случайно удалить их из хранилища и тогда сообщение становится бессмысленным. В правилах форума есть пункт 4.11:
Картинки и любые другие файлы загружайте на форум, во избежание их удаления или потери на сторонних ресурсах. По этой же причине коды программ также должны находиться на форуме.
Прикрепил ваши исходники:
Вложения
Тип файла: zip PixiExample.zip (297.1 Кб, 4 просмотров)
0
9953 / 2954 / 497
Регистрация: 05.10.2013
Сообщений: 8,075
Записей в блоге: 242
08.06.2024, 21:50
Современный способ подключения Pixi.js 8 через ES6-модуль

У вас во всех проектах, даже в больших, весь код находится в одном файле "index.html". Неудобно изучать и дорабатывать код, когда он находится в одном огромном файле. Надо разбивать проект на файлы. Так в них проще будет ориентироваться. Покажу современный способ подключения крайней версии Pixi.js v8.1.6, как ES6-модуля, то есть использование ключевого слова "import" в отдельном JavaScript-файле. На UNPKG есть файл "pixi.min.mjs", который представляет из себя ES6-модуль. Эту ссылку и имя (в данном случае, имя - это "pixi.js") можно добавить в "importmaps" в файле "index.html":

PHP/HTML
1
2
3
4
5
6
7
    <script type="importmap">
        {
            "imports": {
                "pixi.js": "https://unpkg.com/pixi.js@8.1.6/dist/pixi.min.mjs"
            }
        }
    </script>
Пусть у вас главный JavaScript-файл называется "index.js" и он находится в папке "js", тогда главный JavaScript-файл нужно подключить так:

PHP/HTML
1
    <script type="module" src="./js/index.js"></script>
В файле "index.js" нужно импортировать Pixi.js-классы по имени ссылки, которое было задано в "importmaps". В данном случае, было задано имя "pixi.js":

index.js

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Импортируем нужные нам Pixi.js-классы
import { Application, Graphics } from "pixi.js";
 
// Создаём главное приложение с заданным размером холста
const app = new Application();
await app.init({ width: 480, height: 480 });
document.body.appendChild(app.canvas);
 
// Создаём линию
const line = new Graphics();
line.moveTo(20, 20);
line.lineTo(400, 400);
// Задаём цвет линии
line.stroke("#D5402B"); // либо так: "rgb(213, 64, 43)"
 
// Добавляем линию на холст
app.stage.addChild(line);
Результат в песочнице: https://plnkr.co/edit/73Abkx9gynRQFcBX&preview

Фигуры на Pixi.js 8.1.6

Прямоугольник можно нарисовать двумя способами. Первый способ - drawRect/fill:

JavaScript
1
2
3
4
const rect1 = new Graphics();
rect1.drawRect(20, 200, 100, 150); // x, y, width, heigth
rect1.fill(0x709FE9);
app.stage.addChild(rect1);
Второй способ - с помощью beginFill/drawRect/endFill:

JavaScript
1
2
3
4
5
const rect2 = new Graphics();
rect2.beginFill(0x709FE9, 1);
rect2.drawRect(20, 20, 100, 150); // x, y, width, heigth
rect2.endFill();
app.stage.addChild(rect2);
Круг:

JavaScript
1
2
3
4
const circle = new Graphics();
circle.drawCircle(200, 150, 50);
circle.fill("blue");
app.stage.addChild(circle);
Заполненный треугольник:

JavaScript
1
2
3
4
5
6
7
const triangle = new Graphics();
triangle.moveTo(120, 300);
triangle.lineTo(200, 380);
triangle.lineTo(120, 380);
triangle.lineTo(120, 300);
triangle.fill(0x4A5FB4);
app.stage.addChild(triangle);
Пустой треугольник с заданной толщиной линии:

JavaScript
1
2
3
4
5
6
7
8
const triangle2 = new Graphics();
triangle2.lineStyle(5, 0x4A5FB4, 1);
triangle2.moveTo(20, 300);
triangle2.lineTo(100, 380);
triangle2.lineTo(20, 380);
triangle2.lineTo(20, 300);
triangle2.stroke();
app.stage.addChild(triangle2);
0
9953 / 2954 / 497
Регистрация: 05.10.2013
Сообщений: 8,075
Записей в блоге: 242
10.06.2024, 21:14
В архиве "PixiExample.zip" выше в первой папке находится пример рисования: линии, прямоугольника, круга и треугольника, но используется Pixi.js версии 4.6.1, которая была создана в 2017 году. Сейчас актуальна версия 8.1.6. В сообщении выше я попытался перевести на восьмую версию, но оказывается методы: "drawRect", drawCircle" и "lineStyle" были признаны deprecated в версии 8.0.0. Это можно увидеть в документации если ввести названия этих методов в строке поиска в левом верхнем углу: https://pixijs.download/v8.0.0... l#drawRect Если использовать TypeScript, то сообщения о deprecated методах будут выводиться в консоль при компиляции. Вместо перечисленных методов надо использовать: "rect", "circle" и "setStrokeStyle".

Фигуры на Pixi.js 8.1.6

Выбрать цвет можно с помощью онлайн-калькулятора:

Линия заданной толщины и цвета: https://plnkr.co/edit/c513akxqXKf2eNLe?preview

PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
 
<html>
 
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Set up Pixi.js 8 as ES6-module in JavaScript</title>
</head>
 
<body>
    <script type="importmap">
        {
            "imports": {
                "pixi.js": "https://8observer8.github.io/libs/pixi.js@8.1.6/pixi.min.mjs"
            }
        }
    </script>
 
    <script type="module">
        // Импортируем нужные нам Pixi.js-классы
        import { Application, Graphics } from "pixi.js";
 
        // Создаём главное приложение с заданным размером холста
        const app = new Application({ width: 400, height: 400 });
        await app.init();
        document.body.appendChild(app.canvas);
 
        // Создаём линию заданной толщины и цвета
        const line = new Graphics();
        // Цвет можно задать так: "rgb(213, 64, 43)"
        ring.setStrokeStyle({ color: 0xCC5FB4, width: 5 });
        line.lineStyle(5, 0xCC5FB4, 1);
        line.moveTo(20, 20);
        line.lineTo(350, 350);
        line.stroke(); // вместо вызова setStrokeStyle выше можно
                       // вызвать line.stroke({ color: 0xCC5FB4, width: 5 })
 
        // Добавляем линию на холст
        app.stage.addChild(line);
    </script>
</body>
 
</html>
Прямоугольник:

JavaScript
1
2
3
4
const rectangle = new Graphics();
rectangle.rect(20, 200, 100, 150); // x, y, width, heigth
rectangle.fill(0x709FE9);
app.stage.addChild(rectangle);
Прямоугольная рамка заданной толщиной:

JavaScript
1
2
3
4
5
const frame = new Graphics();
frame.setStrokeStyle({ color: 0x4A5FB4, width: 5 });
frame.rect(20, 200, 100, 150);
frame.stroke();
app.stage.addChild(frame);
Круг:

JavaScript
1
2
3
4
const circle = new Graphics();
circle.circle(200, 150, 50);
circle.fill("blue");
app.stage.addChild(circle);
Кольцо заданной толщины:

JavaScript
1
2
3
4
5
const ring = new Graphics();
ring.setStrokeStyle({ color: 0xCC5FB4, width: 5 });
ring.circle(250, 80, 50);
ring.stroke();
app.stage.addChild(ring);
Заполненный треугольник:

JavaScript
1
2
3
4
5
6
7
const triangle = new Graphics();
triangle.moveTo(120, 300);
triangle.lineTo(200, 380);
triangle.lineTo(120, 380);
triangle.lineTo(120, 300);
triangle.fill(0x4A5FB4);
app.stage.addChild(triangle);
Пустой треугольник с заданной толщиной линий:

JavaScript
1
2
3
4
5
6
7
8
const triangle2 = new Graphics();
triangle2.setStrokeStyle({ color: 0x4A5FB4, width: 5 });
triangle2.moveTo(20, 300);
triangle2.lineTo(100, 380);
triangle2.lineTo(20, 380);
triangle2.lineTo(20, 300);
triangle2.stroke();
app.stage.addChild(triangle2);
0
9953 / 2954 / 497
Регистрация: 05.10.2013
Сообщений: 8,075
Записей в блоге: 242
16.06.2024, 13:29
Мне не понравилась библиотека Pixi.js 8, потому что она содержит баг (как я считаю), но даже не в баге дело, а в том что на официальном Discord никто не попытался помочь или хотя бы подсказать, что это возможно баг. Я попытался использовать методы save() и restore(), которые являются аналогами методов с тем же названием из Canvas API. Я сделал рисование коллайдеров для @box2d/core. Повёрнутый квадрат падает на платформу, но работает неверно. Я создал issue для Pixi.js 8: https://github.com/pixijs/pixijs/issues/10632

Демка проблемы в песочнице



index.html

PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
 
<html>
 
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Set up Pixi.js 8 as ES6-module in JavaScript</title>
</head>
 
<body>
    <script type="importmap">
        {
            "imports": {
                "@box2d/core": "https://8observer8.github.io/libs/box2d-core@0.10.0/box2d-core.min.js",
                "pixi.js": "https://8observer8.github.io/libs/pixi.js@8.1.6/pixi.min.mjs"
            }
        }
    </script>
 
    <script type="module" src="./js/index.js"></script>
</body>
 
</html>
index.js

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { b2BodyType, b2PolygonShape, b2World } from "@box2d/core";
import { DrawShapes } from "@box2d/core";
import { Application, Graphics } from "pixi.js";
import DebugDrawer from "./debug-drawer.js";
 
// Create the main application and the canvas
const app = new Application();
await app.init({ width: 400, height: 400 });
document.body.appendChild(app.canvas);
 
const world = b2World.Create({ x: 0, y: 10 });
const pixelsPerMeter = 30;
 
// Ground
const groundShape = new b2PolygonShape();
groundShape.SetAsBox(130 / pixelsPerMeter, 20 / pixelsPerMeter);
const groundBody = world.CreateBody({
    type: b2BodyType.b2_staticBody,
    position: { x: 150 / pixelsPerMeter, y: 270 / pixelsPerMeter }
});
groundBody.CreateFixture({ shape: groundShape });
 
// Box
const boxShape = new b2PolygonShape();
boxShape.SetAsBox(30 / pixelsPerMeter, 30 / pixelsPerMeter);
const boxBody = world.CreateBody({
    type: b2BodyType.b2_dynamicBody,
    angle: 10 * Math.PI / 180,
    position: { x: 200 / pixelsPerMeter, y: 30 / pixelsPerMeter }
});
boxBody.CreateFixture({ shape: boxShape, density: 1 });
 
const debugGraphics = new Graphics();
const debugDrawer = new DebugDrawer(debugGraphics, pixelsPerMeter);
app.stage.addChild(debugGraphics);
 
draw();
 
function draw() {
    world.Step(0.016, { velocityIterations: 3, positionIterations: 2 });
 
    debugGraphics.clear();
    DrawShapes(debugDrawer, world);
 
    requestAnimationFrame(draw);
}
debug-drawer.js

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import { Color } from "pixi.js";
 
export default class DebugDrawer {
 
    constructor(graphics, pixelsPerMeter, lineWidth = 5) {
        this.graphics = graphics;
        this.ppm = pixelsPerMeter;
        this.lineWidth = lineWidth;
    }
 
    DrawSolidPolygon(vertices, vertexCount, color) {
        const c = new Color([color.r, color.g, color.b]).toHex();
        this.graphics.moveTo(vertices[0].x * this.ppm, vertices[0].y * this.ppm);
        this.graphics.lineTo(vertices[1].x * this.ppm, vertices[1].y * this.ppm);
        this.graphics.lineTo(vertices[2].x * this.ppm, vertices[3].y * this.ppm);
        this.graphics.lineTo(vertices[3].x * this.ppm, vertices[3].y * this.ppm);
        this.graphics.lineTo(vertices[0].x * this.ppm, vertices[0].y * this.ppm);
        this.graphics.stroke({ color: c, width: this.lineWidth });
    }
 
    DrawSolidCircle(center, radius, axis, color) {
 
    }
 
    PushTransform(xf) {
        this.graphics.context.save();
        this.graphics.context.translate(xf.p.x * this.ppm, xf.p.y * this.ppm);
        this.graphics.context.rotate(xf.q.GetAngle());
    }
 
    PopTransform(xf) {
        this.graphics.context.restore();
    }
 
    DrawCircle(center, radius, color) {}
    DrawPolygon(vertices, vertexCount, color) {}
    DrawSegment(p1, p2, color) {}
    DrawTransform(xf) {}
    DrawPoint(p, size, color) {}
}
Миниатюры
0
403 / 19 / 5
Регистрация: 17.01.2017
Сообщений: 572
18.06.2024, 21:23  [ТС]
8Observer8, я библиотеку Pixi.js использовала, только потому что там есть свойства для создрания маски. Маска накладывается, чтобы создать эффект разбивания сферы, как в посте 61. Можете переписать на Phaser, если нужно. Там тоже есть возможность создавать маски. Я просто выбрала Pixi для пробы.

Библиотеку Box2D не использовала, поэтому о всех багах не знаю. Разумеется когда буду использовать Box2D выберу подходящий движок для рисования и добавления объектов.
0
9953 / 2954 / 497
Регистрация: 05.10.2013
Сообщений: 8,075
Записей в блоге: 242
03.07.2024, 12:46
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Повёрнутый квадрат падает на платформу, но работает неверно. Я создал issue для Pixi.js 8: https://github.com/pixijs/pixijs/issues/10632
Оказывается, это не баг. Нужно просто поменять последовательность поворота и перемещения, тогда работает: https://plnkr.co/edit/1RizUv5yknLrb9w4?preview

JavaScript
1
2
3
4
5
    PushTransform(xf) {
        this.graphics.context.save();
        this.graphics.context.rotate(xf.q.GetAngle());
        this.graphics.context.translate(xf.p.x * this.ppm, xf.p.y * this.ppm);
    }
Но, что интересно, для Phaser 3 должно быть наоборот - сначала перемещение, а потом поворот: https://plnkr.co/edit/QZ6ce2LwdIExLdBf?preview

JavaScript
1
2
3
4
5
6
    PushTransform(xf) {
        this.graphics.save();
        this.graphics.translateCanvas(xf.p.x * this.pixelsPerMeter,
            xf.p.y * this.pixelsPerMeter);
        this.graphics.rotateCanvas(xf.q.GetAngle());
    }
Название: 321203764-53315605-54d7-4169-b820-b708271d8bd8.gif
Просмотров: 122

Размер: 188.7 Кб
1
403 / 19 / 5
Регистрация: 17.01.2017
Сообщений: 572
10.07.2024, 05:12  [ТС]
8Observer8, cделала код на JS. Систему частиц. При столкновении небесных тел с героем запускается система particles.

На самом деле я переписала старую библиотеку на Flash.

Цель: понять можно ли переписать AS 3.0. на JS, чтобы он полностью соответствовал Flash (ActionScript 3.0.).

Результат: При реализации пришлось отказаться от интерфейсов, я не знаю как их сделать на JavaScript, зато получилось сделать override переопределения метода из базового класса. Используется при наследования, здесь вместо override применила __proto__. Чтобы заменить некоторые функции Flash пришлось подключить дополнительные библиотеки.

1.clasess.js – для get и set параметров.
2.easeljs.js – библиотека для добавления объектов.
3.Event.js
4.EventDispatcher.js
5.Point.js

Полностью библиотеку Flash я реализовывать не стала. Сделала только те функции которые используются в коде.
Вот исходники на JS ExampleCollision.zip.
В архиве три примера.
1.Отношение к звездопаду не имеет. Просто протестировала zimjs.
ZimJS написана как дополнение к EaselJS. В этом пример окружность сталкивается с квадратом. Для этого мышкой нужно перетащить круг на квадрат. Используется функция hitTestCircleRect для Collision.
2.Перемещение прямоугольника кнопками клавиатуры. При столкновении с окружностью прямоугольник перекрещивается. Нужно чтобы фиксировать столкновение с звездами. Способ Rectangle To Circle подходит, так как звезды имеют форму окружности.
3.Сам зведопад.
Исходники на Flash. Для сравнения. star.zip
Очень помогла справка от Adobe: Сопоставление фрагментов кода ActionScript и HTML5
1
403 / 19 / 5
Регистрация: 17.01.2017
Сообщений: 572
15.07.2024, 02:44  [ТС]
Следующий пример столкновение объектов с помощью функции distance. Пришлось изменить немного функцию Point библиотеки Easeljs.

Для столкновения используется Math.sqrt и когда дистанция до объекта сокращается до установленного значения в переменных, то происходит collision.

Суть игры: собрать весь мусор в городе и отвести в специальное место. Пример игры ниже.


Встречается всего три типа мусора – пакеты, бутылки и банки. Для каждого предмета свой контейнер. Сколько осталось мусора показано на панели сверху, там же можно увидеть время игры.
За один раз мусоровоз может увести 10 предметов. Игра заканчивается, когда весь мусор будет собран.

Мусор разбросан только по дорогам, внутри кварталов где дома мусора нет. Для этого в районе были размещены специальные блоки и написали условие с hitTestObject. Где проверяется размещение предмета и игнорируется жилой регион.

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
for(var i=0;i<this.numTrashObjects;i++) {
        while (true) {
         var x = Math.floor(Math.random()*this.mapRect.width)+this.mapRect.x;
     var y = Math.floor(Math.random()*this.mapRect.height)+this.mapRect.y;
     ar isOnBlock = false;
                    for(var j=0;j<this.blocks.length;j++) {
                        
                        if (this.blocks[j].hitTestObject(x,y)) {
                            isOnBlock = true;
                            break;
                        }
                    }
                    
                    if (!isOnBlock) {
                        var newObject = new game.TrashObject();
                        newObject.x = x;
                        newObject.y = y;
                        newObject._gotoAndStop(Math.floor(Math.random()*3));
                        this.gamesprite.addChild(newObject);
                        this.trashObjects.push(newObject);
                        break;
                    }
                    
        }
        
      }
Исходники игры TopDownDrive.zip

В предыдущем примере я переводила код с Flash на Html5. Среди своих файлов случайно нашла

Колин Мук. ActionScript 3.0. Подробное руководство – исходники https://disk.yandex.ru/d/suQ5EmdOa3_D5Q.

Может кому пригодиться. Подойдет для практики, чтобы перевести flash на html5 и посмотреть результат. Там есть interface и implements, но как они работают на html я так и не поняла.
0
9953 / 2954 / 497
Регистрация: 05.10.2013
Сообщений: 8,075
Записей в блоге: 242
15.07.2024, 12:45
Цитата Сообщение от Katerina1993
Я разместила новый пост по ссылке Как сделать столкновение объектов?, но у меня резко просела скорость интернета и я не смогла загрузить исходники на 3 мб, а бросать пост и ждать скорости долго тем более я уже все написала. Можете загрузить исходники moock_eas3_examples.zip с яндекс диск и прикрепить к посту?
Да, конечно, мне несложно
Вложения
Тип файла: zip moock_eas3_examples.zip (2.76 Мб, 0 просмотров)
0
9953 / 2954 / 497
Регистрация: 05.10.2013
Сообщений: 8,075
Записей в блоге: 242
09.11.2024, 15:32
Цитата Сообщение от Katerina1993 Посмотреть сообщение
Мне удалось найти не только эту функцию на и целую библиотеку. Называется она IvankLib. Там есть почти все функции Flash
На сайте IvankLib есть демка с исходниками на Box2D: https://lib.ivank.net/?p=demos&d=box2D

Если будет желание и время, то перепишите следующие примеры с Flash и Box2D на IvankLib:

Lesson 1.1 - Introduction to Chapter 1 - http://youtu.be/2NvNoBUNIX0
Lesson 1.2 - Disclaimers, thanks, and comments - http://youtu.be/jhKWFgvR8No
Lesson 1.3 - What you're gonna need... - http://youtu.be/rB_WrFt4-5s
Lesson 1.4 - Understanding Box2D - http://youtu.be/95lW-zWkZPE
Lesson 1.5 - The kinda long and boring lesson on setting everything up - http://youtu.be/MDtGGyI8OTc
Lesson 1.6 - Creating the world and getting to know some classes - http://youtu.be/WzIacPkLtIc
Lesson 1.7 - Defining the size of the universe - http://youtu.be/vYksP9ctHMI
Lesson 1.8 - A quick digression about units - http://youtu.be/CnCS2NeBZ0E
Lesson 1.9 - Finishing up our b2World object - http://youtu.be/lVtVKeGiBco
Lesson 1.10 - If you're following along and getting errors... - http://youtu.be/7yqEjjFfrIE
Lesson 1.11 - How do you make a body? - http://youtu.be/h6TozLhho80
Lesson 1.12 - Creating our first shape definition - http://youtu.be/sbbsvKMMr_w
Lesson 1.13 - Finishing up our floor - http://youtu.be/OSwRv4Nzdz0
Lesson 1.14 - Creating the walls - http://youtu.be/iCLP-Ok1ab4
Lesson 1.15 - Creating our falling crate - http://youtu.be/31sVPYW3icE
Lesson 1.16 - Making our world update over time - http://youtu.be/_MbfGRD8Ibk
Lesson 1.17 - Let's Get Visual, Visual - http://youtu.be/KNm8fdkrFuE
Lesson 1.18 - Adding lots of crates! Whee! - http://youtu.be/1d72y6oX9nc
Lesson 1.19 - Experimenting with our values - http://youtu.be/2PCeecp3vv4
Lesson 1.20 - The difference between a shape and a body - http://youtu.be/s_t0MaFDUsM
Lesson 1.21 - Defs, OrientedBoxes, and Coordinates - http://youtu.be/g0FR0WCVFFA
Lesson 1.22 - Conclusion - http://youtu.be/Di5rrYHhN6g

Chapter 2: Making Puggle

Lesson 2.1 - Making a real application -- an Introduction to Chapter 2 - http://youtu.be/85FoF_w-HOM
Lesson 2.2 - Everything we did in Chapter 1 in about six minutes - http://youtu.be/SPAEPPGClQg
Lesson 2.3 - Getting a Sprite to move like a Body - http://youtu.be/fyDGU0haNcg
Lesson 2.4 - Introducing the Actor Class! - http://youtu.be/deA4MMsuOHk
Lesson 2.5 - Creating our first Actor class - http://youtu.be/7e7iF2_Dr0o
Lesson 2.6 - Creating the BallActor class - http://youtu.be/ouEkR8Wlg_E
Lesson 2.7 - Creating the PegActor, Part 1 - http://youtu.be/5wQIrISylxs
Lesson 2.8 - Creating the PegActor, Part 2 - http://youtu.be/268gpaMz0XE
Lesson 2.9 - Adding all those pegs to the world - http://youtu.be/bjeiNwIv5DY
Lesson 2.10 - The ArbitraryStaticActor... as exciting as it sounds! - http://youtu.be/HJ8HeREdjmM
Lesson 2.11 - Finishing the ArbiStaticActor, and adding some walls - http://youtu.be/FZ9SdB4M9og
Lesson 2.12 - Adding some ramps! Yay! - http://youtu.be/G0sqizu4XqQ
Lesson 2.13 - Discussion Questions, like "Why isn't Todd a better coder?" - http://youtu.be/5pxRiw7wuA4
Lesson 2.14 - More Discussion Questions that you probably weren't wondering about - http://youtu.be/Q9JHCTqsY0E
Lesson 2.15 - Getting to know the b2ContactListener - http://youtu.be/FklxMpYi8ww
Lesson 2.16 - Figuring out who bumped into who - http://youtu.be/OBVxTSJjRGs
Lesson 2.17 - Making a peg light up! And some warnings... - http://youtu.be/eP4T8BE7qq0
Lesson 2.18 - How to remove an Actor (insert Hollywood-themed joke here) - http://youtu.be/MGX8GOmzJ8A
Lesson 2.19 - Finishing that Actor's destroy() function - http://youtu.be/CgK3IgYnua4
Lesson 2.20 - Removing our ball and creating a custom event - http://youtu.be/tOgNzVRe_po
Lesson 2.21 - Removing those PegActors we took so long to make (sigh) - http://youtu.be/YT34taQO3QI
Lesson 2.22 - Our game's got a lotta balls. - http://youtu.be/KnEODTxkg54
Lesson 2.23 - Creating the BonusChuteActor class - http://youtu.be/0hQ8CJT2kxc
Lesson 2.24 - Adding a sensor to our BonusChute - http://youtu.be/MZLizo67dA0
Lesson 2.25 - Getting a platform to move -- the wrong way - http://youtu.be/Kiy28DvQxnA
Lesson 2.26 - Getting a platform to move -- the right way - http://youtu.be/C1sgWy07Ek4
Lesson 2.27 - Fixing bugs in our platform and using bullets - http://youtu.be/WBvAnaxJ9KI
Lesson 2.28 - Introducing the camera! - http://youtu.be/PLcsxKRPVbw
Lesson 2.29 - Making our camera dumbly zoom in - http://youtu.be/ess3kNVvvF8
Lesson 2.30 - Tracking our ball and Goal Peg - http://youtu.be/2oAcFim65is
Lesson 2.31 - Zooming in, the smart way - http://youtu.be/JMTb0PJp1_w
Lesson 2.32 - How to control time! (Katana not required) - http://youtu.be/K6Oh-8Yux_8
Lesson 2.33 - Cleaning up, part 1: Removing the flicker - http://youtu.be/DsGJ41ERIKE
Lesson 2.34 - Cleaning up, part 2: Allowing multiple goal pegs - http://youtu.be/H_I0gpqvb6E
Lesson 2.35 - Creating the aiming line, part 1 - http://youtu.be/v0HHg3nrWCE
Lesson 2.36 - Creating the aiming line, part 2 - http://youtu.be/pv-VLmurMo0
Lesson 2.37 - Tweaking the settings - http://youtu.be/dntwtnGDDdY
Lesson 2.38 - Making a rotating shooter turret thing - http://youtu.be/BIIYnGseBTM
Lesson 2.39 - Oops! Fixing one bug with the shooter - http://youtu.be/1i7H2B7hPOM
Lesson 2.40 - Making a smooth camera zoom through TweenLite - http://youtu.be/R98ER9iREW8
Lesson 2.41 - Smoothing the zoom out and slow down moments - http://youtu.be/led40OjZtjI
Lesson 2.42 - Making the pegs fade out - http://youtu.be/iVuJhoTO2dw
Lesson 2.43 - How to NOT make Peggle - http://youtu.be/24Rm18C5E_I
Lesson 2.44 - Turning our static pegs to moving pegs - http://youtu.be/ZU5P7kPdURM
Lesson 2.45 - REALLY turning our static pegs into moving ones - http://youtu.be/7lHoKW2j1o4
Lesson 2.46 - Getting our chute to follow our mouse - http://youtu.be/Pc6PJha93cI
Lesson 2.47 - Making our pegs react more realistically, part 1 - http://youtu.be/7AQv88f14-M
Lesson 2.48 - Even more realistic pegs, ApplyForce and ApplyImpulse - http://youtu.be/IgUr4xrcTEI
Lesson 2.49 - Normals and crazy mathy stuff - http://youtu.be/JruODUnV2o4
Lesson 2.50 - Final to-do list and conclusion - http://youtu.be/pUZ-PVCquOI
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.11.2024, 15:32

Столкновение объектов на странице
Всем привет! Предположим у меня есть два шарика, один статичный, просто стоит в определенном месте, а другой бегает по странице от...

JavaScript: столкновение объектов
Прошу спецов по Java подсказать или помочь доработать скрипт Зинковского (написан на Java и VBScript). Описание: игра-стрелялка,...

Как сделать столкновение объектов?
Как проверять, столкнулся ли один шар с другим? Первый шар двигается нажатием клавиши, а остальные находятся на рандомных позициях, как...

Как сделать, чтобы столкновение объектов было абсолютно неупругим
Нашел пример попиксельного столкновения. Работает прекрасно, но что делать в момент столкновения, если нужно, чтоб оно было абсолютно...

Столкновение объектов. Как правильно реализовать?
Здравствуйте! Пишу игру в танчики. Borland C++ 3.1. Сейчас реализовал работу с клавиатурой, ознакомиться можно здесь :...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
71
Ответ Создать тему
Новые блоги и статьи
После бана на Пикабу не работает авторизация аккаунта с Яндекса.
Hrethgir 09.07.2026
В частности https:/ / auto. ru/ logbook/ zapret-na-vozhdenie-posle-65-let_1cf28789-07b4-4c75-a2f7-4cd4edf9deeb тут хотел оставить комментарий такой Зрите в корень - монополизация на разработку программ. . .
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru