Add SetScreenScale (#115)

This commit is contained in:
Hajime Hoshi 2015-02-10 00:10:50 +09:00
parent fdedee9aab
commit cd4188b0a3
5 changed files with 83 additions and 16 deletions

View File

@ -15,8 +15,10 @@
package main
import (
"fmt"
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil"
"image/color"
_ "image/jpeg"
"log"
)
@ -24,17 +26,20 @@ import (
const (
initScreenWidth = 320
initScreenHeight = 240
initScreenScale = 2
)
var (
gophersImage *ebiten.Image
screenWidth = initScreenWidth
screenHeight = initScreenHeight
screenScale = initScreenScale
keyStates = map[ebiten.Key]int{
ebiten.KeyUp: 0,
ebiten.KeyDown: 0,
ebiten.KeyLeft: 0,
ebiten.KeyRight: 0,
ebiten.KeyS: 0,
}
)
@ -51,16 +56,25 @@ func update(screen *ebiten.Image) error {
screenHeight += 16
}
if keyStates[ebiten.KeyDown] == 1 {
screenHeight -= 16
if 16 < screenHeight {
screenHeight -= 16
}
}
if keyStates[ebiten.KeyLeft] == 1 {
screenWidth -= 16
if 16 < screenWidth {
screenWidth -= 16
}
}
if keyStates[ebiten.KeyRight] == 1 {
screenWidth += 16
}
if keyStates[ebiten.KeyS] == 1 {
screenScale = 3 - screenScale // Swap 1 and 2
}
ebiten.SetScreenSize(screenWidth, screenHeight)
ebiten.SetScreenScale(screenScale)
screen.Fill(color.RGBA{0x80, 0x80, 0xc0, 0xff})
w, h := gophersImage.Size()
w2, h2 := screen.Size()
op := &ebiten.DrawImageOptions{}
@ -69,7 +83,11 @@ func update(screen *ebiten.Image) error {
return err
}
ebitenutil.DebugPrint(screen, "Press arrow keys")
x, y := ebiten.CursorPosition()
msg := fmt.Sprintf(`Press arrow keys to change the window size
Press S key to change the window scale
Cursor: (%d, %d)`, x, y)
ebitenutil.DebugPrint(screen, msg)
return nil
}
@ -79,7 +97,7 @@ func main() {
if err != nil {
log.Fatal(err)
}
if err := ebiten.Run(update, initScreenWidth, initScreenHeight, 2, "Window Size (Ebiten Demo)"); err != nil {
if err := ebiten.Run(update, initScreenWidth, initScreenHeight, initScreenScale, "Window Size (Ebiten Demo)"); err != nil {
log.Fatal(err)
}
}

View File

@ -33,6 +33,8 @@ type channel struct {
var MaxChannel = 32
var channels = make([]*channel, MaxChannel)
// NOTE: In GopherJS, sync.Mutex blocks a function and requires gopherjs:blocking comments.
var channelsLock sync.Mutex
func init() {

View File

@ -93,6 +93,11 @@ func SetScreenSize(width, height int) (bool, int) {
return result, currentUI.actualScale
}
func SetScreenScale(scale int) (bool, int) {
result := currentUI.setScreenSize(currentUI.width, currentUI.height, scale)
return result, currentUI.actualScale
}
type userInterface struct {
window *glfw.Window
width int

View File

@ -52,6 +52,13 @@ func SetScreenSize(width, height int) (bool, int) {
return result, actualScale
}
func SetScreenScale(scale int) (bool, int) {
width, height := currentUI.size()
result := currentUI.setScreenSize(width, height, scale)
actualScale := canvas.Get("dataset").Get("ebitenActualScale").Int()
return result, actualScale
}
var canvas js.Object
type userInterface struct{}
@ -228,15 +235,21 @@ func (u *userInterface) start(width, height, scale int, title string) (actualSca
return actualScale, nil
}
func (*userInterface) setScreenSize(width, height, scale int) bool {
func (*userInterface) size() (width, height int) {
a := canvas.Get("dataset").Get("ebitenActualScale").Int()
if a != 0 {
w := canvas.Get("width").Int() / a
h := canvas.Get("height").Int() / a
s := canvas.Get("dataset").Get("ebitenScale").Int()
if w == width && h == height && s == scale {
return false
}
if a == 0 {
return
}
width = canvas.Get("width").Int() / a
height = canvas.Get("height").Int() / a
return
}
func (u *userInterface) setScreenSize(width, height, scale int) bool {
w, h := u.size()
s := canvas.Get("dataset").Get("ebitenScale").Int()
if w == width && h == height && s == scale {
return false
}
actualScale := scale * devicePixelRatio()

37
run.go
View File

@ -25,6 +25,7 @@ var runContext = &struct {
fps float64
newScreenWidth int
newScreenHeight int
newScreenScale int
}{}
// CurrentFPS returns the current number of frames per second.
@ -43,6 +44,9 @@ func CurrentFPS() float64 {
// If you need to care about time, you need to check current time every time f is called.
func Run(f func(*Image) error, width, height, scale int, title string) error {
runContext.running = true
defer func() {
runContext.running = false
}()
actualScale, err := ui.Start(width, height, scale, title)
if err != nil {
@ -58,8 +62,20 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
frames := 0
t := time.Now().UnixNano()
for {
if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight {
changed, actualScale := ui.SetScreenSize(runContext.newScreenWidth, runContext.newScreenHeight)
if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight || 0 < runContext.newScreenScale {
changed := false
actualScale := 0
if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight {
c, a := ui.SetScreenSize(runContext.newScreenWidth, runContext.newScreenHeight)
changed = changed || c
actualScale = a
}
if 0 < runContext.newScreenScale {
c, a := ui.SetScreenScale(runContext.newScreenScale)
changed = changed || c
// actualScale of SetScreenState is more reliable than one of SetScreenSize
actualScale = a
}
if changed {
w, h := runContext.newScreenWidth, runContext.newScreenHeight
if err := graphicsContext.setSize(w, h, actualScale); err != nil {
@ -69,6 +85,7 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
}
runContext.newScreenWidth = 0
runContext.newScreenHeight = 0
runContext.newScreenScale = 0
if err := ui.DoEvents(); err != nil {
return err
@ -110,10 +127,22 @@ func SetScreenSize(width, height int) {
if !runContext.running {
panic("SetScreenSize must be called during Run")
}
if width <= 0 || height <= 0 {
panic("width and height must be positive")
}
runContext.newScreenWidth = width
runContext.newScreenHeight = height
}
// TODO: Create SetScreenPosition (for GLFW)
// SetScreenSize changes the scale of the screen.
func SetScreenScale(scale int) {
if !runContext.running {
panic("SetScreenScale must be called during Run")
}
if scale <= 0 {
panic("scale must be positive")
}
runContext.newScreenScale = scale
}
// TODO: Create SetScreenScale
// TODO: Create SetScreenPosition (for GLFW)