From 002e753f48c43605df71b617603666278d262987 Mon Sep 17 00:00:00 2001 From: Jerry Caligiure Date: Wed, 11 Jul 2018 11:35:17 -0400 Subject: [PATCH] credits and game over --- scenes/credits/entities.go | 26 ++++ scenes/credits/scene.go | 200 ++++++++++++++++++++++++++++ scenes/game/scene.go | 8 ++ scenes/gameend/entities.go | 19 +++ scenes/gameend/scene.go | 161 ++++++++++++++++++++++ scenes/mainmenu/scene.go | 7 +- systems/creditroll/component.go | 9 ++ systems/creditroll/entity.go | 12 ++ systems/creditroll/interface.go | 15 +++ systems/creditroll/system.go | 62 +++++++++ systems/creditsbtn/entity.go | 11 ++ systems/creditsbtn/system.go | 55 ++++++++ systems/endcredits/system.go | 16 +++ systems/gameover/system.go | 16 ++- systems/gamerestart/entity.go | 11 ++ systems/gamerestart/system.go | 23 ++++ systems/{credits => menu}/entity.go | 2 +- systems/{credits => menu}/system.go | 7 +- 18 files changed, 649 insertions(+), 11 deletions(-) create mode 100644 scenes/credits/entities.go create mode 100644 scenes/credits/scene.go create mode 100644 scenes/gameend/entities.go create mode 100644 scenes/gameend/scene.go create mode 100644 systems/creditroll/component.go create mode 100644 systems/creditroll/entity.go create mode 100644 systems/creditroll/interface.go create mode 100644 systems/creditroll/system.go create mode 100644 systems/creditsbtn/entity.go create mode 100644 systems/creditsbtn/system.go create mode 100644 systems/endcredits/system.go create mode 100644 systems/gamerestart/entity.go create mode 100644 systems/gamerestart/system.go rename systems/{credits => menu}/entity.go (87%) rename systems/{credits => menu}/system.go (80%) diff --git a/scenes/credits/entities.go b/scenes/credits/entities.go new file mode 100644 index 0000000..d440c91 --- /dev/null +++ b/scenes/credits/entities.go @@ -0,0 +1,26 @@ +package credits + +import ( + "engo.io/ecs" + "engo.io/engo/common" + + "github.com/Noofbiz/hypnic/systems/creditroll" +) + +type sprite struct { + ecs.BasicEntity + common.SpaceComponent + common.RenderComponent +} + +type mobilesprite struct { + ecs.BasicEntity + common.SpaceComponent + common.RenderComponent + creditroll.Component +} + +type bgm struct { + ecs.BasicEntity + common.AudioComponent +} diff --git a/scenes/credits/scene.go b/scenes/credits/scene.go new file mode 100644 index 0000000..2c6e580 --- /dev/null +++ b/scenes/credits/scene.go @@ -0,0 +1,200 @@ +package credits + +import ( + "image/color" + + "engo.io/ecs" + "engo.io/engo" + "engo.io/engo/common" + + "github.com/Noofbiz/hypnic/systems/creditroll" + "github.com/Noofbiz/hypnic/systems/endcredits" +) + +type Scene struct { + BGM bool + BGMLevel float64 + + fnt, dfnt *common.Font + curPos float32 + w *ecs.World +} + +func (s *Scene) Type() string { + return "CreditsScene" +} + +func (s *Scene) Preload() { + engo.Files.Load("bg.png", "bgm.mp3", "Gaegu-Regular.ttf", "kenpixel_square.ttf") +} + +func (s *Scene) Setup(u engo.Updater) { + w, _ := u.(*ecs.World) + s.w = w + common.SetBackground(color.White) + + // Add Render System + var renderable *common.Renderable + var notrenderable *common.NotRenderable + s.w.AddSystemInterface(&common.RenderSystem{}, renderable, notrenderable) + + // add audio system + var audioable *common.Audioable + var notaudioable *common.NotAudioable + s.w.AddSystemInterface(&common.AudioSystem{}, audioable, notaudioable) + + // add credit roll system + var creditrollable *creditroll.Able + s.w.AddSystemInterface(&creditroll.System{}, creditrollable, nil) + + // add end credit system + s.w.AddSystem(&endcredits.System{}) + + //add background + bgs, _ := common.LoadedSprite("bg.png") + bg := sprite{ + BasicEntity: ecs.NewBasic(), + SpaceComponent: common.SpaceComponent{ + Position: engo.Point{X: 0, Y: 0}, + Width: 320, + Height: 480, + }, + RenderComponent: common.RenderComponent{ + Drawable: bgs, + }, + } + s.w.AddEntity(&bg) + + // background music + bgmp, _ := common.LoadedPlayer("bgm.mp3") + bgmp.SetVolume(s.BGMLevel) + b := bgm{BasicEntity: ecs.NewBasic()} + b.AudioComponent = common.AudioComponent{ + Player: bgmp, + } + if s.BGM { + b.AudioComponent.Player.Repeat = true + b.AudioComponent.Player.Play() + } + s.w.AddEntity(&b) + + s.curPos = 2 * engo.GameHeight() / 3 + + //up font + s.fnt = &common.Font{ + URL: "Gaegu-Regular.ttf", + FG: color.White, + Size: 32, + } + s.fnt.CreatePreloaded() + + //down font + s.dfnt = &common.Font{ + URL: "kenpixel_square.ttf", + FG: color.White, + Size: 24, + } + s.dfnt.CreatePreloaded() + + //Title + s.createLines("hypnic") + + //me + s.createLines("A Game By", "Jerry Caligiure", "noofbiz.github.io") + + // sprites + s.createLines("sprites") + // background + s.createLines("Background", "Robin Caligiure") + + // bullet + s.createLines("Statue Bullets", "Kenney", "kenney.nl") + + // main menu buttons + s.createLines("Main Menu Buttons", "Under the moon", "opengameart.org/users/under-the-moon") + + // health bars + s.createLines("Health Bars", "Scrittl", "opengameart.org/users/scrittl") + + // mage player + s.createLines("Player Mage", "Sollision", "opengameart.org/user/30796", + "Jordan Irwin", "opengameart.org/users/antumdeluge") + + // mage statue + s.createLines("Mage Statue", "Johann C", "opengameart.org/users/johann-c") + + // gem + s.createLines("Gem", "Code Inferno Games", "codeinferno.com") + + // walls + s.createLines("Walls", "Blarget2", "opengameart.org/users/blarget2") + + // potion + s.createLines("Potion", "Bonsaiheldin", "bonsaiheld.org") + + // scroll background + s.createLines("Paper", "darkwood67", "deviantart.com/darkwood67/") + + // sound + s.createLines("sounds") + // menu bgm + s.createLines("Menu BGM", "HorrorPen", "opengameart.org/users/horrorpen") + + // game bgm + s.createLines("Game BGM", "xXUnderTowerXx", "opengameart.org/users/xxundertowerxx") + + // potion pickup + s.createLines("Potion Sound", "Bart Kelsey", "opengameart.org/users/bart") + + // hit + s.createLines("On Hit", "wobbleboxx", "wobbleboxx.com") + + // gem + s.createLines("Gem Sound", "wobbleboxx", "wobbleboxx.com") + + // statue fire + s.createLines("Statue Fire", "dklon", "opengameart.org/users/dklon") + + // font + s.createLines("fonts") + + // kenpixel + s.createLines("Square Pixel", "Kenney", "kenney.nl") + + // Gaegu + s.createLines("Gaegu", "JIKJI SOFT", "fonts.google.com/specimen/Gaegu") +} + +func (s *Scene) createLines(lines ...string) { + for i, line := range lines { + l := mobilesprite{BasicEntity: ecs.NewBasic()} + if i%2 == 1 { + l.RenderComponent.Drawable = s.dfnt.Render(line) + l.RenderComponent.Scale = engo.Point{ + X: 1, + Y: 1, + } + } else if i == 0 { + l.RenderComponent.Drawable = s.fnt.Render(line) + l.RenderComponent.Scale = engo.Point{ + X: 1, + Y: 1, + } + } else if i%2 == 0 { + l.RenderComponent.Drawable = s.fnt.Render(line) + l.RenderComponent.Scale = engo.Point{ + X: 0.5, + Y: 0.5, + } + } + l.SpaceComponent.Width = l.RenderComponent.Drawable.Width() * l.RenderComponent.Scale.X + l.SpaceComponent.Height = l.RenderComponent.Drawable.Height() * l.RenderComponent.Scale.Y + l.SpaceComponent.SetCenter(engo.Point{ + X: engo.GameWidth() / 2, + Y: s.curPos, + }) + s.w.AddEntity(&l) + s.curPos += 28 + } + s.curPos += 30 +} diff --git a/scenes/game/scene.go b/scenes/game/scene.go index 9986a28..ee97783 100644 --- a/scenes/game/scene.go +++ b/scenes/game/scene.go @@ -49,6 +49,14 @@ func (s *Scene) Setup(u engo.Updater) { rand.Seed(time.Now().UnixNano()) + // save game scene with current run stuffs + engo.RegisterScene(&Scene{ + BGM: s.BGM, + SFX: s.SFX, + MLvl: s.MLvl, + SFXLvl: s.SFXLvl, + }) + // Add Render System // To be added to the render system needs // ecs.BasicEntity diff --git a/scenes/gameend/entities.go b/scenes/gameend/entities.go new file mode 100644 index 0000000..3fdab8d --- /dev/null +++ b/scenes/gameend/entities.go @@ -0,0 +1,19 @@ +package gameend + +import ( + "engo.io/ecs" + "engo.io/engo/common" +) + +type sprite struct { + ecs.BasicEntity + common.SpaceComponent + common.RenderComponent +} + +type button struct { + ecs.BasicEntity + common.SpaceComponent + common.RenderComponent + common.MouseComponent +} diff --git a/scenes/gameend/scene.go b/scenes/gameend/scene.go new file mode 100644 index 0000000..bcf1bcf --- /dev/null +++ b/scenes/gameend/scene.go @@ -0,0 +1,161 @@ +package gameend + +import ( + "image/color" + "strconv" + + "engo.io/ecs" + "engo.io/engo" + "engo.io/engo/common" + + "github.com/Noofbiz/hypnic/systems/gamerestart" + "github.com/Noofbiz/hypnic/systems/menu" +) + +type Scene struct { + Score int +} + +func (s *Scene) Type() string { + return "GameEndScene" +} + +func (s *Scene) Preload() { + engo.Files.Load("bg.png", "kenpixel_square.ttf", "scroll.png", "button.png") +} + +func (s *Scene) Setup(u engo.Updater) { + w, _ := u.(*ecs.World) + common.SetBackground(color.White) + + // Add Render System + // To be added to the render system needs + // ecs.BasicEntity + // common.SpaceComponent + // common.RenderComponent + var renderable *common.Renderable + var notrenderable *common.NotRenderable + w.AddSystemInterface(&common.RenderSystem{}, renderable, notrenderable) + + // Add Mouse System + var mouseable *common.Mouseable + var notmouseable *common.NotMouseable + w.AddSystemInterface(&common.MouseSystem{}, mouseable, notmouseable) + + // add game start system + restart := &gamerestart.System{} + w.AddSystem(restart) + + // add menu system + m := &menu.System{} + w.AddSystem(m) + + // loaded Font + fnt := &common.Font{ + URL: "kenpixel_square.ttf", + FG: color.White, + Size: 24, + } + fnt.CreatePreloaded() + + // black font + bfnt := &common.Font{ + URL: "kenpixel_square.ttf", + FG: color.Black, + Size: 28, + } + bfnt.CreatePreloaded() + + //add background + bgs, _ := common.LoadedSprite("bg.png") + bg := sprite{ + BasicEntity: ecs.NewBasic(), + SpaceComponent: common.SpaceComponent{ + Position: engo.Point{X: 0, Y: 0}, + Width: 320, + Height: 480, + }, + RenderComponent: common.RenderComponent{ + Drawable: bgs, + }, + } + w.AddEntity(&bg) + + // Paper texture + ps, _ := common.LoadedSprite("scroll.png") + p := sprite{BasicEntity: ecs.NewBasic()} + p.RenderComponent.Drawable = ps + p.RenderComponent.SetZIndex(1) + p.SpaceComponent.Position = engo.Point{ + X: 10, + Y: 20, + } + w.AddEntity(&p) + + // Score + t := "Score: " + strconv.Itoa(s.Score) + sc := sprite{BasicEntity: ecs.NewBasic()} + sc.RenderComponent.Drawable = common.Text{ + Font: bfnt, + Text: t, + } + sc.RenderComponent.SetZIndex(1) + sc.SpaceComponent.Position = engo.Point{ + X: 50, + Y: 65, + } + w.AddEntity(&sc) + + // Start game button + sgs, _ := common.LoadedSprite("button.png") + sg := button{BasicEntity: ecs.NewBasic()} + sg.RenderComponent.Drawable = sgs + sg.RenderComponent.SetZIndex(2) + sg.SpaceComponent.Position = engo.Point{ + X: 20, + Y: 100, + } + sg.SpaceComponent.Width = sg.RenderComponent.Drawable.Width() + sg.SpaceComponent.Height = sg.RenderComponent.Drawable.Height() + w.AddEntity(&sg) + restart.Add(&sg.BasicEntity, &sg.MouseComponent) + + // Start game text + sgt := sprite{BasicEntity: ecs.NewBasic()} + sgt.RenderComponent.Drawable = common.Text{ + Font: fnt, + Text: "Play Again", + } + sgt.RenderComponent.SetZIndex(3) + sgt.SpaceComponent.Position = engo.Point{ + X: 80, + Y: 130, + } + w.AddEntity(&sgt) + + // main menu button + mm := button{BasicEntity: ecs.NewBasic()} + mm.RenderComponent.Drawable = sgs + mm.RenderComponent.SetZIndex(2) + mm.SpaceComponent.Position = engo.Point{ + X: 20, + Y: 180, + } + mm.SpaceComponent.Width = mm.RenderComponent.Drawable.Width() + mm.SpaceComponent.Height = mm.RenderComponent.Drawable.Height() + w.AddEntity(&mm) + m.Add(&mm.BasicEntity, &mm.MouseComponent) + + // main menu text + mmt := sprite{BasicEntity: ecs.NewBasic()} + mmt.RenderComponent.Drawable = common.Text{ + Font: fnt, + Text: "Main Menu", + } + mmt.RenderComponent.SetZIndex(3) + mmt.SpaceComponent.Position = engo.Point{ + X: 80, + Y: 210, + } + w.AddEntity(&mmt) +} diff --git a/scenes/mainmenu/scene.go b/scenes/mainmenu/scene.go index 090b71a..6605785 100644 --- a/scenes/mainmenu/scene.go +++ b/scenes/mainmenu/scene.go @@ -7,7 +7,7 @@ import ( "engo.io/engo" "engo.io/engo/common" - "github.com/Noofbiz/hypnic/systems/credits" + "github.com/Noofbiz/hypnic/systems/creditsbtn" "github.com/Noofbiz/hypnic/systems/gamestart" "github.com/Noofbiz/hypnic/systems/musicbx" "github.com/Noofbiz/hypnic/systems/musicdown" @@ -36,6 +36,9 @@ func (s *Scene) Setup(u engo.Updater) { w, _ := u.(*ecs.World) common.SetBackground(color.White) + // register main menu scene + engo.RegisterScene(&Scene{}) + // Add Render System // To be added to the render system needs // ecs.BasicEntity @@ -80,7 +83,7 @@ func (s *Scene) Setup(u engo.Updater) { w.AddSystem(sadj) // add credits system - crds := &credits.System{} + crds := &creditsbtn.System{} w.AddSystem(crds) // add sfx checkbox system diff --git a/systems/creditroll/component.go b/systems/creditroll/component.go new file mode 100644 index 0000000..2d3913b --- /dev/null +++ b/systems/creditroll/component.go @@ -0,0 +1,9 @@ +package creditroll + +// Component is the bullet component +type Component struct{} + +// GetCreditRollComponent returns the bullet component +func (c *Component) GetCreditRollComponent() *Component { + return c +} diff --git a/systems/creditroll/entity.go b/systems/creditroll/entity.go new file mode 100644 index 0000000..52dc556 --- /dev/null +++ b/systems/creditroll/entity.go @@ -0,0 +1,12 @@ +package creditroll + +import ( + "engo.io/ecs" + "engo.io/engo/common" +) + +type entity struct { + *ecs.BasicEntity + *common.SpaceComponent + *Component +} diff --git a/systems/creditroll/interface.go b/systems/creditroll/interface.go new file mode 100644 index 0000000..83f26aa --- /dev/null +++ b/systems/creditroll/interface.go @@ -0,0 +1,15 @@ +package creditroll + +import "engo.io/engo/common" + +// Face is the interface for an entity with a bullet component +type Face interface { + GetCreditRollComponent() *Component +} + +// Able is the interface for if the entity is compatible with the bullet system +type Able interface { + common.BasicFace + common.SpaceFace + Face +} diff --git a/systems/creditroll/system.go b/systems/creditroll/system.go new file mode 100644 index 0000000..c561a78 --- /dev/null +++ b/systems/creditroll/system.go @@ -0,0 +1,62 @@ +package creditroll + +import ( + "engo.io/ecs" + "engo.io/engo" + "engo.io/engo/common" +) + +// System is the bullet system +type System struct { + entities []entity + speed float32 + w *ecs.World +} + +func (s *System) New(w *ecs.World) { + s.w = w + s.speed = 25 +} + +// Add adds an entity to the System +func (s *System) Add(basic *ecs.BasicEntity, space *common.SpaceComponent, cred *Component) { + s.entities = append(s.entities, entity{basic, space, cred}) +} + +// AddByInterface adds an entity that implements the bullet able interface +func (s *System) AddByInterface(i ecs.Identifier) { + o, _ := i.(Able) + s.Add(o.GetBasicEntity(), o.GetSpaceComponent(), o.GetCreditRollComponent()) +} + +// Remove removes an entity from the System +func (s *System) Remove(basic ecs.BasicEntity) { + d := s.elementExists(basic) + if d >= 0 { + s.entities = append(s.entities[:d], s.entities[d+1:]...) + } +} + +// Update is called each frame +func (s *System) Update(dt float32) { + for i := 0; i < len(s.entities); i++ { + s.entities[i].SpaceComponent.Position.Subtract(engo.Point{ + X: 0, + Y: s.speed * dt, + }) + if s.entities[i].Position.Y < -50 { + s.w.RemoveEntity(*s.entities[i].BasicEntity) + } + } +} + +func (s *System) elementExists(basic ecs.BasicEntity) int { + d := -1 + for i, e := range s.entities { + if e.ID() == basic.ID() { + d = i + break + } + } + return d +} diff --git a/systems/creditsbtn/entity.go b/systems/creditsbtn/entity.go new file mode 100644 index 0000000..526014a --- /dev/null +++ b/systems/creditsbtn/entity.go @@ -0,0 +1,11 @@ +package creditsbtn + +import ( + "engo.io/ecs" + "engo.io/engo/common" +) + +type entity struct { + *ecs.BasicEntity + *common.MouseComponent +} diff --git a/systems/creditsbtn/system.go b/systems/creditsbtn/system.go new file mode 100644 index 0000000..8bb1865 --- /dev/null +++ b/systems/creditsbtn/system.go @@ -0,0 +1,55 @@ +package creditsbtn + +import ( + "engo.io/ecs" + "engo.io/engo" + "engo.io/engo/common" + + "github.com/Noofbiz/hypnic/messages" + "github.com/Noofbiz/hypnic/scenes/credits" +) + +type System struct { + e entity + + bgm bool + mlvl float64 +} + +func (s *System) New(w *ecs.World) { + s.bgm = true + s.mlvl = 1 + + engo.Mailbox.Listen(messages.MusicType, func(m engo.Message) { + msg, ok := m.(messages.Music) + if !ok { + return + } + if msg.Cb { + s.bgm = !s.bgm + return + } + s.mlvl += msg.Amount + if s.mlvl >= 1 { + s.mlvl = 0.99999 + } + if s.mlvl <= 0 { + s.mlvl = 0.00001 + } + }) +} + +func (s *System) Add(basic *ecs.BasicEntity, mouse *common.MouseComponent) { + s.e = entity{basic, mouse} +} + +func (s *System) Remove(basic ecs.BasicEntity) {} + +func (s *System) Update(float32) { + if s.e.Clicked { + engo.SetScene(&credits.Scene{ + BGM: s.bgm, + BGMLevel: s.mlvl, + }, true) + } +} diff --git a/systems/endcredits/system.go b/systems/endcredits/system.go new file mode 100644 index 0000000..16b7080 --- /dev/null +++ b/systems/endcredits/system.go @@ -0,0 +1,16 @@ +package endcredits + +import ( + "engo.io/ecs" + "engo.io/engo" +) + +type System struct{} + +func (s *System) Remove(basic ecs.BasicEntity) {} + +func (s *System) Update(float32) { + if engo.Input.Mouse.Action == engo.Press { + engo.SetSceneByName("MainMenuScene", true) + } +} diff --git a/systems/gameover/system.go b/systems/gameover/system.go index 56042c4..219f14a 100644 --- a/systems/gameover/system.go +++ b/systems/gameover/system.go @@ -1,17 +1,17 @@ package gameover import ( - "log" - "engo.io/ecs" "engo.io/engo" "github.com/Noofbiz/hypnic/messages" + "github.com/Noofbiz/hypnic/scenes/gameend" ) // System handles the game over conditions type System struct { gameover bool + score int } // New sets up the game over system @@ -23,6 +23,13 @@ func (s *System) New(w *ecs.World) { } s.gameover = true }) + engo.Mailbox.Listen(messages.ScoreType, func(m engo.Message) { + msg, ok := m.(messages.Score) + if !ok { + return + } + s.score += msg.Amount + }) } // Remove doesn't do anything as the system has no entities @@ -31,7 +38,8 @@ func (s *System) Remove(e ecs.BasicEntity) {} // Update is called once each frame. Checks if any lose conditions have been met. func (s *System) Update(dt float32) { if s.gameover { - log.Println("game over. user wins. Nooooooo! Bob!") - s.gameover = false + engo.SetScene(&gameend.Scene{ + Score: s.score, + }, true) } } diff --git a/systems/gamerestart/entity.go b/systems/gamerestart/entity.go new file mode 100644 index 0000000..5a54bb8 --- /dev/null +++ b/systems/gamerestart/entity.go @@ -0,0 +1,11 @@ +package gamerestart + +import ( + "engo.io/ecs" + "engo.io/engo/common" +) + +type entity struct { + *ecs.BasicEntity + *common.MouseComponent +} diff --git a/systems/gamerestart/system.go b/systems/gamerestart/system.go new file mode 100644 index 0000000..77b0de1 --- /dev/null +++ b/systems/gamerestart/system.go @@ -0,0 +1,23 @@ +package gamerestart + +import ( + "engo.io/ecs" + "engo.io/engo" + "engo.io/engo/common" +) + +type System struct { + e entity +} + +func (s *System) Add(basic *ecs.BasicEntity, mouse *common.MouseComponent) { + s.e = entity{basic, mouse} +} + +func (s *System) Remove(basic ecs.BasicEntity) {} + +func (s *System) Update(float32) { + if s.e.Clicked { + engo.SetSceneByName("GameScene", true) + } +} diff --git a/systems/credits/entity.go b/systems/menu/entity.go similarity index 87% rename from systems/credits/entity.go rename to systems/menu/entity.go index 7b8ba04..b21dce4 100644 --- a/systems/credits/entity.go +++ b/systems/menu/entity.go @@ -1,4 +1,4 @@ -package credits +package menu import ( "engo.io/ecs" diff --git a/systems/credits/system.go b/systems/menu/system.go similarity index 80% rename from systems/credits/system.go rename to systems/menu/system.go index f89b6e4..519ac86 100644 --- a/systems/credits/system.go +++ b/systems/menu/system.go @@ -1,9 +1,8 @@ -package credits +package menu import ( - "fmt" - "engo.io/ecs" + "engo.io/engo" "engo.io/engo/common" ) @@ -19,6 +18,6 @@ func (s *System) Remove(basic ecs.BasicEntity) {} func (s *System) Update(float32) { if s.e.Clicked { - fmt.Println("credits roll") + engo.SetSceneByName("MainMenuScene", true) } }