func (w *World) Draw(target pixel.Target) {
	for i := range w.Entities {
		w.DrawEntity(i)
	}
	for i := range w.Batches {
		w.Batches[i].Draw(target)
	}
	if w.imd == nil {
		w.imd = imdraw.New(nil)
	}
}
/*
Object returns the object at dot, very expensive
func (w *World) Object(dot pixel.Vec) Object {

var ob Object
for i := range w.Objects {
if w.Objects[i].Rect.Contains(dot) {
ob = w.Objects[i]
if ob.Type == O_BLOCK { // prefer block over tile
return ob
}
}
}
return ob

}
package rpg
import (
	"fmt"
	"log"
	"math/rand"
	"time"
	"golang.org/x/image/colornames"
	"github.com/faiface/pixel"
	"github.com/faiface/pixel/imdraw"
	"github.com/faiface/pixel/text"
)
var SpriteFrame = pixel.R(-100, -100, 100, 100)
type World struct {
	Name          string
	Bounds        pixel.Rect
	Regions       []*Region
	DObjects      []*DObject
	Tiles, Blocks []Object                     
	Background    string                       
	background    *pixel.Sprite                
	Batches       map[EntityType]*pixel.Batch  
	Color         pixel.RGBA                   
	Entities      []*Entity
	Sheets        map[EntityType]pixel.Picture
	Anims         map[EntityType]map[EntityState]map[Direction][]pixel.Rect  
	Char          *Character
	Animations    []*Animation
	Messages      []string
	Settings      WorldSettings
	imd           *imdraw.IMDraw
	text          *text.Text
}
type WorldSettings struct {
	NumEnemy int
}
func NewWorld(name string, difficulty int) *World {
	w := new(World)
	w.Name = name
	w.Color = RandomColor()
	w.Sheets = make(map[EntityType]pixel.Picture)
	w.Anims = make(map[EntityType]map[EntityState]map[Direction][]pixel.Rect)
	char := NewCharacter("char")
	char.Inventory = []Item{MakeGold(uint64(rand.Intn(7)))}  
	char.W = w
	w.Char = char
	w.Batches = map[EntityType]*pixel.Batch{}
	for _, t := range []EntityType{SKELETON, SKELETON_GUARD} {
		sheet, anims, err := LoadEntitySheet("sprites/"+t.String()+".png", 13, 21)
		if err != nil {
			panic(fmt.Errorf("error loading sheet: %s %v", t, err))
		}
		w.Sheets[t] = sheet
		w.Anims[t] = anims
		w.Batches[t] = pixel.NewBatch(&pixel.TrianglesData{}, w.Sheets[t])
	}
	log.Println("Loading...")
	if e := w.LoadMap("maps/" + name + ".map"); e != nil {
		log.Println(e)
		if e = w.LoadMapFile(name); e != nil {
			log.Println(e)
			return nil
		}
	}
	if len(w.Tiles) == 0 {
		log.Println("Invalid map. No objects found")
		return nil
	}
	char.Rect = char.Rect.Moved(FindRandomTile(w.Tiles))
	w.Settings.NumEnemy = difficulty
	return w
}
func (w World) String() string {
	return w.Name
}
func (w *World) Update(dt float64) {
	w.checkLevel()
	dobjects := []*DObject{}
	for i := range w.DObjects {
		if time.Since(w.DObjects[i].Until) > time.Millisecond {
			continue
		}
		dobjects = append(dobjects, w.DObjects[i])
	}
	w.DObjects = dobjects
	entities := []*Entity{}
	for i := range w.Entities {
		if len(w.Entities) < i || w.Entities[i] == nil {
			continue
		}
		w.Entities[i].ChangeMind(dt)
		w.Entities[i].Update(dt)
		if w.Entities[i].P.Health > 0 {
			entities = append(entities, w.Entities[i])
			continue
		}
		if len(w.Entities) > 10 {
			continue
		}
		npc := w.NewEntity(SKELETON_GUARD)
		npc.Rect = npc.Rect.Moved(FindRandomTile(w.Tiles))
		entities = append(entities, npc)
		npc = w.NewEntity(SKELETON)
		npc.Rect = npc.Rect.Moved(FindRandomTile(w.Tiles))
		entities = append(entities, npc)
	}
	w.Entities = entities
	if len(w.Animations) > 0 {
		for i := range w.Animations {
			w.Animations[i].update(dt)
		}
	}
	for _, a := range w.Animations {
		if a == nil || time.Since(a.start) < time.Millisecond*300 || time.Since(a.until) > time.Millisecond {
			continue
		}
		for i, v := range w.Entities {
			if a.rect.Contains(v.Rect.Center()) {
				if a.ticker != nil {
					select {
					default:
						continue
					case <-a.ticker:
					}
				}
				w.Entities[i].P.Health -= a.damage
				if w.Entities[i].P.Health <= 0 {
					if w.Entities[i].P.IsDead {
						w.Entities[i].P.Health = 0
						continue
					}
					w.Entities[i].P.Health = 0
					w.Entities[i].P.IsDead = true
					w.NewLoot(v.Center(), v.P.Loot)
					w.Char.Stats.Kills++
					w.Char.ExpUp(v.P.XP)
				}
				log.Printf("%s took %v damage, now at %v HP",
					w.Entities[i].Name, a.damage, w.Entities[i].P.Health)
			}
		}
	}
}
func (w *World) DrawEntity(n int) {
	w.Entities[n].Draw(w.Batches[w.Entities[n].Type], w)
}
func (w *World) Tile(dot pixel.Vec) Object {
	if w.Tiles == nil {
		log.Println("nil tiles!")
		return Object{W: w, Type: O_BLOCK}
	}
	if len(w.Tiles) == 0 {
		log.Println("no tiles to look in")
		return Object{W: w, Type: O_BLOCK}
	}
	for i := len(w.Tiles) - 1; i >= 0; i-- {
		if w.Tiles[i].Rect.Contains(dot) {
			ob := w.Tiles[i]
			ob.W = w
			return ob
		}
	}
	return Object{W: w, Type: O_BLOCK}
}
func (w *World) Block(dot pixel.Vec) Object {
	for i := range w.Blocks {
		if w.Blocks[i].Rect.Contains(dot) {
			return w.Blocks[i]
		}
	}
	return Object{}
}
func (w *World) Object(dot pixel.Vec) Object {
	if w.Blocks != nil {
		for _, v := range w.Blocks {
			if v.Rect.Contains(dot) {
				return v
			}
		}
	}
	for _, v := range w.Tiles {
		if v.Rect.Contains(dot) {
			return v
		}
	}
	return Object{Type: O_NONE}
}