Update checks the entities for collision with eachother. Only Main entities are check for collision explicitly. If one of the entities are solid, the SpaceComponent is adjusted so that the other entities don't pass through it.
(dt float32)
| 556 | // Update checks the entities for collision with eachother. Only Main entities are check for collision explicitly. |
| 557 | // If one of the entities are solid, the SpaceComponent is adjusted so that the other entities don't pass through it. |
| 558 | func (c *CollisionSystem) Update(dt float32) { |
| 559 | for i1, e1 := range c.entities { |
| 560 | if e1.CollisionComponent.Main == 0 { |
| 561 | //Main cannot pass bitwise comparison with any other items. Do not loop. |
| 562 | continue // with other entities |
| 563 | } |
| 564 | |
| 565 | var collided CollisionGroup |
| 566 | |
| 567 | for i2, e2 := range c.entities { |
| 568 | if i1 == i2 { |
| 569 | continue // with other entities, because we won't collide with ourselves |
| 570 | } |
| 571 | cgroup := e1.CollisionComponent.Main & e2.CollisionComponent.Group |
| 572 | if cgroup == 0 { |
| 573 | continue //Items are not in a comparible group dont bother |
| 574 | } |
| 575 | |
| 576 | offsetA := engo.Point{X: e1.CollisionComponent.Extra.X / 2, Y: e1.CollisionComponent.Extra.Y / 2} |
| 577 | offsetB := engo.Point{X: e2.CollisionComponent.Extra.X / 2, Y: e2.CollisionComponent.Extra.Y / 2} |
| 578 | if overlaps, mtd := e1.Overlaps(*e2.SpaceComponent, offsetA, offsetB); overlaps { |
| 579 | if cgroup&c.Solids > 0 { |
| 580 | if e2.CollisionComponent.Main&e1.CollisionComponent.Group&c.Solids != 0 { |
| 581 | //collision of equals (both main) |
| 582 | e1.SpaceComponent.Position.X += mtd.X / 2 |
| 583 | e1.SpaceComponent.Position.Y += mtd.Y / 2 |
| 584 | e2.SpaceComponent.Position.X -= mtd.X / 2 |
| 585 | e2.SpaceComponent.Position.Y -= mtd.Y / 2 |
| 586 | //As the entities are no longer overlapping |
| 587 | //e2 wont collide as main |
| 588 | engo.Mailbox.Dispatch(CollisionMessage{Entity: e2, To: e1, Groups: cgroup}) |
| 589 | } else { |
| 590 | //collision with one main |
| 591 | e1.SpaceComponent.Position.X += mtd.X |
| 592 | e1.SpaceComponent.Position.Y += mtd.Y |
| 593 | } |
| 594 | } |
| 595 | |
| 596 | //collided can now list the types of collision |
| 597 | collided = collided | cgroup |
| 598 | engo.Mailbox.Dispatch(CollisionMessage{Entity: e1, To: e2, Groups: cgroup}) |
| 599 | |
| 600 | //update the position tracker of e1 |
| 601 | entityAABB := e1.SpaceComponent.AABB() |
| 602 | offset := engo.Point{X: e1.CollisionComponent.Extra.X / 2, Y: e1.CollisionComponent.Extra.Y / 2} |
| 603 | entityAABB.Min.X -= offset.X |
| 604 | entityAABB.Min.Y -= offset.Y |
| 605 | entityAABB.Max.X += offset.X |
| 606 | entityAABB.Max.Y += offset.Y |
| 607 | } |
| 608 | } |
| 609 | |
| 610 | e1.CollisionComponent.Collides = collided |
| 611 | } |
| 612 | } |
| 613 | |
| 614 | // IsIntersecting tells if two engo.AABBs intersect. |
| 615 | func IsIntersecting(rect1 engo.AABB, rect2 engo.AABB) bool { |