예제 #1
0
func (p *Physics) isValidPlace(pt state.Point, size state.Sized, gamestate state.GameState) bool {
	hasCollision := false

	powerup := state.Powerup{
		Sized: size,
		Point: pt,
	}
	for _, b := range gamestate.Bases {
		if collision.Collides(powerup, b) {
			hasCollision = true
		}
	}
	for _, v := range gamestate.Vehicles {
		if collision.Collides(powerup, v) {
			hasCollision = true
		}
	}
	for _, b := range gamestate.Shields {
		if collision.Collides(powerup, b) {
			hasCollision = true
		}
	}
	for _, s := range gamestate.ShieldGenerators {
		if collision.Collides(powerup, s) {
			hasCollision = true
		}
	}
	for _, p := range gamestate.PowerUps {
		if collision.Collides(powerup, p) {
			hasCollision = true
		}
	}

	return !hasCollision
}
예제 #2
0
func (p *Physics) MoveRocket(rocket *state.Rocket, duration time.Duration) {

	t := rocket.Target
	if t == nil {
		rocket.ShouldRemove = true
		return
	}

	dx := t.X - rocket.X
	dy := t.Y - rocket.Y
	rocket.Angle = math.Atan2(dy, dx) * RadToDeg
	x, y := p.move2d(rocket.X, rocket.Y, rocket.Angle, rocket.Velocity, duration)

	rocket.X = x
	rocket.Y = y

	if collision.Collides(rocket, t) {
		rocket.ShouldRemove = true
		p.damageVehicle(t, p.BulletDamage*20)
	}
}
예제 #3
0
// Performs next step in the game
// Empties g.commandsToProcess and processes them
// Also progresses GameState based upon elapsed time
// Threadsafe
func (g *GameManager) tick() {
	commandsMutex.Lock()
	commands := g.commandsToProcess
	g.commandsToProcess = g.commandsToProcess[:0]
	commandsMutex.Unlock()

	stateMutex.Lock()
	tickDuration := time.Since(g.lastTick)
	if tickDuration > (50 * time.Millisecond) {
		log.Println("Lag spike detected")
	}

	for _, command := range commands {
		proc := g.commandFactory.GetCommandProcessor(command)
		proc.Run(&(g.gameState), *command)
	}

	g.physicsManager.ApplyGravity(&g.gameState)

	if time.Since(g.lastPowerupDespawn) >= g.physicsManager.PowerupRespawn && len(g.gameState.PowerUps) < g.physicsManager.MaxPowerups {
		g.physicsManager.SpawnPowerup(&g.gameState)
		g.lastPowerupDespawn = time.Now()
	}

	for _, rocket := range g.gameState.Rockets {
		g.physicsManager.MoveRocket(rocket, tickDuration)
	}

	for _, well := range g.gameState.GravityWells {
		if time.Now().After(well.Expires) {
			well.ShouldRemove = true
		}
	}

	for _, bullet := range g.gameState.Bullets {
		g.physicsManager.MoveBullet(bullet, tickDuration)
		g.physicsManager.BoundBullet(bullet)
	}

	for _, bullet := range g.gameState.Bullets {

		for _, shield := range g.gameState.Shields {
			if shield.IsEnabled {
				if collision.Collides(bullet, shield) {
					bullet.ShouldRemove = true
				}
			}
		}

		for _, shieldGenerator := range g.gameState.ShieldGenerators {
			if collision.Collides(shieldGenerator, bullet) {
				g.physicsManager.DamageShieldGenerator(bullet, shieldGenerator)
			}
		}

		for _, base := range g.gameState.Bases {
			if collision.Collides(bullet, base) {
				if g.physicsManager.DamageBase(bullet, base) {
					g.gameState.GameOver = base.TeamId
					g.restartTime = time.Now().Add(time.Duration(g.gameRestart) * time.Second)
					g.gameState.SecToRestart = g.gameRestart
				}
			}
		}

	}

	for z, vehicle := range g.gameState.Vehicles {
		g.physicsManager.RespawnVehicle(vehicle, g.gameState)
		g.physicsManager.VehicleBounding(vehicle)
		g.physicsManager.MoveVehicle(vehicle, tickDuration)
		g.physicsManager.VehicleFrictionSlow(vehicle, tickDuration)

		for i := z + 1; i < len(g.gameState.Vehicles); i++ {
			if collision.Collides(vehicle, g.gameState.Vehicles[i]) {
				g.physicsManager.VehicleCollision(vehicle, g.gameState.Vehicles[i])
			}
		}
		for _, bullet := range g.gameState.Bullets {
			if bullet.OwnerId != vehicle.Owner && vehicle.IsAlive {
				if collision.Collides(vehicle, bullet) {
					g.physicsManager.DamageVehicle(vehicle, bullet)
				}
			}
		}

		for _, shield := range g.gameState.Shields {
			if shield.IsEnabled {
				if collision.Collides(shield, vehicle) {
					g.physicsManager.VehicleCollision(vehicle, &state.Vehicle{Angle: vehicle.Angle, IsAlive: true})
				}
			}
		}

		for _, shieldGenerator := range g.gameState.ShieldGenerators {
			if collision.Collides(shieldGenerator, vehicle) {
				g.physicsManager.VehicleCollision(vehicle, &state.Vehicle{Angle: vehicle.Angle, IsAlive: true})
			}
		}

		for _, base := range g.gameState.Bases {
			if collision.Collides(base, vehicle) {
				g.physicsManager.VehicleCollision(vehicle, &state.Vehicle{Angle: vehicle.Angle, IsAlive: true})
			}
		}

		for _, powerup := range g.gameState.PowerUps {
			if collision.Collides(powerup, vehicle) {
				g.physicsManager.PickupPowerUp(vehicle, powerup)
				g.lastPowerupDespawn = time.Now()
			}
		}

	}

	g.gameState.Bullets = processor.CleanupBullets(g.gameState.Bullets)
	g.gameState.PowerUps = processor.CleanupPowerups(g.gameState.PowerUps)
	g.gameState.Rockets = processor.CleanupRockets(g.gameState.Rockets)
	g.gameState.GravityWells = processor.CleanupWells(g.gameState.GravityWells)

	stateMutex.Unlock()

}
예제 #4
0
func TestCollisions(t *testing.T) {
	Convey("Basic No Collision", t, func() {
		v1 := state.Vehicle{
			Point: state.NewPoint(10, 10),
			Sized: state.NewSized(10, 10),
			Angle: 0}
		v2 := state.Vehicle{
			Point: state.NewPoint(30, 30),
			Sized: state.NewSized(10, 10),
			Angle: 0}

		check := collision.Collides(v1, v2)

		So(check, ShouldEqual, false)
	})

	Convey("Basic Should Collide", t, func() {
		v1 := state.Vehicle{
			Point: state.NewPoint(10, 10),
			Sized: state.NewSized(10, 10),
			Angle: 0}

		v2 := state.Vehicle{
			Point: state.NewPoint(5, 5),
			Sized: state.NewSized(10, 10),
			Angle: 0}
		check := collision.Collides(v1, v2)

		So(check, ShouldEqual, true)
	})

	Convey("Basic Should Collide", t, func() {
		v1 := state.Vehicle{
			Point: state.NewPoint(10, 10),
			Sized: state.NewSized(10, 10),
			Angle: 0}
		v2 := state.Vehicle{
			Point: state.NewPoint(7, 7),
			Sized: state.NewSized(10, 10),
			Angle: 0}
		check := collision.Collides(v1, v2)

		So(check, ShouldEqual, true)
	})

	Convey("Basic Should Collide with Rotation", t, func() {
		v1 := state.Vehicle{
			Point: state.NewPoint(10, 10),
			Sized: state.NewSized(10, 10),
			Angle: 90}
		v2 := state.Vehicle{
			Point: state.NewPoint(7, 7),
			Sized: state.NewSized(10, 10),
			Angle: 0}
		check := collision.Collides(v1, v2)

		So(check, ShouldEqual, true)
	})

	Convey("Basic Should Collide with Rotation", t, func() {
		v1 := state.Vehicle{
			Point: state.NewPoint(10, 10),
			Sized: state.NewSized(10, 10),
			Angle: 90}
		v2 := state.Vehicle{
			Point: state.NewPoint(7, 7),
			Sized: state.NewSized(10, 10),
			Angle: 90}
		check := collision.Collides(v1, v2)

		So(check, ShouldEqual, true)
	})
}