Simple 2D game prototyping framework.

prototype

Simply prototype 2D games using an easy, minimal interface that lets you draw simple primitives and images on the screen, easily handle mouse and keyboard events and play sounds.

Games

Installation

Install the Go programming language. After clicking the download link you will be referred to the installation instructions for your specific operating system.

Install Git and make it available in the PATH so the go tool can use it.

For Linux and OS X you need a C compiler installed. On Windows this is not necessary.

On Linux there are two backends available, GLFW and SDL2. For GLFW you need these libraries installed (tested on Linux Mint, other distros might be slightly different):

libx11-dev libxrandr-dev libgl1-mesa-dev libxcursor-dev libxinerama-dev libxi-dev

GLFW is used by default. To use SDL2 you need to add -tags sdl2 to your Go builds, e.g. go run -tags sdl2 main.go. Also you need the SDL2 libraries installed:

libsdl2-dev libsdl2-mixer-dev libsdl2-image-dev

Install the library and samples by running the following on your command line:

go get github.com/gonutz/prototype/...

Documentation

For a description of all library functions, see the godoc page for this project. Note that most of the functionality is in the Window interface and hence the descriptions are listed as code comments in the source for that type.

Example

package main

import (
	"math"

	"github.com/gonutz/prototype/draw"
)

func main() {
	draw.RunWindow("Title", 640, 480, update)
}

func update(window draw.Window) {
	// find the screen center
	w, h := window.Size()
	centerX, centerY := w/2, h/2

	// draw a button in the center of the screen
	mouseX, mouseY := window.MousePosition()
	mouseInCircle := math.Hypot(float64(mouseX-centerX), float64(mouseY-centerY)) < 20
	color := draw.DarkRed
	if mouseInCircle {
		color = draw.Red
	}
	window.FillEllipse(centerX-20, centerY-20, 40, 40, color)
	window.DrawEllipse(centerX-20, centerY-20, 40, 40, draw.White)
	if mouseInCircle {
		window.DrawScaledText("Close!", centerX-40, centerY+25, 1.6, draw.Green)
	}

	// check all mouse clicks that happened during this frame
	for _, click := range window.Clicks() {
		dx, dy := click.X-centerX, click.Y-centerY
		squareDist := dx*dx + dy*dy
		if squareDist <= 20*20 {
			// close the window and end the application
			window.Close()
		}
	}
}

This example displays a window with a round button in the middle to close it. It demonstrates some basic drawing and event handling code.

