Added a base (mainly initialization).

This commit is contained in:
Sander Schobers 2020-05-08 18:38:26 +02:00
parent 9d2b259ba1
commit a56ceae2e3
12 changed files with 477 additions and 8 deletions

View File

@ -1,7 +1,47 @@
# TINS 2020 # TINS 2020
## Additional Rules ## Additional Rules
TBD
### Genre requirement
**** There will be 1 genre rule
**genre rule #130**
Theme: Flowers - There should be different flowers in the game, the more the better!
Comments: This rule just reminds me of my favourite platformer, Super Mario World 2: Yoshi's island - it was FULL of flowers: flower enemies, flower collectables, flowers in the background, flowers that grow to form new platforms, shy guys using flowers as camouflage in the flower beds...
### Artistic requirements
**** There will be 1 artistical rule
**artistical rule #60**
make fun of old-fashioned things.
Comments:E.g. have a mode in which the game plays in black and white, featuring an old granny in the corner saying "I didn't pay my colour television license for this", or occasionally "I was in a war" Some more inspirations [here](https://www.youtube.com/watch?v=67OPI3cXAaE) and [here](https://twitter.com/Bill_Gross/status/920406104911233024)
### Technical requirement
**** There will be 2 technical rules
**technical rule #10**
Your game must include procedural content. Bonus points if procedural generation is used to create the gameplay environment.
**technical rule #68**
some kind of special text scroller
Comments: I'll leave you with some inspirational links
- [Wikipedia on procedural generation](https://en.wikipedia.org/wiki/Procedural_generation)
- [Extra Credits video on procedural content](https://www.youtube.com/watch?v=TgbuWfGeG2o)
- [A star wars text scroller](http://blogs.sitepointstatic.com/examples/tech/css3-starwars/index.html)
- [An old fasioned text scroller from the demo scene](https://www.youtube.com/watch?v=3rcXPBJhFf4)
### Bonus rule
**** There will be 1 bonus rule
**bonus rule #9**
Act of monkey - you may replace a single rule by a rule that has the opposite effect
Comments: Lots of wiggle room here. For example, you could revert the last technical rule to have a non-text scroller, non-scrolling text, or simply, no text scroller.
## Building ## Building
Prerequisites: Prerequisites:

70
cmd/example/example.go Normal file
View File

@ -0,0 +1,70 @@
// author: Jacky Boen
package main
import (
"fmt"
"os"
"github.com/veandco/go-sdl2/img"
"github.com/veandco/go-sdl2/sdl"
)
var winTitle string = "Go-SDL2 Texture"
var winWidth, winHeight int32 = 800, 600
var imageName string = "../../assets/test.png"
func run() int {
var window *sdl.Window
var renderer *sdl.Renderer
var texture *sdl.Texture
var src, dst sdl.Rect
var err error
window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
winWidth, winHeight, sdl.WINDOW_SHOWN)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err)
return 1
}
defer window.Destroy()
renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err)
return 2
}
defer renderer.Destroy()
image, err := img.Load(imageName)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to load PNG: %s\n", err)
return 3
}
defer image.Free()
texture, err = renderer.CreateTextureFromSurface(image)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create texture: %s\n", err)
return 4
}
defer texture.Destroy()
src = sdl.Rect{0, 0, 512, 512}
dst = sdl.Rect{100, 50, 512, 512}
renderer.Clear()
renderer.SetDrawColor(255, 0, 0, 255)
renderer.FillRect(&sdl.Rect{0, 0, int32(winWidth), int32(winHeight)})
renderer.Copy(texture, &src, &dst)
renderer.Present()
sdl.PollEvent()
sdl.Delay(2000)
return 0
}
func main() {
os.Exit(run())
}

View File

@ -0,0 +1,15 @@
package main
import "opslag.de/schobers/tins2020"
type terrainRenderer struct {
terrain *tins2020.Map
}
func newTerrainRenderer(terrain *tins2020.Map) *terrainRenderer {
return &terrainRenderer{terrain}
}
func (r *terrainRenderer) Render(ctx *tins2020.Context) {
}

View File

