예제 #1
0
파일: pong.go 프로젝트: refola/golang
func Play() {
	// initial setup
	w, err := x11.NewWindow()
	if err != nil {
		panic("Could not make window!")
	}
	bounds := w.Screen().Bounds()
	midY := (bounds.Max.Y - bounds.Min.Y) / 2
	b := ball{place{(bounds.Max.X - bounds.Min.X) / 2, midY}, math.Pi / 6}
	left := player{0, place{bounds.Min.X, midY}}
	right := player{0, place{bounds.Max.X, midY}}
	g := &game{w, b, left, right}

	// event channel
	events := make(chan func(), 1) // a buffer size of one should be plenty

	// window events
	keys := map[int]func(){'a': func() { left.up(bounds.Min.Y) }, 'z': func() { left.down(bounds.Max.Y) }, 'q': func() { os.Exit(0) }}
	go func() {
		c := w.EventChan()
		for {
			e := <-c
			switch t := e.(type) {
			case gui.ConfigEvent:
				g.redoImage()
			case gui.ErrEvent:
				panic("Cannot handle gui.ErrEvent!")
			case gui.KeyEvent:
				if f, ok := keys[t.Key]; ok {
					events <- f
				}
			case gui.MouseEvent:
				// ignored
			default:
				panic("Unknown event type!")
			}
		}
	}()

	// time events
	go func() {
		t := time.NewTicker(500 * 1e6) // 1e6 = 1 million nanos = 1 milli
		for {
			<-t.C
			events <- func() { g.tick() }
		}
	}()

	// main loop - respond to events
	for {
		(<-events)() // Can event-driven programming get any simpler?
	}
}
예제 #2
0
func main() {
	window, err := x11.NewWindow()
	if err != nil {
		fmt.Printf("Cannot open an x11 window\n")
		return
	}
	screen := window.Screen()
	gc := draw2d.NewGraphicContext(screen)
	gc.SetStrokeColor(image.Black)
	gc.SetFillColor(image.White)
	gc.Clear()
	for i := 0.0; i < 360; i = i + 10 { // Go from 0 to 360 degrees in 10 degree steps
		gc.BeginPath() // Start a new path
		gc.Save()      // Keep rotations temporary
		gc.MoveTo(144, 144)
		gc.Rotate(i * (math.Pi / 180.0)) // Rotate by degrees on stack from 'for'
		gc.RLineTo(72, 0)
		gc.Stroke()
		gc.Restore() // Get back the unrotated state
	}

	window.FlushImage()

	gc.SetLineWidth(3)
	nbclick := 0
	for {

		switch evt := (<-window.EventChan()).(type) {
		case gui.KeyEvent:
			if evt.Key == 'q' {
				window.Close()
			}
		case gui.MouseEvent:
			if evt.Buttons&1 != 0 {
				if nbclick%2 == 0 {
					gc.MoveTo(float64(evt.Loc.X), float64(evt.Loc.Y))
				} else {
					gc.LineTo(float64(evt.Loc.X), float64(evt.Loc.Y))
					gc.Stroke()
					window.FlushImage()
				}
				nbclick = nbclick + 1
			}
		}
	}
}
예제 #3
0
func main() {
	var window Window
	flag.Parse()

	// Parse image paths
	fmt.Printf("%s\n", *imgPath)
	if *imgPath != "" {
		r := strings.TrimFunc(*imgPath, TrimFunc)
		split := strings.Split(r[1:len(r)-1], "-")
		start, _ := strconv.Atoi(split[0])
		end, _ := strconv.Atoi(split[1])
		f := 0
		for i := start; i <= end; i++ {
			path := strings.Replace(*imgPath, r, strconv.Itoa(i), -1)
			window.Frames = append(window.Frames, Frame{Id: f, Path: path})
			f++
		}
		window.FrameCount = f
	} else if *savefile != "" {
		load(&window, *savefile)
	}

	// Do cpu profiling if asked for
	if *cpuprof != "" {
		f, err := os.Create(*cpuprof)
		if err != nil {
			fmt.Printf("Error: %v\n", err)
		} else {
			pprof.StartCPUProfile(f)
			defer pprof.StopCPUProfile()
		}
	}

	// Calibration data
	window.Dist = *dist
	if *calPath != "" {
		calimg, err := getImage(*calPath)
		if err == nil {
			window.Calibration = Frame{Path: *calPath, img: calimg}
		}
	}

	// Create X11 window
	xwindow, err := x11.NewWindow()
	window.Window = xwindow
	if err != nil {
		fmt.Printf("Error: %v\n", err)
	}
	window.Screen = xwindow.Screen()
	window.DrawFrame(window.Cfra)

	memno := 1

	// Event loop
	for {
		event, ok := <-xwindow.EventChan()
		if ok != true {
			break
		}

		switch e := event.(type) {
		case gui.ConfigEvent:
			window.Screen = xwindow.Screen()
			window.DrawFrame(window.Cfra)
			break
		case gui.MouseEvent:
			window.DrawFrame(window.Cfra)
			break
		case gui.KeyEvent:
			switch e.Key {
			case 'c':
			case 's':
				fmt.Printf("Saving to %s ... ", *savefile)
				err := save(&window, *savefile)
				if err != nil {
					fmt.Printf("Error while saving: %s\n", err)
					break
				}
				fmt.Println("Done!")
			case 'l':
				fmt.Printf("Loading from %s ... ", *savefile)
				err := load(&window, *savefile)
				if err != nil {
					fmt.Printf("Error while loading: %s\n", err)
					break
				}
				fmt.Println("Done!")
			case 'm':
				if *memprof == "" {
					break
				}
				f, _ := os.Create(fmt.Sprintf("%s%d", *memprof, memno))
				pprof.WriteHeapProfile(f)
				f.Close()
				memno++
			case 'a': // Find all circles
				go func() {
					fmt.Println("Trying to transform all frames .. ")
					for window.GetState() == WORKING {
						time.Sleep(1e9)
					}

					frame := window.Cfra
					for i := 0; i < window.FrameCount; i++ {
						if window.Frames[frame].Calculated {
							continue
						}
						window.Frames[frame].Centre = findCircle(&window, frame)
						window.Frames[frame].Calculated = true
						frame++
						runtime.GC()
					}
					fmt.Println("All frames transformed!")
				}()
			case 'g':
				fmt.Println("Garbage collecting")
				runtime.GC()
			case KEY_SPACE: // space
				go func() {
					cfra := window.Cfra

					if window.Frames[cfra].Calculated {
						return
					}

					for window.GetState() == WORKING {
						time.Sleep(1e9)
					}

					window.Frames[cfra].Centre = findCircle(&window, cfra)
					window.Frames[cfra].Calculated = true
					window.DrawFrame(cfra)
					runtime.GC()
				}()
			case KEY_LEFT:
				if window.Cfra > 0 {
					window.Cfra--
				}
				window.DrawFrame(window.Cfra)
			case KEY_RIGHT:
				if window.Cfra < window.FrameCount-1 {
					window.Cfra++
				}
				window.DrawFrame(window.Cfra)
			default:
			}
		}
	}
}