コード例 #1
0
ファイル: linear_test.go プロジェクト: runningwild/linear
func PolySpec2(c gospec.Context) {
	p := linear.Poly{
		{-1, 0},
		{-3, 0},
		{0, 10},
		{3, 0},
		{1, 0},
		{2, 1},
		{-2, 1},
	}
	c.Specify("Check that exterior and interior segments of a polygon are correctly identified.", func() {
		visible_exterior := []linear.Seg2{
			linear.MakeSeg2(-1, 0, -3, 0),
			linear.MakeSeg2(2, 1, -2, 1),
			linear.MakeSeg2(3, 0, 1, 0),
		}
		visible_interior := []linear.Seg2{
			linear.MakeSeg2(2, 1, -2, 1),
			linear.MakeSeg2(-3, 0, 0, 10),
			linear.MakeSeg2(0, 10, 3, 0),
			linear.MakeSeg2(-1, 0, -3, 0),
			linear.MakeSeg2(3, 0, 1, 0),
		}
		c.Expect(p.VisibleExterior(linear.Vec2{0, -10}), ContainsExactly, visible_exterior)
		c.Expect(p.VisibleInterior(linear.Vec2{0, 5}), ContainsExactly, visible_interior)
	})
}
コード例 #2
0
ファイル: linear_test.go プロジェクト: runningwild/linear
func PolySpec1(c gospec.Context) {
	p := linear.Poly{
		{0, 0},
		{-1, 2},
		{0, 1},
		{1, 2},
	}
	c.Specify("Check that exterior and interior segments of a polygon are correctly identified.", func() {
		visible_exterior := []linear.Seg2{
			linear.MakeSeg2(-1, 2, 0, 1),
			linear.MakeSeg2(0, 1, 1, 2),
		}
		visible_interior := []linear.Seg2{
			linear.MakeSeg2(0, 1, 1, 2),
			linear.MakeSeg2(1, 2, 0, 0),
			linear.MakeSeg2(0, 0, -1, 2),
		}
		c.Expect(p.VisibleExterior(linear.Vec2{0, 2}), ContainsExactly, visible_exterior)
		c.Expect(p.VisibleInterior(linear.Vec2{0.5, 1.4}), ContainsExactly, visible_interior)
	})
}
コード例 #3
0
ファイル: linear_test.go プロジェクト: runningwild/linear
func PolySpec3(c gospec.Context) {
	p := linear.Poly{
		{0, 0},
		{0, 1},
		{1, 1},
		{1, 0},
	}
	c.Specify("Check that Poly.Seg(i) returns the i-th segment.", func() {
		s0 := linear.MakeSeg2(0, 0, 0, 1)
		VecExpect(c, p.Seg(0).P, Equals, s0.P)
		VecExpect(c, p.Seg(0).Q, Equals, s0.Q)
		s1 := linear.MakeSeg2(0, 1, 1, 1)
		VecExpect(c, p.Seg(1).P, Equals, s1.P)
		VecExpect(c, p.Seg(1).Q, Equals, s1.Q)
		s2 := linear.MakeSeg2(1, 1, 1, 0)
		VecExpect(c, p.Seg(2).P, Equals, s2.P)
		VecExpect(c, p.Seg(2).Q, Equals, s2.Q)
		s3 := linear.MakeSeg2(1, 0, 0, 0)
		VecExpect(c, p.Seg(3).P, Equals, s3.P)
		VecExpect(c, p.Seg(3).Q, Equals, s3.Q)
	})
}
コード例 #4
0
ファイル: linear_test.go プロジェクト: runningwild/linear
func SegmentsSpec(c gospec.Context) {
	s1 := linear.MakeSeg2(0, 0, 9, 9)
	s2 := linear.MakeSeg2(0, 2, 7, 2)
	s3 := linear.MakeSeg2(10, 0, -10, -1)
	s4 := linear.MakeSeg2(-1, 0, 1, -1)
	s5 := linear.MakeSeg2(1000, 1000, 999, 1001)
	s6 := linear.MakeSeg2(1, 0, 1, 3)
	s7 := linear.MakeSeg2(1, 1, 2, 1)
	c.Specify("Check that intersections are computed correctly.", func() {
		i12 := s1.Isect(s2)
		VecExpect(c, i12, IsWithin(1e-9), linear.Vec2{2, 2})
		i34 := s3.Isect(s4)
		VecExpect(c, i34, IsWithin(1e-9), linear.Vec2{0, -0.5})
	})
	c.Specify("Check DoesIsect().", func() {
		c.Expect(s6.DoesIsect(s7), Equals, false)
		c.Expect(s7.DoesIsect(s6), Equals, false)
	})
	c.Specify("Check DistFromOrigin().", func() {
		c.Expect(s1.DistFromOrigin(), IsWithin(1e-9), 0.0)
		c.Expect(s2.DistFromOrigin(), IsWithin(1e-9), 2.0)
		c.Expect(s3.DistFromOrigin(), IsWithin(1e-9), 0.499376169)
		c.Expect(s4.DistFromOrigin(), IsWithin(1e-9), 0.447213595)
	})
	c.Specify("Check Left() and Right().", func() {
		c.Expect(s1.Left(linear.Vec2{0, 1}), Equals, true)
		c.Expect(s1.Right(linear.Vec2{0, 1}), Equals, false)
		c.Expect(s1.Left(linear.Vec2{1000, 10000}), Equals, true)
		c.Expect(s1.Right(linear.Vec2{1000, 10000}), Equals, false)
		c.Expect(s1.Left(linear.Vec2{0, -0.001}), Equals, false)
		c.Expect(s1.Right(linear.Vec2{0, -0.001}), Equals, true)

		c.Expect(s4.Left(linear.Vec2{0, 0}), Equals, true)
		c.Expect(s4.Right(linear.Vec2{0, 0}), Equals, false)
		c.Expect(s4.Left(linear.Vec2{0, -1000000}), Equals, false)
		c.Expect(s4.Right(linear.Vec2{0, -1000000}), Equals, true)

		c.Expect(s5.Left(linear.Vec2{999.5, 1000.5001}), Equals, false)
		c.Expect(s5.Right(linear.Vec2{999.5, 1000.5001}), Equals, true)
		c.Expect(s5.Left(linear.Vec2{999.5, 1000.4999}), Equals, true)
		c.Expect(s5.Right(linear.Vec2{999.5, 1000.4999}), Equals, false)
	})
}
コード例 #5
0
ファイル: linear_test.go プロジェクト: runningwild/linear
func SegmentsSpec2(c gospec.Context) {
	s1 := linear.MakeSeg2(0, 0, 9, 9)
	s2 := linear.MakeSeg2(0, 5, 10, 5)
	s3 := linear.MakeSeg2(-10, 10, -20, 10)
	s4 := linear.MakeSeg2(-15, 10000, -15, -10000)
	s5 := linear.MakeSeg2(0, 1, 1, 0)
	s6 := linear.MakeSeg2(0.4, 0.4, 0.6, 0.6)
	s7 := linear.MakeSeg2(0.5, 0.5, 0.6, 0.6)
	s8 := linear.MakeSeg2(0.4, 0.4, 0.5, 0.5)
	c.Specify("Check function that determines whether or not segments intersect.", func() {
		c.Expect(s1.DoesIsect(s2), Equals, true)
		c.Expect(s2.DoesIsect(s1), Equals, true)
		c.Expect(s3.DoesIsect(s4), Equals, true)
		c.Expect(s4.DoesIsect(s3), Equals, true)
		c.Expect(s1.DoesIsect(s3), Equals, false)
		c.Expect(s1.DoesIsect(s4), Equals, false)
		c.Expect(s2.DoesIsect(s3), Equals, false)
		c.Expect(s2.DoesIsect(s4), Equals, false)
		c.Expect(s3.DoesIsect(s1), Equals, false)
		c.Expect(s3.DoesIsect(s2), Equals, false)
		c.Expect(s4.DoesIsect(s1), Equals, false)
		c.Expect(s4.DoesIsect(s2), Equals, false)
		c.Expect(s5.DoesIsect(s6), Equals, true)
		c.Expect(s5.DoesIsect(s7), Equals, false)
		c.Expect(s5.DoesIsect(s8), Equals, false)
		c.Expect(s6.DoesIsect(s5), Equals, true)
		c.Expect(s7.DoesIsect(s5), Equals, false)
		c.Expect(s8.DoesIsect(s5), Equals, false)
	})
	t0 := linear.MakeSeg2(0, 0, 5, 5)
	t1 := linear.MakeSeg2(0, 10, 10, 0)
	t2 := linear.MakeSeg2(0, 0, 4.99, 4.99)
	c.Specify("Check function that determines whether or not segments intersect or touch.", func() {
		// Should return true for everything that DoesIsect returns true for.
		c.Expect(s1.DoesIsectOrTouch(s2), Equals, true)
		c.Expect(s2.DoesIsectOrTouch(s1), Equals, true)
		c.Expect(s3.DoesIsectOrTouch(s4), Equals, true)
		c.Expect(s4.DoesIsectOrTouch(s3), Equals, true)
		c.Expect(s5.DoesIsectOrTouch(s6), Equals, true)
		c.Expect(s6.DoesIsectOrTouch(s5), Equals, true)

		c.Expect(t0.DoesIsectOrTouch(t1), Equals, true)
		c.Expect(t2.DoesIsectOrTouch(t1), Equals, false)
	})
}
コード例 #6
0
ファイル: game.go プロジェクト: dgthunder/magnus
func (p *Player) Think(g *Game) {
	if p.Exile_frames > 0 {
		p.Exile_frames--
		return
	}

	// This will clear out old conditions
	p.Stats.Think()
	var dead []int
	for i, process := range p.Processes {
		process.Think(g)
		if process.Phase() == PhaseComplete {
			dead = append(dead, i)
		}
	}
	for _, i := range dead {
		delete(p.Processes, i)
	}
	// And here we add back in all processes that are still alive.
	for _, process := range p.Processes {
		p.Stats.ApplyCondition(process)
	}

	if p.Delta.Speed > p.Stats.MaxAcc() {
		p.Delta.Speed = p.Stats.MaxAcc()
	}
	if p.Delta.Speed < -p.Stats.MaxAcc() {
		p.Delta.Speed = -p.Stats.MaxAcc()
	}
	if p.Delta.Angle < -p.Stats.MaxTurn() {
		p.Delta.Angle = -p.Stats.MaxTurn()
	}
	if p.Delta.Angle > p.Stats.MaxTurn() {
		p.Delta.Angle = p.Stats.MaxTurn()
	}

	in_lava := false
	for _, lava := range g.Room.Lava {
		if vecInsideConvexPoly(p.Pos(), lava) {
			in_lava = true
		}
	}
	if in_lava {
		p.Stats.ApplyDamage(stats.Damage{stats.DamageFire, 5})
	}

	p.Vx += p.Delta.Speed * math.Cos(p.Angle)
	p.Vy += p.Delta.Speed * math.Sin(p.Angle)
	mangle := math.Atan2(p.Vy, p.Vx)
	friction := g.Friction
	if in_lava {
		friction = g.Friction_lava
	}
	p.Vx *= math.Pow(friction, 1+3*math.Abs(math.Sin(p.Angle-mangle)))
	p.Vy *= math.Pow(friction, 1+3*math.Abs(math.Sin(p.Angle-mangle)))

	move := linear.MakeSeg2(p.X, p.Y, p.X+p.Vx, p.Y+p.Vy)
	size := 12.0
	px := p.X
	py := p.Y
	p.X += p.Vx
	p.Y += p.Vy
	for _, poly := range g.Room.Walls {
		for i := range poly {
			// First check against the leading vertex
			{
				v := poly[i]
				dist := v.DistToLine(move)
				if v.Sub(move.Q).Mag() < size {
					dist = v.Sub(move.Q).Mag()
					// Add a little extra here otherwise a player can sneak into geometry
					// through the corners
					ray := move.Q.Sub(v).Norm().Scale(size + 0.1)
					final := v.Add(ray)
					move.Q.X = final.X
					move.Q.Y = final.Y
				} else if dist < size {
					// TODO: This tries to prevent passthrough but has other problems
					// cross := move.Ray().Cross()
					// perp := linear.Seg2{v, cross.Sub(v)}
					// if perp.Left(move.P) != perp.Left(move.Q) {
					//   shift := perp.Ray().Norm().Scale(size - dist)
					//   move.Q.X += shift.X
					//   move.Q.Y += shift.Y
					// }
				}
			}

			// Now check against the segment itself
			w := poly.Seg(i)
			if w.Ray().Cross().Dot(move.Ray()) <= 0 {
				shift := w.Ray().Cross().Norm().Scale(size)
				col := linear.Seg2{shift.Add(w.P), shift.Add(w.Q)}
				if move.DoesIsect(col) {
					cross := col.Ray().Cross()
					fix := linear.Seg2{move.Q, cross.Add(move.Q)}
					isect := fix.Isect(col)
					move.Q.X = isect.X
					move.Q.Y = isect.Y
				}
			}
		}
	}
	p.X = move.Q.X
	p.Y = move.Q.Y
	p.Vx = p.X - px
	p.Vy = p.Y - py

	p.Angle += p.Delta.Angle
	if p.Angle < 0 {
		p.Angle += math.Pi * 2
	}
	if p.Angle > math.Pi*2 {
		p.Angle -= math.Pi * 2
	}

	p.Delta.Angle = 0
	p.Delta.Speed = 0
}