Compare commits
3 Commits
c02fb342a7
...
cbb6e6c144
Author | SHA1 | Date | |
---|---|---|---|
cbb6e6c144 | |||
b9515823d3 | |||
72da0ef462 |
73
cmd/imadapt/imadapt.go
Normal file
73
cmd/imadapt/imadapt.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/png"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func run() error {
|
||||||
|
flag.Parse()
|
||||||
|
args := flag.Args()
|
||||||
|
if len(args) < 1 {
|
||||||
|
return errors.New("no command specified")
|
||||||
|
}
|
||||||
|
switch args[0] {
|
||||||
|
case "setalpha":
|
||||||
|
flags := flag.NewFlagSet("setalpha", flag.ContinueOnError)
|
||||||
|
var alpha int
|
||||||
|
flags.IntVar(&alpha, "alpha", 127, "sets the target alpha")
|
||||||
|
flags.Parse(args[1:])
|
||||||
|
for _, path := range flags.Args() {
|
||||||
|
err := setAlpha(path, alpha)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("couldn't set alpha for '%s'; error: %v", path, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setAlpha(path string, alpha int) error {
|
||||||
|
src, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer src.Close()
|
||||||
|
im, _, err := image.Decode(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bounds := im.Bounds()
|
||||||
|
dst := image.NewNRGBA(bounds)
|
||||||
|
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
|
||||||
|
for x := bounds.Min.X; x < bounds.Max.X; x++ {
|
||||||
|
c := color.NRGBAModel.Convert(im.At(x, y)).(color.NRGBA)
|
||||||
|
if c.A > 0 {
|
||||||
|
c.A = uint8(alpha)
|
||||||
|
}
|
||||||
|
dst.Set(x, y, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return encodePNG(path, dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodePNG(path string, im image.Image) error {
|
||||||
|
dst, err := os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer dst.Close()
|
||||||
|
return png.Encode(dst, im)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := run(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
BIN
cmd/tins2020/res/images/game_control_hover.png
Normal file
BIN
cmd/tins2020/res/images/game_control_hover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 297 B |
BIN
cmd/tins2020/res/images/tile_hover.png
Normal file
BIN
cmd/tins2020/res/images/tile_hover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
@ -1,7 +1,9 @@
|
|||||||
|
game-control-hover: images/game_control_hover.png
|
||||||
|
|
||||||
tile-dirt: images/tile_dirt.png
|
tile-dirt: images/tile_dirt.png
|
||||||
tile-grass: images/tile_grass.png
|
tile-grass: images/tile_grass.png
|
||||||
tile-snow: images/tile_snow.png
|
tile-snow: images/tile_snow.png
|
||||||
|
tile-hover: images/tile_hover.png
|
||||||
|
|
||||||
cactus-small-1: images/cactus_short_NE.png
|
cactus-small-1: images/cactus_short_NE.png
|
||||||
cactus-small-2: images/cactus_short_NW.png
|
cactus-small-2: images/cactus_short_NW.png
|
||||||
|
@ -92,6 +92,8 @@ func run() error {
|
|||||||
app := tins2020.NewContainer()
|
app := tins2020.NewContainer()
|
||||||
overlays := tins2020.NewContainer()
|
overlays := tins2020.NewContainer()
|
||||||
overlays.AddChild(&tins2020.FPS{})
|
overlays.AddChild(&tins2020.FPS{})
|
||||||
|
gameControls := tins2020.NewGameControls()
|
||||||
|
overlays.AddChild(gameControls)
|
||||||
content := tins2020.NewContainer()
|
content := tins2020.NewContainer()
|
||||||
app.AddChild(content)
|
app.AddChild(content)
|
||||||
app.AddChild(overlays)
|
app.AddChild(overlays)
|
||||||
|
@ -38,6 +38,8 @@ func (c *Context) Init(renderer *sdl.Renderer) {
|
|||||||
c.Renderer = renderer
|
c.Renderer = renderer
|
||||||
c.Fonts.Init(c.Resources.Copy())
|
c.Fonts.Init(c.Resources.Copy())
|
||||||
c.Textures.Init(renderer, c.Resources.Copy())
|
c.Textures.Init(renderer, c.Resources.Copy())
|
||||||
|
|
||||||
|
c.Renderer.SetDrawBlendMode(sdl.BLENDMODE_BLEND)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) Quit() { c.ShouldQuit = true }
|
func (c *Context) Quit() { c.ShouldQuit = true }
|
||||||
|
@ -34,8 +34,8 @@ type FlowerResistance struct {
|
|||||||
// NewPoppyTraits creates the traits of a poppy, a very generic flower that thrives in a moderate climate.
|
// NewPoppyTraits creates the traits of a poppy, a very generic flower that thrives in a moderate climate.
|
||||||
func NewPoppyTraits() FlowerTraits {
|
func NewPoppyTraits() FlowerTraits {
|
||||||
return FlowerTraits{
|
return FlowerTraits{
|
||||||
Spread: 0.01,
|
Spread: 0.0007,
|
||||||
Life: 0.9991,
|
Life: 0.99991,
|
||||||
Resistance: FlowerResistance{
|
Resistance: FlowerResistance{
|
||||||
Cold: 0.3,
|
Cold: 0.3,
|
||||||
Hot: 0.3,
|
Hot: 0.3,
|
||||||
|
110
gamecontrols.go
Normal file
110
gamecontrols.go
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package tins2020
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GameControls struct {
|
||||||
|
ControlBase
|
||||||
|
|
||||||
|
menu ButtonBar
|
||||||
|
flowers ButtonBar
|
||||||
|
}
|
||||||
|
|
||||||
|
type ButtonBar struct {
|
||||||
|
Top int32
|
||||||
|
Left int32
|
||||||
|
Bottom int32
|
||||||
|
Hover int
|
||||||
|
Buttons []Button
|
||||||
|
}
|
||||||
|
|
||||||
|
type Button struct {
|
||||||
|
Icon string
|
||||||
|
Disabled string
|
||||||
|
|
||||||
|
IsDisabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
const buttonBarWidth = 96
|
||||||
|
|
||||||
|
func (b *ButtonBar) Handle(ctx *Context, event sdl.Event) {
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *sdl.MouseMotionEvent:
|
||||||
|
if e.X > b.Left && e.X < b.Left+buttonBarWidth {
|
||||||
|
button := int(e.Y-b.Top) / buttonBarWidth
|
||||||
|
if button < 0 || button >= len(b.Buttons) || b.Buttons[button].IsDisabled {
|
||||||
|
button = -1
|
||||||
|
}
|
||||||
|
b.Hover = button
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *ButtonBar) Render(ctx *Context) {
|
||||||
|
ctx.Renderer.FillRect(&sdl.Rect{X: b.Left, Y: b.Top, W: b.Left + buttonBarWidth, H: b.Bottom})
|
||||||
|
texture := func(b Button) *Texture {
|
||||||
|
if b.IsDisabled {
|
||||||
|
texture := ctx.Textures.Texture(b.Disabled)
|
||||||
|
if texture != nil {
|
||||||
|
return texture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctx.Textures.Texture(b.Icon)
|
||||||
|
}
|
||||||
|
hoverTexture := ctx.Textures.Texture("game-control-hover")
|
||||||
|
for i, button := range b.Buttons {
|
||||||
|
pos := Pt(b.Left, b.Top+int32(i)*buttonBarWidth)
|
||||||
|
texture := texture(button)
|
||||||
|
texture.Copy(ctx.Renderer, &sdl.Rect{X: pos.X, Y: pos.Y, W: buttonBarWidth, H: buttonBarWidth})
|
||||||
|
if b.Hover == i {
|
||||||
|
hoverTexture.Copy(ctx.Renderer, hoverTexture.RectOffset(pos))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGameControls() *GameControls {
|
||||||
|
return &GameControls{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GameControls) Init(ctx *Context) error {
|
||||||
|
c.flowers.Buttons = []Button{
|
||||||
|
Button{Icon: "flower-poppy-1", Disabled: "flower-red-c-1"},
|
||||||
|
Button{Icon: "flower-poppy-1", Disabled: "flower-red-c-1", IsDisabled: true},
|
||||||
|
}
|
||||||
|
return c.updateBarPositions(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GameControls) Handle(ctx *Context, event sdl.Event) {
|
||||||
|
c.menu.Handle(ctx, event)
|
||||||
|
c.flowers.Handle(ctx, event)
|
||||||
|
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *sdl.WindowEvent:
|
||||||
|
switch e.Event {
|
||||||
|
case sdl.WINDOWEVENT_RESIZED:
|
||||||
|
err := c.updateBarPositions(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GameControls) Render(ctx *Context) {
|
||||||
|
ctx.Renderer.SetDrawColor(74, 198, 154, 255)
|
||||||
|
c.menu.Render(ctx)
|
||||||
|
c.flowers.Render(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GameControls) updateBarPositions(ctx *Context) error {
|
||||||
|
w, h, err := ctx.Renderer.GetOutputSize()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.menu.Top, c.menu.Left, c.menu.Bottom = 0, 0, h
|
||||||
|
c.flowers.Top, c.flowers.Left, c.flowers.Bottom = 0, w-buttonBarWidth, h
|
||||||
|
return nil
|
||||||
|
}
|
2
math.go
2
math.go
@ -34,4 +34,6 @@ func Min32(a, b float32) float32 {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Round32(x float32) float32 { return float32(math.Round(float64(x))) }
|
||||||
|
|
||||||
func Sqrt32(x float32) float32 { return float32(math.Sqrt(float64(x))) }
|
func Sqrt32(x float32) float32 { return float32(math.Sqrt(float64(x))) }
|
||||||
|
@ -64,7 +64,7 @@ func (p *projection) update(renderer *sdl.Renderer) {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
p.windowCenter = Pt(windowW/2, windowH/2)
|
p.windowCenter = Pt(windowW/2, windowH/2)
|
||||||
p.windowRect = sdl.Rect{X: 0, Y: 0, W: windowW - 0, H: windowH - 0}
|
p.windowRect = sdl.Rect{X: buttonBarWidth, Y: 0, W: windowW - 2*buttonBarWidth, H: windowH - 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *projection) visibleTiles(action func(int32, int32, Point)) {
|
func (p *projection) visibleTiles(action func(int32, int32, Point)) {
|
||||||
|
@ -4,12 +4,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
"opslag.de/schobers/geom"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type terrainRenderer struct {
|
type terrainRenderer struct {
|
||||||
terrain *Map
|
terrain *Map
|
||||||
hover PointF
|
hover *Point
|
||||||
project projection
|
project projection
|
||||||
|
|
||||||
interact interaction
|
interact interaction
|
||||||
@ -42,7 +41,12 @@ func (r *terrainRenderer) Handle(ctx *Context, event sdl.Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *sdl.MouseMotionEvent:
|
case *sdl.MouseMotionEvent:
|
||||||
r.hover = r.project.screenToMap(e.X, e.Y)
|
if insideRect(e.X, e.Y, &r.project.windowRect) {
|
||||||
|
hover := r.project.screenToMap(e.X, e.Y)
|
||||||
|
r.hover = &Point{X: int32(Round32(hover.X)), Y: int32(Round32(hover.Y))}
|
||||||
|
} else {
|
||||||
|
r.hover = nil
|
||||||
|
}
|
||||||
if r.interact.mouseDrag != nil {
|
if r.interact.mouseDrag != nil {
|
||||||
r.project.center = r.project.center.Sub(r.project.screenToMapRel(e.X-r.interact.mouseDrag.X, e.Y-r.interact.mouseDrag.Y))
|
r.project.center = r.project.center.Sub(r.project.screenToMapRel(e.X-r.interact.mouseDrag.X, e.Y-r.interact.mouseDrag.Y))
|
||||||
r.project.update(ctx.Renderer)
|
r.project.update(ctx.Renderer)
|
||||||
@ -63,8 +67,15 @@ func (r *terrainRenderer) Handle(ctx *Context, event sdl.Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func insideRect(x, y int32, rect *sdl.Rect) bool {
|
||||||
|
return x >= rect.X && x < rect.X+rect.W && y >= rect.Y && y < rect.Y+rect.H
|
||||||
|
}
|
||||||
|
|
||||||
|
func insideRectPt(p Point, rect *sdl.Rect) bool { return insideRect(p.X, p.Y, rect) }
|
||||||
|
|
||||||
func (r *terrainRenderer) Render(ctx *Context) {
|
func (r *terrainRenderer) Render(ctx *Context) {
|
||||||
toTileTexture := func(temp, humid float64) *Texture {
|
toTileTexture := func(x, y int32) *Texture {
|
||||||
|
temp := r.terrain.Temp.Value(x, y)
|
||||||
if temp < .35 {
|
if temp < .35 {
|
||||||
return ctx.Textures.Texture("tile-snow")
|
return ctx.Textures.Texture("tile-snow")
|
||||||
}
|
}
|
||||||
@ -141,16 +152,14 @@ func (r *terrainRenderer) Render(ctx *Context) {
|
|||||||
// horizontal: [191, 321) = 130
|
// horizontal: [191, 321) = 130
|
||||||
// vertical: [267,332) = 65
|
// vertical: [267,332) = 65
|
||||||
|
|
||||||
hover := Pt(int32(geom.Round32(r.hover.X)), int32(geom.Round32(r.hover.Y)))
|
|
||||||
r.project.visibleTiles(func(x, y int32, pos Point) {
|
r.project.visibleTiles(func(x, y int32, pos Point) {
|
||||||
if x == hover.X && y == hover.Y {
|
text := toTileTexture(x, y)
|
||||||
return
|
|
||||||
}
|
|
||||||
temp := r.terrain.Temp.Value(x, y)
|
|
||||||
humid := r.terrain.Humid.Value(x, y)
|
|
||||||
text := toTileTexture(temp, humid)
|
|
||||||
rect := r.project.screenToTileRect(pos)
|
rect := r.project.screenToTileRect(pos)
|
||||||
text.Copy(ctx.Renderer, rect)
|
text.Copy(ctx.Renderer, rect)
|
||||||
|
|
||||||
|
if r.hover != nil && x == r.hover.X && y == r.hover.Y {
|
||||||
|
ctx.Textures.Texture("tile-hover").Copy(ctx.Renderer, rect)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
r.project.visibleTiles(func(x, y int32, pos Point) {
|
r.project.visibleTiles(func(x, y int32, pos Point) {
|
||||||
@ -160,7 +169,7 @@ func (r *terrainRenderer) Render(ctx *Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
placeX, placeY := r.terrain.PlaceX.Value(x, y), r.terrain.PlaceY.Value(x, y)
|
placeX, placeY := r.terrain.PlaceX.Value(x, y), r.terrain.PlaceY.Value(x, y)
|
||||||
pos = r.project.mapToScreenF(float32(x)-.2+float32(.8*placeX-.4), float32(y)-.2+float32(.8*placeY-.4))
|
pos = r.project.mapToScreenF(float32(x)-.2+float32(.9*placeX-.45), float32(y)-.2+float32(.9*placeY-.45))
|
||||||
text.Copy(ctx.Renderer, r.project.screenToTileRect(pos))
|
text.Copy(ctx.Renderer, r.project.screenToTileRect(pos))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user