Ejemplo n.º 1
0
// Handle movement assuming there is a physics body associated with the camera.
// This attempts to smooth out movement by adding a higher initial velocity push
// and then capping movement once max accelleration is reached.
func (c *cam) move(bod vu.Pov, x, y, z float64, dir *lin.Q) {
	if body := bod.Body(); body != nil {
		boost := 40.0    // kick into high gear from stop.
		maxAccel := 10.0 // limit accelleration.
		sx, _, sz := body.Speed()
		if x != 0 {
			switch {
			case sx == 0.0:
				// apply push in the current direction.
				dx, dy, dz := lin.MultSQ(x*boost, 0, 0, dir)
				body.Push(dx, dy, dz)
			case math.Abs(sx) < maxAccel && math.Abs(sz) < maxAccel:
				dx, dy, dz := lin.MultSQ(x, 0, 0, dir)
				body.Push(dx, dy, dz)
			}
		}
		if z != 0 {
			switch {
			case sz == 0.0:
				dx, dy, dz := lin.MultSQ(0, 0, z*boost, dir)
				body.Push(dx, dy, dz)
			case math.Abs(sx) < maxAccel && math.Abs(sz) < maxAccel:
				dx, dy, dz := lin.MultSQ(0, 0, z, dir)
				body.Push(dx, dy, dz)
			}
		}
	} else {
		bod.Move(x, y, z, dir)
	}
}
Ejemplo n.º 2
0
// newPlayer sets the player hud location and creates the white background.
func newPlayer(root vu.Pov, screenWidth, screenHeight int) *player {
	pl := &player{}
	pl.cx, pl.cy = 100, 100
	pl.bg = root.NewPov().SetScale(110, 110, 1).SetLocation(pl.cx, pl.cy, 0)
	pl.bg.NewModel("uv").LoadMesh("icon").AddTex("hudbg")
	return pl
}
Ejemplo n.º 3
0
Archivo: sg.go Proyecto: skyview059/vu
// newCube's are often started with 1 corner, 2 edges, or 4 bottom side pieces.
func newCube(tr vu.Pov, x, y, z, cubeSize float64) *cube {
	c := &cube{}
	c.part = tr.NewPov()
	c.cells = []vu.Pov{}
	c.cx, c.cy, c.cz, c.csize = x, y, z, cubeSize
	c.ccnt, c.cmax = 0, 8
	c.mergec = func() { c.merge() }
	c.trashc = func() { c.trash() }
	c.addc = func() { c.addCell() }
	c.remc = func() { c.removeCell() }

	// calculate the cell center locations (unsorted)
	qs := c.csize * 0.25
	c.centers = csort{
		&lin.V3{X: x - qs, Y: y - qs, Z: z - qs},
		&lin.V3{X: x - qs, Y: y - qs, Z: z + qs},
		&lin.V3{X: x - qs, Y: y + qs, Z: z - qs},
		&lin.V3{X: x - qs, Y: y + qs, Z: z + qs},
		&lin.V3{X: x + qs, Y: y - qs, Z: z - qs},
		&lin.V3{X: x + qs, Y: y - qs, Z: z + qs},
		&lin.V3{X: x + qs, Y: y + qs, Z: z - qs},
		&lin.V3{X: x + qs, Y: y + qs, Z: z + qs},
	}
	return c
}
Ejemplo n.º 4
0
// newMinimap initializes the minimap. It still needs to be populated.
func newMinimap(root vu.Pov, numTroops int) *minimap {
	mm := &minimap{}
	mm.radius = 120
	mm.scale = 5.0
	mm.cores = []vu.Pov{}
	mm.view = root.NewView()
	mm.view.SetUI()
	mm.view.SetCull(vu.NewRadiusCull(float64(mm.radius)))
	mm.cam = mm.view.Cam()
	mm.cam.SetTransform(vu.XZ_XY)

	// create the parent for all the visible minimap pieces.
	mm.part = root.NewPov().SetLocation(float64(mm.x), 0, float64(-mm.y))

	// add the white background.
	mm.bg = mm.part.NewPov().SetScale(110, 1, 110)
	mm.bg.NewModel("uv").LoadMesh("icon_xz").AddTex("hudbg")

	// create the sentinel position markers
	mm.spms = []vu.Pov{}
	for cnt := 0; cnt < numTroops; cnt++ {
		tpm := mm.part.NewPov().SetScale(mm.scale, mm.scale, mm.scale)
		tpm.NewModel("alpha").LoadMesh("square_xz").LoadMat("tred")
		mm.spms = append(mm.spms, tpm)
	}

	// create the player marker and center map marker.
	mm.cpm = mm.part.NewPov().SetScale(mm.scale, mm.scale, mm.scale)
	mm.cpm.NewModel("alpha").LoadMesh("square_xz").LoadMat("blue")
	mm.ppm = mm.part.NewPov().SetScale(mm.scale, mm.scale, mm.scale)
	mm.ppm.NewModel("alpha").LoadMesh("tri_xz").LoadMat("tblack")
	return mm
}
Ejemplo n.º 5
0
Archivo: rl.go Proyecto: skyview059/vu
func (rl *rltag) newText(parent vu.Pov, gap int) vu.Model {
	text := parent.NewPov().SetLocation(10, 0, float64(-rl.wh+40+gap*24))
	text.Spin(-90, 0, 0) // orient to the X-Z plane.
	m := text.NewModel("uv").AddTex("lucidiaSu16White").LoadFont("lucidiaSu16")
	m.SetPhrase(" ")
	return m
}
Ejemplo n.º 6
0
// makePlayer: the player is the camera... the player-trooper is used by the hud
// to show player status and as such this trooper is part of the hud scene.
func (lvl *level) makePlayer(root vu.Pov, levelNum int) *trooper {
	player := newTrooper(root.NewPov(), levelNum)
	player.part.Spin(15, 0, 0)
	player.part.Spin(0, 15, 0)
	player.setScale(100)
	player.part.SetListener()
	return player
}
Ejemplo n.º 7
0
// createCore makes the new core model.
// Create a core image using a single multi-texture shader.
func (cc *coreControl) createCore(root vu.Pov, fade float64) vu.Pov {
	core := root.NewPov().SetScale(0.25, 0.25, 0.25)
	model := core.NewModel("spinball").LoadMesh("billboard")
	model.AddTex("ele").AddTex("ele").AddTex("halo").AddTex("halo")
	model.SetAlpha(0.6)
	model.SetUniform("fd", fade)
	return core
}
Ejemplo n.º 8
0
// energyLossEffect creates the model shown when the player gets hit
// by a sentinel.
func (hd *hud) energyLossEffect(root vu.Pov) vu.Pov {
	ee := root.NewPov()
	ee.SetVisible(false)
	m := ee.NewModel("uvra").LoadMesh("icon").AddTex("loss")
	m.SetAlpha(0.5)
	m.SetUniform("fd", 1000)
	m.SetUniform("spin", 2.0)
	return ee
}
Ejemplo n.º 9
0
// teleportEffect creates the model shown when the user teleports.
func (hd *hud) teleportEffect(root vu.Pov) vu.Pov {
	te := root.NewPov()
	te.SetVisible(false)
	m := te.NewModel("uvra").LoadMesh("icon").AddTex("smoke")
	m.SetAlpha(0.5)
	m.SetUniform("spin", 10.0)
	m.SetUniform("fd", 1000)
	return te
}
Ejemplo n.º 10
0
Archivo: rc.go Proyecto: toophy/vu
// makeSphere creates a sphere at the given x, y, z location and with
// the given r, g, b colour.
func (rc *rctag) makeSphere(parent vu.Pov, x, y, z float64, r, g, b float32) vu.Pov {
	sz := 0.5
	sp := parent.NewPov()
	sp.NewBody(vu.NewSphere(sz))
	sp.SetLocation(x, y, z)
	sp.SetScale(sz, sz, sz)
	model := sp.NewModel("solid").LoadMesh("sphere")
	model.SetUniform("kd", r, g, b)
	return sp
}
Ejemplo n.º 11
0
// makeSentries creates some AI sentinels.
func (lvl *level) makeSentries(root vu.Pov, levelNum int) {
	sentinels := []*sentinel{}
	numSentinels := gameMuster[levelNum]
	for cnt := 0; cnt < numSentinels; cnt++ {
		sentry := newSentinel(root.NewPov(), levelNum, lvl.units, lvl.fade)
		sentry.setScale(0.25)
		sentinels = append(sentinels, sentry)
	}
	lvl.sentries = sentinels
}
Ejemplo n.º 12
0
// newStartAnimation creates the start screen animation.
func newStartAnimation(mp *bampf, parent vu.Pov, screenWidth, screenHeight int) *startAnimation {
	sa := &startAnimation{}
	sa.parent = parent
	sa.scale = 200
	sa.hilite = parent.NewPov()
	sa.hilite.NewModel("alpha").LoadMesh("square").LoadMat("white")
	sa.hilite.SetVisible(false)
	sa.resize(screenWidth, screenHeight)
	sa.showLevel(0)
	return sa
}
Ejemplo n.º 13
0
// newPanel creates a panel with no cubes. The cubes are added later using
// panel.addCube().
func newPanel(part vu.Pov, x, y, z float64, level int) *panel {
	p := &panel{}
	p.part = part.NewPov()
	p.lvl = level
	p.cubes = []*cube{}
	p.cx, p.cy, p.cz = x, y, z
	p.ccnt, p.cmax = 0, (level-1)*(level-1)*8
	p.mergec = func() { p.merge() }
	p.trashc = func() { p.trash() }
	p.addc = func() { p.addCell() }
	p.remc = func() { p.removeCell() }
	return p
}
Ejemplo n.º 14
0
// newElectron creates a new electron model.
func newElectron(root vu.Pov, band int, angle float64) *electron {
	ele := &electron{}
	ele.band = band
	x, y := ele.initialLocation(angle)
	ele.core = root.NewPov().SetLocation(x, y, 0)

	// rotating image.
	cimg := ele.core.NewPov().SetScale(0.25, 0.25, 0.25)
	model := cimg.NewModel("spinball").LoadMesh("billboard")
	model.AddTex("ele").AddTex("ele").AddTex("halo").AddTex("halo")
	model.SetAlpha(0.6)
	return ele
}
Ejemplo n.º 15
0
// label adds a banner to a button or updates the banner if there is
// an existing banner.
func (b *button) label(part vu.Pov, keyCode int) {
	if keysym := vu.Keysym(keyCode); keysym > 0 {
		texture := "lucidiaSu22Black"
		if b.banner == nil {
			b.banner = part.NewPov().SetLocation(float64(b.x), float64(b.y), 0)
			b.banner.NewModel("uv").AddTex(texture).LoadFont("lucidiaSu22")
		}
		if keyCode == 0 {
			keyCode = vu.K_Space
		}
		b.banner.Model().SetPhrase(string(keysym))
	}
}
Ejemplo n.º 16
0
Archivo: sg.go Proyecto: skyview059/vu
// newBlock creates a panel with no cubes.  The cubes are added later using
// panel.addCube().
func newBlock(part vu.Pov, x, y, z float64, level int) *block {
	b := &block{}
	b.part = part.NewPov()
	b.lvl = level
	b.cubes = []*cube{}
	b.cx, b.cy, b.cz = x, y, z
	b.ccnt, b.cmax = 0, (level-1)*(level-1)*8
	b.mergec = func() { b.merge() }
	b.trashc = func() { b.trash() }
	b.addc = func() { b.addCell() }
	b.remc = func() { b.removeCell() }
	return b
}
Ejemplo n.º 17
0
// newSentinel creates a player enemy.
func newSentinel(part vu.Pov, level, units int, fade float64) *sentinel {
	s := &sentinel{}
	s.part = part
	s.units = float64(units)
	s.part.SetLocation(0, 0.5, 0)
	if level > 0 {
		s.center = s.part.NewPov().SetScale(0.125, 0.125, 0.125)
		m := s.center.NewModel("flata").LoadMesh("cube").LoadMat("tred")
		m.SetUniform("fd", fade)
	}
	s.model = part.NewPov()
	m := s.model.NewModel("flata").LoadMesh("cube").LoadMat("tblue")
	m.SetUniform("fd", fade)
	return s
}
Ejemplo n.º 18
0
// newButton creates a button. Buttons are initialized with a size and repositioned later.
//   root   is the parent transform.
//   size   is both the width and height.
//   icon   is the (already loaded) texture image.
//   action is the action to perform when the button is pressed.
func newButton(root vu.Pov, size int, icon string, eventId int, eventData interface{}) *button {
	btn := &button{}
	btn.model = root.NewPov()
	btn.eventId = eventId
	btn.eventData = eventData
	btn.w, btn.h = size, size

	// create the button icon.
	btn.id = icon
	btn.icon = btn.model.NewPov().SetScale(float64(btn.w/2), float64(btn.h/2), 1)
	btn.icon.NewModel("uv").LoadMesh("icon").AddTex(icon).SetAlpha(0.5)

	// create a hilite that is only shown on mouse over.
	btn.hilite = btn.model.NewPov().SetScale(float64(btn.w/2.0), float64(btn.h/2.0), 1)
	btn.hilite.SetVisible(false)
	btn.hilite.NewModel("alpha").LoadMesh("square").LoadMat("tblue")
	return btn
}
Ejemplo n.º 19
0
// buildFloorPlan creates the level layout.
func (lvl *level) buildFloorPlan(root vu.Pov, hd *hud, plan grid.Grid) {
	width, height := plan.Size()
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			xc := float64(x * lvl.units)
			yc := float64(-y * lvl.units)
			band := plan.Band(x, y) / 3
			if x == width/2 && y == height/2 {
				lvl.gcx, lvl.gcy = x, y // remember the maze center location
				lvl.center = root.NewPov().SetLocation(xc, 0, yc)
				m := lvl.center.NewModel("uvra").LoadMesh("tile").AddTex("drop1")
				m.SetAlpha(0.7)
				m.SetUniform("spin", 1.0)
				m.SetUniform("fd", lvl.fade)
			} else if plan.IsOpen(x, y) {

				// the floor tiles.
				tileLabel := lvl.tileLabel(band)
				tile := root.NewPov().SetLocation(xc, 0, yc)
				m := tile.NewModel("uva").LoadMesh("tile").AddTex(tileLabel)
				m.SetAlpha(0.7)
				m.SetUniform("fd", lvl.fade)

				// remember the tile locations for drop spots inside the maze.
				lvl.cc.addDropLocation(x, y)
			} else {

				// draw flat on the y plane with the maze extending into the screen.
				wm := lvl.wallMeshLabel(band)
				wt := lvl.wallTextureLabel(band)
				wall := root.NewPov().SetLocation(xc, 0, yc)
				m := wall.NewModel("uva").LoadMesh(wm).AddTex(wt)
				m.SetUniform("fd", lvl.fade)
				lvl.walls = append(lvl.walls, wall)

				// add the wall to the minimap
				hd.addWall(xc, yc)
			}
		}
	}

	// add core drop locations around the outside of the maze.
	for x := -1; x < width+1; x++ {
		lvl.cc.addDropLocation(x, -1)
		lvl.cc.addDropLocation(x, height)
	}
	for y := 0; y < height; y++ {
		lvl.cc.addDropLocation(-1, y)
		lvl.cc.addDropLocation(width, y)
	}
}
Ejemplo n.º 20
0
// cloakingEffect creates the model shown when the user cloaks.
func (hd *hud) cloakingEffect(root vu.Pov) vu.Pov {
	ce := root.NewPov()
	ce.SetVisible(false)
	ce.NewModel("uv").LoadMesh("icon").AddTex("cloakon").SetAlpha(0.5)
	return ce
}
Ejemplo n.º 21
0
Archivo: cr.go Proyecto: toophy/vu
// getBall creates a visible sphere physics body.
func (cr *crtag) getBall(p vu.Pov) {
	p.NewBody(vu.NewSphere(1))
	p.SetSolid(1, 0.5)
	p.NewModel("gouraud").LoadMesh("sphere").LoadMat("sphere")
}
Ejemplo n.º 22
0
// newXpbar creates all three status bars.
func newXpbar(root vu.Pov, screenWidth, screenHeight int) *xpbar {
	xp := &xpbar{}
	xp.border = 5
	xp.linew = 2
	xp.setSize(screenWidth, screenHeight)

	// add the xp background and foreground bars.
	xp.bg = root.NewPov()
	xp.bg.NewModel("alpha").LoadMesh("square").LoadMat("tblack")
	xp.fg = root.NewPov()
	xp.fg.NewModel("uv").LoadMesh("icon").AddTex("xpgreen")

	// add the xp bar text.
	xp.hb = root.NewPov()
	m := xp.hb.NewModel("uv").AddTex("lucidiaSu22White").LoadFont("lucidiaSu22")
	xp.hbw = m.SetPhrase("0").PhraseWidth()

	// teleport energy background and foreground bars.
	xp.tbg = root.NewPov()
	xp.tbg.NewModel("alpha").LoadMesh("square").LoadMat("tblack")
	xp.tfg = root.NewPov()
	xp.tfg.NewModel("uv").LoadMesh("icon").AddTex("xpblue")

	// the teleport bar text.
	xp.tk = root.NewPov()
	m = xp.tk.NewModel("uv").AddTex("lucidiaSu18White").LoadFont("lucidiaSu18")
	xp.tkw = m.SetPhrase("0").PhraseWidth()

	// cloak energy background and foreground bars.
	xp.cbg = root.NewPov()
	xp.cbg.NewModel("alpha").LoadMesh("square").LoadMat("tblack")
	xp.cfg = root.NewPov()
	xp.cfg.NewModel("uv").LoadMesh("icon").AddTex("xpblue")

	// the cloak bar text.
	xp.ck = root.NewPov()
	m = xp.ck.NewModel("uv").AddTex("lucidiaSu18White").LoadFont("lucidiaSu18")
	xp.ckw = m.SetPhrase("0").PhraseWidth()
	xp.resize(screenWidth, screenHeight)
	return xp
}
Ejemplo n.º 23
0
Archivo: cr.go Proyecto: toophy/vu
// getBox creates a visible box physics body.
func (cr *crtag) getBox(p vu.Pov) {
	p.SetScale(2, 2, 2)
	p.NewBody(vu.NewBox(1, 1, 1))
	p.SetSolid(1, 0)
	p.NewModel("gouraud").LoadMesh("cube").LoadMat("sphere")
}
Ejemplo n.º 24
0
// newTrooper creates a trooper for the given level.
//    level 0: 1x1x1 :  0 edge cubes 0 panels, (only 1 cube)
//    level 1: 2x2x2 :  8 edge cubes + 6 panels of 0x0 cubes + 0x0x0 center.
//    level 2: 3x3x3 : 20 edge cubes + 6 panels of 1x1 cubes + 1x1x1 center.
//    level 3: 4x4x4 : 32 edge cubes + 6 panels of 2x2 cubes + 2x2x2 center.
//    ...
func newTrooper(part vu.Pov, level int) *trooper {
	tr := &trooper{}
	tr.lvl = level
	tr.part = part
	tr.bits = []box{}
	tr.ipos = []int{}
	tr.mid = tr.lvl*tr.lvl*tr.lvl*8 - (tr.lvl-1)*(tr.lvl-1)*(tr.lvl-1)*8

	// set max energies.
	tr.cemax, tr.temax = 1000, 1000

	// special case for a level 0 (start screen) trooper.
	if tr.lvl == 0 {
		cube := newCube(tr.part, 0, 0, 0, 1)
		cube.edgeSort(1)
		tr.bits = append(tr.bits, cube)
		return tr
	}

	// create the panels. These are used in each level after level 1.
	cubeSize := 1.0 / float64(tr.lvl+1)
	centerOffset := cubeSize * 0.5
	panelCenter := float64(tr.lvl) * centerOffset
	tr.bits = append(tr.bits, newPanel(tr.part, panelCenter, 0.0, 0.0, tr.lvl))
	tr.bits = append(tr.bits, newPanel(tr.part, -panelCenter, 0.0, 0.0, tr.lvl))
	tr.bits = append(tr.bits, newPanel(tr.part, 0.0, panelCenter, 0.0, tr.lvl))
	tr.bits = append(tr.bits, newPanel(tr.part, 0.0, -panelCenter, 0.0, tr.lvl))
	tr.bits = append(tr.bits, newPanel(tr.part, 0.0, 0.0, panelCenter, tr.lvl))
	tr.bits = append(tr.bits, newPanel(tr.part, 0.0, 0.0, -panelCenter, tr.lvl))

	// troopers are made out of cubes and panels.
	mx := float64(-tr.lvl)
	for cx := 0; cx <= tr.lvl; cx++ {
		my := float64(-tr.lvl)
		for cy := 0; cy <= tr.lvl; cy++ {
			mz := float64(-tr.lvl)
			for cz := 0; cz <= tr.lvl; cz++ {

				// create the outer edges.
				newCells := 0
				if (cx == 0 || cx == tr.lvl) && (cy == 0 || cy == tr.lvl) && (cz == 0 || cz == tr.lvl) {

					// corner cube
					newCells = 1
				} else if (cx == 0 || cx == tr.lvl) && (cy == 0 || cy == tr.lvl) ||
					(cx == 0 || cx == tr.lvl) && (cz == 0 || cz == tr.lvl) ||
					(cy == 0 || cy == tr.lvl) && (cz == 0 || cz == tr.lvl) {

					// edge cube
					newCells = 2
				} else if cx == 0 || cx == tr.lvl || cy == 0 || cy == tr.lvl || cz == 0 || cz == tr.lvl {

					// side cubes are added to a panel.
					x, y, z := mx*centerOffset, my*centerOffset, mz*centerOffset
					if cx == tr.lvl && x > y && x > z {
						tr.bits[0].(*panel).addCube(x, y, z, float64(cubeSize))
					} else if cx == 0 && x < y && x < z {
						tr.bits[1].(*panel).addCube(x, y, z, float64(cubeSize))
					} else if cy == tr.lvl && y > x && y > z {
						tr.bits[2].(*panel).addCube(x, y, z, float64(cubeSize))
					} else if cy == 0 && y < x && y < z {
						tr.bits[3].(*panel).addCube(x, y, z, float64(cubeSize))
					} else if cz == tr.lvl && z > x && z > y {
						tr.bits[4].(*panel).addCube(x, y, z, float64(cubeSize))
					} else if cz == 0 && z < x && z < y {
						tr.bits[5].(*panel).addCube(x, y, z, float64(cubeSize))
					}
				}
				if newCells > 0 {
					x, y, z := mx*centerOffset, my*centerOffset, mz*centerOffset
					cube := newCube(tr.part, x, y, z, float64(cubeSize))
					cube.edgeSort(newCells)
					tr.bits = append(tr.bits, cube)
				}
				mz += 2
			}
			my += 2
		}
		mx += 2
	}
	tr.addCenter()

	// its easier to remember the initial positions than recalculate them.
	tr.ipos = make([]int, len(tr.bits))
	for cnt, b := range tr.bits {
		tr.ipos[cnt] = b.box().ccnt
	}

	// create the noises the trooper can make.
	tr.noise = part.NewNoise()
	tr.noise.Add("teleport") // teleportSound
	tr.noise.Add("fetch")    // fetchSound
	tr.noise.Add("cloak")    // cloakSound
	tr.noise.Add("decloak")  // decloakSound
	tr.noise.Add("collide")  // collideSound
	return tr
}
Ejemplo n.º 25
0
Archivo: ff.go Proyecto: skyview059/vu
// chaser moves towards a goal.
func newChaser(parent vu.Pov) *chaser {
	c := &chaser{}
	c.pov = parent.NewPov()
	c.pov.NewModel("uv").LoadMesh("icon").AddTex("token")
	return c
}