Add ui.UI

This commit is contained in:
Hajime Hoshi 2013-10-15 00:49:30 +09:00
parent ef932bd5ae
commit 9d83ae1cfa
5 changed files with 133 additions and 70 deletions

View File

@ -8,6 +8,7 @@ import (
"github.com/hajimehoshi/go-ebiten/example/game/rects" "github.com/hajimehoshi/go-ebiten/example/game/rects"
"github.com/hajimehoshi/go-ebiten/example/game/rotating" "github.com/hajimehoshi/go-ebiten/example/game/rotating"
"github.com/hajimehoshi/go-ebiten/example/game/sprites" "github.com/hajimehoshi/go-ebiten/example/game/sprites"
"github.com/hajimehoshi/go-ebiten/ui"
"github.com/hajimehoshi/go-ebiten/ui/cocoa" "github.com/hajimehoshi/go-ebiten/ui/cocoa"
_ "github.com/hajimehoshi/go-ebiten/ui/glut" _ "github.com/hajimehoshi/go-ebiten/ui/glut"
"os" "os"
@ -41,5 +42,6 @@ func main() {
} }
const screenScale = 2 const screenScale = 2
cocoa.Run(game, 256, 240, screenScale, "Ebiten Demo") cocoaUI := cocoa.New(256, 240, screenScale, "Ebiten Demo")
ui.Run(cocoaUI, game)
} }

View File

@ -12,7 +12,6 @@ import "C"
import ( import (
"github.com/hajimehoshi/go-ebiten" "github.com/hajimehoshi/go-ebiten"
"github.com/hajimehoshi/go-ebiten/graphics/opengl" "github.com/hajimehoshi/go-ebiten/graphics/opengl"
"time"
"unsafe" "unsafe"
) )
@ -20,16 +19,74 @@ type UI struct {
screenWidth int screenWidth int
screenHeight int screenHeight int
screenScale int screenScale int
graphicsDevice *opengl.Device title string
initializing chan ebiten.Game initializing chan ebiten.Game
initialized chan ebiten.Game initialized chan ebiten.Game
updating chan ebiten.Game updating chan ebiten.Game
updated chan ebiten.Game updated chan ebiten.Game
input chan ebiten.InputState input chan ebiten.InputState
graphicsDevice *opengl.Device
} }
var currentUI *UI var currentUI *UI
func New(screenWidth, screenHeight, screenScale int, title string) *UI {
if currentUI != nil {
panic("UI can't be duplicated.")
}
ui := &UI{
screenWidth: screenWidth,
screenHeight: screenHeight,
screenScale: screenScale,
title: title,
initializing: make(chan ebiten.Game),
initialized: make(chan ebiten.Game),
updating: make(chan ebiten.Game),
updated: make(chan ebiten.Game),
input: make(chan ebiten.InputState),
}
currentUI = ui
return ui
}
func (ui *UI) MainLoop() {
cTitle := C.CString(ui.title)
defer C.free(unsafe.Pointer(cTitle))
C.Run(C.size_t(ui.screenWidth),
C.size_t(ui.screenHeight),
C.size_t(ui.screenScale),
cTitle)
}
func (ui *UI) ScreenWidth() int {
return ui.screenWidth
}
func (ui *UI) ScreenHeight() int {
return ui.screenHeight
}
func (ui *UI) Initializing() chan<- ebiten.Game {
return ui.initializing
}
func (ui *UI) Initialized() <-chan ebiten.Game {
return ui.initialized
}
func (ui *UI) Updating() chan<- ebiten.Game {
return ui.updating
}
func (ui *UI) Updated() <-chan ebiten.Game {
return ui.updated
}
func (ui *UI) Input() <-chan ebiten.InputState {
return ui.input
}
//export ebiten_EbitenOpenGLView_Initialized //export ebiten_EbitenOpenGLView_Initialized
func ebiten_EbitenOpenGLView_Initialized() { func ebiten_EbitenOpenGLView_Initialized() {
if currentUI.graphicsDevice != nil { if currentUI.graphicsDevice != nil {
@ -76,64 +133,3 @@ func ebiten_EbitenOpenGLView_InputUpdated(inputType C.InputType, cx, cy C.int) {
} }
currentUI.input <- ebiten.InputState{x, y} currentUI.input <- ebiten.InputState{x, y}
} }
func Run(game ebiten.Game, screenWidth, screenHeight, screenScale int,
title string) {
currentUI = &UI{
screenWidth: screenWidth,
screenHeight: screenHeight,
screenScale: screenScale,
initializing: make(chan ebiten.Game),
initialized: make(chan ebiten.Game),
updating: make(chan ebiten.Game),
updated: make(chan ebiten.Game),
input: make(chan ebiten.InputState),
}
go func() {
frameTime := time.Duration(
int64(time.Second) / int64(ebiten.FPS))
tick := time.Tick(frameTime)
gameContext := &GameContext{
screenWidth: screenWidth,
screenHeight: screenHeight,
inputState: ebiten.InputState{-1, -1},
}
currentUI.initializing <- game
game = <-currentUI.initialized
for {
select {
case gameContext.inputState = <-currentUI.input:
case <-tick:
game.Update(gameContext)
case currentUI.updating <- game:
game = <-currentUI.updated
}
}
}()
cTitle := C.CString(title)
defer C.free(unsafe.Pointer(cTitle))
C.Run(C.size_t(screenWidth),
C.size_t(screenHeight),
C.size_t(screenScale),
cTitle)
}
type GameContext struct {
screenWidth int
screenHeight int
inputState ebiten.InputState
}
func (context *GameContext) ScreenWidth() int {
return context.screenWidth
}
func (context *GameContext) ScreenHeight() int {
return context.screenHeight
}
func (context *GameContext) InputState() ebiten.InputState {
return context.inputState
}

View File

@ -14,11 +14,13 @@
styleMask:style]; styleMask:style];
NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
NSSize screenSize = [screen visibleFrame].size; NSSize screenSize = [screen visibleFrame].size;
// Reference: Mac OS X Human Interface Guidelines: UI Element Guidelines: Windows // Reference: Mac OS X Human Interface Guidelines: UI Element Guidelines:
// Windows
// http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AppleHIGuidelines/Windows/Windows.html // http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AppleHIGuidelines/Windows/Windows.html
NSRect contentRect = NSMakeRect((screenSize.width - windowRect.size.width) / 2, NSRect contentRect =
(screenSize.height - windowRect.size.height) * 2 / 3, NSMakeRect((screenSize.width - windowRect.size.width) / 2,
size.width, size.height); (screenSize.height - windowRect.size.height) * 2 / 3,
size.width, size.height);
self = [super initWithContentRect:contentRect self = [super initWithContentRect:contentRect
styleMask:style styleMask:style
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
@ -53,9 +55,10 @@
alternateButton:nil alternateButton:nil
otherButton:@"Cancel" otherButton:@"Cancel"
informativeTextWithFormat:@""]; informativeTextWithFormat:@""];
SEL selector = @selector(alertDidEnd:returnCode:contextInfo:);
[alert beginSheetModalForWindow:sender [alert beginSheetModalForWindow:sender
modalDelegate:self modalDelegate:self
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) didEndSelector:selector
contextInfo:nil]; contextInfo:nil];
} }
return NO; return NO;