Comments
  • Is there a way to have the screen size smaller than the window size?

    Is there a way to have the screen size smaller than the window size?

    I want to use this for pixel art games, but I don't want to have a tiny window. So how do I make the screen size smaller than the window size? For example, having the window 960x600 but drawing on it like it's 320x200.

  • Build errors on Windows w/go 1.15 and 1.16

    Build errors on Windows w/go 1.15 and 1.16

    > go build .
    go: finding module for package github.com/gonutz/prototype/draw
    go: found github.com/gonutz/prototype/draw in github.com/gonutz/prototype v0.0.0-20210219081453-295a54f2a887
    go: finding module for package github.com/gonutz/d3d9
    go: finding module for package github.com/gonutz/mixer
    go: finding module for package github.com/gonutz/w32
    go: finding module for package github.com/gonutz/mixer/wav
    go: found github.com/gonutz/d3d9 in github.com/gonutz/d3d9 v1.0.1
    go: found github.com/gonutz/mixer in github.com/gonutz/mixer v0.0.0-20171129091500-a40121441cc5
    go: found github.com/gonutz/mixer/wav in github.com/gonutz/mixer v0.0.0-20171129091500-a40121441cc5
    go: found github.com/gonutz/w32 in github.com/gonutz/w32 v1.0.0
    go: finding module for package github.com/gonutz/ds
    go: found github.com/gonutz/ds in github.com/gonutz/ds v0.0.0-20170706082326-82969548412b
    # github.com/gonutz/prototype/draw
    ..\..\..\..\..\pkg\mod\github.com\gonutz\[email protected]\draw\window_windows.go:93:8: undefined: w32.UnregisterClassAtom
    ..\..\..\..\..\pkg\mod\github.com\gonutz\[email protected]\draw\window_windows.go:442:7: undefined: w32.WM_MOUSEHWHEEL
    ..\..\..\..\..\pkg\mod\github.com\gonutz\[email protected]\draw\window_windows.go:515:10: cannot use style & ^w32.WS_OVERLAPPEDWINDOW (type int32) as type uint32 in argument to w32.SetWindowLong
    

    What version of go is wanted/desired? It might be worth adding a go.mod file (go mod init) so you can specify the go and dependency versions inline?

    Steps to reproduce:

    I tested with the built-in Windows Sandbox feature (if not enabled, hit start, type enough of 'turn windows features on' to get a completion, and enable 'Windows Sandbox' in the list of optional features). Could also be done with a virtual machine.

    • Install latest git: https://github.com/git-for-windows/git/releases/download/v2.30.1.windows.1/Git-2.30.1-64-bit.exe

    • Install go 1.16: https://golang.org/dl/go1.16.windows-amd64.msi

    • Open a Powershell session (I'm a linux/bash guy, powershell is based on the same spec as bash so it's a little more natural to me) -- hit start -- type 'powershell'

    • ensure git and go are installed (note: powershell supports completion on flags and arguments)

      gcm git -ea stop # short for: get-command git -erroraction stop gcm go -ea stop

    • create a local go project:

      cd (mkdir -f (join-path $env:GOPATH local/scratch))

    • initialize local go module

      go mod init local/scratch

    • create a simple test file

      notepad main.go with the following code package main

      import "github.com/gonutz/prototype/draw"

      func main() { draw.RunWindow("Test", 640, 480, update) }

      func update(window draw.Window) { window.DrawLine(100, 100, 440, 380, draw.Blue) }

    • install dependencies

      go mod tidy

    • attempt to run PS C:\Users\WDAGUtilityAccount\go\local\scratch> go run . # github.com/gonutz/prototype/draw ....\pkg\mod\github.com\gonutz\[email protected]\draw\window_windows.go:93:8: undefined: w32.UnregisterClassAtom ....\pkg\mod\github.com\gonutz\[email protected]\draw\window_windows.go:442:7: undefined: w32.WM_MOUSEHWHEEL ....\pkg\mod\github.com\gonutz\[email protected]\draw\window_windows.go:515:10: cannot use style & ^w32.WS_OVERLAPPEDWINDOW (type int32) as type uint32 in argument to w32.SetWindowLong

  • Web Assembly?

    Web Assembly?

    Will there be any support for Web Assembly? I want to use this for game jams, but usually people don't want to download games, so I usually put web builds of my games. :smile:

  • I know this isn't technically an issue but,

    I know this isn't technically an issue but,

    It is an issue that this is so underrated! I've been trying everything everywhere from Vulkan-go to glfw-go and NOTHING worked cross platform! Thank you guys, and I'll probably contribute to this in the future! :smile:

  • some tips

    some tips

    hello I am again sorry(I am only student who do not understand many things), but I am working on my bachalor and I would like to share tip how to improve code(if I do found and it is already exist, sorry):

    • I was create interface "shape":
    type Shape interface {
    	GetXY() (int, int)
    	SetXY(x, y int)
    
    	GetSize() (int, int)
    	SetSize(width, height int)
    
    	GetIdName() (int, string)
    
    	WasPressed() bool
    	WasActive() bool
    	In(x int, y int) bool
    
    	GetFunc() func(window draw.Window)
            SetFunc(function func(window draw.Window))
    	Paint(window draw.Window, scaledText float32)
    	CarryEvent(window draw.Window)
    }
    
    • I was create several structures("basic", TextField, Label, CheckBox, Button), "basic" is implementing Shape and other have embed it, so all are Shape and can also overwrite method....... .
    type Basic struct {
    	x, y, endX, endY, width, height float64
    	id                              int64
    	name                            string
    	pressed, active                 bool
    	function                        func(draw.Window)
    }
    ......
    
    • you can prepare slice structures:= make([]Shape,...) before "animation loop"(or during first turn - I have "init turn" because I use func "GetScaledText") and your "main code" will look like:
    func DrawControlAll(window draw.Window) {
    	for i := 0; i < len(shapes); i++ {
    		shape := shapes[i]
    		shape.CarryEvent(window)
    		shape.Paint(window, 3)
    	}
    }
    
    • if you would like to control themself, you can also at init make lamda with references to themself like this:
            label := my_package.NewLabel(name)
    	label.SetFunc(func(window draw.Window) {
    		label.DoSomeThingSpecial()//e.g. Hide by name
    	})
    
    • this only tip ............
  • some errors on linux arm

    some errors on linux arm

    hello, i am sorry(I am only begener) but I was trying this library on linux arm(andronix, you can see on Linux Distro on Android) and I found this:

    • build with sdl2:
    ./sdl2
    shared memfd open() failed: Function not implemented
    shared memfd open() failed: Function not implemented
    
    • build without tags:
    ./default
    fatal error: unexpected signal during runtime execution
    [signal SIGSEGV: segmentation violation code=0x2 addr=0x7f7d92a000 pc=0x7f54028800]
    
    runtime stack:
    runtime.throw(0x5ccad6, 0x2a)
    /usr/local/go/src/runtime/panic.go:1117 +0x54
    runtime.sigpanic()
    /usr/local/go/src/runtime/signal_unix.go:718 +0x29c
    
    goroutine 1 [syscall, locked to thread]:
    runtime.cgocall(0x580a40, 0x40000bfdb8, 0x4000070000)
    /usr/local/go/src/runtime/cgocall.go:154 +0x50 fp=0x40000bfd80 sp=0x40000bfd40 pc=0x445ba0
    github.com/gonutz/glfw/v3.3/glfw._Cfunc_glfwSwapBuffers(0x76ab60)
    _cgo_gotypes.go:2403 +0x40 fp=0x40000bfdb0 sp=0x40000bfd80 pc=0x54ec10
    github.com/gonutz/glfw/v3.3/glfw.(*Window).SwapBuffers.func1(0x40000d0000)
    /root/go/pkg/mod/github.com/gonutz/[email protected]/v3.3/glfw/context.go:41 +0x50 fp=0x40000bfdf0 sp=0x40000bfdb0 pc=0x551580
    github.com/gonutz/glfw/v3.3/glfw.(*Window).SwapBuffers(0x40000d0000)
    /root/go/pkg/mod/github.com/gonutz/[email protected]/v3.3/glfw/context.go:41 +0x28 fp=0x40000bfe30 sp=0x40000bfdf0 pc=0x54ef28
    github.com/gonutz/prototype/draw.RunWindow(0x5b7992, 0x5, 0x280, 0x1e0, 0x5ce898, 0x0, 0x0)
    /root/go/pkg/mod/github.com/gonutz/[email protected]/draw/window_glfw.go:125 +0x6a8 fp=0x40000bff20 sp=0x40000bfe30 pc=0x554c58
    main.main()
    /root/go/src/my/my.go:10 +0x50 fp=0x40000bff70 sp=0x40000bff20 pc=0x558fb0
    runtime.main()
    /usr/local/go/src/runtime/proc.go:225 +0x274 fp=0x40000bffd0 sp=0x40000bff70 pc=0x475bf4
    runtime.goexit()
    /usr/local/go/src/runtime/asm_arm64.s:1130 +0x4 fp=0x40000bffd0 sp=0x40000bffd0 pc=0x4a4bc4
    
  • Fix/w32 modules ref

    Fix/w32 modules ref

    Prototype references github.com/gonutz/w32 which, with modules, fetches the v1.0.0 version that does not build. This change updates prototype to build with go 1.15 and 1.16 in a fresh environment.

    Testing:

    • reimaged a vm, win 10 2020 h2
    • installed git, go,
    • clone github.com/kfsone/prototype into $env:GOPATH/src/github.com/gonutz/prototype and checked out the fix/w32-modules-ref branch
    • execute the following steps:
        $nutzdir = Join-Path $env:GOPATH src/github.com/gonutz
        $srcurl = "https://raw.githubusercontent.com/gonutz/prototype/master/samples/worm/worm.go"
    
        cd (mkdir (join-path $nutzdir proto.before))
        invoke-webrequest $srcurl -outfile worm.go  # iwr for short
        go run worm.go
    
        # go 1.16 fails because no modules stuff
        go mod init ; go mod tidy
        go run worm.go
    

    fails:

    # github.com/gonutz/prototype/draw
    ..\..\..\..\pkg\mod\github.com\gonutz\[email protected]\draw\window_windows.go:93:8: undefined: w32.UnregisterClassAtom
    ..\..\..\..\pkg\mod\github.com\gonutz\[email protected]\draw\window_windows.go:442:7: undefined: w32.WM_MOUSEHWHEEL
    ..\..\..\..\pkg\mod\github.com\gonutz\[email protected]\draw\window_windows.go:515:10: cannot use style & ^w32.WS_OVERLAPPEDWINDOW (type int32) as type uint32 in argument to w32.SetWindowLong
    

    then I used go mod edit to switch to using the local on-disk copy of prototype:

        cd (mkdir (Join-Path $testdir proto.after))
        iwr $srcurl -outfile worm.go
    
        go mod init
        # --vv--
        go mod edit -replace github.com/gonutz/prototype=../../gonutz/prototype  ## <<
        # --^^--
        go mod tidy
        go run worm.go
    

    which works

    image

  • Cannot call RunWindow mutliple times

    Cannot call RunWindow mutliple times

    Tested on Windows: calling RunWindow twice should open a window and once that is closed should open another one. Currently after closing the first window, no second window appears.

  • Is it possible to draw triangles or polygons?

    Is it possible to draw triangles or polygons?

    Looking at the source code, there doesn't seem to be any way to draw triangles or polygons.

    Is there any way to access lower-level functions to achieve this, or is this being planned for a future update?

    Thanks!

