1st commit
This commit is contained in:
29
assets/levels/gen.sh
Executable file
29
assets/levels/gen.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
width=$(grep "width int" ../main.go | awk '{print $4}')
|
||||
height=$(grep "height int" ../main.go | awk '{print $4}')
|
||||
|
||||
read -p " Enter level name: " name
|
||||
read -p " Enter background: " background
|
||||
read -p "Enter description: " des
|
||||
|
||||
if test -z "$name"; then
|
||||
name="newlevel"
|
||||
fi
|
||||
|
||||
if test -z "$bbackground"; then
|
||||
background="background-lila"
|
||||
fi
|
||||
|
||||
(
|
||||
echo "Description: $des"
|
||||
echo "Background: $background"
|
||||
w=$(($width / 32))
|
||||
h=$(($height / 32))
|
||||
|
||||
for x in $(seq 1 $h); do
|
||||
for y in $(seq 1 $w); do
|
||||
echo -n " "
|
||||
done
|
||||
echo
|
||||
done
|
||||
)
|
||||
17
assets/levels/gurke.lvl
Normal file
17
assets/levels/gurke.lvl
Normal file
@@ -0,0 +1,17 @@
|
||||
Description: find the fruit
|
||||
Background: background-orange
|
||||
|
||||
|
||||
##############
|
||||
# #
|
||||
############ #
|
||||
# S #
|
||||
# ############
|
||||
# #
|
||||
############ #
|
||||
# # # #
|
||||
# ##### # # #
|
||||
# # #
|
||||
##############
|
||||
|
||||
|
||||
17
assets/levels/intro.lvl
Normal file
17
assets/levels/intro.lvl
Normal file
@@ -0,0 +1,17 @@
|
||||
Description: Introduction: collect the goods by moving the ball onto them
|
||||
Background: background-lila
|
||||
####################
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# ######
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
####################
|
||||
150
assets/loader-levels.go
Normal file
150
assets/loader-levels.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
_ "image/png"
|
||||
"io/fs"
|
||||
"log"
|
||||
"openquell/util"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
var Levels = LoadLevels("levels")
|
||||
var Tiles = InitTiles()
|
||||
|
||||
// Tile: contains image, identifier (as used in level data) and
|
||||
// additional properties
|
||||
type Tile struct {
|
||||
Id byte
|
||||
Sprite *ebiten.Image
|
||||
Class string
|
||||
Solid bool
|
||||
Player bool
|
||||
Renderable bool
|
||||
Velocity bool
|
||||
}
|
||||
|
||||
func NewTilePlayer() *Tile {
|
||||
return &Tile{
|
||||
Id: 'S',
|
||||
Sprite: Assets["sphere-blue"],
|
||||
Class: "sphere",
|
||||
Renderable: true,
|
||||
Player: true,
|
||||
Velocity: true,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTileBlock(class string) *Tile {
|
||||
return &Tile{
|
||||
Id: '#',
|
||||
Sprite: Assets[class],
|
||||
Class: class,
|
||||
Solid: true,
|
||||
Renderable: true,
|
||||
}
|
||||
}
|
||||
|
||||
// used to map level data bytes to actual tiles
|
||||
type TileRegistry map[byte]*Tile
|
||||
|
||||
// holds a raw level spec:
|
||||
//
|
||||
// Name: the name of the level file w/o the .lvl extension
|
||||
// Background: an image name used as game background for this level
|
||||
// Description: text to display on top
|
||||
// Data: a level spec consisting of chars of the above mapping and spaces, e.g.:
|
||||
// ####
|
||||
// # #
|
||||
// ####
|
||||
//
|
||||
// Each level data must be 20 chars wide (= 640 px width) and 15 chars
|
||||
// high (=480 px height).
|
||||
type RawLevel struct {
|
||||
Name string
|
||||
Description string
|
||||
Background *ebiten.Image
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func InitTiles() TileRegistry {
|
||||
return TileRegistry{
|
||||
' ': {Id: ' ', Class: "floor", Renderable: false},
|
||||
'#': NewTileBlock("block-grey32"),
|
||||
'S': NewTilePlayer(),
|
||||
}
|
||||
}
|
||||
|
||||
// load levels at compile time into ram, creates a slice of raw levels
|
||||
func LoadLevels(dir string) []RawLevel {
|
||||
levels := []RawLevel{}
|
||||
|
||||
// we use embed.FS to iterate over all files in ./levels/
|
||||
entries, err := assetfs.ReadDir(dir)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to read level dir %s: %s", dir, err)
|
||||
}
|
||||
|
||||
for _, levelfile := range entries {
|
||||
if levelfile.Type().IsRegular() && strings.Contains(levelfile.Name(), ".lvl") {
|
||||
path := filepath.Join("assets", dir)
|
||||
fmt.Printf("LOADING level %s/%s ... ", path, levelfile)
|
||||
level := ParseRawLevel(path, levelfile)
|
||||
fmt.Printf("done\n")
|
||||
levels = append(levels, level)
|
||||
}
|
||||
}
|
||||
|
||||
return levels
|
||||
}
|
||||
|
||||
func ParseRawLevel(dir string, levelfile fs.DirEntry) RawLevel {
|
||||
fd, err := os.Open(filepath.Join(dir, levelfile.Name()))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to read level file %s: %s", levelfile.Name(), err)
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
name := strings.TrimSuffix(levelfile.Name(), ".lvl")
|
||||
des := ""
|
||||
background := &ebiten.Image{}
|
||||
data := []byte{}
|
||||
|
||||
scanner := bufio.NewScanner(fd)
|
||||
for scanner.Scan() {
|
||||
// ignore any whitespace
|
||||
line := scanner.Text()
|
||||
|
||||
// ignore empty lines
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.Contains(line, "Background:"):
|
||||
haveit := strings.Split(line, ": ")
|
||||
if util.Exists(Assets, haveit[1]) {
|
||||
background = Assets[haveit[1]]
|
||||
}
|
||||
case strings.Contains(line, "Description:"):
|
||||
haveit := strings.Split(line, ": ")
|
||||
des = haveit[1]
|
||||
default:
|
||||
// all other non-empty and non-equalsign lines are
|
||||
// level definition matrix data, merge thes into data
|
||||
data = append(data, line+"\n"...)
|
||||
}
|
||||
}
|
||||
|
||||
return RawLevel{
|
||||
Name: name,
|
||||
Data: data,
|
||||
Background: background,
|
||||
Description: des,
|
||||
}
|
||||
}
|
||||
58
assets/loader-sprites.go
Normal file
58
assets/loader-sprites.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"image"
|
||||
_ "image/png"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
// Maps image name to image data
|
||||
type AssetRegistry map[string]*ebiten.Image
|
||||
|
||||
//go:embed levels/*.lvl sprites/*.png
|
||||
var assetfs embed.FS
|
||||
|
||||
var Assets = LoadImages("sprites")
|
||||
|
||||
func LoadImages(dir string) AssetRegistry {
|
||||
images := AssetRegistry{}
|
||||
|
||||
// we use embed.FS to iterate over all files in ./assets/
|
||||
entries, err := assetfs.ReadDir(dir)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to read assets dir %s: %s", dir, err)
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
fmt.Println(entry.Name())
|
||||
}
|
||||
|
||||
for _, imagefile := range entries {
|
||||
path := filepath.Join("assets", dir, imagefile.Name())
|
||||
fmt.Printf("LOADING %s ... ", path)
|
||||
fd, err := os.Open(path)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open image file %s: %s", imagefile.Name(), err)
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
name := strings.TrimSuffix(imagefile.Name(), ".png")
|
||||
|
||||
img, _, err := image.Decode(fd)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to decode image %s: %s", imagefile.Name(), err)
|
||||
}
|
||||
|
||||
images[name] = ebiten.NewImageFromImage(img)
|
||||
fmt.Printf("done\n")
|
||||
}
|
||||
|
||||
return images
|
||||
}
|
||||
BIN
assets/sprites/background-lila.png
Normal file
BIN
assets/sprites/background-lila.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 145 KiB |
BIN
assets/sprites/background-orange.png
Normal file
BIN
assets/sprites/background-orange.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 152 KiB |
BIN
assets/sprites/block-grey.png
Normal file
BIN
assets/sprites/block-grey.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 584 B |
BIN
assets/sprites/block-grey32.png
Normal file
BIN
assets/sprites/block-grey32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
BIN
assets/sprites/block-orange-32.png
Normal file
BIN
assets/sprites/block-orange-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
assets/sprites/sphere-blue.png
Normal file
BIN
assets/sprites/sphere-blue.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
Reference in New Issue
Block a user