示例#1
0
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
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
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
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
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
}