View File

@ -7,8 +7,9 @@
void Run(size_t width, size_t height, size_t scale, const char* title) { void Run(size_t width, size_t height, size_t scale, const char* title) {
@autoreleasepool { @autoreleasepool {
NSSize size = NSMakeSize(width * scale, height * scale);
EbitenWindow* window = [[EbitenWindow alloc] EbitenWindow* window = [[EbitenWindow alloc]
initWithSize:NSMakeSize(width * scale, height * scale)]; initWithSize:size];
[window setTitle: [[NSString alloc] initWithUTF8String:title]]; [window setTitle: [[NSString alloc] initWithUTF8String:title]];
EbitenController* controller = [[EbitenController alloc] EbitenController* controller = [[EbitenController alloc]
initWithWindow:window]; initWithWindow:window];

61
ui/ui.go Normal file
View File

@ -0,0 +1,61 @@
package ui
import (
"github.com/hajimehoshi/go-ebiten"
"time"
)
type UI interface {
MainLoop()
ScreenWidth() int
ScreenHeight() int
Initializing() chan<- ebiten.Game
Initialized() <-chan ebiten.Game
Updating() chan<- ebiten.Game
Updated() <-chan ebiten.Game
Input() <-chan ebiten.InputState
}
func mainLoop(ui UI, game ebiten.Game) {
frameTime := time.Duration(int64(time.Second) / int64(ebiten.FPS))
tick := time.Tick(frameTime)
gameContext := &GameContext{
screenWidth: ui.ScreenWidth(),
screenHeight: ui.ScreenHeight(),
inputState: ebiten.InputState{-1, -1},
}
ui.Initializing() <- game
game = <-ui.Initialized()
for {
select {
case gameContext.inputState = <-ui.Input():
case <-tick:
game.Update(gameContext)
case ui.Updating() <- game:
game = <-ui.Updated()
}
}
}
func Run(ui UI, game ebiten.Game) {
go mainLoop(ui, game)
ui.MainLoop()
}
type GameContext struct {
screenWidth int
screenHeight int
inputState ebiten.InputState
}
func (context *GameContext) ScreenWidth() int {
return context.screenWidth
}
func (context *GameContext) ScreenHeight() int {
return context.screenHeight
}
func (context *GameContext) InputState() ebiten.InputState {
return context.inputState
}