日曜日, 11月 07, 2010

GoでGordonさまと遊ぶ

Go言語のマスコットのGordonさまは、みんなから気持ち悪いと言われていますが、じっと見ていると、かわいいところが無く無くない気がしてきました。

なので、ちょっとコードが整理されていませんが、GoでGordonさまをいっぱい並べられるものを作ってみました。
コールバックな関数はどう書けばいいんだろう。

main.go

package main

import (
"fmt"
"exp/draw/x11"
"image"

"./event"
"./gordon"
)


func main() {
gordon1, e := gordon.NewGordon(image.Point{X: 0, Y: 0})
if e != nil {
fmt.Printf("Error %v\n", e)
return
}

win, e := x11.NewWindow()
if e != nil {
fmt.Printf("Error %v\n", e)
return
}

eventChan := win.EventChan()
sync := make(<-chan bool)
go event.Handle(eventChan, win, gordon1)
<-sync

}


gordon.go

package gordon

import (
"bufio"
"image"
"image/png"
"os"
)

type Gordon struct {
image.Image
Rect image.Rectangle
}

func (g *Gordon) Position(x, y int) {
r := g.Bounds()
g.Rect = image.Rect(
x, y,
x+r.Max.X, y+r.Max.Y)
}

func (g *Gordon) Canon() image.Rectangle {
return g.Rect.Canon()
}

func NewGordon(point image.Point) (gordon *Gordon, e os.Error) {
gordon = new(Gordon)
img, e := loadGordon()
if e != nil {
return nil, e
}
gordon.Image = img
gordon.Position(point.X, point.Y)
return gordon, e
}

func loadGordon() (image.Image, os.Error) {
file, e := os.Open("./Gordon.png", os.O_RDONLY, 0666)
if e != nil {
return nil, e
}

read := bufio.NewReader(file)
icon, e := png.Decode(read)
if e != nil {
return nil, e
}
return icon, nil
}


event.go

package event

import (
"exp/draw"
"fmt"
"image"
)

type Character interface {
image.Image
Canon() image.Rectangle
Position(x, y int)
}

func Handle(eventChan <-chan interface{}, win draw.Window, char Character) {
for {
event := <-eventChan
switch e := event.(type) {
case draw.MouseEvent:
{
me := MouseEvent(e)
go me.handleMouseEvent(win.Screen(), char)
}
case draw.KeyEvent:
{
ke := KeyEvent(e)
go ke.handleKeyEvent(win.Screen(), char)
}
}
win.FlushImage()
}
}


type MouseEvent draw.MouseEvent
type KeyEvent draw.KeyEvent

func (me *MouseEvent) handleMouseEvent(screen draw.Image, char Character) {
fmt.Printf("MouseEvent: Button= %d, Loc= %v : %v\n", me.Buttons, me.Loc, char)
char.Position(me.Loc.X, me.Loc.Y)
draw.Draw(screen, char.Canon(), char, image.ZP)
}

func (ke *KeyEvent) handleKeyEvent(screen draw.Image, char Character) {
fmt.Printf("KeyEvent: Key= %d\n", ke.Key)
}


実行結果

0 件のコメント: