mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 19:28:57 +01:00
examples/drag: refactoring
This commit is contained in:
parent
457f6bb964
commit
f6ffd86ca8
@ -44,6 +44,7 @@ type Sprite struct {
|
|||||||
alphaImage *image.Alpha
|
alphaImage *image.Alpha
|
||||||
x int
|
x int
|
||||||
y int
|
y int
|
||||||
|
dragged bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// In returns true if (x, y) is in the sprite, and false otherwise.
|
// In returns true if (x, y) is in the sprite, and false otherwise.
|
||||||
@ -57,12 +58,12 @@ func (s *Sprite) In(x, y int) bool {
|
|||||||
return s.alphaImage.At(x-s.x, y-s.y).(color.Alpha).A > 0
|
return s.alphaImage.At(x-s.x, y-s.y).(color.Alpha).A > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// MoveBy moves the sprite by (x, y).
|
// MoveTo moves the sprite to the position (x, y).
|
||||||
func (s *Sprite) MoveBy(x, y int) {
|
func (s *Sprite) MoveTo(x, y int) {
|
||||||
w, h := s.image.Bounds().Dx(), s.image.Bounds().Dy()
|
w, h := s.image.Bounds().Dx(), s.image.Bounds().Dy()
|
||||||
|
|
||||||
s.x += x
|
s.x = x
|
||||||
s.y += y
|
s.y = y
|
||||||
if s.x < 0 {
|
if s.x < 0 {
|
||||||
s.x = 0
|
s.x = 0
|
||||||
}
|
}
|
||||||
@ -78,9 +79,9 @@ func (s *Sprite) MoveBy(x, y int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws the sprite.
|
// Draw draws the sprite.
|
||||||
func (s *Sprite) Draw(screen *ebiten.Image, dx, dy int, alpha float32) {
|
func (s *Sprite) Draw(screen *ebiten.Image, alpha float32) {
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
op.GeoM.Translate(float64(s.x+dx), float64(s.y+dy))
|
op.GeoM.Translate(float64(s.x), float64(s.y))
|
||||||
op.ColorScale.ScaleAlpha(alpha)
|
op.ColorScale.ScaleAlpha(alpha)
|
||||||
screen.DrawImage(s.image, op)
|
screen.DrawImage(s.image, op)
|
||||||
screen.DrawImage(s.image, op)
|
screen.DrawImage(s.image, op)
|
||||||
@ -120,65 +121,42 @@ func (t *TouchStrokeSource) IsJustReleased() bool {
|
|||||||
type Stroke struct {
|
type Stroke struct {
|
||||||
source StrokeSource
|
source StrokeSource
|
||||||
|
|
||||||
// initX and initY represents the position when dragging starts.
|
// offsetX and offsetY represents a relative value from the sprite's upper-left position to the cursor position.
|
||||||
initX int
|
offsetX int
|
||||||
initY int
|
offsetY int
|
||||||
|
|
||||||
// currentX and currentY represents the current position
|
// sprite represents a sprite being dragged.
|
||||||
currentX int
|
sprite *Sprite
|
||||||
currentY int
|
|
||||||
|
|
||||||
released bool
|
|
||||||
|
|
||||||
// draggingObject represents a object (sprite in this case)
|
|
||||||
// that is being dragged.
|
|
||||||
draggingObject any
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStroke(source StrokeSource) *Stroke {
|
func NewStroke(source StrokeSource, sprite *Sprite) *Stroke {
|
||||||
cx, cy := source.Position()
|
sprite.dragged = true
|
||||||
|
x, y := source.Position()
|
||||||
return &Stroke{
|
return &Stroke{
|
||||||
source: source,
|
source: source,
|
||||||
initX: cx,
|
offsetX: x - sprite.x,
|
||||||
initY: cy,
|
offsetY: y - sprite.y,
|
||||||
currentX: cx,
|
sprite: sprite,
|
||||||
currentY: cy,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stroke) Update() {
|
func (s *Stroke) Update() {
|
||||||
if s.released {
|
if !s.sprite.dragged {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s.source.IsJustReleased() {
|
if s.source.IsJustReleased() {
|
||||||
s.released = true
|
s.sprite.dragged = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
x, y := s.source.Position()
|
x, y := s.source.Position()
|
||||||
s.currentX = x
|
x -= s.offsetX
|
||||||
s.currentY = y
|
y -= s.offsetY
|
||||||
|
s.sprite.MoveTo(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stroke) IsReleased() bool {
|
func (s *Stroke) Sprite() *Sprite {
|
||||||
return s.released
|
return s.sprite
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stroke) Position() (int, int) {
|
|
||||||
return s.currentX, s.currentY
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stroke) PositionDiff() (int, int) {
|
|
||||||
dx := s.currentX - s.initX
|
|
||||||
dy := s.currentY - s.initY
|
|
||||||
return dx, dy
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stroke) DraggingObject() any {
|
|
||||||
return s.draggingObject
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stroke) SetDraggingObject(object any) {
|
|
||||||
s.draggingObject = object
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
@ -244,50 +222,38 @@ func (g *Game) spriteAt(x, y int) *Sprite {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) updateStroke(stroke *Stroke) {
|
func (g *Game) moveSpriteToFront(sprite *Sprite) {
|
||||||
stroke.Update()
|
|
||||||
if !stroke.IsReleased() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
s := stroke.DraggingObject().(*Sprite)
|
|
||||||
if s == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
s.MoveBy(stroke.PositionDiff())
|
|
||||||
|
|
||||||
index := -1
|
index := -1
|
||||||
for i, ss := range g.sprites {
|
for i, ss := range g.sprites {
|
||||||
if ss == s {
|
if ss == sprite {
|
||||||
index = i
|
index = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the dragged sprite to the front.
|
|
||||||
g.sprites = append(g.sprites[:index], g.sprites[index+1:]...)
|
g.sprites = append(g.sprites[:index], g.sprites[index+1:]...)
|
||||||
g.sprites = append(g.sprites, s)
|
g.sprites = append(g.sprites, sprite)
|
||||||
|
|
||||||
stroke.SetDraggingObject(nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Update() error {
|
func (g *Game) Update() error {
|
||||||
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
|
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
|
||||||
s := NewStroke(&MouseStrokeSource{})
|
if sp := g.spriteAt(ebiten.CursorPosition()); sp != nil {
|
||||||
s.SetDraggingObject(g.spriteAt(s.Position()))
|
s := NewStroke(&MouseStrokeSource{}, sp)
|
||||||
g.strokes[s] = struct{}{}
|
g.strokes[s] = struct{}{}
|
||||||
|
g.moveSpriteToFront(sp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g.touchIDs = inpututil.AppendJustPressedTouchIDs(g.touchIDs[:0])
|
g.touchIDs = inpututil.AppendJustPressedTouchIDs(g.touchIDs[:0])
|
||||||
for _, id := range g.touchIDs {
|
for _, id := range g.touchIDs {
|
||||||
s := NewStroke(&TouchStrokeSource{id})
|
if sp := g.spriteAt(ebiten.TouchPosition(id)); sp != nil {
|
||||||
s.SetDraggingObject(g.spriteAt(s.Position()))
|
s := NewStroke(&TouchStrokeSource{id}, sp)
|
||||||
g.strokes[s] = struct{}{}
|
g.strokes[s] = struct{}{}
|
||||||
|
g.moveSpriteToFront(sp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for s := range g.strokes {
|
for s := range g.strokes {
|
||||||
g.updateStroke(s)
|
s.Update()
|
||||||
if s.IsReleased() {
|
if !s.sprite.dragged {
|
||||||
delete(g.strokes, s)
|
delete(g.strokes, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,23 +261,11 @@ func (g *Game) Update() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Draw(screen *ebiten.Image) {
|
func (g *Game) Draw(screen *ebiten.Image) {
|
||||||
draggingSprites := map[*Sprite]struct{}{}
|
|
||||||
for s := range g.strokes {
|
|
||||||
if sprite := s.DraggingObject().(*Sprite); sprite != nil {
|
|
||||||
draggingSprites[sprite] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, s := range g.sprites {
|
for _, s := range g.sprites {
|
||||||
if _, ok := draggingSprites[s]; ok {
|
if s.dragged {
|
||||||
continue
|
s.Draw(screen, 0.5)
|
||||||
}
|
} else {
|
||||||
s.Draw(screen, 0, 0, 1)
|
s.Draw(screen, 1)
|
||||||
}
|
|
||||||
for s := range g.strokes {
|
|
||||||
dx, dy := s.PositionDiff()
|
|
||||||
if sprite := s.DraggingObject().(*Sprite); sprite != nil {
|
|
||||||
sprite.Draw(screen, dx, dy, 0.5)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user