diff --git a/game.go b/game.go index 5907114f..56f082eb 100644 --- a/game.go +++ b/game.go @@ -254,7 +254,7 @@ func Gopt_Game_Run(game Gamer, resource interface{}, gameConf ...*Config) { } g.startLoad(fs, &conf) for i, n := 0, v.NumField(); i < n; i++ { - name, val := getFieldPtrOrAlloc(v, i) + name, val := getFieldPtrOrAlloc(g, v, i) switch fld := val.(type) { case *Sound: if g.canBindSound(name) { @@ -301,17 +301,24 @@ func instance(gamer reflect.Value) *Game { return fld.Addr().Interface().(*Game) } -func getFieldPtrOrAlloc(v reflect.Value, i int) (name string, val interface{}) { +func getFieldPtrOrAlloc(g *Game, v reflect.Value, i int) (name string, val interface{}) { tFld := v.Type().Field(i) vFld := v.Field(i) typ := tFld.Type word := unsafe.Pointer(vFld.Addr().Pointer()) ret := reflect.NewAt(typ, word).Interface() + if vFld.Kind() == reflect.Ptr && typ.Implements(tySpriter) { obj := reflect.New(typ.Elem()) reflect.ValueOf(ret).Elem().Set(obj) ret = obj.Interface() } + + if vFld.Kind() == reflect.Interface && typ.Implements(tySprite) && g.canBindSprite(tFld.Name) { + obj := reflect.New(g.typs[tFld.Name]) + reflect.ValueOf(ret).Elem().Set(obj) + ret = obj.Interface() + } return tFld.Name, ret } @@ -338,6 +345,10 @@ func findObjPtr(v reflect.Value, name string, from int) interface{} { word := unsafe.Pointer(vFld.Pointer()) return reflect.NewAt(typ.Elem(), word).Interface() } + if vFld.Kind() == reflect.Interface { + word := unsafe.Pointer(vFld.Addr().Pointer()) + return reflect.NewAt(tFld.Type, word).Elem().Interface() + } word := unsafe.Pointer(vFld.Addr().Pointer()) return reflect.NewAt(typ, word).Interface() } @@ -483,7 +494,7 @@ func Gopt_Game_Reload(game Gamer, index interface{}) (err error) { g := instance(v) g.reset() for i, n := 0, v.NumField(); i < n; i++ { - name, val := getFieldPtrOrAlloc(v, i) + name, val := getFieldPtrOrAlloc(g, v, i) if fld, ok := val.(Spriter); ok { if err := g.loadSprite(fld, name, v); err != nil { panic(err) @@ -589,6 +600,7 @@ func (p *Game) addStageSprites(g reflect.Value, v specsp, inits []Spriter) []Spr var ( tySpriter = reflect.TypeOf((*Spriter)(nil)).Elem() + tySprite = reflect.TypeOf((*Sprite)(nil)).Elem() ) // ----------------------------------------------------------------------------- diff --git a/sprite.go b/sprite.go index c9218865..9b053e82 100644 --- a/sprite.go +++ b/sprite.go @@ -63,6 +63,9 @@ const ( type Sprite interface { IEventSinks + Shape + Main() + Animate(name string) Ask(msg interface{}) BounceOffEdge()