func step(dt float32) {
	space.Step(vect.Float(dt))

	for i := 0; i < len(rooms); i++ {
		rooms[i].Box.Body.SetAngle(vect.Float(0))
	}
}
Пример #2
0
func circle2circleQuery(p1, p2 vect.Vect, r1, r2 vect.Float, con *Contact) int {
	minDist := r1 + r2

	delta := vect.Sub(p2, p1)
	distSqr := delta.LengthSqr()

	if distSqr >= minDist*minDist {
		return 0
	}

	dist := vect.Float(math.Sqrt(float64(distSqr)))

	pDist := dist
	if dist == 0.0 {
		pDist = vect.Float(math.Inf(1))
	}

	pos := vect.Add(p1, vect.Mult(delta, 0.5+(r1-0.5*minDist)/pDist))

	norm := vect.Vect{1, 0}

	if dist != 0.0 {
		norm = vect.Mult(delta, 1.0/dist)
	}

	con.reset(pos, norm, dist-minDist, 0)

	return 1
}
Пример #3
0
func newBox(width, height float32) *box {
	var err error

	box := new(box)

	// Sound player

	box.player, err = mandala.NewAudioPlayer()
	if err != nil {
		mandala.Fatalf("%s\n", err.Error())
	}

	// Chipmunk body

	box.physicsShape = chipmunk.NewBox(
		vect.Vect{0, 0},
		vect.Float(width),
		vect.Float(height),
	)

	box.physicsShape.SetElasticity(BoxElasticity)
	box.physicsBody = chipmunk.NewBody(vect.Float(BoxMass), box.physicsShape.Moment(float32(BoxMass)))
	box.physicsBody.AddShape(box.physicsShape)
	box.physicsBody.CallbackHandler = callbacks{}

	// OpenGL shape

	box.openglShape = shapes.NewBox(width, height)

	return box
}
func jump() {
	// add a computer beep on jump.
	fmt.Print("\x07")
	for _, flappyBird := range flappyBirds {
		flappyBird.Body.UpdateVelocity(space.Gravity, vect.Float(-.1), vect.Float(-.3))
	}
}
Пример #5
0
func (w *world) dropBox(x, y float32) {
	box := newBox(20, 20)
	box.physicsBody.SetMass(200)
	box.physicsBody.AddAngularVelocity(10)
	box.physicsBody.SetAngle(vect.Float(2 * math.Pi * chipmunk.DegreeConst * rand.Float32()))
	box.physicsBody.SetPosition(vect.Vect{vect.Float(x), vect.Float(float32(w.height) - y)})
	w.addBox(box)
}
Пример #6
0
func (w *World) CreateFromSvg(filename string) {
	var svg svgFile

	responseCh := make(chan mandala.LoadResourceResponse)
	mandala.ReadResource(filename, responseCh)
	response := <-responseCh

	if response.Error != nil {
		mandala.Fatalf(response.Error.Error())
	}
	buf := response.Buffer

	err := xml.Unmarshal(buf, &svg)
	if err != nil {
		mandala.Fatalf(err.Error())
	}

	scaleX := float32(w.width) / svg.Width
	scaleY := float32(w.height) / svg.Height

	for _, group := range svg.Groups {
		for _, rect := range group.Rects {
			rX := (rect.X + rect.Width/2) * scaleX
			rY := float32(w.height) - (rect.Y+rect.Height/2)*scaleY
			rW := rect.Width * scaleX
			rH := rect.Height * scaleY
			box := newBox(w, rW, rH)
			pos := vect.Vect{
				vect.Float(rX),
				vect.Float(rY),
			}

			box.physicsBody.SetPosition(pos)

			if rect.Transform != "" {
				var a, b, c float32
				_, err = fmt.Sscanf(rect.Transform, "rotate(%f %f,%f)", &a, &b, &c)
				if err != nil {
					mandala.Fatalf(err.Error())
				}
				box.physicsBody.SetAngle(90 / chipmunk.DegreeConst)
			}

			box.openglShape.SetColor(colorful.HappyColor())
			w.addBox(box)
		}
	}
	line := svg.Groups[0].Line
	w.setGround(newGround(
		w,
		0,
		float32(w.height)-float32(line.Y1*scaleY),
		float32(w.width),
		float32(w.height)-float32(line.Y2*scaleY),
	))
}
// add a row of 7 pipe boxes to the space
func addPipe() {
	// pick a random position for hole in the pipe
	hole := int(math.Floor(rand.Float64()*6)) + 1
	// add pipe boxes
	for i := 0; i < 9; i++ {
		if i != hole && i != hole+1 {
			addOnePipeBox(vect.Vect{vect.Float(winWidth), vect.Float(i*60 + 30 + i*10)})
		}
	}
}
Пример #8
0
func preStepGameObject(g *GameObject) {
	if g.Physics != nil && g.active && !g.Physics.Body.IsStatic() && g.Physics.started() {
		pos := g.Transform().WorldPosition()
		angle := g.Transform().Angle() * RadianConst

		if g.Physics.Interpolate {
			//Interpolation check: if position/angle has been changed directly and not by the physics engine, change g.Physics.lastPosition/lastAngle
			if vect.Float(pos.X) != g.Physics.interpolatedPosition.X || vect.Float(pos.Y) != g.Physics.interpolatedPosition.Y {
				g.Physics.interpolatedPosition = vect.Vect{vect.Float(pos.X), vect.Float(pos.Y)}
				g.Physics.Body.SetPosition(g.Physics.interpolatedPosition)
			}
			if vect.Float(angle) != g.Physics.interpolatedAngle {
				g.Physics.interpolatedAngle = vect.Float(angle)
				g.Physics.Body.SetAngle(g.Physics.interpolatedAngle)
			}
		} else {
			var pPos vect.Vect
			pPos.X, pPos.Y = vect.Float(pos.X), vect.Float(pos.Y)

			g.Physics.Body.SetAngle(vect.Float(angle))
			g.Physics.Body.SetPosition(pPos)
		}
		g.Physics.lastPosition = g.Physics.Body.Position()
		g.Physics.lastAngle = g.Physics.Body.Angle()
	}
}
Пример #9
0
func (w *world) explosion(x, y float32) {
	w.explosionPlayer.Play(w.explosionBuffer, nil)
	y = float32(w.height) - y
	for _, box := range w.boxes {
		cx, cy := box.openglShape.Center()
		force := vect.Sub(vect.Vect{vect.Float(cx), vect.Float(cy)}, vect.Vect{vect.Float(x), vect.Float(y)})
		length := force.Length()
		force.Normalize()
		force.Mult(vect.Float(1 / length * 3e6))
		box.physicsBody.SetForce(float32(force.X), float32(force.Y))
	}
}
Пример #10
0
func addBall() {
	x := rand.Intn(350-115) + 115
	ball := chipmunk.NewCircle(vect.Vector_Zero, float32(ballRadius))
	ball.SetElasticity(0.95)

	body := chipmunk.NewBody(vect.Float(ballMass), ball.Moment(float32(ballMass)))
	body.SetPosition(vect.Vect{vect.Float(x), 600.0})
	body.SetAngle(vect.Float(rand.Float32() * 2 * math.Pi))

	body.AddShape(ball)
	space.AddBody(body)
	balls = append(balls, ball)
}
Пример #11
0
// add a pipe box to the space
func addOnePipeBox(pos vect.Vect) {
	pipeBox := chipmunk.NewBox(vect.Vector_Zero, vect.Float(pipeSide), vect.Float(pipeSide))
	pipeBox.SetElasticity(0.6)

	body := chipmunk.NewBody(chipmunk.Inf, chipmunk.Inf)
	body.SetPosition(pos)
	body.SetVelocity(pipeVelX, pipeVelY)
	body.IgnoreGravity = true

	body.AddShape(pipeBox)
	space.AddBody(body)
	pipe = append(pipe, pipeBox)
}
func getRandomPointInCircle(radius float64) vect.Vect {
	t := 2 * math.Pi * rand.Float64()
	u := rand.Float64() + rand.Float64()
	r := .0
	if u > 1 {
		r = 2 - u
	} else {
		r = u
	}
	return vect.Vect{
		X: vect.Float(roundm(radius*r*math.Cos(t), 4.0)) + 300,
		Y: vect.Float(roundm(radius*r*math.Sin(t), 4.0)) + 300,
	}
}
Пример #13
0
// Explosion produce an explosion at the given coordinates.
func (w *World) Explosion(x, y float32) {
	w.explosionPlayer.Play(w.explosionBuffer, nil)
	y = float32(w.height) - y
	for _, box := range w.boxes {
		cx, cy := box.openglShape.Center()
		force := vect.Sub(
			vect.Vect{vect.Float(cx / float32(w.width)), vect.Float(cy / float32(w.height))},
			vect.Vect{vect.Float(x / float32(w.width)), vect.Float(y / float32(w.height))},
		)
		force.Normalize()
		force.Mult(vect.Float(1 / force.Length() * 1e5))
		box.physicsBody.SetForce(float32(force.X), float32(force.Y))
	}
}
Пример #14
0
// Remove removes the box at the given coordinates.
func (w *World) Remove(x, y float32) int {
	y = float32(w.height) - y
	for id, box := range w.boxes {
		cx, cy := box.openglShape.Center()
		distance := vect.Sub(
			vect.Vect{vect.Float(cx), vect.Float(cy)},
			vect.Vect{vect.Float(x), vect.Float(y)},
		)
		if distance.LengthSqr() < vect.Float(BoxSize) {
			w.removeBox(box, id)
			return id
		}
	}
	return -1
}
Пример #15
0
func addFlappy() {
	flappyBird := chipmunk.NewBox(vect.Vector_Zero, vect.Float(pipeSide), vect.Float(pipeSide))
	flappyBird.SetElasticity(0.95)

	body := chipmunk.NewBody(vect.Float(flappyMass), vect.Float(flappyMoment))
	body.SetPosition(vect.Vect{100, vect.Float(winHeight)})
	body.SetAngularVelocity(float32(10 * deg2rad))

	// hook collision events
	handlers := collisionHandlers{}
	body.CallbackHandler = handlers

	body.AddShape(flappyBird)
	space.AddBody(body)
	flappyBirds = append(flappyBirds, flappyBird)
}
Пример #16
0
func (p *Physics) Start() {
	//p.Interpolate = true
	pos := p.GameObject().Transform().WorldPosition()
	p.Body.SetAngle(vect.Float(p.GameObject().Transform().WorldRotation().Z) * RadianConst)
	p.Body.SetPosition(vect.Vect{vect.Float(pos.X), vect.Float(pos.Y)})
	p.lastPosition = p.Body.Position()
	p.lastAngle = p.Body.Angle()

	if p.GameObject().Sprite != nil {
		p.GameObject().Sprite.UpdateShape()
		p.Body.UpdateShapes()
	}

	//p.Body.UpdateShapes()
	Space.AddBody(p.Body)
}
Пример #17
0
func NewPhysics(static bool) *Physics {
	var body *chipmunk.Body

	box := chipmunk.NewBox(vect.Vect{0, 0}, vect.Float(1), vect.Float(1))

	if static {
		body = chipmunk.NewBodyStatic()
	} else {
		body = chipmunk.NewBody(1, box.Moment(1))
	}

	p := &Physics{BaseComponent: NewComponent(), Body: body, Box: box.GetAsBox(), Shape: box}

	body.AddShape(box)
	return p
}
Пример #18
0
func (cSpace *ChipmonkSpace) Update(dt float64) {
	cSpace.Space.Step(vect.Float(dt))
	if cSpace.OnCollision != nil {
		for _, a := range cSpace.Space.Arbiters {
			cSpace.OnCollision(a.ShapeA, a.ShapeB)
		}
	}
}
Пример #19
0
func NewEnemy(ballRadius, ballMass int32, game *Game) *Enemy {
	x := rand.Intn(1280)
	ball := chipmunk.NewCircle(vect.Vector_Zero, float32(ballRadius))
	ball.SetElasticity(0.95)
	ball.SetFriction(1.5)

	body := chipmunk.NewBody(vect.Float(ballMass), ball.Moment(float32(ballMass)))
	body.SetPosition(vect.Vect{vect.Float(x), 800.0})
	body.SetPosition(vect.Vect{vect.Float(x), 600.0})
	body.SetAngle(vect.Float(rand.Float32() * 2 * math.Pi))

	body.AddShape(ball)

	game.Space.AddBody(body)

	return &Enemy{Body: ball.Body, ball: ball, alive: true, Radius: ballRadius, Mass: ballMass}
}
Пример #20
0
func NewPlayer(ballRadius, ballMass int32, game *Game) *Player {
	x := rand.Intn(350-115) + 115
	ball := chipmunk.NewCircle(vect.Vector_Zero, float32(ballRadius))
	ball.SetElasticity(0.95)
	ball.SetFriction(1.5)

	body := chipmunk.NewBody(vect.Float(ballMass), ball.Moment(float32(ballMass)))
	body.SetPosition(vect.Vect{vect.Float(x), 600.0})
	body.SetAngle(vect.Float(rand.Float32() * 2 * math.Pi))

	body.AddShape(ball)

	game.Space.AddBody(body)

	return &Player{Body: ball.Body, ball: ball,
		Radius: ballRadius, Mass: ballMass,
		jumpTickStop: 2, jumpTick: 0, jumping: false, speed: 5}
}
Пример #21
0
// Creates a new CircleShape with the given center and radius.
func NewCircle(pos vect.Vect, radius float32) *Shape {
	shape := newShape()
	circle := &CircleShape{
		Position: pos,
		Radius:   vect.Float(radius),
		Shape:    shape,
	}
	shape.ShapeClass = circle
	return shape
}
Пример #22
0
func k_tensor(a, b *Body, r1, r2 vect.Vect, k1, k2 *vect.Vect) {
	// calculate mass matrix
	// If I wasn't lazy and wrote a proper matrix class, this wouldn't be so gross...
	m_sum := a.m_inv + b.m_inv

	// start with I*m_sum
	k11 := vect.Float(m_sum)
	k12 := vect.Float(0)
	k21 := vect.Float(0)
	k22 := vect.Float(m_sum)

	// add the influence from r1
	a_i_inv := a.i_inv
	r1xsq := r1.X * r1.X * a_i_inv
	r1ysq := r1.Y * r1.Y * a_i_inv
	r1nxy := -r1.X * r1.Y * a_i_inv
	k11 += r1ysq
	k12 += r1nxy
	k21 += r1nxy
	k22 += r1xsq

	// add the influnce from r2
	b_i_inv := b.i_inv
	r2xsq := r2.X * r2.X * b_i_inv
	r2ysq := r2.Y * r2.Y * b_i_inv
	r2nxy := -r2.X * r2.Y * b_i_inv
	k11 += r2ysq
	k12 += r2nxy
	k21 += r2nxy
	k22 += r2xsq

	// invert
	determinant := (k11 * k22) - (k12 * k21)
	if determinant == 0 {
		panic("Unsolvable constraint.")
	}

	det_inv := 1.0 / determinant
	*k1 = vect.Vect{k22 * det_inv, -k12 * det_inv}
	*k2 = vect.Vect{-k21 * det_inv, k11 * det_inv}
}
Пример #23
0
func newGround(x1, y1, x2, y2 float32) *ground {
	ground := new(ground)

	// Chipmunk body

	ground.physicsBody = chipmunk.NewBodyStatic()
	ground.physicsShape = chipmunk.NewSegment(
		vect.Vect{vect.Float(x1), vect.Float(y1)},
		vect.Vect{vect.Float(x2), vect.Float(y2)},
		GroundRadius,
	)

	ground.physicsBody.AddShape(ground.physicsShape)

	// OpenGL shape

	ground.openglShape = shapes.NewSegment(x1, y1, x2, y2)
	ground.openglShape.Color(color.White)

	return ground
}
Пример #24
0
func (w *world) createFromString(s []string) {
	// Number of boxes of both axes
	nY := len(s)
	nX := len(s[0])

	// Y coord of the ground
	_, groundY := w.ground.openglShape.Center()
	maxY := float32(w.height)
	maxHeight := float32(maxY) - groundY

	// Calculate box size
	boxW := float32(w.width) / float32(nX)
	boxH := maxHeight / float32(nY)

	// Force a square box
	if boxW >= boxH {
		boxW = boxH
	} else {
		boxH = boxW
	}

	startY := groundY + float32(nY)*boxH

	for y, line := range s {
		for x, b := range line {
			if b == '+' {
				box := newBox(boxW, boxH)
				pos := vect.Vect{
					vect.Float(float32(x) * boxW),
					vect.Float(startY - (float32(y) * boxH)),
				}
				box.physicsBody.SetPosition(pos)
				box.physicsBody.SetAngle(0)
				box.openglShape.Color(colorful.HappyColor())
				w.addBox(box)
			}
		}
	}
}
Пример #25
0
// step advances the physics engine and cleans up flappy or any pipes that are off-screen
func step(dt float32) {
	space.Step(vect.Float(dt))

	// clean up flappy
	for i := 0; i < len(flappyBirds); i++ {
		p := flappyBirds[i].Body.Position()
		if p.Y < vect.Float(-pipeSide/2) || p.Y > vect.Float(winHeight+pipeSide/2) {
			restartGame()
		}
	}

	// clean up any off-screen pipe
	for i := 0; i < len(pipe); i++ {
		p := pipe[i].Body.Position()
		if p.X < vect.Float(-pipeSide/2) {
			space.RemoveBody(pipe[i].Body)
			pipe[i] = nil
			pipe = append(pipe[:i], pipe[i+1:]...)
			i-- // consider same index again
		}
	}
}
Пример #26
0
func newBox(world *World, width, height float32) *Box {
	box := new(Box)

	// Chipmunk body

	box.physicsShape = chipmunk.NewBox(
		vect.Vect{0, 0},
		vect.Float(width),
		vect.Float(height),
	)

	box.physicsShape.SetElasticity(BoxElasticity)
	box.physicsBody = chipmunk.NewBody(vect.Float(BoxMass), box.physicsShape.Moment(float32(BoxMass)))
	box.physicsBody.AddShape(box.physicsShape)
	box.physicsBody.CallbackHandler = callbacks{}

	// OpenGL shape

	box.openglShape = shapes.NewBox(world.boxProgramShader, width, height)

	return box
}
Пример #27
0
func (poly *PolygonShape) Moment(mass float32) vect.Float {

	sum1 := vect.Float(0)
	sum2 := vect.Float(0)

	println("using bad Moment calculation")
	offset := vect.Vect{0, 0}

	for i := 0; i < poly.NumVerts; i++ {

		v1 := vect.Add(poly.Verts[i], offset)
		v2 := vect.Add(poly.Verts[(i+1)%poly.NumVerts], offset)

		a := vect.Cross(v2, v1)
		b := vect.Dot(v1, v1) + vect.Dot(v1, v2) + vect.Dot(v2, v2)

		sum1 += a * b
		sum2 += a
	}

	return (vect.Float(mass) * sum1) / (6.0 * sum2)
}
Пример #28
0
// step advances the physics engine and cleans up any balls that are off-screen
func step(dt float32) {
	space.Step(vect.Float(dt))

	for i := 0; i < len(balls); i++ {
		p := balls[i].Body.Position()
		if p.Y < -100 {
			space.RemoveBody(balls[i].Body)
			balls[i] = nil
			balls = append(balls[:i], balls[i+1:]...)
			i-- // consider same index again
		}
	}
}
Пример #29
0
func (m *Map) GenerateCollision() {

	var shapes []*chipmunk.Shape

	for x := 0; x < m.Width; x++ {
		for y := 0; y < m.Height; y++ {
			if t, e := m.GetTile(x, y); e {
				if t.Collision() != CollisionNone {
					p, _ := m.GetTilePos(x, y)
					shape := chipmunk.NewBox(vect.Vect{vect.Float(p.X), vect.Float(p.Y)},
						vect.Float(m.TileSize), vect.Float(m.TileSize))

					shape.Layer = chipmunk.Layer(m.Layer)
					shape.SetFriction(0)
					shapes = append(shapes, shape)
				}
			}
		}
	}

	m.GameObject().AddComponent(engine.NewPhysicsShapes(true, shapes))

}
Пример #30
0
func (this *PlayerController) Start() {
	j := engine.NewGameObject("Joint")
	j.Transform().SetParent2(GameSceneGeneral.Layer1)
	j.Transform().SetWorldPosition(this.Transform().WorldPosition())
	j.AddComponent(engine.NewPhysics(false))
	j.Physics.Body.SetMass(engine.Inf)
	j.Physics.Body.SetMoment(engine.Inf)
	this.Joint = chipmunk.NewPivotJoint(j.Physics.Body, this.GameObject().Physics.Body)
	engine.Space.AddConstraint(this.Joint)
	j.Physics.Shape.IsSensor = true
	this.Joint.MaxBias = vect.Float(this.WalkSpeed)
	this.Joint.MaxForce = 3000
	this.JointGameObject = j
}