move source files to src

This commit is contained in:
2023-07-08 12:20:34 +02:00
parent 6028c5770f
commit e5c2294f6c
43 changed files with 23 additions and 21 deletions

69
src/konstructor/config.go Normal file
View File

@@ -0,0 +1,69 @@
package konstructor
import "image/color"
type ResolutionSet struct {
Width int
Height int
}
var QVGAResolutionSet = ResolutionSet{
Width: 320,
Height: 240,
}
var VGAResolutionSet = ResolutionSet{
Width: 640,
Height: 480,
}
var SVGAResolutionSet = ResolutionSet{
Width: 800,
Height: 600,
}
var XGAResolutionSet = ResolutionSet{
Width: 1024,
Height: 768,
}
var ResolutionSets = []ResolutionSet{
QVGAResolutionSet,
VGAResolutionSet,
SVGAResolutionSet,
XGAResolutionSet,
}
type KeyMap struct {
Up any
Down any
Right any
Left any
Action0 any
Action1 any
Action2 any
Action3 any
}
type ScreenConfig struct {
Width int
Height int
Scale int
}
type HeaderConfig struct {
BackgroundColor color.Color
Height int
FontLayout FontLayout
}
type Config struct {
Name string
Screen *ScreenConfig
Header *HeaderConfig
KeyMap KeyMap
}
func (c *Config) SetResolution(set ResolutionSet) {
c.Screen.Width = set.Width
c.Screen.Height = set.Height
}

View File

@@ -0,0 +1,57 @@
package easy_ebitengine
import (
"fmt"
"reflect"
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/inpututil"
)
func (e *Engine) WatchKeyPress() {
values := reflect.ValueOf(e.Config.KeyMap)
for i := 0; i < values.NumField(); i++ {
key := values.Field(i).Interface().(ebiten.Key)
if inpututil.IsKeyJustPressed(key) {
fmt.Printf("Key pressed: %s\n", key)
e.PressedKey = key
}
}
}
func (e *Engine) ClearKeyPresed() {
e.PressedKey = Engine{}.PressedKey
}
func (e *Engine) UpPressed() bool {
return e.PressedKey == e.Config.KeyMap.Up.(ebiten.Key)
}
func (e *Engine) DownPressed() bool {
return e.PressedKey == e.Config.KeyMap.Down.(ebiten.Key)
}
func (e *Engine) RightPressed() bool {
return e.PressedKey == e.Config.KeyMap.Right.(ebiten.Key)
}
func (e *Engine) LeftPressed() bool {
return e.PressedKey == e.Config.KeyMap.Left.(ebiten.Key)
}
func (e *Engine) Action0Pressed() bool {
return e.PressedKey == e.Config.KeyMap.Action0.(ebiten.Key)
}
func (e *Engine) Action1Pressed() bool {
return e.PressedKey == e.Config.KeyMap.Action1.(ebiten.Key)
}
func (e *Engine) Action2Pressed() bool {
return e.PressedKey == e.Config.KeyMap.Action2.(ebiten.Key)
}
func (e *Engine) Action3Pressed() bool {
return e.PressedKey == e.Config.KeyMap.Action3.(ebiten.Key)
}

View File

@@ -0,0 +1,55 @@
package easy_ebitengine
import (
"game/src/konstructor"
"os"
"github.com/hajimehoshi/ebiten"
)
type Engine struct {
Domain konstructor.DomainInterface
Config *konstructor.Config
KContext *konstructor.KContext
PressedKey ebiten.Key
}
func (e *Engine) Layout(outsideWidth, outsideHeight int) (int, int) {
return e.Config.Screen.Width, e.Config.Screen.Height
}
func (e *Engine) Update(screen *ebiten.Image) error {
e.WatchKeyPress()
if e.KContext.ScreenTypeIs(konstructor.MenuScreenType) {
e.MenuUpdate()
}
if e.KContext.ScreenTypeIs(konstructor.DialogScreenType) {
e.DialogUpdate()
}
if e.KContext.ScreenTypeIs(konstructor.PlaygroundScreenType) {
e.PlaygroundUpdate()
}
if e.KContext.ScreenTypeIs(konstructor.InventoryScreenType) {
e.InventoryUpdate()
}
return nil
}
func (e *Engine) Draw(screen *ebiten.Image) {
if e.KContext.ScreenTypeIs(konstructor.MenuScreenType) {
e.MenuDraw(screen)
}
if e.KContext.ScreenTypeIs(konstructor.DialogScreenType) {
e.DialogDraw(screen)
}
if e.KContext.ScreenTypeIs(konstructor.PlaygroundScreenType) {
e.PlaygroundDraw(screen)
}
if e.KContext.ScreenTypeIs(konstructor.InventoryScreenType) {
e.InventoryDraw(screen)
}
if e.Action3Pressed() {
os.Exit(1)
}
e.ClearKeyPresed()
}