Simple 2D game to teach myself various things about game development and ECS, etc

2d-grass-game I really don't know what to name this game. Its a big grass field, and its in 2d so....2D Grass game This is a simple 2D game to teach m

Jan 17, 2022
Arkanoid game in Go using Ebiten game engine with ECS.
Arkanoid game in Go using Ebiten game engine with ECS.

Arkanoid-go Arkanoid game in Go using Ebiten game engine with ECS. You must have Git LFS installed when cloning the repository to download assets. See

Oct 9, 2022
AircraftWar - a game powered by Go+ spx game engine
AircraftWar - a game powered by Go+ spx game engine

AircraftWar - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download thi

Jan 5, 2022
FlappyCalf - a game powered by Go+ spx game engine
FlappyCalf - a game powered by Go+ spx game engine

FlappyCalf - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download this

Nov 6, 2022
FlappyCalf - a game powered by Go+ spx game engine
FlappyCalf - a game powered by Go+ spx game engine

FlappyCalf - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download this

Nov 6, 2022
MazePlay - a game powered by Go+ spx game engine
MazePlay - a game powered by Go+ spx game engine

MazePlay - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download this g

Dec 16, 2021
RundQuiz-Game - This is a Go exercise that implements and builds a quiz game from a list of math questions in a CSV file.