@ -3,7 +3,10 @@ package main
import ( import (
"log" "log"
rice "github.com/GeertJohan/go.rice"
"github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/sdl"
"github.com/veandco/go-sdl2/ttf"
"opslag.de/schobers/tins2020"
) )
func main() { func main() {
@ -19,33 +22,66 @@ func run() error {
} }
defer sdl.Quit() defer sdl.Quit()
window, err := sdl.CreateWindow("TINS 2020", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, if err := ttf.Init(); err != nil {
return err
}
defer ttf.Quit()
ctx, err := tins2020.NewContext(rice.MustFindBox("res"))
if err != nil {
return err
}
defer ctx.Destroy()
if ctx.Settings.Window.Location == nil {
ctx.Settings.Window.Location = &tins2020.Point{
X: sdl.WINDOWPOS_UNDEFINED,
Y: sdl.WINDOWPOS_UNDEFINED,
}
}
window, err := sdl.CreateWindow("TINS 2020", ctx.Settings.Window.Location.X, ctx.Settings.Window.Location.Y,
800, 600, sdl.WINDOW_SHOWN) 800, 600, sdl.WINDOW_SHOWN)
if err != nil { if err != nil {
return err return err
} }
defer window.Destroy() defer window.Destroy()
surface, err := window.GetSurface() renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
if err != nil { if err != nil {
return err return err
} }
surface.FillRect(nil, 0) defer renderer.Destroy()
rect := sdl.Rect{0, 0, 200, 200} ctx.Init(renderer)
surface.FillRect(&rect, 0xffff0000)
window.UpdateSurface() err = ctx.Fonts.Load("default", "fonts/OpenSans-Regular.ttf", 12)
if err != nil {
return err
}
running := true running := true
for running { for running {
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch event.(type) { switch e := event.(type) {
case *sdl.QuitEvent: case *sdl.QuitEvent:
println("Quit") println("Quit")
running = false running = false
break break
case *sdl.WindowEvent:
switch e.Event {
case sdl.WINDOWEVENT_MOVED:
x, y := window.GetPosition()
ctx.Settings.Window.Location = &tins2020.Point{X: x, Y: y}
} }
} }
} }
renderer.SetDrawColor(0, 0, 0, 255)
renderer.Clear()
renderer.SetDrawColor(255, 0, 0, 255)
renderer.FillRect(&sdl.Rect{0, 0, 200, 200})
renderer.Present()
}
return nil return nil
} }

38
context.go Normal file
View File

@ -0,0 +1,38 @@
package tins2020
import (
rice "github.com/GeertJohan/go.rice"
"github.com/veandco/go-sdl2/sdl"
)
type Context struct {
Fonts Fonts
Resources Resources
Textures Textures
Settings Settings
}
func NewContext(res *rice.Box) (*Context, error) {
ctx := &Context{}
err := ctx.Settings.Init()
if err != nil {
return nil, err
}
err = ctx.Resources.Open(res)
if err != nil {
return nil, err
}
return ctx, nil
}
func (c *Context) Init(renderer *sdl.Renderer) {
c.Fonts.Init(c.Resources.Copy())
c.Textures.Init(renderer)
}
func (c *Context) Destroy() {
c.Fonts.Destroy()
c.Resources.Destroy()
c.Textures.Destroy()
c.Settings.Store()
}

41
fonts.go Normal file
View File

@ -0,0 +1,41 @@
package tins2020
import (
"github.com/veandco/go-sdl2/ttf"
"opslag.de/schobers/fs/vfs"
)
type Fonts struct {
dir vfs.CopyDir
fonts map[string]*ttf.Font
}
func (f *Fonts) Init(dir vfs.CopyDir) {
f.dir = dir
f.fonts = map[string]*ttf.Font{}
}
func (f *Fonts) Load(name, path string, size int) error {
fontPath, err := f.dir.Retrieve(path)
if err != nil {
return err
}
font, err := ttf.OpenFont(fontPath, size)
if err != nil {
return err
}
if font, ok := f.fonts[name]; ok {
font.Close()
}
f.fonts[name] = font
return nil
}
func (f *Fonts) Destroy() {
if f.fonts == nil {
return
}
for _, f := range f.fonts {
f.Close()
}
}

61
game.go Normal file
View File

