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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user