func step(dt float32) { space.Step(vect.Float(dt)) for i := 0; i < len(rooms); i++ { rooms[i].Box.Body.SetAngle(vect.Float(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 }
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)) } }
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) }
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)}) } } }
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() } }
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)) } }
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) }
// 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, } }
// 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)) } }
// 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 }
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) }
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) }
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 }
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) } } }
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} }
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} }
// 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 }
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} }
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 }
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) } } } }
// 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 } } }
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 }
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) }
// 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 } } }
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)) }
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 }