Go RundQuiz Game Exercise details This exercise is broken into two parts to help simplify the process of explaining it as well as to make it easier to

Jan 5, 2022
A game server framework in Go (golang)

Leaf A pragmatic game server framework in Go (golang). Features Extremely easy to use Reliable Multicore support Modularity Community QQ 群:376389675 D

Jan 2, 2023
Lightweight, facility, high performance golang based game server framework
Lightweight, facility, high performance golang based game server framework

Nano Nano is an easy to use, fast, lightweight game server networking library for Go. It provides a core network architecture and a series of tools an

Jan 1, 2023
Scalable game server framework with clustering support and client libraries for iOS, Android, Unity and others through the C SDK.

pitaya Pitaya is an simple, fast and lightweight game server framework with clustering support and client libraries for iOS, Android, Unity and others

Jan 2, 2023
a framework in golang for game server or app server
a framework in golang for game server or app server

einx a framework in golang for game server or app server. a example server for einx (https://github.com/Cyinx/game_server_einx) Features User-Friendly

Dec 8, 2022
A game server side framework with both web API and realtime communication.

HAYABUSA Framework Hayabusa is a server side framework for Japan-like social games. Easy to understand and use for beginners Powerful controller, flex

May 21, 2022
Fab.io is a lightweight game backend framework written in Go (Golang).

Fab.io is a lightweight real-time game backend framework written in Go (Golang).

Jun 20, 2022
A dead simple 2D game library for Go
A dead simple 2D game library for Go

Ebiten (v2) A dead simple 2D game library for Go Ebiten is an open source game library for the Go programming language. Ebiten's simple API allows you

Dec 28, 2022
Bampf is a simple 3D arcade style game. Collect Energy Cores in order to finish a level. Teleport (bampf) to safety or use cloaking abilities to avoid Sentinels.

Bampf Bampf is a simple 3D arcade style game. Collect energy cores in order to finish a level. Teleport (bampf) to safety or use cloaking abilities to

Dec 12, 2022
This is a "simple" game server. Main functionalities are matching and establishing a connection between players
This is a

Game Server This is a "simple" game server. Main functionalities are matching and establishing a connection between players How to Run? run the server

Aug 28, 2022
Simple rule based matchmaking for your online game with support of Redcon(RESP) protocol.
 Simple rule based matchmaking for your online game with support of Redcon(RESP) protocol.

Simple Matchmaking Simple rule based matchmaking for your online game with support of Redcon(RESP) protocol. 1- Simple Match Rule Easiest usage of sys

Jan 4, 2023
A simple desktop snake game

A simple desktop snake game that's supposed to run on Linux and Mac OS (maybe eventually on Windows). Work on the game is currently in progress - so i

Oct 12, 2021
Simple word guessing game written in golang.
Simple word guessing game written in golang.

Word Guessing Game Simple word guessing game written in golang. successTexts := []string{ "You guessed right! ????????", "Correct! ✅", "Horray!

Oct 19, 2021