diff --git a/assets/building/building.png b/assets/building/building.png new file mode 100644 index 0000000..ddfd081 Binary files /dev/null and b/assets/building/building.png differ diff --git a/assets/building/building.xml b/assets/building/building.xml new file mode 100644 index 0000000..ce379ca --- /dev/null +++ b/assets/building/building.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/city/core/action/auto.go b/city/core/control/auto.go similarity index 95% rename from city/core/action/auto.go rename to city/core/control/auto.go index 018c545..4f17814 100644 --- a/city/core/action/auto.go +++ b/city/core/control/auto.go @@ -1,4 +1,4 @@ -package action +package control import ( "math/rand" @@ -20,6 +20,7 @@ type ActionEntity struct { common.SpaceComponent WalkComponent + Offset engo.Point ActionState } @@ -112,6 +113,10 @@ func (s *ActionState) Update(dt float32) { } } +func (s *ActionState) Finished() bool { + return s.elapsed >= s.duration +} + func (s *ActionState) Next() { s.Code = rand.Intn(2) diff --git a/city/core/control.go b/city/core/control/control.go similarity index 55% rename from city/core/control.go rename to city/core/control/control.go index 1a776d1..98c2e66 100644 --- a/city/core/control.go +++ b/city/core/control/control.go @@ -1,14 +1,23 @@ -package core +package control import ( "github.com/EngoEngine/ecs" "github.com/EngoEngine/engo" "github.com/EngoEngine/engo/common" + "github.com/Z2Y/trpgo/city/core" "github.com/Z2Y/trpgo/city/core/input" ) +const ( + UpButton = "up" + LeftButton = "left" + RightButton = "right" + DownButton = "down" +) + type ControlSystem struct { - grid *WorldSystem + grid *core.WorldSystem + hero *ActionEntity camera *common.CameraSystem touchHandler *input.TouchHandler @@ -66,21 +75,90 @@ func (c *ControlSystem) setWorldCamera() { Incremental: false}) } +func (c *ControlSystem) setupButton() { + engo.Input.RegisterButton(UpButton, engo.KeyW, engo.KeyArrowUp) + engo.Input.RegisterButton(LeftButton, engo.KeyA, engo.KeyArrowLeft) + engo.Input.RegisterButton(RightButton, engo.KeyD, engo.KeyArrowRight) + engo.Input.RegisterButton(DownButton, engo.KeyS, engo.KeyArrowDown) +} + func (c *ControlSystem) Remove(basic ecs.BasicEntity) { - // do nothing + c.hero = nil } -func (c *ControlSystem) Update(float32) { +func (c *ControlSystem) Add(entity *ActionEntity) { + c.hero = entity +} + +func (c *ControlSystem) Update(dt float32) { for { ok := c.touchHandler.Update() - c.update() + if c.hero != nil { + c.updateHero(dt) + c.followHero() + } if !ok { break } } } -func (c *ControlSystem) update() { +func (c *ControlSystem) updateHero(dt float32) { + speed := engo.Point{X: 0, Y: 0} + if engo.Input.Button(UpButton).Down() { + speed.Y -= 1 + } + if engo.Input.Button(LeftButton).Down() { + speed.X -= 1 + } + if engo.Input.Button(RightButton).Down() { + speed.X += 1 + } + if engo.Input.Button(DownButton).Down() { + speed.Y += 1 + } + + preState := c.hero.ActionState.Code + c.hero.ActionState.elapsed += dt + + if speed.X != c.hero.ActionState.Speed.X || speed.Y != c.hero.ActionState.Speed.Y { + if speed.X == 0 && speed.Y == 0 { + c.hero.ActionState.Code = ActionIdle + } else { + c.hero.ActionState.Code = ActionWalking + } + c.hero.ActionState.elapsed = 0 + c.hero.ActionState.duration = 0.2 + c.hero.ActionState.Speed = speed + } + + switch c.hero.ActionState.Code { + case ActionIdle: + if preState != ActionIdle { + engo.Mailbox.Dispatch(ActionMessage{BasicEntity: &c.hero.BasicEntity, State: c.hero.ActionState}) + } + case ActionWalking: + if c.hero.ActionState.elapsed == 0 { + engo.Mailbox.Dispatch(ActionMessage{BasicEntity: &c.hero.BasicEntity, State: c.hero.ActionState}) + } + } +} + +func (c *ControlSystem) followHero() { + engo.Mailbox.Dispatch(common.CameraMessage{Axis: common.XAxis, + Value: c.hero.SpaceComponent.Position.X + c.hero.Offset.X, + Incremental: false}) + engo.Mailbox.Dispatch(common.CameraMessage{Axis: common.YAxis, + Value: c.hero.SpaceComponent.Position.Y + c.hero.Offset.Y, + Incremental: false}) + + if engo.Input.Mouse.ScrollY != 0 { + engo.Mailbox.Dispatch(common.CameraMessage{Axis: common.ZAxis, Value: (engo.Input.Mouse.ScrollY * c.ZoomSpeed), Incremental: true}) + } + +} + +func (c *ControlSystem) TrackCamera() { var ( mouseX = engo.Input.Mouse.X // *c.camera.Z() + (c.camera.X()-(engo.GameWidth()/2)*c.camera.Z()+(engo.ResizeXOffset/2))/engo.GetGlobalScale().X mouseY = engo.Input.Mouse.Y // *c.camera.Z() + (c.camera.Y()-(engo.GameHeight()/2)*c.camera.Z()+(engo.ResizeYOffset/2))/engo.GetGlobalScale().Y @@ -120,7 +198,7 @@ func (c *ControlSystem) New(w *ecs.World) { switch sys := system.(type) { case *common.CameraSystem: c.camera = sys - case *WorldSystem: + case *core.WorldSystem: c.grid = sys } } @@ -128,5 +206,6 @@ func (c *ControlSystem) New(w *ecs.World) { if c.grid != nil && c.camera != nil { c.setWorldCamera() } + c.setupButton() c.touchHandler = input.NewTouchHandler() } diff --git a/city/core/action/walk.go b/city/core/control/walk.go similarity index 88% rename from city/core/action/walk.go rename to city/core/control/walk.go index 6782be3..2923335 100644 --- a/city/core/action/walk.go +++ b/city/core/control/walk.go @@ -1,4 +1,4 @@ -package action +package control import ( "github.com/EngoEngine/ecs" @@ -78,8 +78,7 @@ func (s *WalkSystem) Remove(basic ecs.BasicEntity) { func (s *WalkSystem) Update(dt float32) { for _, e := range s.entities { - speed := engo.GameWidth() * dt - nextPosition := engo.Point{X: e.SpaceComponent.Position.X + speed*e.WalkComponent.Point.X, Y: e.SpaceComponent.Position.Y + speed*e.WalkComponent.Point.Y} + nextPosition := engo.Point{X: e.SpaceComponent.Position.X + e.WalkComponent.Point.X, Y: e.SpaceComponent.Position.Y + e.WalkComponent.Point.Y} if nextPosition.Within(s.land) { e.SpaceComponent.Position = nextPosition diff --git a/city/core/gridsys.go b/city/core/gridsys.go index b128c65..61d5467 100644 --- a/city/core/gridsys.go +++ b/city/core/gridsys.go @@ -75,6 +75,7 @@ func (w *WorldSystem) LoadWorldMap(worldMap *WorldMap) { } w.generateTrees(height_map, worldMap.xLen, worldMap.yLen) + w.generateBuildings(height_map, worldMap.xLen, worldMap.yLen) } func (w *WorldSystem) generateTrees(height_map *mapgenerator.HeightMap, width, height int) { @@ -103,6 +104,30 @@ func (w *WorldSystem) generateTrees(height_map *mapgenerator.HeightMap, width, h } } +func (w *WorldSystem) generateBuildings(height_map *mapgenerator.HeightMap, width, height int) { + for x := 0; x < width; x++ { + for y := 0; y < height; y++ { + code := rand.Intn(1000) + if code < len(Buildings) && (height_map.Value(x, y) >= 10 && height_map.Value(x, y) < 30) { + space := &common.SpaceComponent{ + Position: engo.Point{X: float32(x*(gridSize/2) + y*gridSize/2), Y: float32(y*gridSize/4 - x*gridSize/4)}, + Width: gridSize, + Height: gridSize, + } + render := &common.RenderComponent{ + Drawable: Entitys[Buildings[code]].Drawable, + Scale: Entitys[Buildings[code]].Scale, + StartZIndex: 2, + } + ground := w.ground[x][y] + if ground != nil { + ground.SubEntites = append(ground.SubEntites, &Grid{BasicEntity: ecs.NewBasic(), RenderComponent: render, SpaceComponent: space}) + } + } + } + } +} + func (w *WorldSystem) Size() (float32, float32) { return w.width, w.height } diff --git a/city/core/map.go b/city/core/map.go index db7a18f..d49b0ea 100644 --- a/city/core/map.go +++ b/city/core/map.go @@ -28,11 +28,12 @@ var SampleWorldMap = WorldMap{ } var ( - Entitys = map[int]*common.RenderComponent{} - Lands = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} - Waters = []int{13} - Sand = []int{12} - Trees = []int{101, 102, 103, 104, 105} + Entitys = map[int]*common.RenderComponent{} + Lands = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} + Waters = []int{13} + Sand = []int{12} + Trees = []int{101, 102, 103, 104, 105} + Buildings = []int{201, 202, 203, 204, 205} ) func RegistRenderComponent(code int, d *common.RenderComponent) { @@ -53,4 +54,13 @@ func InitRenderComponents() { RegistRenderComponent(104, &common.RenderComponent{Scale: treeScale, Drawable: asset.LoadedSubSprite("foliagePack_007.png")}) RegistRenderComponent(105, &common.RenderComponent{Scale: treeScale, Drawable: asset.LoadedSubSprite("foliagePack_008.png")}) RegistRenderComponent(106, &common.RenderComponent{Scale: treeScale, Drawable: asset.LoadedSubSprite("foliagePack_012.png")}) + + buildingScale := engo.Point{X: 0.5, Y: 0.5} + RegistRenderComponent(201, &common.RenderComponent{Scale: buildingScale, Drawable: asset.LoadedSubSprite("building_1.png")}) + RegistRenderComponent(202, &common.RenderComponent{Scale: buildingScale, Drawable: asset.LoadedSubSprite("building_2.png")}) + RegistRenderComponent(203, &common.RenderComponent{Scale: buildingScale, Drawable: asset.LoadedSubSprite("building_3.png")}) + RegistRenderComponent(204, &common.RenderComponent{Scale: buildingScale, Drawable: asset.LoadedSubSprite("building_4.png")}) + RegistRenderComponent(205, &common.RenderComponent{Scale: buildingScale, Drawable: asset.LoadedSubSprite("building_5.png")}) + RegistRenderComponent(206, &common.RenderComponent{Scale: buildingScale, Drawable: asset.LoadedSubSprite("building_6.png")}) + } diff --git a/city/core/ui/image.go b/city/core/ui/image.go new file mode 100644 index 0000000..1957759 --- /dev/null +++ b/city/core/ui/image.go @@ -0,0 +1,42 @@ +package ui + +import ( + "github.com/EngoEngine/ecs" + "github.com/EngoEngine/engo" + "github.com/EngoEngine/engo/common" +) + +type Image struct { + UIBasic + + Texture *common.Texture + Position engo.Point + Width float32 + Height float32 +} + +func NewImage(img Image) *Image { + + img.BasicEntity = ecs.NewBasic() + + img.SpaceComponent = common.SpaceComponent{ + Position: img.Position, + Width: img.Width, + Height: img.Height, + } + + img.RenderComponent = common.RenderComponent{ + Drawable: img.Texture, + Scale: engo.Point{X: img.Width / img.Texture.Width(), Y: img.Height / img.Texture.Height()}, + } + + img.SetShader(common.HUDShader) + img.SetZIndex(UILayerIndex) + + return &img +} + +func (img *Image) SetPosition(pos engo.Point) { + img.Position = pos + img.SpaceComponent.Position = pos +} diff --git a/city/core/ui/text.go b/city/core/ui/text.go index 7971293..a33fa2b 100644 --- a/city/core/ui/text.go +++ b/city/core/ui/text.go @@ -79,7 +79,7 @@ func SetDefaultFont(URL string) { fnt := &common.Font{ URL: URL, FG: color.White, - Size: 32, + Size: 24, } err := fnt.CreatePreloaded() diff --git a/city/game.go b/city/game.go index 916bd5b..6dc194e 100644 --- a/city/game.go +++ b/city/game.go @@ -29,6 +29,7 @@ func Start(width, height int) { MobileHeight: height, FPSLimit: 120, ScaleOnResize: true, + NotResizable: true, GlobalScale: engo.Point{X: gameScale, Y: gameScale}, } diff --git a/city/human/human.go b/city/human/human.go index c34973f..2a1d3c6 100644 --- a/city/human/human.go +++ b/city/human/human.go @@ -6,7 +6,7 @@ import ( "github.com/EngoEngine/engo" "github.com/EngoEngine/engo/common" - "github.com/Z2Y/trpgo/city/core/action" + "github.com/Z2Y/trpgo/city/core/control" ) var ( @@ -16,11 +16,11 @@ var ( ) type Human struct { - action.ActionEntity + control.ActionEntity common.AnimationComponent common.RenderComponent - Offset engo.Point + CurrentAnimation *common.AnimationComponent } func frames(size int) []int { @@ -47,7 +47,7 @@ func Init() { } func NewHuman(point engo.Point) *Human { - entity := &Human{ActionEntity: action.NewActionEntity()} + entity := &Human{ActionEntity: control.NewActionEntity()} entity.RenderComponent = common.RenderComponent{ Drawable: DefaultAnimation.Drawables[0], @@ -62,6 +62,7 @@ func NewHuman(point engo.Point) *Human { } entity.AnimationComponent = *DefaultAnimation + entity.SetAnimation(DefaultAnimation) entity.listenAction() @@ -82,20 +83,30 @@ func getCenterOfRender(render common.RenderComponent) engo.Point { func (h *Human) listenAction() { engo.Mailbox.Listen("ActionMessage", func(message engo.Message) { - msg, isAction := message.(action.ActionMessage) + msg, isAction := message.(control.ActionMessage) if isAction && h.ID() == msg.BasicEntity.ID() { switch msg.State.Code { - case action.ActionIdle: - h.AnimationComponent = *DefaultAnimation - case action.ActionWalking: + case control.ActionIdle: + h.SetAnimation(DefaultAnimation) + case control.ActionWalking: h.UpdateFace() - h.AnimationComponent = *Animations["walking"] + h.SetAnimation(Animations["walking"]) } } }) } +func (h *Human) SetAnimation(animation *common.AnimationComponent) { + if h.CurrentAnimation != animation { + h.AnimationComponent = *animation + h.CurrentAnimation = animation + } +} + func (h *Human) UpdateFace() { + if h.ActionState.Speed.X == 0 { + return + } if h.ActionState.Speed.X < 0 { h.RenderComponent.Scale.X = -0.5 } else { diff --git a/city/scene/game.go b/city/scene/game.go index 2716a5e..e48303e 100644 --- a/city/scene/game.go +++ b/city/scene/game.go @@ -9,7 +9,7 @@ import ( "github.com/Z2Y/trpgo/city/asset" "github.com/Z2Y/trpgo/city/core" - "github.com/Z2Y/trpgo/city/core/action" + "github.com/Z2Y/trpgo/city/core/control" "github.com/Z2Y/trpgo/city/core/ui" "github.com/Z2Y/trpgo/city/human" ) @@ -31,6 +31,7 @@ func (g *Game) Preload() { asset.LoadAsset("npc/idle.png") asset.LoadAsset("npc/walking.png") asset.LoadAsset("land/foliagePack_default.xml") + asset.LoadAsset("building/building.xml") asset.LoadAsset("land.png") human.Init() core.InitRenderComponents() @@ -50,8 +51,8 @@ func (g *Game) Setup(u engo.Updater) { w.AddSystem(&common.FPSSystem{Display: true, Font: ui.DefaultFont}) w.AddSystem(&common.AnimationSystem{}) w.AddSystem(g.world) - w.AddSystem(&core.ControlSystem{ZoomSpeed: -0.125}) - w.AddSystem(&action.AutoActionSystem{}) + w.AddSystem(&control.ControlSystem{ZoomSpeed: -0.125}) + w.AddSystem(&control.AutoActionSystem{}) for _, system := range w.Systems() { switch sys := system.(type) { @@ -59,8 +60,10 @@ func (g *Game) Setup(u engo.Updater) { sys.Add(&hero.BasicEntity, &hero.RenderComponent, &hero.SpaceComponent) case *common.AnimationSystem: sys.Add(&hero.BasicEntity, &hero.AnimationComponent, &hero.RenderComponent) - case *action.AutoActionSystem: + case *control.ControlSystem: sys.Add(&hero.ActionEntity) + case *control.WalkSystem: + sys.Add(&hero.BasicEntity, &hero.WalkComponent, &hero.SpaceComponent) } } } diff --git a/city/scene/mainmenu.go b/city/scene/mainmenu.go index 765e8de..a28bf21 100644 --- a/city/scene/mainmenu.go +++ b/city/scene/mainmenu.go @@ -19,6 +19,7 @@ func (s *MainMenu) Type() string { func (s *MainMenu) Preload() { asset.LoadAsset("ui/blueSheet.xml") + asset.LoadAsset("background.jpg") asset.LoadAsset("font/CN.ttf") } @@ -32,14 +33,19 @@ func (s *MainMenu) Setup(u engo.Updater) { buttonBg := asset.LoadedSubSprite("blue_button00.png") text := ui.NewText(ui.Text{Value: "开始游戏"}) - button := ui.NewButton(ui.Button{Text: text, Image: buttonBg, Width: 150, Height: 50}) + button := ui.NewButton(ui.Button{Text: text, Image: buttonBg, Width: 100, Height: 36}) + background := ui.NewImage(ui.Image{Texture: asset.LoadedSubSprite("background.jpg"), Width: engo.WindowWidth() / engo.GetGlobalScale().X, Height: engo.WindowHeight() / engo.GetGlobalScale().Y}) button.SetPosition(layout.AlignToWorldCenter(button.SpaceComponent.AABB())) + background.SetPosition(layout.AlignToWorldCenter(background.SpaceComponent.AABB())) + background.SetZIndex(ui.UILayerIndex - 1) button.OnClick(func() { engo.SetScene(&Game{}, true) }) + w.AddEntity(background) w.AddEntity(button) w.AddEntity(text) + }