@ -0,0 +1,61 @@
package tins2020
import (
"math/rand"
"opslag.de/schobers/geom/noise"
)
type Game struct {
Terrain *Map
Flowers []Flower
Bees []Bee
}
type Map struct {
Temp *NoiseMap
Humid *NoiseMap
}
type NoiseMap struct {
noise *noise.Perlin
alpha, beta float64
harmonics int
}
func NewNoiseMap(seed int64) *NoiseMap {
return &NoiseMap{
noise: noise.NewPerlin(seed),
alpha: 2,
beta: 2,
harmonics: 4,
}
}
func (m *NoiseMap) Value(x, y int) float64 {
return m.noise.Noise2D(float64(x), float64(y), m.alpha, m.beta, m.harmonics)
}
func NewGame() *Game {
terrain := &Map{
Temp: NewNoiseMap(rand.Int63()),
Humid: NewNoiseMap(rand.Int63()),
}
return &Game{
Terrain: terrain,
Flowers: []Flower{},
Bees: []Bee{},
}
}
type PointF struct {
X, Y float32
}
type Flower struct {
Location PointF
}
type Bee struct {
Location PointF
}

50
io.go Normal file
View File

@ -0,0 +1,50 @@
package tins2020
import (
"encoding/json"
"os"
"path/filepath"
)
func DecodeJSON(path string, v interface{}) error {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
err = json.NewDecoder(f).Decode(v)
if err != nil {
return err
}
return nil
}
func EncodeJSON(path string, v interface{}) error {
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
return json.NewEncoder(f).Encode(v)
}
func UserDir() (string, error) {
config, err := os.UserConfigDir()
if err != nil {
return "", err
}
dir := filepath.Join(config, "tins2020")
err = os.MkdirAll(dir, 0777)
if err != nil {
return "", err
}
return dir, nil
}
func UserFile(name string) (string, error) {
dir, err := UserDir()
if err != nil {
return "", err
}
return filepath.Join(dir, name), nil
}

6
point.go Normal file
View File

@ -0,0 +1,6 @@
package tins2020
type Point struct {
X int32
Y int32
}

39
resources.go Normal file
View File

@ -0,0 +1,39 @@
package tins2020
import (
rice "github.com/GeertJohan/go.rice"
"github.com/spf13/afero"
"opslag.de/schobers/fs/ricefs"
"opslag.de/schobers/fs/vfs"
)
type Resources struct {
box *rice.Box
fs afero.Fs
copy vfs.CopyDir
}
func (r *Resources) Destroy() {
r.copy.Destroy()
}
func (r *Resources) Fs() afero.Fs {
return r.fs
}
func (r *Resources) Open(box *rice.Box) error {
r.box = box
r.fs = vfs.NewOsFsFallback(r.box.Name(), ricefs.NewFs(box))
copy, err := vfs.NewCopyDir(r.fs)
if err != nil {
return err
}
r.copy = copy
return nil
}
func (r *Resources) Copy() vfs.CopyDir { return r.copy }
func (r *Resources) Retrieve(name string) (string, error) {
return r.copy.Retrieve(name)
}

34
settings.go Normal file
View File

@ -0,0 +1,34 @@
package tins2020
import "os"
type Settings struct {
Window WindowSettings
}
func SettingsPath() (string, error) {
return UserFile("settings.json")
}
func (s *Settings) Init() error {
path, err := SettingsPath()
if err != nil {
return err
}
if _, err := os.Stat(path); os.IsNotExist(err) {
return nil
}
return DecodeJSON(path, s)
}
func (s *Settings) Store() error {
path, err := SettingsPath()
if err != nil {
return err
}
return EncodeJSON(path, s)
}
type WindowSettings struct {
Location *Point
}

39
textures.go Normal file
View File

@ -0,0 +1,39 @@
package tins2020
import (
"github.com/veandco/go-sdl2/img"
"github.com/veandco/go-sdl2/sdl"
)
type Textures struct {
renderer *sdl.Renderer
textures map[string]*sdl.Texture
}
func (t *Textures) Init(renderer *sdl.Renderer) {
t.renderer = renderer
t.textures = map[string]*sdl.Texture{}
}
func (t *Textures) Load(name, path string, size int) error {
surface, err := img.Load(name)
if err != nil {
return err
}
defer surface.Free()
texture, err := t.renderer.CreateTextureFromSurface(surface)
if t.textures == nil {
t.textures = map[string]*sdl.Texture{}
}
t.textures[name] = texture
return nil
}
func (t *Textures) Destroy() {
if t.textures == nil {
return
}
for _, t := range t.textures {
t.Destroy()
}
}