View File

@@ -0,0 +1,19 @@
package easy_ebitengine
import (
"game/src/konstructor"
"log"
_ "image/png"
"github.com/hajimehoshi/ebiten"
)
func (e *Engine) GetImage(render_options konstructor.Render) *ebiten.Image {
img := render_options.GetImage()
out, err := ebiten.NewImageFromImage(img, 0)
if err != nil {
log.Fatal(err)
}
return out
}

View File

@@ -0,0 +1,25 @@
package easy_ebitengine
import (
"game/src/konstructor"
"github.com/hajimehoshi/ebiten"
)
type EngineWrapper struct {
Engine Engine
}
func (ew *EngineWrapper) Init(options konstructor.EngineArgs) {
ew.Engine = Engine{
KContext: options.KContext,
Domain: options.Domain,
Config: options.Config,
}
ebiten.SetWindowSize(options.Config.Screen.Width, options.Config.Screen.Height)
ebiten.SetWindowTitle(options.Config.Name)
}
func (ew *EngineWrapper) Run() {
ebiten.RunGame(&ew.Engine)
}

View File

@@ -0,0 +1,34 @@
package easy_ebitengine
import (
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/text"
)
func (e *Engine) DialogUpdate() {
dialog := e.Domain.GetDialog(e.KContext.ActiveDialog)
if e.UpPressed() && dialog.CurrentSelected != 0 {
dialog.CurrentSelected--
}
if e.DownPressed() && dialog.CurrentSelected != len(dialog.Choices)-1 {
dialog.CurrentSelected++
}
if e.Action0Pressed() {
dialog.Choices[dialog.CurrentSelected].Handler()
}
e.Domain.SetDialog(e.KContext.ActiveDialog, dialog)
}
func (e *Engine) DialogDraw(screen *ebiten.Image) {
dialog := e.Domain.GetDialog(e.KContext.ActiveDialog)
face := dialog.Layout.ChoiceFont.GetFontFace(e.Config.Screen.Scale)
for i, choice := range dialog.Choices {
offset := int(dialog.Layout.ChoiceFont.Size) * (i + 1)
text.Draw(screen, choice.Label+"\n", face, 8, offset, dialog.GetChoiceColor(i))
}
}

View File

@@ -0,0 +1,25 @@
package easy_ebitengine
import (
"game/src/konstructor"
"github.com/hajimehoshi/ebiten"
)
func (e *Engine) InventoryUpdate() {
}
func (e *Engine) InventoryDraw(screen *ebiten.Image) {
}
func (e *Engine) AddToInventory(item *konstructor.Item) {
e.Domain.AddToInventory(item)
}
func (e *Engine) RemoveFromInventory(item *konstructor.Item) {
e.Domain.RemoveFromInventory(item)
}
func (e *Engine) UseInventoryItem(item *konstructor.Item) {
e.Domain.UseInventoryItem(item)
}

View File

@@ -0,0 +1,35 @@
package easy_ebitengine
import (
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/text"
)
func (e *Engine) MenuUpdate() {
menu := e.Domain.GetMenu(e.KContext.ActiveMenu)
if e.UpPressed() && menu.CurrentSelected != 0 {
menu.CurrentSelected--
}
if e.DownPressed() && menu.CurrentSelected != len(menu.MenuItems)-1 {
menu.CurrentSelected++
}
if e.Action0Pressed() {
menu.MenuItems[menu.CurrentSelected].Handler()
}
e.Domain.SetMenu(e.KContext.ActiveMenu, menu)
}
func (e *Engine) MenuDraw(screen *ebiten.Image) {
menu := e.Domain.GetMenu(e.KContext.ActiveMenu)
face := menu.Layout.MenuItemFont.GetFontFace(e.Config.Screen.Scale)
for i, menu_item := range menu.MenuItems {
color := menu.GetMenuItemColor(i)
offset := int(menu.Layout.MenuItemFont.Size) * (i + 1)
text.Draw(screen, menu_item.Label+"\n", face, 8, offset, color)
}
}

View File

