-
Notifications
You must be signed in to change notification settings - Fork 1
/
scene.go
106 lines (97 loc) · 2.9 KB
/
scene.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright 2016 Josh Deprez
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package awakengine
import (
"github.com/DrJosh9000/vec"
"github.com/hajimehoshi/ebiten"
)
// Scene manages drawing one scene.
//
// Using a Scene as a parent will subtract the camera position. To use screen coordinates,
// use a parent of nil.
type Scene struct {
*View
World, HUD *View
fixed drawList
fixedSorted bool
loose drawList
dispFixed drawList
dispLoose drawList
dispMerged drawList
}
func NewScene(camSize, terrainSize vec.I2) *Scene {
s := &Scene{
View: &View{},
World: &View{},
HUD: &View{},
}
s.View.SetSize(camSize)
s.World.SetSize(terrainSize)
s.World.SetParent(s.View)
s.HUD.SetSize(camSize)
s.HUD.SetParent(s.View)
s.HUD.SetZ(100000) // HUD over World, always
return s
}
// AddPart adds parts to the pipeline.
func (s *Scene) AddPart(parts ...Part) {
for _, p := range parts {
dp, ok := p.(drawPosition)
if !ok {
dp = drawPosition{p}
}
if p.Fixed() {
s.fixedSorted = false
s.fixed = append(s.fixed, dp)
} else {
s.loose = append(s.loose, dp)
}
}
}
func (s *Scene) sortFixedIfNeeded() {
if s.fixedSorted {
return
}
s.fixed.Sort()
s.fixedSorted = true
}
// CameraFocus sets the World offset such that p should be center of screen, or at least
// within the bounds of the terrain.
func (s *Scene) CameraFocus(p vec.I2) {
sz := s.View.Size()
p = p.Sub(sz.Div(2))
p = p.ClampLo(vec.I2{})
p = p.ClampHi(s.World.Size().Sub(sz))
s.World.SetPosition(p.Mul(-1))
}
func (s *Scene) Draw(screen *ebiten.Image) error { return s.dispMerged.draw(screen) }
func (s *Scene) Update() {
// Reorganise objects to display.
s.fixed = s.fixed.gc(s.fixed[:0])
s.loose = s.loose.gc(s.loose[:0])
s.sortFixedIfNeeded()
s.dispFixed = s.fixed.cull(s.dispFixed[:0], s)
s.dispLoose = s.loose.cull(s.dispLoose[:0], s)
s.dispLoose.Sort()
s.dispMerged = merge(s.dispMerged[:0], s.dispFixed, s.dispLoose)
/*
if config.Debug {
log.Printf("{len, cap}(fixedObjects): %d, %d", len(fixedObjects), cap(fixedObjects))
log.Printf("{len, cap}(looseObjects): %d, %d", len(looseObjects), cap(looseObjects))
log.Printf("{len, cap}(displayedFixed): %d, %d", len(displayedFixed), cap(displayedFixed))
log.Printf("{len, cap}(displayedLoose): %d, %d", len(displayedLoose), cap(displayedLoose))
log.Printf("{len, cap}(displayedMerged): %d, %d", len(displayedMerged), cap(displayedMerged))
}
*/
}