Mały i pokręcony pomysł czyli kolejna gierka

(Z Wikipedii) "wieloparadygmatowy język programowania opracowany przez pracowników firmy Google: Roberta Griesemera, Roba Pike'a oraz Kena Thompsona. Łączy w sobie łatwość pisania aplikacji charakterystyczną dla języków dynamicznych (np. Python, Lisp), jak również wydajność języków kompilowanych (np. C, C++)."
ODPOWIEDZ
Awatar użytkownika
SunRiver
Użytkownik
Posty: 1343
Rejestracja: 08 paź 2017, 11:27
Lokalizacja: Festung Oppeln
Kontakt:

Mały i pokręcony pomysł czyli kolejna gierka

Post autor: SunRiver »

Tak kolejna mała gierka O nazwie Sun-Tower
na razie szkielet z uruchomioną mechaniką
Tym razem wszystko na GIT https://github.com/SunDUINO/Sun-Tower-Game
chciałbym w tym temacie poruszać ew dodatki do kodu i usprawnienia
jak również znaleźć chętnych do współtworzenia tej gierki ..
Awatar użytkownika
SunRiver
Użytkownik
Posty: 1343
Rejestracja: 08 paź 2017, 11:27
Lokalizacja: Festung Oppeln
Kontakt:

Re: Mały i pokręcony pomysł czyli kolejna gierka

Post autor: SunRiver »

Dodałem kilka poprawek do kodu.
--- poprawiłem detekcję kolizji
--- poprawiłem rysowanie bloków
--- dodałem cienie
--- teraz widać kolor kuli gotowej do rzutu
--- w rogu widać następny kolor kuli

-- sterowanie bez zmian --- obracanie wieży strzałkami
-- strzał i celowanie myszka LMB

