feat: ...
This commit is contained in:
parent
d4ac7909db
commit
348c03cfc9
18 changed files with 397 additions and 343 deletions
24
camera.go
24
camera.go
|
@ -3,8 +3,19 @@ package gg
|
||||||
// Implements the camera component
|
// Implements the camera component
|
||||||
// for the main window.
|
// for the main window.
|
||||||
type Camera struct {
|
type Camera struct {
|
||||||
|
// The shaders that will be applied to everything
|
||||||
|
// that the camera shows.
|
||||||
|
ShaderOptions
|
||||||
Transform
|
Transform
|
||||||
buf *Matrix
|
buf *Matrix
|
||||||
|
engine *Engine
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Engine) NewCamera() *Camera {
|
||||||
|
ret := &Camera{}
|
||||||
|
ret.Transform = T()
|
||||||
|
ret.engine = e
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the matrix satysfying camera
|
// Returns the matrix satysfying camera
|
||||||
|
@ -14,11 +25,16 @@ type Camera struct {
|
||||||
// (Should implement buffering it so we do not
|
// (Should implement buffering it so we do not
|
||||||
// need to calculate it each time for each object. )
|
// need to calculate it each time for each object. )
|
||||||
func (c *Camera)RealMatrix() Matrix {
|
func (c *Camera)RealMatrix() Matrix {
|
||||||
|
/*if c.buf != nil {
|
||||||
|
return *(c.buf)
|
||||||
|
}*/
|
||||||
g := &Matrix{}
|
g := &Matrix{}
|
||||||
g.Translate(-c.P.X, -c.P.Y)
|
g.Translate(-c.Position.X, -c.Position.Y)
|
||||||
g.Rotate(c.R)
|
g.Rotate(c.Rotation)
|
||||||
g.Scale(c.S.X, c.S.Y)
|
siz := c.engine.AbsWinSize()
|
||||||
g.Translate(c.RA.X, c.RA.Y)
|
g.Translate(c.Around.X * siz.X, c.Around.Y * siz.Y)
|
||||||
|
g.Scale(c.Scale.X, c.Scale.Y)
|
||||||
|
|
||||||
|
|
||||||
c.buf = g
|
c.buf = g
|
||||||
|
|
||||||
|
|
40
cmd/test/debug.go
Normal file
40
cmd/test/debug.go
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/di4f/gg"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Debug struct {
|
||||||
|
gg.Visibility
|
||||||
|
gg.Layer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Debug) Draw(c *Context) {
|
||||||
|
e := c.Engine
|
||||||
|
keyStrs := []string{}
|
||||||
|
for _, k := range e.Keys() {
|
||||||
|
keyStrs = append(keyStrs, k.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if rectMove.ContainsPoint(e.AbsCursorPosition()) {
|
||||||
|
keyStrs = append(keyStrs, "contains cursor")
|
||||||
|
}
|
||||||
|
|
||||||
|
if rectMove.Vertices().Contained(rect).Len() > 0 ||
|
||||||
|
rect.Vertices().Contained(rectMove).Len() > 0 {
|
||||||
|
keyStrs = append(keyStrs, "rectangles intersect")
|
||||||
|
}
|
||||||
|
|
||||||
|
keyStrs = append(keyStrs, fmt.Sprintf("%v", e.CursorPosition()))
|
||||||
|
keyStrs = append(keyStrs, fmt.Sprintf("%v", e.AbsCursorPosition()))
|
||||||
|
keyStrs = append(keyStrs, fmt.Sprintf("absWinSize: %v", c.AbsWinSize()))
|
||||||
|
|
||||||
|
e.DebugPrint(c.Image,
|
||||||
|
strings.Join(keyStrs, "\n"))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Debug) IsVisible() bool { return true }
|
256
cmd/test/main.go
256
cmd/test/main.go
|
@ -3,12 +3,10 @@ package main
|
||||||
import (
|
import (
|
||||||
"github.com/di4f/gg"
|
"github.com/di4f/gg"
|
||||||
"github.com/hajimehoshi/ebiten/v2/examples/resources/images"
|
"github.com/hajimehoshi/ebiten/v2/examples/resources/images"
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
//"strings"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Context = gg.Context
|
type Context = gg.Context
|
||||||
|
@ -22,94 +20,6 @@ const (
|
||||||
LowestL
|
LowestL
|
||||||
)
|
)
|
||||||
|
|
||||||
type Player struct {
|
|
||||||
*gg.Sprite
|
|
||||||
MoveSpeed gg.Float
|
|
||||||
ScaleSpeed gg.Float
|
|
||||||
gg.Layer
|
|
||||||
}
|
|
||||||
|
|
||||||
type Debug struct {
|
|
||||||
gg.Visibility
|
|
||||||
gg.Layer
|
|
||||||
}
|
|
||||||
|
|
||||||
type Rect struct {
|
|
||||||
*gg.DrawableRectangle
|
|
||||||
gg.Layer
|
|
||||||
}
|
|
||||||
|
|
||||||
type Tri struct {
|
|
||||||
*gg.DrawablePolygon
|
|
||||||
gg.Layer
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTri() *Tri {
|
|
||||||
ret := &Tri{}
|
|
||||||
ret.DrawablePolygon = &gg.DrawablePolygon{}
|
|
||||||
ret.Transform.S = gg.V(1, 1)
|
|
||||||
|
|
||||||
ret.Triangles = gg.Triangles{
|
|
||||||
gg.Triangle{
|
|
||||||
gg.V(0, 0),
|
|
||||||
gg.V(100, 100),
|
|
||||||
gg.V(0, -50),
|
|
||||||
},
|
|
||||||
gg.Triangle{
|
|
||||||
gg.V(0, 0),
|
|
||||||
gg.V(-100, -100),
|
|
||||||
gg.V(0, 50),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
ret.Color = gg.Color{gg.MaxColorV, gg.MaxColorV, 0, gg.MaxColorV}
|
|
||||||
ret.Visible = true
|
|
||||||
ret.Layer = TriangleL
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRect() *Rect {
|
|
||||||
ret := &Rect{&gg.DrawableRectangle{
|
|
||||||
Rectangle: gg.Rectangle{
|
|
||||||
Transform: gg.Transform{
|
|
||||||
S: gg.Vector{
|
|
||||||
X: 200,
|
|
||||||
Y: 400,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Color: gg.Color{
|
|
||||||
gg.MaxColorV,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
gg.MaxColorV,
|
|
||||||
},
|
|
||||||
Visible: true,
|
|
||||||
/*Shader: gg.SolidWhiteColorShader,
|
|
||||||
Options: gg.ShaderOptions{
|
|
||||||
Images: [4]*gg.Image{
|
|
||||||
playerImg,
|
|
||||||
nil,
|
|
||||||
nil,
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
},*/
|
|
||||||
},
|
|
||||||
RectL,
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Rect) Update(c *Context) error {
|
|
||||||
//r.R += 0.3 * e.DT()
|
|
||||||
r.P = c.AbsCursorPosition()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Rect) Event(c *Context) {
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
playerImg *gg.Image
|
playerImg *gg.Image
|
||||||
player *Player
|
player *Player
|
||||||
|
@ -118,170 +28,6 @@ var (
|
||||||
tri *Tri
|
tri *Tri
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewPlayer() *Player {
|
|
||||||
ret := &Player{
|
|
||||||
Sprite: &gg.Sprite{
|
|
||||||
Transform: gg.Transform{
|
|
||||||
S: gg.Vector{5, 5},
|
|
||||||
RA: gg.Vector{.5, .5},
|
|
||||||
},
|
|
||||||
Visible: true,
|
|
||||||
ShaderOptions: gg.ShaderOptions{
|
|
||||||
Shader: gg.SolidWhiteColorShader,
|
|
||||||
Uniforms: make(map[string]any),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MoveSpeed: 90.,
|
|
||||||
ScaleSpeed: .2,
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.Images[0] = playerImg
|
|
||||||
ret.Layer = PlayerL
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) Draw(c *Context) {
|
|
||||||
p.Sprite.Draw(c)
|
|
||||||
t := p.Transform
|
|
||||||
t.S.X *= 4.
|
|
||||||
t.S.Y *= 4.
|
|
||||||
rectMove = gg.Rectangle{
|
|
||||||
Transform: t,
|
|
||||||
}
|
|
||||||
r := &gg.DrawableRectangle{
|
|
||||||
Rectangle: rectMove,
|
|
||||||
Color: gg.Color{0, 0, gg.MaxColorV, gg.MaxColorV},
|
|
||||||
}
|
|
||||||
r.Draw(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) Start(c *Context) {
|
|
||||||
fmt.Println("starting")
|
|
||||||
cam := c.Camera()
|
|
||||||
cam.RA = gg.V(360, 240)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) Update(c *Context) error {
|
|
||||||
dt := c.DT()
|
|
||||||
cam := c.Camera()
|
|
||||||
keys := c.Keys()
|
|
||||||
|
|
||||||
p.Uniforms["Random"] = any(rand.Float32())
|
|
||||||
for _, v := range keys {
|
|
||||||
switch v {
|
|
||||||
case ebiten.KeyArrowUp:
|
|
||||||
cam.P.Y += p.MoveSpeed * dt
|
|
||||||
case ebiten.KeyArrowLeft:
|
|
||||||
cam.P.X -= p.MoveSpeed * dt
|
|
||||||
case ebiten.KeyArrowDown:
|
|
||||||
cam.P.Y -= p.MoveSpeed * dt
|
|
||||||
case ebiten.KeyArrowRight:
|
|
||||||
cam.P.X += p.MoveSpeed * dt
|
|
||||||
case ebiten.KeyW:
|
|
||||||
p.P.Y += p.MoveSpeed * dt
|
|
||||||
case ebiten.KeyA:
|
|
||||||
p.P.X -= p.MoveSpeed * dt
|
|
||||||
case ebiten.KeyS:
|
|
||||||
p.P.Y -= p.MoveSpeed * dt
|
|
||||||
case ebiten.KeyD:
|
|
||||||
p.P.X += p.MoveSpeed * dt
|
|
||||||
case ebiten.KeyR:
|
|
||||||
cam.R += gg.Pi * p.ScaleSpeed * dt
|
|
||||||
case ebiten.KeyT:
|
|
||||||
cam.R -= gg.Pi * p.ScaleSpeed * dt
|
|
||||||
case ebiten.KeyRightBracket:
|
|
||||||
if c.IsPressed(gg.KeyShift) {
|
|
||||||
p.R -= gg.Pi * 0.3 * dt
|
|
||||||
} else {
|
|
||||||
p.R += gg.Pi * 0.3 * dt
|
|
||||||
}
|
|
||||||
case gg.KeyF:
|
|
||||||
if c.IsPressed(ebiten.KeyShift) {
|
|
||||||
cam.S.X -= gg.Pi * p.ScaleSpeed * dt
|
|
||||||
} else {
|
|
||||||
cam.S.X += gg.Pi * p.ScaleSpeed * dt
|
|
||||||
}
|
|
||||||
case gg.KeyG:
|
|
||||||
if c.IsPressed(ebiten.KeyShift) {
|
|
||||||
cam.S.Y -= gg.Pi * p.ScaleSpeed * dt
|
|
||||||
} else {
|
|
||||||
cam.S.Y += gg.Pi * p.ScaleSpeed * dt
|
|
||||||
}
|
|
||||||
case gg.KeyZ:
|
|
||||||
if c.IsPressed(ebiten.KeyShift) {
|
|
||||||
cam.RA.X -= gg.Pi * p.MoveSpeed * dt
|
|
||||||
} else {
|
|
||||||
cam.RA.X += gg.Pi * p.MoveSpeed * dt
|
|
||||||
}
|
|
||||||
case gg.KeyX:
|
|
||||||
if c.IsPressed(ebiten.KeyShift) {
|
|
||||||
cam.RA.Y -= gg.Pi * p.MoveSpeed * dt
|
|
||||||
} else {
|
|
||||||
cam.RA.Y += gg.Pi * p.MoveSpeed * dt
|
|
||||||
}
|
|
||||||
case gg.KeyV:
|
|
||||||
if c.IsPressed(ebiten.KeyShift) {
|
|
||||||
tri.R -= gg.Pi * 0.3 * dt
|
|
||||||
} else {
|
|
||||||
tri.R += gg.Pi * 0.3 * dt
|
|
||||||
}
|
|
||||||
case gg.KeyLeftBracket:
|
|
||||||
if c.IsPressed(ebiten.KeyShift) {
|
|
||||||
rect.R -= gg.Pi * 0.3 * dt
|
|
||||||
} else {
|
|
||||||
rect.R += gg.Pi * 0.3 * dt
|
|
||||||
}
|
|
||||||
case gg.Key0:
|
|
||||||
c.Del(p)
|
|
||||||
case gg.KeyB:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) Signal(e *gg.Engine, ev any) {
|
|
||||||
fmt.Println("event:", ev)
|
|
||||||
switch ec := ev.(type) {
|
|
||||||
case *gg.KeyDown:
|
|
||||||
switch {
|
|
||||||
case ec.Key == gg.KeyB:
|
|
||||||
if p.Layer != PlayerL {
|
|
||||||
p.Layer = PlayerL
|
|
||||||
} else {
|
|
||||||
p.Layer = HighestL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Debug) Draw(c *Context) {
|
|
||||||
e := c.Engine
|
|
||||||
keyStrs := []string{}
|
|
||||||
for _, k := range e.Keys() {
|
|
||||||
keyStrs = append(keyStrs, k.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
if rectMove.ContainsPoint(e.AbsCursorPosition()) {
|
|
||||||
keyStrs = append(keyStrs, "contains cursor")
|
|
||||||
}
|
|
||||||
|
|
||||||
if rectMove.Vertices().Contained(rect).Len() > 0 ||
|
|
||||||
rect.Vertices().Contained(rectMove).Len() > 0 {
|
|
||||||
keyStrs = append(keyStrs, "THIS IS SHIT")
|
|
||||||
}
|
|
||||||
|
|
||||||
keyStrs = append(keyStrs, fmt.Sprintf("%v", e.CursorPosition()))
|
|
||||||
keyStrs = append(keyStrs, fmt.Sprintf("%v", e.AbsCursorPosition()))
|
|
||||||
|
|
||||||
e.DebugPrint(c.Image,
|
|
||||||
strings.Join(keyStrs, ", "))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Debug) IsVisible() bool { return true }
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
e := gg.NewEngine(&gg.WindowConfig{
|
e := gg.NewEngine(&gg.WindowConfig{
|
||||||
Title: "Test title",
|
Title: "Test title",
|
||||||
|
|
129
cmd/test/player.go
Normal file
129
cmd/test/player.go
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"math/rand"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
import "github.com/di4f/gg"
|
||||||
|
|
||||||
|
type Player struct {
|
||||||
|
gg.Sprite
|
||||||
|
MoveSpeed gg.Float
|
||||||
|
ScaleSpeed gg.Float
|
||||||
|
gg.Layer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPlayer() *Player {
|
||||||
|
ret := &Player{}
|
||||||
|
ret.Transform = gg.T()
|
||||||
|
ret.Scale = gg.V(5, 5)
|
||||||
|
// Around center.
|
||||||
|
ret.Around = gg.V(.5, .5)
|
||||||
|
ret.MoveSpeed = 90.
|
||||||
|
ret.ScaleSpeed = .2
|
||||||
|
|
||||||
|
ret.Visible = true
|
||||||
|
|
||||||
|
ret.Images[0] = playerImg
|
||||||
|
ret.Layer = PlayerL
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom drawing function.
|
||||||
|
func (p *Player) Draw(c *Context) {
|
||||||
|
p.Sprite.Draw(c)
|
||||||
|
t := p.Transform
|
||||||
|
t.Scale.X *= 4.
|
||||||
|
t.Scale.Y *= 4.
|
||||||
|
|
||||||
|
r := &gg.DrawableRectangle{}
|
||||||
|
r.Color = gg.Rgba(0, 0, 1, 1)
|
||||||
|
r.Rectangle = gg.Rectangle{
|
||||||
|
Transform: t,
|
||||||
|
}
|
||||||
|
r.Draw(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) Update(c *Context) {
|
||||||
|
dt := c.DT()
|
||||||
|
cam := c.Camera
|
||||||
|
keys := c.Keys()
|
||||||
|
|
||||||
|
//p.Uniforms["Random"] = any(rand.Float32())
|
||||||
|
for _, v := range keys {
|
||||||
|
switch v {
|
||||||
|
case gg.KeyArrowUp:
|
||||||
|
cam.Position.Y += p.MoveSpeed * dt
|
||||||
|
case gg.KeyArrowLeft:
|
||||||
|
cam.Position.X -= p.MoveSpeed * dt
|
||||||
|
case gg.KeyArrowDown:
|
||||||
|
cam.Position.Y -= p.MoveSpeed * dt
|
||||||
|
case gg.KeyArrowRight:
|
||||||
|
cam.Position.X += p.MoveSpeed * dt
|
||||||
|
case gg.KeyW:
|
||||||
|
p.Position.Y += p.MoveSpeed * dt
|
||||||
|
case gg.KeyA:
|
||||||
|
p.Position.X -= p.MoveSpeed * dt
|
||||||
|
case gg.KeyS:
|
||||||
|
p.Position.Y -= p.MoveSpeed * dt
|
||||||
|
case gg.KeyD:
|
||||||
|
p.Position.X += p.MoveSpeed * dt
|
||||||
|
case gg.KeyR:
|
||||||
|
cam.Rotation += gg.Pi * p.ScaleSpeed * dt
|
||||||
|
case gg.KeyT:
|
||||||
|
cam.Rotation -= gg.Pi * p.ScaleSpeed * dt
|
||||||
|
case gg.KeyRightBracket:
|
||||||
|
if c.IsPressed(gg.KeyShift) {
|
||||||
|
p.Rotation -= gg.Pi * 0.3 * dt
|
||||||
|
} else {
|
||||||
|
p.Rotation += gg.Pi * 0.3 * dt
|
||||||
|
}
|
||||||
|
case gg.KeyF:
|
||||||
|
if c.IsPressed(gg.KeyShift) {
|
||||||
|
cam.Scale = cam.Scale.Add(gg.V1(p.ScaleSpeed * dt))
|
||||||
|
} else {
|
||||||
|
cam.Scale = cam.Scale.Add(gg.V1(-p.ScaleSpeed * dt))
|
||||||
|
}
|
||||||
|
case gg.KeyG:
|
||||||
|
if c.IsPressed(gg.KeyShift) {
|
||||||
|
cam.Scale.Y -= gg.Pi * p.ScaleSpeed * dt
|
||||||
|
} else {
|
||||||
|
cam.Scale.Y += gg.Pi * p.ScaleSpeed * dt
|
||||||
|
}
|
||||||
|
case gg.KeyV:
|
||||||
|
if c.IsPressed(gg.KeyShift) {
|
||||||
|
tri.Rotation -= gg.Pi * 0.3 * dt
|
||||||
|
} else {
|
||||||
|
tri.Rotation += gg.Pi * 0.3 * dt
|
||||||
|
}
|
||||||
|
case gg.KeyLeftBracket:
|
||||||
|
if c.IsPressed(gg.KeyShift) {
|
||||||
|
rect.Rotation -= gg.Pi * 0.3 * dt
|
||||||
|
} else {
|
||||||
|
rect.Rotation += gg.Pi * 0.3 * dt
|
||||||
|
}
|
||||||
|
case gg.Key0:
|
||||||
|
c.Del(p)
|
||||||
|
case gg.KeyB:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) Event(c *gg.Context) {
|
||||||
|
fmt.Println("event:", c.Event)
|
||||||
|
switch ec := c.Event.(type) {
|
||||||
|
case *gg.KeyDown:
|
||||||
|
switch {
|
||||||
|
case ec.Key == gg.KeyB:
|
||||||
|
if p.Layer != PlayerL {
|
||||||
|
p.Layer = PlayerL
|
||||||
|
} else {
|
||||||
|
p.Layer = HighestL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
30
cmd/test/rect.go
Normal file
30
cmd/test/rect.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/di4f/gg"
|
||||||
|
|
||||||
|
type Rect struct {
|
||||||
|
gg.DrawableRectangle
|
||||||
|
gg.Layer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRect() *Rect {
|
||||||
|
ret := &Rect{}
|
||||||
|
ret.Scale = gg.V(200, 400)
|
||||||
|
ret.Color = gg.Color{
|
||||||
|
gg.MaxColorV,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
gg.MaxColorV,
|
||||||
|
}
|
||||||
|
ret.Layer = RectL
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Rect) Update(c *Context) {
|
||||||
|
//r.R += 0.3 * e.DT()
|
||||||
|
//r.Position = c.AbsCursorPosition()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Rect) Event(c *Context) {
|
||||||
|
}
|
41
cmd/test/trianlge.go
Normal file
41
cmd/test/trianlge.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/di4f/gg"
|
||||||
|
//import "fmt"
|
||||||
|
|
||||||
|
type Tri struct {
|
||||||
|
*gg.DrawablePolygon
|
||||||
|
gg.Layer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTri() *Tri {
|
||||||
|
ret := &Tri{}
|
||||||
|
ret.DrawablePolygon = &gg.DrawablePolygon{}
|
||||||
|
ret.Transform.Scale = gg.V(1, 1)
|
||||||
|
|
||||||
|
ret.Triangles = gg.Triangles{
|
||||||
|
gg.Triangle{
|
||||||
|
gg.V(0, 0),
|
||||||
|
gg.V(100, 100),
|
||||||
|
gg.V(0, -50),
|
||||||
|
},
|
||||||
|
gg.Triangle{
|
||||||
|
gg.V(0, 0),
|
||||||
|
gg.V(-100, -100),
|
||||||
|
gg.V(0, 50),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ret.Color = gg.Color{gg.MaxColorV, gg.MaxColorV, 0, gg.MaxColorV}
|
||||||
|
ret.Visible = true
|
||||||
|
ret.Layer = TriangleL
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tri) Update(c *Context) {
|
||||||
|
if t.ContainsPoint(c.AbsCursorPosition()) {
|
||||||
|
t.Color = gg.Rgba(0, 1, 0, 1)
|
||||||
|
} else {
|
||||||
|
t.Color = gg.Rgba(1, 0, 1, 1)
|
||||||
|
}
|
||||||
|
}
|
96
engine.go
96
engine.go
|
@ -3,8 +3,8 @@ package gg
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||||
"github.com/omnipunk/gods/maps"
|
"github.com/di4f/gods/maps"
|
||||||
"fmt"
|
//"fmt"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,11 +18,16 @@ func (l Layer) GetLayer() Layer {
|
||||||
|
|
||||||
// Window configuration type.
|
// Window configuration type.
|
||||||
type WindowConfig struct {
|
type WindowConfig struct {
|
||||||
|
// The title of the window.
|
||||||
Title string
|
Title string
|
||||||
|
|
||||||
|
// Width and height of the window
|
||||||
|
// in pixels.
|
||||||
Width,
|
Width,
|
||||||
Height int
|
Height int
|
||||||
|
|
||||||
|
// Optional settings with
|
||||||
|
// self describing names.
|
||||||
FixedSize,
|
FixedSize,
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
VSync bool
|
VSync bool
|
||||||
|
@ -31,26 +36,30 @@ type WindowConfig struct {
|
||||||
// The main structure that represents current state of [game] engine.
|
// The main structure that represents current state of [game] engine.
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
wcfg *WindowConfig
|
wcfg *WindowConfig
|
||||||
objects maps.Map[Object, struct{}]
|
|
||||||
|
// The main holder for objects.
|
||||||
|
// Uses the map structure to quickly
|
||||||
|
// delete and create new objects.
|
||||||
|
Objects maps.Map[Object, struct{}]
|
||||||
|
|
||||||
|
// The main camera to display in window.
|
||||||
|
// If is set to nil then the engine will panic.
|
||||||
|
Camera *Camera
|
||||||
|
|
||||||
|
// The same delta time for all frames
|
||||||
|
// and all objects.
|
||||||
lastTime time.Time
|
lastTime time.Time
|
||||||
dt Float
|
dt Float
|
||||||
camera *Camera
|
|
||||||
|
// Temporary stuff
|
||||||
keys, prevKeys []Key
|
keys, prevKeys []Key
|
||||||
|
cursorPos, prevCursorPos Vector
|
||||||
|
mouseButtons, prevMouseButtons []MouseButton
|
||||||
outerEvents, handleEvents EventChan
|
outerEvents, handleEvents EventChan
|
||||||
}
|
}
|
||||||
|
|
||||||
type engine Engine
|
type engine Engine
|
||||||
|
|
||||||
// Return current camera.
|
|
||||||
func (e *Engine) Camera() *Camera {
|
|
||||||
return e.camera
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set new current camera.
|
|
||||||
func (e *Engine) SetCamera(c *Camera) {
|
|
||||||
e.camera = c
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get currently pressed keys.
|
// Get currently pressed keys.
|
||||||
func (e *Engine) Keys() []Key {
|
func (e *Engine) Keys() []Key {
|
||||||
return e.keys
|
return e.keys
|
||||||
|
@ -60,22 +69,29 @@ func (e *Engine) Keys() []Key {
|
||||||
func NewEngine(
|
func NewEngine(
|
||||||
cfg *WindowConfig,
|
cfg *WindowConfig,
|
||||||
) *Engine {
|
) *Engine {
|
||||||
w := Float(cfg.Width)
|
/*w := Float(cfg.Width)
|
||||||
h := Float(cfg.Height)
|
h := Float(cfg.Height)*/
|
||||||
return &Engine{
|
|
||||||
wcfg: cfg,
|
ret := &Engine{}
|
||||||
camera: &Camera{
|
|
||||||
Transform: Transform{
|
ret.wcfg = cfg
|
||||||
// Normal, no distortion.
|
ret.Camera = ret.NewCamera()
|
||||||
S: Vector{1, 1},
|
ret.outerEvents = make(EventChan)
|
||||||
// Center.
|
ret.handleEvents = make(EventChan)
|
||||||
RA: V(w/2, h/2),
|
ret.Objects = maps.NewOrdered[Object, struct{}]()
|
||||||
},
|
return ret
|
||||||
},
|
|
||||||
objects: maps.NewOrdered[Object, struct{}](),
|
|
||||||
outerEvents: make(EventChan),
|
|
||||||
handleEvents: make(EventChan),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the real window size in the current context.
|
||||||
|
func (c *Engine) RealWinSize() Vector {
|
||||||
|
return V(
|
||||||
|
Float(c.wcfg.Width),
|
||||||
|
Float(c.wcfg.Height),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Engine) AbsWinSize() Vector {
|
||||||
|
return c.RealWinSize().Div(c.Camera.Scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) EventInput() EventChan {
|
func (e *Engine) EventInput() EventChan {
|
||||||
|
@ -86,7 +102,7 @@ func (e *Engine) EventInput() EventChan {
|
||||||
// interfaces it implements.
|
// interfaces it implements.
|
||||||
func (e *Engine) Add(b any) error {
|
func (e *Engine) Add(b any) error {
|
||||||
object, _ := b.(Object)
|
object, _ := b.(Object)
|
||||||
if e.objects.Has(object) {
|
if e.Objects.Has(object) {
|
||||||
return ObjectExistErr
|
return ObjectExistErr
|
||||||
}
|
}
|
||||||
/*o, ok := e.makeObject(b)
|
/*o, ok := e.makeObject(b)
|
||||||
|
@ -101,7 +117,7 @@ func (e *Engine) Add(b any) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
e.objects.Set(object, struct{}{})
|
e.Objects.Set(object, struct{}{})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -109,7 +125,7 @@ func (e *Engine) Add(b any) error {
|
||||||
// Delete object from Engine.
|
// Delete object from Engine.
|
||||||
func (e *Engine) Del(b any) error {
|
func (e *Engine) Del(b any) error {
|
||||||
object, _ := b.(Object)
|
object, _ := b.(Object)
|
||||||
if !e.objects.Has(object) {
|
if !e.Objects.Has(object) {
|
||||||
return ObjectNotExistErr
|
return ObjectNotExistErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,14 +136,13 @@ func (e *Engine) Del(b any) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
e.objects.Del(b)
|
e.Objects.Del(b)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (e *engine) Update() error {
|
func (e *engine) Update() error {
|
||||||
var err error
|
|
||||||
eng := (*Engine)(e)
|
eng := (*Engine)(e)
|
||||||
|
|
||||||
e.prevKeys = e.keys
|
e.prevKeys = e.keys
|
||||||
|
@ -152,7 +167,7 @@ func (e *engine) Update() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
e.dt = time.Since(e.lastTime).Seconds()
|
e.dt = time.Since(e.lastTime).Seconds()
|
||||||
for object := range e.objects.KeyChan() {
|
for object := range e.Objects.KeyChan() {
|
||||||
eventer, ok := object.(Eventer)
|
eventer, ok := object.(Eventer)
|
||||||
if ok {
|
if ok {
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
|
@ -166,12 +181,9 @@ func (e *engine) Update() error {
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = updater.Update(&Context{
|
updater.Update(&Context{
|
||||||
Engine: eng,
|
Engine: eng,
|
||||||
})
|
})
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
e.lastTime = time.Now()
|
e.lastTime = time.Now()
|
||||||
|
|
||||||
|
@ -181,7 +193,7 @@ func (e *engine) Update() error {
|
||||||
func (e *engine) Draw(i *ebiten.Image) {
|
func (e *engine) Draw(i *ebiten.Image) {
|
||||||
eng := (*Engine)(e)
|
eng := (*Engine)(e)
|
||||||
m := map[Layer][]Drawer{}
|
m := map[Layer][]Drawer{}
|
||||||
for object := range eng.objects.KeyChan() {
|
for object := range eng.Objects.KeyChan() {
|
||||||
drawer, ok := object.(Drawer)
|
drawer, ok := object.(Drawer)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
|
@ -208,6 +220,8 @@ func (e *engine) Draw(i *ebiten.Image) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Empty the buff to generate it again.
|
||||||
|
eng.Camera.buf = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) Layout(ow, oh int) (int, int) {
|
func (e *engine) Layout(ow, oh int) (int, int) {
|
||||||
|
@ -231,7 +245,7 @@ func (e *Engine) Run() error {
|
||||||
ebiten.SetVsyncEnabled(e.wcfg.VSync)
|
ebiten.SetVsyncEnabled(e.wcfg.VSync)
|
||||||
|
|
||||||
e.lastTime = time.Now()
|
e.lastTime = time.Now()
|
||||||
fmt.Println(e.objects)
|
//fmt.Println(e.Objects)
|
||||||
return ebiten.RunGame((*engine)(e))
|
return ebiten.RunGame((*engine)(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -5,8 +5,8 @@ go 1.21
|
||||||
toolchain go1.21.3
|
toolchain go1.21.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/di4f/gods v0.0.0-20231214190239-d523423d8d5e
|
||||||
github.com/hajimehoshi/ebiten/v2 v2.6.0-alpha.3.0.20230521122940-90562ee84b9b
|
github.com/hajimehoshi/ebiten/v2 v2.6.0-alpha.3.0.20230521122940-90562ee84b9b
|
||||||
github.com/omnipunk/gods v0.0.0-20231112101528-1f82aa46d746
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -1,3 +1,5 @@
|
||||||
|
github.com/di4f/gods v0.0.0-20231214190239-d523423d8d5e h1:LdL9GpXPJikQ7DXQZFf5Zz5h5MYAS9R7itEztnscku8=
|
||||||
|
github.com/di4f/gods v0.0.0-20231214190239-d523423d8d5e/go.mod h1:5GbuWHGgBJIIhBiQB/00flvo3k421S8O1XvmrXKWO2U=
|
||||||
github.com/ebitengine/purego v0.4.0-alpha.4 h1:Y7yIV06Yo5M2BAdD7EVPhfp6LZ0tEcQo5770OhYUVes=
|
github.com/ebitengine/purego v0.4.0-alpha.4 h1:Y7yIV06Yo5M2BAdD7EVPhfp6LZ0tEcQo5770OhYUVes=
|
||||||
github.com/ebitengine/purego v0.4.0-alpha.4/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
|
github.com/ebitengine/purego v0.4.0-alpha.4/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b h1:GgabKamyOYguHqHjSkDACcgoPIz3w0Dis/zJ1wyHHHU=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b h1:GgabKamyOYguHqHjSkDACcgoPIz3w0Dis/zJ1wyHHHU=
|
||||||
|
@ -6,8 +8,6 @@ github.com/hajimehoshi/ebiten/v2 v2.6.0-alpha.3.0.20230521122940-90562ee84b9b h1
|
||||||
github.com/hajimehoshi/ebiten/v2 v2.6.0-alpha.3.0.20230521122940-90562ee84b9b/go.mod h1:+fFI6Ag5YvbX1ivNQD2TxNhpWFDPuxEoew421TTQAxI=
|
github.com/hajimehoshi/ebiten/v2 v2.6.0-alpha.3.0.20230521122940-90562ee84b9b/go.mod h1:+fFI6Ag5YvbX1ivNQD2TxNhpWFDPuxEoew421TTQAxI=
|
||||||
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk=
|
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk=
|
||||||
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
||||||
github.com/omnipunk/gods v0.0.0-20231112101528-1f82aa46d746 h1:3Hqv6OBITqr9SUhCqD9ZZG3xXMrYNDvyCsZK7BF4lTo=
|
|
||||||
github.com/omnipunk/gods v0.0.0-20231112101528-1f82aa46d746/go.mod h1:zARHZc37wTaPpL5GVzZd0FK59r8UbPnxodIXWQ59uLk=
|
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
|
11
img.go
11
img.go
|
@ -16,11 +16,20 @@ type Color struct {
|
||||||
R, G, B, A ColorV
|
R, G, B, A ColorV
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MaxColorV = math.MaxUint32
|
MaxColorV = math.MaxUint32
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// The wrapper to make RGBA color via
|
||||||
|
// values from 0 to 1 (no value at all and the max value).
|
||||||
|
func Rgba(r, g, b, a Float) Color {
|
||||||
|
return Color {
|
||||||
|
ColorV(r*MaxColorV),
|
||||||
|
ColorV(g*MaxColorV),
|
||||||
|
ColorV(b*MaxColorV),
|
||||||
|
ColorV(a*MaxColorV),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func LoadImage(input io.Reader) (*Image, error) {
|
func LoadImage(input io.Reader) (*Image, error) {
|
||||||
img, _, err := image.Decode(input)
|
img, _, err := image.Decode(input)
|
||||||
|
|
2
mouse.go
2
mouse.go
|
@ -13,7 +13,7 @@ func (e *Engine) CursorPosition() Vector {
|
||||||
|
|
||||||
func (e *Engine) AbsCursorPosition() Vector {
|
func (e *Engine) AbsCursorPosition() Vector {
|
||||||
m := &Matrix{}
|
m := &Matrix{}
|
||||||
m.Concat(e.Camera().AbsMatrix())
|
m.Concat(e.Camera.AbsMatrix())
|
||||||
return e.CursorPosition().Apply(m)
|
return e.CursorPosition().Apply(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ type Starter interface {
|
||||||
// will call the function on each
|
// will call the function on each
|
||||||
// engine iteration.
|
// engine iteration.
|
||||||
type Updater interface {
|
type Updater interface {
|
||||||
Update(*Context) error
|
Update(*Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementing the interface type
|
// Implementing the interface type
|
||||||
|
|
|
@ -13,6 +13,10 @@ type Polygon struct {
|
||||||
Triangles
|
Triangles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Polygon) ContainsPoint(pnt Point) bool {
|
||||||
|
return p.MakeTriangles().ContainsPoint(pnt)
|
||||||
|
}
|
||||||
|
|
||||||
// Polygon that can be drawn.
|
// Polygon that can be drawn.
|
||||||
type DrawablePolygon struct {
|
type DrawablePolygon struct {
|
||||||
Polygon
|
Polygon
|
||||||
|
|
9
rect.go
9
rect.go
|
@ -9,8 +9,6 @@ import (
|
||||||
|
|
||||||
// The type describes rectangle geometry.
|
// The type describes rectangle geometry.
|
||||||
type Rectangle struct {
|
type Rectangle struct {
|
||||||
// P - position of the rotating center.
|
|
||||||
// Scale represent width and height.
|
|
||||||
Transform
|
Transform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,10 +20,10 @@ type DrawableRectangle struct {
|
||||||
// Solid color of the rectangle.
|
// Solid color of the rectangle.
|
||||||
// Will be ignored if the Shader
|
// Will be ignored if the Shader
|
||||||
// field is not nil.
|
// field is not nil.
|
||||||
Color Color
|
Colority
|
||||||
|
|
||||||
// Should be draw or not.
|
// Should be draw or not.
|
||||||
Visible bool
|
Visibility
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return points of vertices of the rectangle.
|
// Return points of vertices of the rectangle.
|
||||||
|
@ -55,7 +53,6 @@ func (r Rectangle) Triangles() Triangles {
|
||||||
p2 := pts[1]
|
p2 := pts[1]
|
||||||
p3 := pts[2]
|
p3 := pts[2]
|
||||||
p4 := pts[3]
|
p4 := pts[3]
|
||||||
//fmt.Println("in:", p1, p2, p3, p4)
|
|
||||||
|
|
||||||
return Triangles{
|
return Triangles{
|
||||||
Triangle{p1, p2, p3},
|
Triangle{p1, p2, p3},
|
||||||
|
@ -75,7 +72,7 @@ func (r *DrawableRectangle) IsVisible() bool {
|
||||||
|
|
||||||
func (r *DrawableRectangle) Draw(c *Context) {
|
func (r *DrawableRectangle) Draw(c *Context) {
|
||||||
m := r.Matrix()
|
m := r.Matrix()
|
||||||
rm := c.Camera().RealMatrix()
|
rm := c.Camera.RealMatrix()
|
||||||
m.Concat(rm)
|
m.Concat(rm)
|
||||||
// Draw solid color if no shader.
|
// Draw solid color if no shader.
|
||||||
if r.Shader == nil {
|
if r.Shader == nil {
|
||||||
|
|
17
sprite.go
17
sprite.go
|
@ -2,12 +2,14 @@ package gg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
//"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Sprite struct {
|
type Sprite struct {
|
||||||
Transform
|
Transform
|
||||||
ShaderOptions
|
ShaderOptions
|
||||||
Floating, Visible bool
|
Floating bool
|
||||||
|
Visibility
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) Draw(c *Context) {
|
func (s *Sprite) Draw(c *Context) {
|
||||||
|
@ -20,7 +22,7 @@ func (s *Sprite) Draw(c *Context) {
|
||||||
m := &Matrix{}
|
m := &Matrix{}
|
||||||
m.Concat(t.Matrix())
|
m.Concat(t.Matrix())
|
||||||
if !s.Floating {
|
if !s.Floating {
|
||||||
m.Concat(c.Camera().RealMatrix())
|
m.Concat(c.Camera.RealMatrix())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drawing without shader.
|
// Drawing without shader.
|
||||||
|
@ -41,11 +43,6 @@ func (s *Sprite) Draw(c *Context) {
|
||||||
c.DrawRectShader(w, h, s.Shader, opts)
|
c.DrawRectShader(w, h, s.Shader, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check is sprite is visible.
|
|
||||||
func (s *Sprite) IsVisible() bool {
|
|
||||||
return s.Visible
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the rectangle that contains the sprite.
|
// Return the rectangle that contains the sprite.
|
||||||
func (s *Sprite) Rectangle() Rectangle {
|
func (s *Sprite) Rectangle() Rectangle {
|
||||||
if s.Images[0] == nil {
|
if s.Images[0] == nil {
|
||||||
|
@ -54,12 +51,14 @@ func (s *Sprite) Rectangle() Rectangle {
|
||||||
|
|
||||||
w, h := s.Images[0].Size()
|
w, h := s.Images[0].Size()
|
||||||
t := s.Transform
|
t := s.Transform
|
||||||
t.RA.X *= Float(w)
|
t.Around.X *= Float(w)
|
||||||
t.RA.Y *= Float(h)
|
t.Around.Y *= Float(h)
|
||||||
|
|
||||||
return Rectangle{t}
|
return Rectangle{t}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get triangles of the rectangle that contains the sprite
|
||||||
|
// and has the same widght and height.
|
||||||
func (s *Sprite) Triangles() Triangles {
|
func (s *Sprite) Triangles() Triangles {
|
||||||
return s.Rectangle().Triangles()
|
return s.Rectangle().Triangles()
|
||||||
}
|
}
|
||||||
|
|
49
transform.go
49
transform.go
|
@ -8,23 +8,26 @@ import (
|
||||||
// The structure represents basic transformation
|
// The structure represents basic transformation
|
||||||
// features: positioning, rotating and scaling.
|
// features: positioning, rotating and scaling.
|
||||||
type Transform struct {
|
type Transform struct {
|
||||||
// P - absolute phisycal position in engine itself.
|
// Absolute (if no parent) position and
|
||||||
//
|
// the scale.
|
||||||
// S - scale width and height (X and Y).
|
Position, Scale Vector
|
||||||
//
|
// The object rotation in radians.
|
||||||
// RA - rotate around(relatively of position, not absolute).
|
Rotation Float
|
||||||
//
|
// The not scaled offset vector from upper left corner
|
||||||
// For example RA=Vector{0, 0} will rotate around right up corner
|
// which the object should be rotated around.
|
||||||
// and RA=Vector{.5, .5} will rotate around center.
|
Around Vector
|
||||||
P, S, RA Vector
|
// Needs to be implemented.
|
||||||
// Rotation angle in radians.
|
// Makes transform depending on the other one.
|
||||||
R Float
|
// Is the root one if Parent == nil
|
||||||
|
Parent *Transform
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns empty Transform.
|
// Returns empty Transform
|
||||||
|
// with standard scaling. (1/1)
|
||||||
func T() Transform {
|
func T() Transform {
|
||||||
ret := Transform{
|
ret := Transform{
|
||||||
S: Vector{1, 1},
|
Scale: Vector{1, 1},
|
||||||
|
Around: V(.5, .5),
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
@ -34,12 +37,12 @@ func (t Transform) ScaledToXY(x, y Float) Transform {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Transform) ScaledToX(x Float) Transform {
|
func (t Transform) ScaledToX(x Float) Transform {
|
||||||
t.S.X = x
|
t.Scale.X = x
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Transform) ScaledToY(y Float) Transform {
|
func (t Transform) ScaledToY(y Float) Transform {
|
||||||
t.S.Y = y
|
t.Scale.Y = y
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,10 +51,18 @@ func (t Transform) ScaledToY(y Float) Transform {
|
||||||
func (t Transform)Matrix() Matrix {
|
func (t Transform)Matrix() Matrix {
|
||||||
g := &Matrix{}
|
g := &Matrix{}
|
||||||
|
|
||||||
g.Scale(t.S.X, t.S.Y)
|
// Scale first.
|
||||||
g.Translate(-t.RA.X * t.S.X, -t.RA.Y * t.S.Y)
|
g.Scale(t.Scale.X, t.Scale.Y)
|
||||||
g.Rotate(t.R)
|
|
||||||
g.Translate(t.P.X, t.P.Y)
|
// Then move and rotate.
|
||||||
|
g.Translate(
|
||||||
|
-t.Around.X * t.Scale.X,
|
||||||
|
-t.Around.Y * t.Scale.Y,
|
||||||
|
)
|
||||||
|
g.Rotate(t.Rotation)
|
||||||
|
|
||||||
|
// And finally move to the absolute position.
|
||||||
|
g.Translate(t.Position.X, t.Position.Y)
|
||||||
|
|
||||||
return *g
|
return *g
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ func (ts Triangles) ContainsPoint(p Point) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *DrawableTriangles) Draw(c *Context) {
|
func (r *DrawableTriangles) Draw(c *Context) {
|
||||||
m := c.Camera().RealMatrix()
|
m := c.Camera.RealMatrix()
|
||||||
cm := &m
|
cm := &m
|
||||||
|
|
||||||
// Draw solid color if no shader.
|
// Draw solid color if no shader.
|
||||||
|
|
18
vector.go
18
vector.go
|
@ -18,6 +18,24 @@ func V(x, y Float) Vector {
|
||||||
return Vector{x, y}
|
return Vector{x, y}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func V1(v Float) Vector {
|
||||||
|
return V(v, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Vector) Div(o Vector) Vector {
|
||||||
|
return V(
|
||||||
|
v.X / o.X,
|
||||||
|
v.Y / o.Y,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Vector) Scale(o Vector) Vector {
|
||||||
|
return V(
|
||||||
|
v.X * o.X,
|
||||||
|
v.Y * o.Y,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func (v Vector) Eq(o Vector) bool {
|
func (v Vector) Eq(o Vector) bool {
|
||||||
return v.X == o.X && v.Y == o.Y
|
return v.X == o.X && v.Y == o.Y
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue