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 package main
import ( import (
"fmt"
"github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil" "github.com/hajimehoshi/ebiten/ebitenutil"
"image/color"
_ "image/jpeg" _ "image/jpeg"
"log" "log"
) )
@ -24,17 +26,20 @@ import (
const ( const (
initScreenWidth = 320 initScreenWidth = 320
initScreenHeight = 240 initScreenHeight = 240
initScreenScale = 2
) )
var ( var (
gophersImage *ebiten.Image gophersImage *ebiten.Image
screenWidth = initScreenWidth screenWidth = initScreenWidth
screenHeight = initScreenHeight screenHeight = initScreenHeight
screenScale = initScreenScale
keyStates = map[ebiten.Key]int{ keyStates = map[ebiten.Key]int{
ebiten.KeyUp: 0, ebiten.KeyUp: 0,
ebiten.KeyDown: 0, ebiten.KeyDown: 0,
ebiten.KeyLeft: 0, ebiten.KeyLeft: 0,
ebiten.KeyRight: 0, ebiten.KeyRight: 0,
ebiten.KeyS: 0,
} }
) )
@ -51,16 +56,25 @@ func update(screen *ebiten.Image) error {
screenHeight += 16 screenHeight += 16
} }
if keyStates[ebiten.KeyDown] == 1 { if keyStates[ebiten.KeyDown] == 1 {
screenHeight -= 16 if 16 < screenHeight {
screenHeight -= 16
}
} }
if keyStates[ebiten.KeyLeft] == 1 { if keyStates[ebiten.KeyLeft] == 1 {
screenWidth -= 16 if 16 < screenWidth {
screenWidth -= 16
}
} }
if keyStates[ebiten.KeyRight] == 1 { if keyStates[ebiten.KeyRight] == 1 {
screenWidth += 16 screenWidth += 16
} }
if keyStates[ebiten.KeyS] == 1 {
screenScale = 3 - screenScale // Swap 1 and 2
}
ebiten.SetScreenSize(screenWidth, screenHeight) ebiten.SetScreenSize(screenWidth, screenHeight)
ebiten.SetScreenScale(screenScale)
screen.Fill(color.RGBA{0x80, 0x80, 0xc0, 0xff})
w, h := gophersImage.Size() w, h := gophersImage.Size()
w2, h2 := screen.Size() w2, h2 := screen.Size()
op := &ebiten.DrawImageOptions{} op := &ebiten.DrawImageOptions{}
@ -69,7 +83,11 @@ func update(screen *ebiten.Image) error {
return err 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 return nil
} }
@ -79,7 +97,7 @@ func main() {
if err != nil { if err != nil {
log.Fatal(err) 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) log.Fatal(err)
} }
} }

View File

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

View File

@ -93,6 +93,11 @@ func SetScreenSize(width, height int) (bool, int) {
return result, currentUI.actualScale 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 { type userInterface struct {
window *glfw.Window window *glfw.Window
width int width int

View File

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

37
run.go
View File

@ -25,6 +25,7 @@ var runContext = &struct {
fps float64 fps float64
newScreenWidth int newScreenWidth int
newScreenHeight int newScreenHeight int
newScreenScale int
}{} }{}
// CurrentFPS returns the current number of frames per second. // 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. // 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 { func Run(f func(*Image) error, width, height, scale int, title string) error {
runContext.running = true runContext.running = true
defer func() {
runContext.running = false
}()
actualScale, err := ui.Start(width, height, scale, title) actualScale, err := ui.Start(width, height, scale, title)
if err != nil { if err != nil {
@ -58,8 +62,20 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
frames := 0 frames := 0
t := time.Now().UnixNano() t := time.Now().UnixNano()
for { for {
if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight { if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight || 0 < runContext.newScreenScale {
changed, actualScale := ui.SetScreenSize(runContext.newScreenWidth, runContext.newScreenHeight) 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 { if changed {
w, h := runContext.newScreenWidth, runContext.newScreenHeight w, h := runContext.newScreenWidth, runContext.newScreenHeight
if err := graphicsContext.setSize(w, h, actualScale); err != nil { 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.newScreenWidth = 0
runContext.newScreenHeight = 0 runContext.newScreenHeight = 0
runContext.newScreenScale = 0
if err := ui.DoEvents(); err != nil { if err := ui.DoEvents(); err != nil {
return err return err
@ -110,10 +127,22 @@ func SetScreenSize(width, height int) {
if !runContext.running { if !runContext.running {
panic("SetScreenSize must be called during Run") panic("SetScreenSize must be called during Run")
} }
if width <= 0 || height <= 0 {
panic("width and height must be positive")
}
runContext.newScreenWidth = width runContext.newScreenWidth = width
runContext.newScreenHeight = height 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)