Example #1
0
func (cs *CollisionSystem) Update(entity *ecs.Entity, dt float32) {
	var (
		space     *SpaceComponent
		collision *CollisionComponent
		ok        bool
	)

	if space, ok = entity.ComponentFast(space).(*SpaceComponent); !ok {
		return
	}

	if collision, ok = entity.ComponentFast(collision).(*CollisionComponent); !ok {
		return
	}

	if !collision.Main {
		return
	}

	var (
		otherSpace     *SpaceComponent
		otherCollision *CollisionComponent
	)

	for _, other := range cs.Entities() {
		if other.ID() != entity.ID() {
			if otherSpace, ok = other.ComponentFast(otherSpace).(*SpaceComponent); !ok {
				return
			}

			if otherCollision, ok = other.ComponentFast(otherCollision).(*CollisionComponent); !ok {
				return
			}

			entityAABB := space.AABB()
			offset := Point{collision.Extra.X / 2, collision.Extra.Y / 2}
			entityAABB.Min.X -= offset.X
			entityAABB.Min.Y -= offset.Y
			entityAABB.Max.X += offset.X
			entityAABB.Max.Y += offset.Y
			otherAABB := otherSpace.AABB()
			offset = Point{otherCollision.Extra.X / 2, otherCollision.Extra.Y / 2}
			otherAABB.Min.X -= offset.X
			otherAABB.Min.Y -= offset.Y
			otherAABB.Max.X += offset.X
			otherAABB.Max.Y += offset.Y
			if IsIntersecting(entityAABB, otherAABB) {
				if otherCollision.Solid && collision.Solid {
					mtd := MinimumTranslation(entityAABB, otherAABB)
					space.Position.X += mtd.X
					space.Position.Y += mtd.Y
				}

				Mailbox.Dispatch(CollisionMessage{Entity: entity, To: other})
			}
		}
	}
}
Example #2
0
func (as *AudioSystem) Update(entity *ecs.Entity, dt float32) {
	var ac *AudioComponent
	var ok bool
	if ac, ok = entity.ComponentFast(ac).(*AudioComponent); !ok {
		return
	}

	if ac.player == nil {
		f := Files.Sound(ac.File)
		if f == nil {
			return
		}

		var err error
		ac.player, err = NewPlayer(f, 0, 0)
		if err != nil {
			log.Println("Error initializing AudioSystem:", err)
			return
		}
	}

	if ac.player.State() != Playing {
		if ac.player.State() == Stopped {
			if !ac.Repeat {
				al.RewindSources(ac.player.source)
				al.StopSources(ac.player.source)
				entity.RemoveComponent(ac)
				return
			}
		}

		// Prepares if the track hasn't been buffered before.
		if err := ac.player.prepare(ac.Background, 0, false); err != nil {
			log.Println("Error initializing AudioSystem:", err)
			return
		}

		al.PlaySources(ac.player.source)

		if !ac.Background {
			var space *SpaceComponent
			var ok bool
			if space, ok = entity.ComponentFast(space).(*SpaceComponent); !ok {
				return
			}

			ac.player.source.SetPosition(al.Vector{
				(space.Position.X + space.Width/2) / Width(),
				(space.Position.Y + space.Height/2) / Height(),
				0})
		}
	}
}
Example #3
0
func (rs *RenderSystem) Update(entity *ecs.Entity, dt float32) {
	if !rs.changed {
		return
	}

	var render *RenderComponent
	var ok bool

	if render, ok = entity.ComponentFast(render).(*RenderComponent); !ok {
		return
	}

	rs.renders[render.priority] = append(rs.renders[render.priority], entity)
}
Example #4
0
func (c *Calibrate) Update(entity *ecs.Entity, dt float32) {
	if c.frameIndex != 0 {
		return
	}

	var (
		cal *CalibrateComponent
		ok  bool
	)

	if cal, ok = entity.ComponentFast(cal).(*CalibrateComponent); !ok {
		return
	}

	// Render the image again
	plt, err := plot.New()
	if err != nil {
		log.Fatal(err)
	}

	plotutil.AddLinePoints(plt,
		"CH"+strconv.Itoa(int(cal.ChannelIndex)), plotter.XYer(c.channels[cal.ChannelIndex]))
	img := image.NewRGBA(image.Rect(0, 0, 3*dpi, 3*dpi))
	canv := vgimg.NewWith(vgimg.UseImage(img))
	plt.Draw(draw.New(canv))
	bgTexture := engi.NewImageRGBA(img)

	// Give it to engi

	erender := &engi.RenderComponent{
		Display:      engi.NewRegion(engi.NewTexture(bgTexture), 0, 0, 3*dpi, 3*dpi),
		Scale:        engi.Point{1, 1},
		Transparency: 1,
		Color:        color.RGBA{255, 255, 255, 255},
	}
	erender.SetPriority(engi.HUDGround)

	entity.AddComponent(erender)
}
Example #5
0
func (m *Maze) Update(entity *ecs.Entity, dt float32) {
	if entity.ID() != m.playerEntity.ID() {
		return
	}

	var (
		move *MovementComponent
		ok   bool
	)

	if move, ok = entity.ComponentFast(move).(*MovementComponent); ok {
		return // because we're still moving!
	}

	if m.currentLevel.Width == 0 || m.currentLevel.Height == 0 {
		return // because there's no maze
	}

	oldX, oldY := m.currentLevel.PlayerX, m.currentLevel.PlayerY

	if m.currentLevel.Grid[oldY][oldX] == TileGoal {
		// Goal achieved!

		if strings.HasPrefix(m.currentLevel.Name, "Random ") {
			engi.Mailbox.Dispatch(MazeMessage{})
			return
		}

		if m.sequence != SequenceNone {
			m.cleanup()
			m.initialize("")
			return
		}
	}

	switch m.Controller.Action(m.currentLevel) {
	case ActionUp:
		m.currentLevel.PlayerY--
	case ActionDown:
		m.currentLevel.PlayerY++
	case ActionLeft:
		m.currentLevel.PlayerX--
	case ActionRight:
		m.currentLevel.PlayerX++
	case ActionStop:
		return // so don't move
	}

	if !m.currentLevel.IsAvailable(m.currentLevel.PlayerX, m.currentLevel.PlayerY) {
		m.currentLevel.PlayerX, m.currentLevel.PlayerY = oldX, oldY
		return // because it's an invalid move
	}

	entity.AddComponent(&MovementComponent{
		From: engi.Point{float32(oldX) * tileWidth, float32(oldY) * tileHeight},
		To:   engi.Point{float32(m.currentLevel.PlayerX) * tileWidth, float32(m.currentLevel.PlayerY) * tileHeight},
		In:   time.Second / moveSpeed,
		Callback: func() {
			if m.currentLevel.Grid[m.currentLevel.PlayerY][m.currentLevel.PlayerX] == TileRoute {
				m.currentLevel.Grid[m.currentLevel.PlayerY][m.currentLevel.PlayerX] = TileBlank
				m.currentLevel.GridEntities[m.currentLevel.PlayerY][m.currentLevel.PlayerX].AddComponent(tileBlank)
			} else if m.currentLevel.Grid[oldY][oldX] == TileError ||
				m.currentLevel.Grid[oldY][oldX] == TileBlank {
				m.currentLevel.Grid[oldY][oldX] = TileRoute

				if m.currentLevel.Grid[m.currentLevel.PlayerY][m.currentLevel.PlayerX] == TileHiddenError {
					m.currentLevel.Grid[m.currentLevel.PlayerY][m.currentLevel.PlayerX] = TileError
				}
			}
		},
	})
}
Example #6
0
// Update sets the MouseComponent values for each Entity
func (m *MouseSystem) Update(entity *ecs.Entity, dt float32) {
	var (
		mc     *MouseComponent
		space  *SpaceComponent
		render *RenderComponent
		ok     bool
	)

	// We need MouseComponent to save our findings
	if mc, ok = entity.ComponentFast(mc).(*MouseComponent); !ok {
		return
	}

	// We need SpaceComponent for the location
	if space, ok = entity.ComponentFast(space).(*SpaceComponent); !ok {
		return
	}

	// We need RenderComponent for the Priority
	if render, ok = entity.ComponentFast(render).(*RenderComponent); !ok {
		return
	}

	// Reset some values
	mc.Leave = false

	mx := m.mouseX
	my := m.mouseY

	// Special case: HUD
	if render.priority >= HUDGround {
		mx = Mouse.X
		my = Mouse.Y
	}

	// if the Mouse component is a tracker we always update it
	// Check if the X-value is within range
	// and if the Y-value is within range
	if mc.Track || mx > space.Position.X && mx < (space.Position.X+space.Width) &&
		my > space.Position.Y && my < (space.Position.Y+space.Height) {

		mc.Enter = !mc.Hovered
		mc.Hovered = true

		mc.Released = false
		// track mouse position so that systems that need to stay on the mouse
		// position can do it (think an RTS when placing a new building and
		// you get a ghost building following your mouse until you click to
		// place it somewhere in your world.
		mc.MouseX = mx
		mc.MouseY = my

		switch Mouse.Action {
		case PRESS:
			switch Mouse.Button {
			case MouseButtonLeft:
				mc.Clicked = true
			case MouseButtonRight:
				mc.RightClicked = true
			}
			m.mouseDown = true
		case RELEASE:
			switch Mouse.Button {
			case MouseButtonLeft:
				mc.Released = true
			case MouseButtonRight:
				mc.RightReleased = true
			}
			// dragging stops as soon as one of the currently pressed buttons
			// is released
			mc.Dragged = false
			// mouseDown goes false as soon as one of the pressed buttons is
			// released. Effectively ending any dragging
			m.mouseDown = false
		case MOVE:
			if m.mouseDown {
				mc.Dragged = true
			}
		}
	} else {
		if mc.Hovered {
			mc.Leave = true
		}
		mc.Hovered = false
	}
}