---------- poza githubem gdzie będą się pojawiać moje poprawki i może innych chętnych kod v0.1.2 wrzucam też na forum ------------
  1.  
  2. // -----------------------------------------------------------------------------
  3. //
  4. // -- Sun-Tower Game (2025)
  5. // -- SunRiver https://forum.lothar-team.pl,
  6. // -- https://github.com/SunDUINO/Sun-Tower-Game
  7. // -- wersja 0.1.2
  8. // -- Obracanie wieży   kursory lewo /prawo
  9. // -- celowanie i strzał kulą myszka + LMB
  10.  
  11. package main
  12.  
  13. import (
  14.     "fmt"
  15.     "image/color"
  16.     "math"
  17.     "math/rand"
  18.     "time"
  19.  
  20.     "github.com/hajimehoshi/ebiten/v2"
  21.     "github.com/hajimehoshi/ebiten/v2/ebitenutil"
  22. )
  23.  
  24. type Game struct {
  25.     state     string
  26.     angle     float64
  27.     tower     []Block
  28.     ball      Ball
  29.     nextBall  Ball // Nowa kula na górze ekranu
  30.     ballsLeft int
  31.     score     int
  32. }
  33.  
  34. type Block struct {
  35.     angle, y float64
  36.     color    int
  37.     active   bool
  38. }
  39.  
  40. type Ball struct {
  41.     x, y, vx, vy, radius float64
  42.     color                int
  43.     active               bool
  44. }
  45.  
  46. const (
  47.     Width       = 800
  48.     Height      = 600
  49.     centerX     = Width / 2
  50.     baseY       = Height - 200
  51.     radius      = 100
  52.     numFloors   = 11
  53.     numColumns  = 12
  54.     totalBlocks = numFloors * numColumns
  55.     ballSpeed   = 5
  56.     ballStartY  = Height - 50
  57. )
  58.  
  59. func (g *Game) Update() error {
  60.     if g.state == "title" {
  61.         if ebiten.IsKeyPressed(ebiten.KeySpace) {
  62.             g.startGame()
  63.         }
  64.     } else if g.state == "playing" {
  65.         if ebiten.IsKeyPressed(ebiten.KeyLeft) {
  66.             g.angle -= 0.05
  67.         }
  68.         if ebiten.IsKeyPressed(ebiten.KeyRight) {
  69.             g.angle += 0.05
  70.         }
  71.         if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) && g.ballsLeft > 0 && !g.ball.active {
  72.             g.throwBall()
  73.         }
  74.         g.updateBall()
  75.         g.checkCollisions() // Dodanie sprawdzania kolizji
  76.     }
  77.     return nil
  78. }
  79.  
  80. func (g *Game) Draw(screen *ebiten.Image) {
  81.     if g.state == "title" {
  82.         ebitenutil.DebugPrint(screen, "Sun Tower\nPress SPACE to Start")
  83.     } else if g.state == "playing" {
  84.         // Rysowanie bloków z cieniowaniem
  85.         for _, block := range g.tower {
  86.             if block.active {
  87.                 x := centerX + radius*math.Cos(block.angle+g.angle)
  88.                 y := block.y
  89.                 blockImg := ebiten.NewImage(40, 40)
  90.                 blockImg.Fill(getColor(block.color))
  91.                 opt := &ebiten.DrawImageOptions{}
  92.                 opt.GeoM.Translate(x, y)
  93.                 // Dodanie efektu cienia (proste 3D)
  94.                 shadow := ebiten.NewImage(45, 45)
  95.                 shadow.Fill(color.RGBA{0, 0, 0, 100})
  96.                 shadowOpt := &ebiten.DrawImageOptions{}
  97.                 shadowOpt.GeoM.Translate(x+2, y+2)
  98.                 screen.DrawImage(shadow, shadowOpt)
  99.                 screen.DrawImage(blockImg, opt)
  100.             }
  101.         }
  102.  
  103.         // Rysowanie aktywnej kuli
  104.         if g.ball.active {
  105.             g.drawBall(screen, g.ball)
  106.         }
  107.         // Rysowanie następnej kuli na górze ekranu
  108.         g.drawBall(screen, g.nextBall)
  109.         // Rysowanie kuli gotowej do strzału na dole ekranu
  110.         g.drawBall(screen, Ball{x: float64(centerX), y: ballStartY, radius: g.ball.radius, color: g.ball.color, active: true})
  111.         ebitenutil.DebugPrint(screen, fmt.Sprintf("Score: %d\nBalls Left: %d", g.score, g.ballsLeft))
  112.     }
  113. }
  114.  
  115. func (g *Game) throwBall() {
  116.     g.ball = g.nextBall
  117.     g.ball.x = float64(centerX)
  118.     g.ball.y = ballStartY
  119.     mouseX, mouseY := ebiten.CursorPosition()
  120.     dx := float64(mouseX - centerX)
  121.     dy := float64(mouseY - ballStartY)
  122.     dist := math.Hypot(dx, dy)
  123.     g.ball.vx = (dx / dist) * ballSpeed
  124.     g.ball.vy = (dy / dist) * ballSpeed
  125.     g.ball.active = true
  126.     g.ballsLeft--
  127.     g.nextBall = generateRandomBall()
  128. }
  129.  
  130. func (g *Game) drawBall(screen *ebiten.Image, ball Ball) {
  131.     if ball.active {
  132.         ballImg := ebiten.NewImage(int(ball.radius*2), int(ball.radius*2))
  133.         ballImg.Fill(getColor(ball.color))
  134.         opt := &ebiten.DrawImageOptions{}
  135.         opt.GeoM.Translate(ball.x-ball.radius, ball.y-ball.radius)
  136.         screen.DrawImage(ballImg, opt)
  137.     }
  138. }
  139.  
  140. func (g *Game) updateBall() {
  141.     if g.ball.active {
  142.         g.ball.x += g.ball.vx
  143.         g.ball.y += g.ball.vy
  144.         if g.ball.y < 0 {
  145.             g.ball.active = false
  146.         }
  147.     }
  148. }
  149.  
  150. func (g *Game) startGame() {
  151.     g.state = "playing"
  152.     g.ballsLeft = 16
  153.     g.score = 0
  154.     g.tower = generateTower()
  155.     g.ball = Ball{radius: randFloat(8, 15)}
  156.     g.nextBall = generateRandomBall()
  157. }
  158.  
  159. func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
  160.     return Width, Height
  161. }
  162.  
  163. func randFloat(min, max float64) float64 {
  164.     return min + rand.Float64()*(max-min)
  165. }
  166.  
  167. func generateRandomBall() Ball {
  168.     return Ball{
  169.         radius: randFloat(8, 15),
  170.         color:  rand.Intn(4),
  171.         active: true,
  172.     }
  173. }
  174.  
  175. // -- stara funkcja -------------------------------
  176. func generateTower() []Block {
  177.     rand.Seed(time.Now().UnixNano())
  178.     tower := make([]Block, totalBlocks)
  179.     for floor := 0; floor < numFloors; floor++ {
  180.         for col := 0; col < numColumns; col++ {
  181.             angle := (2 * math.Pi / float64(numColumns)) * float64(col)
  182.             tower[floor*numColumns+col] = Block{
  183.                 angle:  angle,
  184.                 y:      float64(baseY - floor*30),
  185.                 color:  rand.Intn(4),
  186.                 active: true,
  187.             }
  188.         }
  189.     }
  190.     return tower
  191. }
  192.  
  193. // Sprawdzanie kolizji kuli z blokami
  194. /*
  195. func (g *Game) checkCollisions() {
  196.     for i := range g.tower {
  197.         block := &g.tower[i]
  198.         if block.active && g.ball.active {
  199.             // Sprawdzamy, czy kula zderza się z blokiem
  200.             x := centerX + radius*math.Cos(block.angle+g.angle)
  201.             y := block.y
  202.  
  203.             // Sprawdzamy kolizję na prostokątnym bloku
  204.             if g.ball.x+g.ball.radius > x && g.ball.x-g.ball.radius < x+30 &&
  205.                 g.ball.y+g.ball.radius > y && g.ball.y-g.ball.radius < y+30 {
  206.                 block.active = false  // Zniszczenie bloku
  207.                 g.score++             // Zwiększenie wyniku
  208.                 g.ball.active = false // Kula przestaje istnieć
  209.             }
  210.         }
  211.     }
  212. }
  213. */
  214. // ---- Poprawiona kolizja ....
  215. func (g *Game) checkCollisions() {
  216.     for i := range g.tower {
  217.         block := &g.tower[i]
  218.         if block.active && g.ball.active {
  219.             // Sprawdzamy, czy kula zderza się z blokiem
  220.             x := centerX + radius*math.Cos(block.angle+g.angle)
  221.             y := block.y
  222.  
  223.             // Sprawdzamy kolizję na prostokątnym bloku
  224.             if g.ball.x+g.ball.radius > x && g.ball.x-g.ball.radius < x+30 &&
  225.                 g.ball.y+g.ball.radius > y && g.ball.y-g.ball.radius < y+30 {
  226.                 block.active = false  // Zniszczenie bloku
  227.                 g.score++             // Zwiększenie wyniku
  228.                 g.ball.active = false // Kula przestaje istnieć
  229.  
  230.                 // Sprawdzanie innych bloków w tym samym kolorze
  231.                 for j := range g.tower {
  232.                     otherBlock := &g.tower[j]
  233.                     if otherBlock.active && block.color == otherBlock.color {
  234.                         // Obliczanie odległości między blokami
  235.                         otherX := centerX + radius*math.Cos(otherBlock.angle+g.angle)
  236.                         otherY := otherBlock.y
  237.  
  238.                         // Sprawdzamy, czy blok znajduje się blisko
  239.                         if math.Hypot(otherX-x, otherY-y) < 50 { // Możesz dostosować 50 do odpowiedniej odległości
  240.                             otherBlock.active = false // Zniszczenie tego bloku
  241.                             g.score++                 // Zwiększenie wyniku
  242.                         }
  243.                     }
  244.                 }
  245.             }
  246.         }
  247.     }
  248. }
  249.  
  250. func getColor(index int) color.Color {
  251.     switch index {
  252.     case 0:
  253.         return color.RGBA{255, 0, 0, 255} // Czerwony
  254.     case 1:
  255.         return color.RGBA{0, 255, 0, 255} // Zielony
  256.     case 2:
  257.         return color.RGBA{0, 0, 255, 255} // Niebieski
  258.     case 3:
  259.         return color.RGBA{255, 255, 0, 255} // Żółty
  260.     default:
  261.         return color.Black
  262.     }
  263. }
  264.  
  265. func main() {
  266.     game := &Game{state: "title"}
  267.     if err := ebiten.RunGame(game); err != nil {
  268.         panic(err)
  269.     }
  270. }
  271.  
  272.  
ODPOWIEDZ

Wróć do „GoLang”