@@ -0,0 +1,41 @@
package easy_ebitengine
import (
"game/src/konstructor"
"github.com/hajimehoshi/ebiten"
)
func (e *Engine) PlaygroundUpdate() {
level := e.Domain.GetLevel(e.KContext.CurrentLevel)
e.Domain.Process(konstructor.DomainProcessArgs{
Level: &level,
KContext: e.KContext,
})
}
func (e *Engine) PlaygroundDraw(screen *ebiten.Image) {
e.PlaygroundBackgroundDraw(screen)
e.PlaygroundPlatformsDraw(screen)
e.PlaygroundItemsDraw(screen)
e.PlaygroundNPCsDraw(screen)
e.PlaygroundDefaultPlayerDraw(screen)
e.PlaygroundHeaderDraw(screen)
}
func (e *Engine) PlaygroundBackgroundDraw(screen *ebiten.Image) {
playground := e.GetPlayground()
e.PlaygroundAssetDraw(screen, playground.Render, konstructor.Position{})
}
func (e *Engine) GetPlayground() konstructor.Playground {
level := e.Domain.GetLevel(e.KContext.CurrentLevel)
return level.Playgrounds[e.KContext.CurrentPlayground]
}
func (e *Engine) PlaygroundAssetDraw(screen *ebiten.Image, render konstructor.Render, position konstructor.Position) {
geoM := ebiten.GeoM{}
geoM.Translate(float64(position.X), float64(position.Y))
geoM.Scale(float64(e.Config.Screen.Scale), float64(e.Config.Screen.Scale))
screen.DrawImage(e.GetImage(render), &ebiten.DrawImageOptions{GeoM: geoM})
}

View File

@@ -0,0 +1,37 @@
package easy_ebitengine
import (
"fmt"
"game/src/konstructor"
"image/color"
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/text"
)
func (e *Engine) PlaygroundHeaderDraw(screen *ebiten.Image) {
e.PlaygroundHeaderBackgroundDraw(screen)
e.PlaygroundHeaderTextDraw(screen)
}
func (e *Engine) PlaygroundHeaderBackgroundDraw(screen *ebiten.Image) {
background, _ := ebiten.NewImage(e.Config.Screen.Width, e.Config.Header.Height, ebiten.FilterDefault)
background.Fill(e.Config.Header.BackgroundColor)
geoM := ebiten.GeoM{}
geoM.Scale(float64(e.Config.Screen.Scale), float64(e.Config.Screen.Scale))
screen.DrawImage(background, &ebiten.DrawImageOptions{GeoM: geoM})
}
func (e *Engine) PlaygroundHeaderTextDraw(screen *ebiten.Image) {
face := e.Config.Header.FontLayout.GetFontFace(e.Config.Screen.Scale)
header_text := fmt.Sprint(e.Config.Name, " LIVES ", e.KContext.LiveCount, " LEVEL ", e.KContext.CurrentLevel)
offset := getTopOffset(e.Config)
text.Draw(screen, header_text, face, 10, offset, color.Black)
}
func getTopOffset(config *konstructor.Config) int {
size := int(config.Header.FontLayout.Size) * config.Screen.Scale
height := config.Header.Height * config.Screen.Scale
return (height-size)/2 + size
}

View File

@@ -0,0 +1,10 @@
package easy_ebitengine
import "github.com/hajimehoshi/ebiten"
func (e *Engine) PlaygroundItemsDraw(screen *ebiten.Image) {
playground := e.GetPlayground()
for _, item := range playground.Items {
e.PlaygroundAssetDraw(screen, item.Type.Render, item.Position)
}
}

View File

@@ -0,0 +1,10 @@
package easy_ebitengine
import "github.com/hajimehoshi/ebiten"
func (e *Engine) PlaygroundNPCsDraw(screen *ebiten.Image) {
playground := e.GetPlayground()
for _, npc := range playground.NPCs {
e.PlaygroundAssetDraw(screen, npc.Type.Render, npc.Position)
}
}

View File

@@ -0,0 +1,10 @@
package easy_ebitengine
import "github.com/hajimehoshi/ebiten"
func (e *Engine) PlaygroundPlatformsDraw(screen *ebiten.Image) {
playground := e.GetPlayground()
for _, platform := range playground.Platforms {
e.PlaygroundAssetDraw(screen, platform.Type.Render, platform.Position)
}
}

View File

@@ -0,0 +1,8 @@
package easy_ebitengine
import "github.com/hajimehoshi/ebiten"
func (e *Engine) PlaygroundDefaultPlayerDraw(screen *ebiten.Image) {
player := e.Domain.GetDefaultPlayer()
e.PlaygroundAssetDraw(screen, player.Type.Render, player.Position)
}

View File

@@ -0,0 +1,53 @@
package konstructor
type DomainBaseFields struct {
MenuMap MenuMap
DialogMap DialogMap
Levels []Level
Players []Player
PlatformTypeMap PlatformTypeMap
ItemTypeMap ItemTypeMap
NPCTypeMap NPCTypeMap
}
type DomainInterface interface {
Init()
GetInitialKContext() *KContext
GetInitialConfig() *Config
GetMenuMap() MenuMap
GetMenu(name MenuMapKey) Menu
SetMenu(name MenuMapKey, menu Menu)
GetDialogMap() DialogMap
GetDialog(name DialogMapKey) Dialog
SetDialog(name DialogMapKey, menu Dialog)
GetLevels() []Level
GetLevel(index int) Level
GetPlayers() []Player
GetPlayer(index int) Player
GetDefaultPlayer() Player
GetPlatformTypeMap() PlatformTypeMap
GetPlatformType(name PlatformTypeMapKey) PlatformType
GetItemTypeMap() ItemTypeMap
GetItemType(name ItemTypeMapKey) ItemType
GetNPCTypeMap() NPCTypeMap
GetNPCType(name NPCTypeMapKey) NPCType
AddToInventory(item *Item) bool
RemoveFromInventory(item *Item) bool
UseInventoryItem(item *Item) bool
Process(DomainProcessArgs)
}
type DomainProcessArgs struct {
Level *Level
KContext *KContext
}

View File

@@ -0,0 +1,12 @@
package konstructor
type EngineArgs struct {
Domain DomainInterface
KContext *KContext
Config *Config
}
type EngineWrapperInterface interface {
Init(options EngineArgs)
Run()
}

View File

@@ -0,0 +1,15 @@
package konstructor
type KContext struct {
ScreenType ScreenType
ActiveMenu MenuMapKey
ActiveDialog DialogMapKey
CurrentLevel int
CurrentPlayground int
Multiplayer bool
LiveCount int
}
func (c *KContext) ScreenTypeIs(name ScreenType) bool {
return c.ScreenType == name
}

View File

@@ -0,0 +1,18 @@
// Game framework inspired by AGI
package konstructor
// Main struct of framework
type Konstructor struct {
Domain DomainInterface
EngineWrapper EngineWrapperInterface
}
func (k Konstructor) Init() {
k.Domain.Init()
k.EngineWrapper.Init(EngineArgs{
Domain: k.Domain,
KContext: k.Domain.GetInitialKContext(),
Config: k.Domain.GetInitialConfig(),
})
k.EngineWrapper.Run()
}

View File

@@ -0,0 +1,39 @@
package konstructor
import (
"image/color"
"io/ioutil"
"golang.org/x/image/font"
"golang.org/x/image/font/opentype"
)
type FontName string
type FontLayout struct {
Path string
DPI float64
Size float64
Color color.Color
SelectedColor color.Color
cachedFontFace font.Face
}
func (fl *FontLayout) GetFontFace(scale int) font.Face {
if fl.cachedFontFace != nil {
return fl.cachedFontFace
}
file, _ := ioutil.ReadFile(fl.Path)
true_type, _ := opentype.Parse(file)
font_face, _ := opentype.NewFace(true_type, &opentype.FaceOptions{
Size: fl.Size * float64(scale),
DPI: fl.DPI,
Hinting: font.HintingVertical,
})
fl.cachedFontFace = font_face
return font_face
}
func GetFontPath(name FontName) string {
return "assets/fonts/" + string(name) + ".ttf"
}

View File

@@ -0,0 +1,34 @@
package konstructor
import (
"bytes"
"image"
"io/ioutil"
"log"
)
type Render struct {
Image string
Width int
Height int
Visible bool
cachedImage image.Image
}
func (ro *Render) GetImage() image.Image {
if ro.cachedImage != nil {
return ro.cachedImage
}
file, err := ioutil.ReadFile(ro.Image)
if err != nil {
log.Fatal(err)
}
img, _, err := image.Decode(bytes.NewReader(file))
if err != nil {
log.Fatal(err)
}
ro.cachedImage = img
return img
}

23
src/konstructor/object.go Normal file
View File

