Private
Public Access
1
0

Add platform-specific implementations for assets, audio, WebSocket, and rendering on Desktop and WebAssembly platforms. Introduce embedded assets for WebAssembly and native file handling for Desktop. Add platform-specific chunk loading and game state synchronization.

This commit is contained in:
Sebastian Unterschütz
2026-01-04 01:25:04 +01:00
parent 85d697df19
commit 3232ee7c2f
86 changed files with 4931 additions and 486 deletions

View File

@@ -56,7 +56,7 @@ var (
ColPlayerRef = color.RGBA{0, 255, 255, 100}
)
var AssetTypes = []string{"obstacle", "platform", "powerup", "enemy", "deco", "coin"}
var AssetTypes = []string{"obstacle", "platform", "wall", "powerup", "enemy", "deco", "coin"}
// --- HILFSFUNKTIONEN ---
@@ -92,6 +92,58 @@ func generateBrickTexture(w, h int) *ebiten.Image {
return img
}
func generateWallTexture(w, h int) *ebiten.Image {
img := ebiten.NewImage(w, h)
// Dunklerer Hintergrund für Wände
img.Fill(color.RGBA{60, 60, 70, 255})
stoneColor := color.RGBA{100, 100, 110, 255}
stoneDark := color.RGBA{80, 80, 90, 255}
stoneLight := color.RGBA{120, 120, 130, 255}
// Mehr Reihen und Spalten für Wände
rows := h / 16
if rows < 2 {
rows = 2
}
cols := w / 16
if cols < 2 {
cols = 2
}
brickH := float32(h) / float32(rows)
brickW := float32(w) / float32(cols)
padding := float32(1)
for row := 0; row < rows; row++ {
for col := 0; col < cols; col++ {
// Versatz für ungeraden Reihen (Mauerwerk-Muster)
xOffset := float32(0)
if row%2 != 0 {
xOffset = brickW / 2
}
x := float32(col)*brickW + xOffset
y := float32(row) * brickH
drawStone := func(bx, by float32) {
// Hauptstein
vector.DrawFilledRect(img, bx+padding, by+padding, brickW-padding*2, brickH-padding*2, stoneColor, false)
// Schatten unten
vector.DrawFilledRect(img, bx+padding, by+brickH-padding-2, brickW-padding*2, 2, stoneDark, false)
// Highlight oben
vector.DrawFilledRect(img, bx+padding, by+padding, brickW-padding*2, 2, stoneLight, false)
}
drawStone(x, y)
// Wrap-around für versetzten Offset
if x+brickW > float32(w) {
drawStone(x-float32(w), y)
}
}
}
return img
}
func saveImageToDisk(img *ebiten.Image, filename string) error {
stdImg := img.SubImage(img.Bounds())
assetDir := filepath.Dir(OutFile)
@@ -282,6 +334,33 @@ func (e *Editor) CreatePlatform() {
e.selectedID = id
}
func (e *Editor) CreateWall() {
w, h := 64, 128
texImg := generateWallTexture(w, h)
timestamp := time.Now().Unix()
filename := fmt.Sprintf("gen_wall_%d.png", timestamp)
id := fmt.Sprintf("wall_%d", timestamp)
if err := saveImageToDisk(texImg, filename); err != nil {
log.Printf("Fehler beim Speichern: %v", err)
return
}
e.assetsImages[id] = texImg
e.manifest.Assets[id] = game.AssetDefinition{
ID: id,
Type: "wall", // Neuer Type für kletterbare Wände
Filename: filename,
Scale: 1.0,
Color: game.HexColor{R: 255, G: 255, B: 255, A: 255},
DrawOffX: float64(-w) / 2,
DrawOffY: float64(-h),
Hitbox: game.Rect{W: float64(w), H: float64(h), OffsetX: float64(-w) / 2, OffsetY: float64(-h)},
}
e.RebuildList()
e.selectedID = id
}
func (e *Editor) Update() error {
if inpututil.IsKeyJustPressed(ebiten.KeyS) && e.activeField == "" {
e.Save()
@@ -335,9 +414,13 @@ func (e *Editor) Update() error {
currentY += float64(LineHeight)
}
if my > CanvasHeight-40 {
// Button-Bereich unten
if my > CanvasHeight-75 && my <= CanvasHeight-40 {
e.CreatePlatform()
}
if my > CanvasHeight-40 {
e.CreateWall()
}
}
return nil
}
@@ -500,10 +583,15 @@ func (e *Editor) Draw(screen *ebiten.Image) {
// --- 1. LISTE LINKS ---
vector.DrawFilledRect(screen, 0, 0, WidthList, CanvasHeight, ColPanel, false)
// Button Neu
btnRect := image.Rect(10, CanvasHeight-35, WidthList-10, CanvasHeight-10)
vector.DrawFilledRect(screen, float32(btnRect.Min.X), float32(btnRect.Min.Y), float32(btnRect.Dx()), float32(btnRect.Dy()), ColHighlight, false)
text.Draw(screen, "+ NEW PLATFORM", basicfont.Face7x13, 20, CanvasHeight-18, color.RGBA{255, 255, 255, 255})
// Button Platform
btnPlatRect := image.Rect(10, CanvasHeight-70, WidthList-10, CanvasHeight-45)
vector.DrawFilledRect(screen, float32(btnPlatRect.Min.X), float32(btnPlatRect.Min.Y), float32(btnPlatRect.Dx()), float32(btnPlatRect.Dy()), ColHighlight, false)
text.Draw(screen, "+ NEW PLATFORM", basicfont.Face7x13, 20, CanvasHeight-53, color.RGBA{255, 255, 255, 255})
// Button Wall
btnWallRect := image.Rect(10, CanvasHeight-35, WidthList-10, CanvasHeight-10)
vector.DrawFilledRect(screen, float32(btnWallRect.Min.X), float32(btnWallRect.Min.Y), float32(btnWallRect.Dx()), float32(btnWallRect.Dy()), color.RGBA{100, 100, 120, 255}, false)
text.Draw(screen, "+ NEW WALL", basicfont.Face7x13, 35, CanvasHeight-18, color.RGBA{255, 255, 255, 255})
// SCROLL BEREICH
startY := 40.0 - e.listScroll
@@ -511,7 +599,7 @@ func (e *Editor) Draw(screen *ebiten.Image) {
// Helper Funktion zum Zeichnen von Listeneinträgen mit Bild
drawListItem := func(label string, id string, col color.Color, img *ebiten.Image) {
if currentY > -float64(LineHeight) && currentY < CanvasHeight-50 {
if currentY > -float64(LineHeight) && currentY < CanvasHeight-80 {
// Bild Vorschau (Thumbnail)
if img != nil {
// Skalierung berechnen (max 28px hoch/breit)