Load and use cozy-people tileset
This commit is contained in:
parent
48f852176d
commit
1239fcbfd3
8 changed files with 110 additions and 83 deletions
|
@ -29,7 +29,11 @@ var (
|
|||
|
||||
ImgCrosshair = LoadImage("image/crosshair.png")
|
||||
|
||||
ImgFishTileset = LoadImage("image/cozy-fishing/global.png")
|
||||
ImgFish = LoadImage("image/cozy-fishing/global.png")
|
||||
|
||||
ImgPeepBody = LoadImage("image/cozy-people/characters/char_all.png")
|
||||
ImgPeepClothesShirt = LoadImage("image/cozy-people/clothes/basic.png")
|
||||
ImgPeepClothesPants = LoadImage("image/cozy-people/clothes/pants.png")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -127,35 +131,31 @@ func LoadOGG(context *audio.Context, p string, loop bool) *audio.Player {
|
|||
return player
|
||||
}
|
||||
|
||||
func FishTileAt(i int) *ebiten.Image {
|
||||
const tileSize = 16
|
||||
const tilesetWidth = 56
|
||||
|
||||
x, y := i%tilesetWidth, i/tilesetWidth
|
||||
|
||||
r := image.Rect(x*tileSize, y*tileSize, (x+1)*tileSize, (y+1)*tileSize)
|
||||
|
||||
return ImgFishTileset.SubImage(r).(*ebiten.Image)
|
||||
}
|
||||
|
||||
func FishTileXY(x, y int) *ebiten.Image {
|
||||
const tileSize = 16
|
||||
const tilesetWidth = 56
|
||||
|
||||
r := image.Rect(x*tileSize, y*tileSize, (x+1)*tileSize, (y+1)*tileSize)
|
||||
|
||||
return ImgFishTileset.SubImage(r).(*ebiten.Image)
|
||||
return ImgFish.SubImage(r).(*ebiten.Image)
|
||||
}
|
||||
|
||||
func FishImage(i int) *ebiten.Image {
|
||||
const tileSize = 16
|
||||
const fishTilesetWidth = 10
|
||||
|
||||
x, y := i%fishTilesetWidth, i/fishTilesetWidth
|
||||
const tilesetWidth = 10
|
||||
|
||||
x, y := i%tilesetWidth, i/tilesetWidth
|
||||
x += 46
|
||||
|
||||
r := image.Rect(x*tileSize, y*tileSize, (x+1)*tileSize, (y+1)*tileSize)
|
||||
|
||||
return ImgFishTileset.SubImage(r).(*ebiten.Image)
|
||||
return ImgFish.SubImage(r).(*ebiten.Image)
|
||||
}
|
||||
|
||||
func PeepImage(tileset *ebiten.Image, i int, frame int) *ebiten.Image {
|
||||
const tileSize = 32
|
||||
const tilesetWidth = 8
|
||||
|
||||
x, y := frame%tilesetWidth, frame/tilesetWidth
|
||||
offsetX, offsetY := i*32*8, 0
|
||||
|
||||
r := image.Rect(offsetX+x*tileSize, offsetY+y*tileSize, offsetX+(x+1)*tileSize, offsetY+(y+1)*tileSize)
|
||||
return tileset.SubImage(r).(*ebiten.Image)
|
||||
}
|
||||
|
|
|
@ -26,4 +26,8 @@ type Sprite struct {
|
|||
|
||||
OverrideColorScale bool
|
||||
ColorScale float64
|
||||
|
||||
OffsetX, OffsetY float64
|
||||
|
||||
Images []*ebiten.Image
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"math/rand"
|
||||
"sync"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
|
||||
"code.rocketnine.space/tslocum/fishfightback/asset"
|
||||
"code.rocketnine.space/tslocum/fishfightback/component"
|
||||
"code.rocketnine.space/tslocum/fishfightback/level"
|
||||
|
@ -21,6 +23,10 @@ func newCreepID() int64 {
|
|||
return newestCreepID
|
||||
}
|
||||
|
||||
func randCreepType() int {
|
||||
return rand.Intn(8)
|
||||
}
|
||||
|
||||
func NewCreep(creepType int, x, y float64) gohan.Entity {
|
||||
creepID := newCreepID()
|
||||
|
||||
|
@ -32,8 +38,18 @@ func NewCreep(creepType int, x, y float64) gohan.Entity {
|
|||
Z: level.LayerCreep,
|
||||
})
|
||||
|
||||
images := []*ebiten.Image{
|
||||
asset.PeepImage(asset.ImgPeepBody, randCreepType(), 0),
|
||||
}
|
||||
if rand.Intn(3) == 0 {
|
||||
images = append(images, asset.PeepImage(asset.ImgPeepClothesShirt, randCreepType(), 0))
|
||||
}
|
||||
images = append(images, asset.PeepImage(asset.ImgPeepClothesPants, randCreepType(), 0))
|
||||
|
||||
creep.AddComponent(&component.Sprite{
|
||||
Image: asset.FishImage(int(level.FishMackerel)),
|
||||
Images: images,
|
||||
OffsetX: -16,
|
||||
OffsetY: -16,
|
||||
})
|
||||
|
||||
creep.AddComponent(&component.Creep{
|
||||
|
|
|
@ -22,7 +22,9 @@ func NewPlayerBullet(x, y, xSpeed, ySpeed float64) gohan.Entity {
|
|||
})
|
||||
|
||||
bullet.AddComponent(&component.Sprite{
|
||||
Image: asset.ImgBlackSquare,
|
||||
Image: asset.ImgBlackSquare,
|
||||
OffsetX: -2,
|
||||
OffsetY: -2,
|
||||
})
|
||||
|
||||
bullet.AddComponent(&component.PlayerBullet{})
|
||||
|
|
|
@ -2,7 +2,6 @@ package system
|
|||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"math"
|
||||
|
||||
"code.rocketnine.space/tslocum/fishfightback/component"
|
||||
|
@ -11,8 +10,6 @@ import (
|
|||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
const rewindThreshold = 1
|
||||
|
||||
type MovementSystem struct {
|
||||
Position *component.Position
|
||||
Velocity *component.Velocity
|
||||
|
@ -29,25 +26,6 @@ func NewMovementSystem() *MovementSystem {
|
|||
return s
|
||||
}
|
||||
|
||||
func drawDebugRect(r image.Rectangle, c color.Color, overrideColorScale bool) gohan.Entity {
|
||||
rectEntity := gohan.NewEntity()
|
||||
|
||||
rectImg := ebiten.NewImage(r.Dx(), r.Dy())
|
||||
rectImg.Fill(c)
|
||||
|
||||
rectEntity.AddComponent(&component.Position{
|
||||
X: float64(r.Min.X),
|
||||
Y: float64(r.Min.Y),
|
||||
})
|
||||
|
||||
rectEntity.AddComponent(&component.Sprite{
|
||||
Image: rectImg,
|
||||
OverrideColorScale: overrideColorScale,
|
||||
})
|
||||
|
||||
return rectEntity
|
||||
}
|
||||
|
||||
func (s *MovementSystem) Update(e gohan.Entity) error {
|
||||
if !world.World.GameStarted {
|
||||
return nil
|
||||
|
@ -128,27 +106,25 @@ func (s *MovementSystem) Update(e gohan.Entity) error {
|
|||
if world.World.NoClip {
|
||||
return nil
|
||||
}
|
||||
bulletSize := 4.0
|
||||
bulletRect := image.Rect(int(position.X), int(position.Y), int(position.X+bulletSize), int(position.Y+bulletSize))
|
||||
|
||||
creepBullet := s.CreepBullet
|
||||
playerBullet := s.PlayerBullet
|
||||
|
||||
var currentSection = world.World.SectionA
|
||||
if world.World.SectionB.X != 0 && position.X >= world.World.SectionB.X && position.X < world.World.SectionB.X+world.SectionWidth {
|
||||
currentSection = world.World.SectionB
|
||||
}
|
||||
tx, ty := int((position.X-currentSection.X)/TileWidth), int((position.Y-currentSection.Y)/TileWidth)
|
||||
offscreen := tx < 0 || ty < 0 || tx >= world.SectionWidth/TileWidth || ty >= world.ScreenHeight/TileWidth
|
||||
|
||||
// Check hazard collisions.
|
||||
if creepBullet != nil {
|
||||
if offscreen {
|
||||
playerRect := image.Rect(int(world.World.PlayerX), int(world.World.PlayerY), int(world.World.PlayerX+world.World.PlayerWidth), int(world.World.PlayerY+world.World.PlayerHeight))
|
||||
bulletSize := 4.0
|
||||
|
||||
var currentSection = world.World.SectionA
|
||||
if world.World.SectionB.X != 0 && position.X >= world.World.SectionB.X && position.X < world.World.SectionB.X+world.SectionWidth {
|
||||
currentSection = world.World.SectionB
|
||||
}
|
||||
tx, ty := int((position.X-currentSection.X)/TileWidth), int((position.Y-currentSection.Y)/TileWidth)
|
||||
if tx < 0 || ty < 0 || tx >= world.SectionWidth/TileWidth || ty >= world.ScreenHeight/TileWidth {
|
||||
e.Remove()
|
||||
return nil
|
||||
}
|
||||
|
||||
playerRect := image.Rect(int(world.World.PlayerX), int(world.World.PlayerY), int(world.World.PlayerX+world.World.PlayerWidth), int(world.World.PlayerY+world.World.PlayerHeight))
|
||||
bulletRect := image.Rect(int(position.X), int(position.Y), int(position.X+bulletSize), int(position.Y+bulletSize))
|
||||
if bulletRect.Overlaps(playerRect) {
|
||||
if !world.World.GodMode {
|
||||
world.World.SetGameOver()
|
||||
|
@ -159,29 +135,48 @@ func (s *MovementSystem) Update(e gohan.Entity) error {
|
|||
}
|
||||
|
||||
if playerBullet != nil {
|
||||
var offscreen bool
|
||||
for oy := -2; oy < 5; oy++ {
|
||||
for ox := -2; ox < 5; ox++ {
|
||||
var currentSection = world.World.SectionA
|
||||
if world.World.SectionB.X != 0 && position.X >= world.World.SectionB.X && position.X < world.World.SectionB.X+world.SectionWidth {
|
||||
currentSection = world.World.SectionB
|
||||
}
|
||||
tx, ty := int((position.X+float64(ox)-currentSection.X)/TileWidth), int((position.Y+float64(oy)-currentSection.Y)/TileWidth)
|
||||
if tx < 0 || ty < 0 || tx >= world.SectionWidth/TileWidth || ty >= world.ScreenHeight/TileWidth {
|
||||
continue // Offscreen
|
||||
}
|
||||
offscreen = false
|
||||
|
||||
// Hit creep.
|
||||
for offset := 0; offset < 2; offset++ {
|
||||
if ty+offset >= world.ScreenHeight/TileWidth {
|
||||
break
|
||||
}
|
||||
creepEntity := currentSection.Creeps[ty+offset][tx]
|
||||
if creepEntity != 0 {
|
||||
var hitCreep bool
|
||||
creepEntity.With(func(creep *component.Creep) {
|
||||
if creep == nil || !creep.Active {
|
||||
return
|
||||
}
|
||||
creep.Health--
|
||||
creep.DamageTicks = 6
|
||||
hitCreep = true
|
||||
})
|
||||
if hitCreep {
|
||||
e.Remove()
|
||||
currentSection.Creeps[ty+offset][tx] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if offscreen {
|
||||
e.Remove()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Hit creep.
|
||||
creepEntity := currentSection.Creeps[ty][tx]
|
||||
if creepEntity != 0 {
|
||||
var hitCreep bool
|
||||
creepEntity.With(func(creep *component.Creep) {
|
||||
if creep == nil || !creep.Active {
|
||||
return
|
||||
}
|
||||
creep.Health--
|
||||
creep.DamageTicks = 6
|
||||
hitCreep = true
|
||||
})
|
||||
if hitCreep {
|
||||
e.Remove()
|
||||
currentSection.Creeps[ty][tx] = 0
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -127,6 +127,11 @@ func (s *RenderSystem) Draw(e gohan.Entity, screen *ebiten.Image) error {
|
|||
colorScale = sprite.ColorScale
|
||||
}
|
||||
|
||||
s.renderSprite(position.X, position.Y, 0, 0, sprite.Angle, 1.0, colorScale, 1.0, sprite.HorizontalFlip, sprite.VerticalFlip, sprite.Image, screen)
|
||||
if len(sprite.Images) == 0 {
|
||||
s.renderSprite(position.X, position.Y, sprite.OffsetX, sprite.OffsetY, sprite.Angle, 1.0, colorScale, 1.0, sprite.HorizontalFlip, sprite.VerticalFlip, sprite.Image, screen)
|
||||
}
|
||||
for _, img := range sprite.Images {
|
||||
s.renderSprite(position.X, position.Y, sprite.OffsetX, sprite.OffsetY, sprite.Angle, 1.0, colorScale, 1.0, sprite.HorizontalFlip, sprite.VerticalFlip, img, screen)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -179,11 +179,8 @@ func (s *Section) Regenerate(lastShoreDepth int) {
|
|||
}
|
||||
|
||||
// Generate buildings.
|
||||
|
||||
// TODO bag of random buildings
|
||||
|
||||
addBuildings := rand.Intn(14)
|
||||
|
||||
for j := 0; j < addBuildings; j++ {
|
||||
specialBuilding := rand.Intn(4) == 0
|
||||
|
||||
|
@ -218,9 +215,10 @@ func (s *Section) Regenerate(lastShoreDepth int) {
|
|||
}
|
||||
|
||||
// Generate creeps.
|
||||
for attempt := 0; attempt < 7; attempt++ {
|
||||
tx, ty := rand.Intn(SectionWidth/16), int(float64(rand.Intn(s.ShoreDepth)))
|
||||
if !s.tileAvailable(tx, ty, true) {
|
||||
const numCreeps = 40 // TODO
|
||||
for attempt := 0; attempt < numCreeps; attempt++ {
|
||||
tx, ty := rand.Intn(SectionWidth/16), int(float64(rand.Intn(s.ShoreDepth-1)))
|
||||
if !s.tileAvailable(tx, ty, true) || (ty != 0 && !s.tileAvailable(tx, ty-1, true)) || !s.tileAvailable(tx, ty+1, true) || !s.tileAvailable(tx-1, ty, true) || !s.tileAvailable(tx+1, ty, true) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,12 @@ const (
|
|||
ScreenHeight = 225
|
||||
)
|
||||
|
||||
var RailSpeed = 0.4
|
||||
const (
|
||||
StartingRailSpeed = 0.4
|
||||
FishSpeedIncrease = 0.05
|
||||
)
|
||||
|
||||
var RailSpeed = StartingRailSpeed
|
||||
|
||||
var NumberPrinter = message.NewPrinter(language.English)
|
||||
|
||||
|
@ -155,4 +160,6 @@ func SetFish(fish level.FishType) {
|
|||
|
||||
sprite.Image = asset.FishImage(int(fish))
|
||||
})
|
||||
|
||||
RailSpeed = StartingRailSpeed + (FishSpeedIncrease * float64(fish))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue