func (s *State) UpdateViewport(ms float32) { var ( r = 0.1 * ms b = s.env.RelativeBounds(s.player.Sprite) v = s.window.View x = Min(Max(b.Min.X+v.Dx()/2, s.screenxmin), s.screenxmax) y = Min(Max(b.Min.Y+v.Dy()/2-s.player.Sprite.Height()/2, s.screenymin), s.screenymax) dy = y - s.env.Y() dx = x - s.env.X() d = twodee.Pt(dx/r, dy/r) ) /* fmt.Printf("Bounds %v\n", s.char.GlobalBounds()) fmt.Printf("s.env.RelativeBounds(s.char) %v\n", s.env.RelativeBounds(s.char)) fmt.Printf("s.char.RelativeBounds(s.env) %v\n", s.char.RelativeBounds(s.env)) fmt.Printf("Moving viewport to %v, %v\n", x, y) */ if s.player.Sprite.Collide { // Only smooth motion if the player isn't dying if ms == 0 || (dy < 1 && dy > -1) { s.env.MoveTo(twodee.Pt(x, y)) return } if dy > 0 { d.Y = Max(1, dy/30) } else { d.Y = Min(-1, dy/30) } } s.env.Move(d) s.env.MoveTo(twodee.Pt(Round(s.env.X()), Round(s.env.Y()))) }
func (p *Player) Bounce(c *Creature) { if c.Sprite.Y() >= p.Sprite.Y() { p.Sprite.VelocityY = -p.JumpSpeed p.Sprite.Move(twodee.Pt(0, -2)) // Clear collision zone } else { p.Sprite.VelocityY = p.JumpSpeed p.Sprite.Move(twodee.Pt(0, 2)) // Clear collision zone } p.Sprite.VelocityX = 0 p.State &= 511 ^ (PLAYER_STOPPED | PLAYER_WALKING) p.State |= (PLAYER_JUMPING) }
func (s *State) SetScore(score int) { s.score = score s.textscore.SetText(fmt.Sprintf("%v", s.score)) s.textscore.MoveTo(twodee.Pt(s.window.View.Max.X-s.textscore.Width(), 0)) if s.score >= s.nextlife { s.ChangeMaxLives(1) s.ChangeLives(1) s.nextlife *= 2 } }
func Init(system *twodee.System, window *twodee.Window) (state *State, err error) { state = &State{} state.creatures = make([]*Creature, 0) state.boundaries = make([]*twodee.Sprite, 0) state.hud = &twodee.Scene{} state.scene = &twodee.Scene{} state.env = &twodee.Env{} state.window = window state.system = system textures := []TexInfo{ TexInfo{"level-textures", "assets/level-textures.png", 16}, TexInfo{"enemy-sm-textures", "assets/enemy-sm-textures-fw.png", 0}, TexInfo{"enemy-textures", "assets/enemy-textures-fw.png", 0}, TexInfo{"font1-textures", "assets/font1-textures.png", 0}, TexInfo{"darwin-textures", "assets/darwin-textures.png", 0}, TexInfo{"powerups-textures", "assets/powerups-textures-fw.png", 0}, } for _, t := range textures { if err = system.LoadTexture(t.Name, t.Path, twodee.IntNearest, t.Width); err != nil { return } } BlockHandler := func(block *twodee.EnvBlock, sprite *twodee.Sprite, x float32, y float32) { state.HandleAddBlock(block, sprite, x, y) } opts := twodee.EnvOpts{ Blocks: []*twodee.EnvBlock{ &twodee.EnvBlock{ Color: color.RGBA{153, 102, 0, 255}, // Dirt Type: FLOOR, FrameIndex: 0, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{0, 204, 51, 255}, // Green top Type: FLOOR, FrameIndex: 1, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{51, 102, 0, 255}, // Top left corner Type: FLOOR, FrameIndex: 2, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{51, 153, 0, 255}, // Top right corner Type: FLOOR, FrameIndex: 3, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{153, 153, 51, 255}, // Left dirt wall Type: FLOOR, FrameIndex: 4, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{153, 153, 102, 255}, // Right dirt wall Type: FLOOR, FrameIndex: 5, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{204, 204, 51, 255}, // Left grass cap Type: FLOOR, FrameIndex: 6, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{204, 204, 102, 255}, // Right grass cap Type: FLOOR, FrameIndex: 7, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{153, 153, 153, 255}, // Rock Type: FLOOR, FrameIndex: 8, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{118, 118, 118, 255}, // Rock left Type: FLOOR, FrameIndex: 9, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{84, 84, 84, 255}, // Rock right Type: FLOOR, FrameIndex: 10, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{0, 0, 0, 255}, Type: START, FrameIndex: 1, Handler: BlockHandler, }, &twodee.EnvBlock{ Color: color.RGBA{51, 51, 51, 255}, Type: BADGUY, FrameIndex: -1, Handler: BlockHandler, }, }, TextureName: "level-textures", MapPath: "assets/level-fw.png", BlockWidth: 32, BlockHeight: 32, } if err = state.env.Load(system, opts); err != nil { return } state.system.SetClearColor(102, 204, 255, 255) state.scene.AddChild(state.env) state.system.SetKeyCallback(func(k, s int) { state.HandleKeys(k, s) }) state.screenxmin = float32(-state.env.Width()) + state.window.View.Max.X state.screenxmax = 0 state.screenymin = float32(-state.env.Height()) + state.window.View.Max.Y state.screenymax = 0 // Do this later so that the hud renders on top of things state.scene.AddChild(state.hud) state.livesbar = NewLivesBar(system, 0, 0) state.hud.AddChild(state.livesbar) state.healthbar = NewLivesBar(system, 0, 0) state.healthbar.Availframe = 3 state.healthbar.Emptyframe = 2 state.healthbar.MoveTo(twodee.Pt(0, 24)) state.hud.AddChild(state.healthbar) state.textscore = system.NewText("font1-textures", 0, 0, 2, "") state.hud.AddChild(state.textscore) state.textfps = system.NewText("font1-textures", 0, float32(state.window.View.Max.Y-32), 1, "") state.hud.AddChild(state.textfps) state.hud.SetZ(0.5) state.nextlife = 400 state.SetScore(0) state.ChangeMaxLives(1) state.ChangeLives(1) state.SetMaxHealth(3) state.ChangeHealth(3) state.running = true state.Victory = false return }
func (s *State) UpdateSprite(sprite *twodee.Sprite, ms float32) (result int) { sprite.VelocityY += 0.005 * ms // Gravity var ( dX = sprite.VelocityX * ms dY = sprite.VelocityY * ms b = sprite.RelativeBounds(s.env) ) if b.Min.X+dX < 0 { result |= HITLEFT sprite.VelocityX = 0 sprite.Move(twodee.Pt(1, 0)) dX = 0 } if b.Max.X+dX > s.env.Width() { /* fmt.Printf("HITRIGHT\n") fmt.Printf("sprite.RelativeBounds(s.env) %v\n", sprite.RelativeBounds(s.env)) fmt.Printf("sprite.LocalBounds() %v\n", sprite.Bounds()) */ result |= HITRIGHT sprite.VelocityX = 0 sprite.Move(twodee.Pt(-1, 0)) dX = 0 } if sprite.Collide { for _, block := range s.boundaries { if dX != 0 && !sprite.TestMove(dX, 0, block) { if sprite.TestMove(dX, -block.Height(), block) { // Allows running up small bumps sprite.Move(twodee.Pt(0, -block.Height())) } else { if dX < 0 { sprite.MoveTo(twodee.Pt(block.X()+block.Width(), sprite.Y())) result |= HITLEFT } else { sprite.MoveTo(twodee.Pt(block.X()-sprite.Width(), sprite.Y())) result |= HITRIGHT } sprite.VelocityX = 0 dX = 0 } } if dY != 0 && !sprite.TestMove(0, dY, block) { if dY < 0 { sprite.MoveTo(twodee.Pt(sprite.X(), block.Y()+block.Height())) result |= HITTOP } else { sprite.MoveTo(twodee.Pt(sprite.X(), block.Y()-sprite.Height())) result |= HITBOTTOM } sprite.VelocityY = 0 dY = 0 } } } if dX != 0 || dY != 0 { sprite.Move(twodee.Pt(dX, dY)) } //sprite.MoveTo(twodee.Pt(Round(sprite.X()), Round(sprite.Y()))) return }
func (p *Player) Respawn() { p.Sprite.Collide = true p.Sprite.VelocityY = 0 p.Sprite.VelocityX = 0 p.Sprite.MoveTo(twodee.Pt(p.StartX, p.StartY)) }