diff --git a/camera.go b/camera.go index 699d4ce8..6966a401 100644 --- a/camera.go +++ b/camera.go @@ -19,6 +19,10 @@ func (c *Camera) init(g *Game, winW, winH float64, worldW, worldH float64) { c.g = g } +func (c *Camera) isWorldRange(pos *math32.Vector2) bool { + return c.freecamera.IsWorldRange(pos) +} + func (c *Camera) SetXYpos(x float64, y float64) { c.on_ = nil c.freecamera.MoveTo(x, y) diff --git a/game.go b/game.go index 6e1d3611..464063a5 100644 --- a/game.go +++ b/game.go @@ -75,21 +75,20 @@ type Game struct { input inputMgr events chan event + // map world + worldWidth_ int + worldHeight_ int + mapMode int + gridUnit float64 + world *ebiten.Image + // window windowWidth_ int windowHeight_ int - stepUnit float64 //global step unit in game - mapMode int - - // world - worldWidth_ int - worldHeight_ int gMouseX, gMouseY int64 sinkMgr eventSinkMgr - - world *ebiten.Image } type Spriter = Shape @@ -311,9 +310,10 @@ type cameraConfig struct { } type mapConfig struct { - Mode string `json:"mode"` - Width int `json:"width"` - Height int `json:"height"` + Width int `json:"width"` + Height int `json:"height"` + Mode string `json:"mode"` + GridUnit float64 `json:"gridUnit"` } func toMapMode(mode string) int { @@ -407,7 +407,6 @@ func (p *Game) startLoad(resource interface{}, cfg *Config) (err error) { p.fs = fs p.windowWidth_ = cfg.Width p.windowHeight_ = cfg.Height - return } @@ -454,9 +453,9 @@ type projConfig struct { Costumes []*costumeConfig `json:"costumes"` CurrentCostumeIndex *int `json:"currentCostumeIndex"` SceneIndex int `json:"sceneIndex"` - StepUnit float64 `json:"stepUnit"` - Map mapConfig `json:"map"` - Camera *cameraConfig `json:"camera"` + + Map mapConfig `json:"map"` + Camera *cameraConfig `json:"camera"` } func (p *projConfig) getScenes() []*costumeConfig { @@ -495,13 +494,21 @@ func (p *Game) loadIndex(g reflect.Value, index interface{}) (err error) { if scenes := proj.getScenes(); len(scenes) > 0 { p.baseObj.init("", scenes, proj.getSceneIndex()) + p.worldWidth_ = 0 + p.doWorldSize() // set world size } else { - p.baseObj.initWithSize(proj.Map.Width, proj.Map.Height) + p.worldWidth_ = proj.Map.Width + p.worldHeight_ = proj.Map.Height + p.baseObj.initWithSize(p.worldWidth_, p.worldHeight_) } + if debugLoad { + log.Println("==> SetWorldSize", p.worldWidth_, p.worldHeight_) + } + p.world = ebiten.NewImage(p.worldWidth_, p.worldHeight_) p.mapMode = toMapMode(proj.Map.Mode) - p.stepUnit = proj.StepUnit - if p.stepUnit == 0 { - p.stepUnit = 1 + p.gridUnit = proj.Map.GridUnit + if p.gridUnit == 0 { + p.gridUnit = 1 } inits := make([]initer, 0, len(proj.Zorder)) @@ -521,54 +528,27 @@ func (p *Game) loadIndex(g reflect.Value, index interface{}) (err error) { ini.Main() } - p.worldWidth_ = 0 - p.doWorldSize() // set world size - - if debugLoad { - log.Println("==> SetWorldSize", p.worldWidth_, p.worldHeight_) - } - p.doWindowSize() // set window size if debugLoad { log.Println("==> SetWindowSize", p.windowWidth_, p.windowHeight_) } - - p.resizeWindow() - if proj.Camera != nil && proj.Camera.On != "" { - p.Camera.On(proj.Camera.On) - } - if loader, ok := g.Addr().Interface().(interface{ OnLoaded() }); ok { - loader.OnLoaded() - } - return -} - -func (p *Game) resizeWindow() { - c := p.costumes[p.costumeIndex_] - img, _, _ := c.needImage(p.fs) - if p.worldWidth_ > img.Bounds().Dx() && p.windowWidth_ < p.worldWidth_ { - p.worldWidth_ = img.Bounds().Dx() - } - if p.worldHeight_ > img.Bounds().Dy() && p.windowHeight_ < p.worldHeight_ { - p.worldHeight_ = img.Bounds().Dy() - } - if p.windowWidth_ > p.worldWidth_ { - p.worldWidth_ = p.windowWidth_ + p.windowWidth_ = p.worldWidth_ } if p.windowHeight_ > p.worldHeight_ { - p.worldHeight_ = p.windowHeight_ - } - if p.world != nil { - p.world.Dispose() + p.windowHeight_ = p.worldHeight_ } - p.world = ebiten.NewImage(p.worldWidth_, p.worldHeight_) - p.Camera.init(p, float64(p.windowWidth_), float64(p.windowHeight_), float64(p.worldWidth_), float64(p.worldHeight_)) ebiten.SetWindowSize(p.windowWidth_, p.windowHeight_) ebiten.SetWindowResizable(true) - + if proj.Camera != nil && proj.Camera.On != "" { + p.Camera.On(proj.Camera.On) + } + if loader, ok := g.Addr().Interface().(interface{ OnLoaded() }); ok { + loader.OnLoaded() + } + return } func (p *Game) endLoad(g reflect.Value, index interface{}) (err error) { @@ -735,9 +715,6 @@ func (p *Game) runLoop(cfg *Config) (err error) { } func (p *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) { - p.windowWidth_ = outsideWidth - p.windowHeight_ = outsideHeight - p.resizeWindow() return p.windowSize_() } diff --git a/internal/camera/freecamera.go b/internal/camera/freecamera.go index dd9a19eb..7954c9c9 100644 --- a/internal/camera/freecamera.go +++ b/internal/camera/freecamera.go @@ -67,6 +67,8 @@ func (c *FreeCamera) updateMatrix() { X: cx, Y: cy, } + c.position.X = pos.X + c.position.Y = -pos.Y c.worldMatrix.Translate(c.worldSize.Sub(c.viewPort).Scale(0.5).Inverted().Coords()) c.worldMatrix.Translate(pos.Inverted().Coords()) @@ -125,3 +127,10 @@ func (c *FreeCamera) Reset() { c.zoom.Set(1, 1) c.updateMatrix() } + +func (c *FreeCamera) IsWorldRange(pos *math32.Vector2) bool { + if pos.X >= -c.worldSize.X/2.0 && pos.X <= c.worldSize.X/2.0 && pos.Y >= -c.worldSize.Y/2.0 && pos.Y <= c.worldSize.Y/2.0 { + return true + } + return false +} diff --git a/spgdi.go b/spgdi.go index c3785f13..08cb534d 100644 --- a/spgdi.go +++ b/spgdi.go @@ -87,7 +87,31 @@ func (p *spriteDrawInfo) drawOn(dc drawContext, fs spxfs.Dir) { func (p *spriteDrawInfo) draw(dc drawContext, ctx *Sprite) { p.doDrawOn(dc, ctx.g.fs) } +func (p *spriteDrawInfo) getUpdateRotateRect(x, y float64) *math32.RotatedRect { + c := p.sprite.costumes[p.sprite.costumeIndex_] + + img, centerX, centerY := c.needImage(p.sprite.g.fs) + rect := image.Rectangle{} + rect.Min.X = 0 + rect.Min.Y = 0 + rect.Max = img.Bounds().Size() + scale := p.sprite.scale / float64(c.bitmapResolution) + + geo := ebiten.GeoM{} + geo.Reset() + direction := p.sprite.direction + c.faceRight + + geo.Translate(-centerX, -centerY) + geo.Scale(scale, scale) + geo.Rotate(toRadian(direction - 90)) + geo.Translate(x, -y) + + geo2 := geo + geo2.Scale(1.0, -1.0) + rRect := math32.ApplyGeoForRotatedRect(rect, &geo2) + return rRect +} func (p *spriteDrawInfo) updateMatrix() { c := p.sprite.costumes[p.sprite.costumeIndex_] diff --git a/sprite.go b/sprite.go index 11e7859c..224c57a7 100644 --- a/sprite.go +++ b/sprite.go @@ -690,19 +690,18 @@ func (p *Sprite) DistanceTo(obj interface{}) float64 { y -= y2 return math.Sqrt(x*x + y*y) } -func (p *Sprite) DistanceStepTo(obj interface{}) float64 { - x, y := p.x, p.y - x2, y2 := p.g.objectPos(obj) - x -= x2 - y -= y2 - return math.Sqrt(x*x+y*y) / float64(p.g.stepUnit) -} func (p *Sprite) doMoveTo(x, y float64) { p.doMoveToForAnim(x, y, nil) } func (p *Sprite) doMoveToForAnim(x, y float64, ani *anim.Anim) { + if !p.isWorldRange(x, y) { + if debugInstr { + log.Printf("sprite [%s] is not in the world range. ", p.name) + } + return + } if p.hasOnMoving { mi := &MovingInfo{OldX: p.x, OldY: p.y, NewX: x, NewY: y, Obj: p, ani: ani} p.doWhenMoving(p, mi) @@ -746,12 +745,12 @@ func (p *Sprite) Step__2(step float64, animname string) { if ani, ok := p.animations[animname]; ok { anicopy := *ani anicopy.From = 0 - anicopy.To = step * float64(p.g.stepUnit) + anicopy.To = step * float64(p.g.gridUnit) anicopy.Duration = math.Abs(step) * ani.Duration p.goAnimate(animname, &anicopy) return } - p.goMoveForward(step * float64(p.g.stepUnit)) + p.goMoveForward(step * float64(p.g.gridUnit)) } // Goto func: @@ -1305,7 +1304,7 @@ func (p *Sprite) CostumeHeight() float64 { } func (p *Sprite) Bounds() *math32.RotatedRect { - return p.rRect + return p.getRotatedRect() } func (p *Sprite) Pixel(x, y float64) color.Color { @@ -1314,9 +1313,23 @@ func (p *Sprite) Pixel(x, y float64) color.Color { geo := p.getDrawInfo().getPixelGeo(cx, cy) color1, p1 := p.getDrawInfo().getPixel(math32.NewVector2(x, y), img, geo) if debugInstr { - log.Printf("<<< { println "no touchingColor Red" } } + + + + + +onKey KeyUp, => { + Camera.changeXYpos 0, 5 +} + +onKey KeyDown, => { + Camera.changeXYpos 0, -5 +} + +onKey KeyLeft, => { + Camera.changeXYpos -5, 0 +} + +onKey KeyRight, => { + Camera.changeXYpos 5, 0 +} + diff --git a/test/Bananas/index.gmx b/test/Bananas/index.gmx index 4c155c95..8e426d8b 100644 --- a/test/Bananas/index.gmx +++ b/test/Bananas/index.gmx @@ -3,4 +3,4 @@ var ( Monkey *Monkey Red *Red ) -run "res", {Title: "Bananas (by Go+)" , Width: 800, Height: 600} +run "res", {Title: "Bananas (by Go+)" , Width: 500, Height: 400} diff --git a/test/Bananas/res/index.json b/test/Bananas/res/index.json index 287e6dd2..021bc575 100644 --- a/test/Bananas/res/index.json +++ b/test/Bananas/res/index.json @@ -6,7 +6,10 @@ } ], "map": { - "mode": "fillCut", + "width":800, + "height":600, + "gridUnit":1, + "mode": "repeat", "mode_test0": "", "mode_test1": "repeat", "mode_test2": "fillRatio",