@@ -0,0 +1,23 @@
package konstructor
type ObjectType string
const (
ItemObjectType ObjectType = "item"
NPCObjectType ObjectType = "npc"
PlatformObjectType ObjectType = "platform"
PlayerObjectType ObjectType = "player"
)
type ObjectDirectoryMap map[ObjectType]string
var ObjectDirectories = ObjectDirectoryMap{
ItemObjectType: "items",
NPCObjectType: "npcs",
PlatformObjectType: "platforms",
PlayerObjectType: "players",
}
func GetObjectDirectory(name ObjectType) string {
return "assets/images/" + ObjectDirectories[name] + "/"
}

View File

@@ -0,0 +1,20 @@
package konstructor
type ItemTypeMapKey string
type ItemTypeMap map[ItemTypeMapKey]ItemType
type ItemType struct {
ID string
Render Render
}
type Item struct {
ID string
Type ItemType
Position Position
}
func GetItemTypeImagePath(name ItemTypeMapKey) string {
return GetObjectDirectory(ItemObjectType) + string(name) + ".png"
}

View File

@@ -0,0 +1,20 @@
package konstructor
type NPCTypeMapKey string
type NPCTypeMap map[NPCTypeMapKey]NPCType
type NPCType struct {
ID string
Render Render
}
type NPC struct {
ID string
Type NPCType
Position Position
}
func GetNPCTypeImagePath(name NPCTypeMapKey) string {
return GetObjectDirectory(NPCObjectType) + string(name) + ".png"
}

View File

@@ -0,0 +1,20 @@
package konstructor
type PlatformTypeMapKey string
type PlatformTypeMap map[PlatformTypeMapKey]PlatformType
type PlatformType struct {
ID string
Render Render
}
type Platform struct {
ID string
Type PlatformType
Position Position
}
func GetPlatformTypeImagePath(name PlatformTypeMapKey) string {
return GetObjectDirectory(PlatformObjectType) + string(name) + ".png"
}

View File

@@ -0,0 +1,29 @@
package konstructor
type PlayerTypeID string
type InventoryItem struct {
Item Item
Used bool
Active bool
}
type Inventory struct {
Items []InventoryItem
}
type PlayerType struct {
ID PlayerTypeID
Render Render
}
type Player struct {
ID string
Type PlayerType
Position Position
Inventory Inventory
}
func GetPlayerTypeImagePath(name PlayerTypeID) string {
return GetObjectDirectory(PlayerObjectType) + string(name) + ".png"
}

View File

@@ -0,0 +1,32 @@
package konstructor
import "image/color"
type DialogMapKey string
type DialogMap map[DialogMapKey]Dialog
type DialogLayout struct {
Render Render
ChoiceFont FontLayout
}
type DialogChoice struct {
ID string
Label string
Handler func()
}
type Dialog struct {
CurrentSelected int
Layout DialogLayout
Choices []DialogChoice
}
func (dialog *Dialog) GetChoiceColor(i int) color.Color {
if dialog.CurrentSelected == i {
return dialog.Layout.ChoiceFont.SelectedColor
} else {
return dialog.Layout.ChoiceFont.Color
}
}

View File

@@ -0,0 +1,31 @@
package konstructor
import "image/color"
type MenuMapKey string
type MenuMap map[MenuMapKey]Menu
type MenuLayout struct {
MenuItemFont FontLayout
}
type MenuItem struct {
ID string
Label string
Handler func()
}
type Menu struct {
CurrentSelected int
Layout MenuLayout
MenuItems []MenuItem
}
func (menu *Menu) GetMenuItemColor(i int) color.Color {
if menu.CurrentSelected == i {
return menu.Layout.MenuItemFont.SelectedColor
} else {
return menu.Layout.MenuItemFont.Color
}
}

View File

@@ -0,0 +1,27 @@
package konstructor
type PlaygroundID string
type Position struct {
X int
Y int
Z int
}
type Playground struct {
ID PlaygroundID
Render Render
Platforms []Platform
NPCs []NPC
Items []Item
}
type Level struct {
ID string
Name string
Playgrounds []Playground
}
func GetPlaygroundImagePath(name PlaygroundID) string {
return "assets/images/playgrounds/" + string(name) + ".png"
}

View File

@@ -0,0 +1,10 @@
package konstructor
type ScreenType string
const (
MenuScreenType ScreenType = "menu"
DialogScreenType ScreenType = "dialog"
PlaygroundScreenType ScreenType = "playground"
InventoryScreenType ScreenType = "inventory"
)