diff --git a/examples/flappy/main.go b/examples/flappy/main.go index f0add557c..0bf126e23 100644 --- a/examples/flappy/main.go +++ b/examples/flappy/main.go @@ -25,7 +25,6 @@ import ( "log" "math" "math/rand" - "runtime" "time" "github.com/golang/freetype/truetype" @@ -392,11 +391,6 @@ func (g *Game) drawGopher(screen *ebiten.Image) { func main() { g := NewGame() - // On browsers, let's use fullscreen so that this is playable on any browsers. - // It is planned to ignore the given 'scale' apply fullscreen automatically on browsers (#571). - if runtime.GOARCH == "js" || runtime.GOOS == "js" { - ebiten.SetFullscreen(true) - } if err := ebiten.Run(g.Update, screenWidth, screenHeight, 1, "Flappy Gopher (Ebiten Demo)"); err != nil { panic(err) } diff --git a/examples/windowsize/main.go b/examples/windowsize/main.go index b7aa1c22a..47d90be93 100644 --- a/examples/windowsize/main.go +++ b/examples/windowsize/main.go @@ -43,9 +43,9 @@ func init() { } const ( - initScreenWidth = 320 - initScreenHeight = 240 - initScreenScale = 2 + initScreenWidth = 480 + initScreenHeight = 360 + initScreenScale = 1 ) var ( @@ -56,16 +56,16 @@ var ( func createRandomIconImage() image.Image { const size = 32 - r := uint8(rand.Intn(0x100)) - g := uint8(rand.Intn(0x100)) - b := uint8(rand.Intn(0x100)) + r := byte(rand.Intn(0x100)) + g := byte(rand.Intn(0x100)) + b := byte(rand.Intn(0x100)) img := image.NewNRGBA(image.Rect(0, 0, size, size)) for j := 0; j < size; j++ { for i := 0; i < size; i++ { img.Pix[j*img.Stride+4*i] = r img.Pix[j*img.Stride+4*i+1] = g img.Pix[j*img.Stride+4*i+2] = b - img.Pix[j*img.Stride+4*i+3] = uint8(float64(i+j) / float64(2*size) * 0xff) + img.Pix[j*img.Stride+4*i+3] = byte(float64(i+j) / float64(2*size) * 0xff) } } @@ -108,6 +108,8 @@ func update(screen *ebiten.Image) error { screenScale = 2 case 2: screenScale = 0.75 + case 0: + // screenScale can be 0 on browsers or mobiles. Ignore this. default: panic("not reached") } @@ -140,7 +142,9 @@ func update(screen *ebiten.Image) error { } ebiten.SetScreenSize(screenWidth, screenHeight) - ebiten.SetScreenScale(screenScale) + if screenScale > 0 { + ebiten.SetScreenScale(screenScale) + } ebiten.SetFullscreen(fullscreen) ebiten.SetRunnableInBackground(runnableInBackground) ebiten.SetCursorVisible(cursorVisible) @@ -173,11 +177,11 @@ func update(screen *ebiten.Image) error { tpsStr = fmt.Sprintf("%d", t) } msg := fmt.Sprintf(`Press arrow keys to change the window size -Press S key to change the window scale -Press F key to switch the fullscreen state +Press S key to change the window scale (only for desktops) +Press F key to switch the fullscreen state (only for desktops) Press B key to switch the run-in-background state Press C key to switch the cursor visibility -Press I key to change the window icon +Press I key to change the window icon (only for desktops) Press V key to switch vsync Press T key to switch TPS (ticks per second) Cursor: (%d, %d) diff --git a/internal/uidriver/js/ui.go b/internal/uidriver/js/ui.go index 415a2c0ef..18c8ed3eb 100644 --- a/internal/uidriver/js/ui.go +++ b/internal/uidriver/js/ui.go @@ -33,7 +33,6 @@ type UserInterface struct { width int height int scale float64 - fullscreen bool runnableInBackground bool vsync bool @@ -75,11 +74,11 @@ func (u *UserInterface) ScreenSizeInFullscreen() (int, int) { } func (u *UserInterface) SetScreenSize(width, height int) { - u.setScreenSize(width, height, u.scale, u.fullscreen) + u.setScreenSize(width, height) } func (u *UserInterface) SetScreenScale(scale float64) { - u.setScreenSize(u.width, u.height, scale, u.fullscreen) + u.scale = scale } func (u *UserInterface) ScreenScale() float64 { @@ -87,11 +86,11 @@ func (u *UserInterface) ScreenScale() float64 { } func (u *UserInterface) SetFullscreen(fullscreen bool) { - u.setScreenSize(u.width, u.height, u.scale, fullscreen) + // Do nothing } func (u *UserInterface) IsFullscreen() bool { - return u.fullscreen + return false } func (u *UserInterface) SetRunnableInBackground(runnableInBackground bool) { @@ -164,9 +163,6 @@ func (u *UserInterface) DeviceScaleFactor() float64 { } func (u *UserInterface) getScale() float64 { - if !u.fullscreen { - return u.scale - } body := document.Get("body") bw := body.Get("clientWidth").Float() bh := body.Get("clientHeight").Float() @@ -432,8 +428,10 @@ func init() { } func (u *UserInterface) Run(width, height int, scale float64, title string, context driver.UIContext, graphics driver.Graphics) error { + // scale is ignored. + document.Set("title", title) - u.setScreenSize(width, height, scale, u.fullscreen) + u.setScreenSize(width, height) canvas.Call("focus") ch := u.loop(context) if runtime.GOARCH == "wasm" { @@ -454,15 +452,12 @@ func (u *UserInterface) RunWithoutMainLoop(width, height int, scale float64, tit panic("js: RunWithoutMainLoop is not implemented") } -func (u *UserInterface) setScreenSize(width, height int, scale float64, fullscreen bool) bool { - if u.width == width && u.height == height && - u.scale == scale && fullscreen == u.fullscreen { +func (u *UserInterface) setScreenSize(width, height int) bool { + if u.width == width && u.height == height { return false } u.width = width u.height = height - u.scale = scale - u.fullscreen = fullscreen u.updateScreenSize() return true } diff --git a/run.go b/run.go index ce2606165..003d199f2 100644 --- a/run.go +++ b/run.go @@ -94,13 +94,20 @@ var theUIContext atomic.Value // The screen size is based on the given values (width and height). // // A window size is based on the given values (width, height and scale). -// scale is used to enlarge the screen. +// +// scale is used to enlarge the screen on desktops. +// scale is ignored on browsers or mobiles. // Note that the actual screen is multiplied not only by the given scale but also // by the device scale on high-DPI display. // If you pass inverse of the device scale, // you can disable this automatical device scaling as a result. // You can get the device scale by DeviceScaleFactor function. // +// On browsers, the scale is automatically adjusted. +// It is strongly recommended to use iframe if you embed an Ebiten application in your website. +// +// On mobiles, if you use ebitenmobile command, the scale is automatically adjusted. +// // Run must be called on the main thread. // Note that Ebiten bounds the main goroutine to the main OS thread by runtime.LockOSThread. // @@ -203,7 +210,7 @@ func SetScreenSize(width, height int) { uiDriver().SetScreenSize(width, height) } -// SetScreenScale changes the scale of the screen. +// SetScreenScale changes the scale of the screen on desktops. // // Note that the actual screen is multiplied not only by the given scale but also // by the device scale on high-DPI display. @@ -211,6 +218,14 @@ func SetScreenSize(width, height int) { // you can disable this automatical device scaling as a result. // You can get the device scale by DeviceScaleFactor function. // +// On browsers, SetScreenScale saves the given value and affects the returned value of ScreenScale, +// but does not affect actual rendering. +// +// On mobiles, SetScreenScale works, but usually the user doesn't have to call this. +// Instead, ebitenmobile calls this automatically. +// +// SetScreenScale panics if scale is not a positive number. +// // SetScreenScale is concurrent-safe. func SetScreenScale(scale float64) { if scale <= 0 { @@ -221,6 +236,8 @@ func SetScreenScale(scale float64) { // ScreenScale returns the current screen scale. // +// ScreenScale returns a value set by SetScreenScale or Run on browsers. +// // If Run is not called, this returns 0. // // ScreenScale is concurrent-safe. @@ -255,14 +272,14 @@ func SetCursorVisibility(visible bool) { // IsFullscreen returns a boolean value indicating whether // the current mode is fullscreen or not. // -// IsFullscreen always returns false on mobiles. +// IsFullscreen always returns false on browsers and mobiles. // // IsFullscreen is concurrent-safe. func IsFullscreen() bool { return uiDriver().IsFullscreen() } -// SetFullscreen changes the current mode to fullscreen or not. +// SetFullscreen changes the current mode to fullscreen or not on desktops. // // On fullscreen mode, the game screen is automatically enlarged // to fit with the monitor. The current scale value is ignored. @@ -270,13 +287,7 @@ func IsFullscreen() bool { // On desktops, Ebiten uses 'windowed' fullscreen mode, which doesn't change // your monitor's resolution. // -// On browsers, the game screen is resized to fit with the body element (client) size. -// Additionally, the game screen is automatically resized when the body element is resized. -// Note that this has nothing to do with 'screen' which is outside of 'window'. -// It is recommended to put Ebiten game in an iframe, and if you want to make the game 'fullscreen' -// on browsers with Fullscreen API, you can do this by applying the API to the iframe. -// -// SetFullscreen does nothing on mobiles. +// SetFullscreen does nothing on browsers or mobiles. // // SetFullscreen is concurrent-safe. func SetFullscreen(fullscreen bool) {