Gra Snake potrzebna pomoc

0

Witam wszystkich mam taki problem chciałbym stworzyć kilka obiektów klasy cube tzw. przeszkód po których waz nie będzie mógł się poruszać bo się skuje i jeszcze pasowało by licznik zjedzonych jabłek proszę o pomoc :) już długo nad tym myślę szukam po forach i nic nie mogę wymyślić z góry dziękuje za wszelką pomoc

import pygame, sys,os
import random
import tkinter as tk
from tkinter import messagebox


class Cube(object):
    rows = 20
    def __init__(self, start, dirnx=1, dirny=0, color=(0,0,0)):
        self.pos = start
        self.dirnx = dirnx
        self.dirny = dirny
        self.color = color

    def move(self, dirnx, dirny):
        self.dirnx = dirnx
        self.dirny = dirny
        self.pos=(self.pos[0] + self.dirnx, self.pos[1] + self.dirny)


    def draw(self, surface, eyes=False):  # oczy węża na pierwszej kostce
        dis = size // rows # do rownej liczby
        rw = self.pos[0]
        cm = self.pos[1]

        pygame.draw.rect(surface, self.color, (rw * dis +1, cm * dis + 1, dis -2, dis -2))

        if eyes:
            # RYSOWANIE OCZU
            center = dis // 2
            radius = 3
            circle_middle = (rw * dis + center - radius, cm * dis + 8)
            circle_middle2 = (rw * dis + dis - radius * 2, cm * dis + 8)
            pygame.draw.circle(surface,(255,255,255), circle_middle, radius)
            pygame.draw.circle(surface, (255, 255,255), circle_middle2, radius)


class snake(object):

    body = []  #lista
    turns = {}  #słownik

    def __init__(self, color, pos):
        self.color = color
        self.head = Cube(pos)
        self.body.append(self.head)
        # na samym poczatku wąż porusza sie w prawo
        self.dirnx = 0
        self.dirny = 1

    def move(self):

        for event in pygame.event.get():
            # zamykanie gry X
            if event.type == pygame.QUIT:
                pygame.quit()



            keys = pygame.key.get_pressed()

            if keys[pygame.K_LEFT]:
                self.dirnx = -1
                self.dirny = 0
                # pozycja w trakcie nacisniecia klawisza i dodajemy do niech wartosc czyli kierunek gdzie nalezy skrecic
                self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]
            elif keys[pygame.K_RIGHT]:
                self.dirnx = 1
                self.dirny = 0
                self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]
            elif keys[pygame.K_UP]:
                self.dirnx = 0
                self.dirny = -1
                self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]
            elif keys[pygame.K_DOWN]:
                self.dirnx = 0
                self.dirny = 1
                self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]
        for i, c in enumerate(self.body):
            p = c.pos[:] # [:] kopiowanie tworzenie nowej a nie zmienianie
            if p in self.turns:
                turn = self.turns[p]
                c.move(turn[0], turn[1]) # ruszenie kostki
                # teraz tworzymy blokade dzieki ktorej po zmianie kierunku wąż nie będzie mogl ruszyć w tą samą strone
                if i== len(self.body) - 1:
                    self.turns.pop(p)
            else:
                #sprawdzanie w ktora strone sie przemieszcza wąż a potem przerzucamy węża na drugą strone ekranu przeciwną

                if c.dirnx == -1 and c.pos[0] <= 0:
                    c.pos = (c.rows - 1 , c.pos[1])
                elif c.dirnx == 1 and c.pos[0] >= c.rows - 1:
                    c.pos = (0, c.pos[1])
                elif c.dirny == 1 and c.pos[1] >= c.rows - 1:
                    c.pos = (c.pos[0],0)
                elif c.dirny == -1 and c.pos[1] <= 0:
                    c.pos = (c.pos[0], c.rows - 1)
                else:
                    c.move(c.dirnx, c.dirny)





    def reset(self):
        for i in range(2, len(self.body)):
            if self.head.pos[0] == self.body[i].pos[0] and self.head.pos[1] == self.body[i].pos[1]:
                tk.messagebox.showinfo(title="Game Over", message="Koniec Gry")
                pygame.quit()


    def eat(self):

        tail = self.body[-1]
        dx, dy = tail.dirnx, tail.dirny

        # sprawdzanie w ktora strone porusza se ostatni element węża i wtedy dodajemy kostke w pozycji ostatnia -1
        if dx ==1 and dy == 0:#prawo
            self.body.append(Cube((tail.pos[0] - 1, tail.pos[1])))

        elif dx ==-1 and dy == 0:#lewo
            self.body.append(Cube((tail.pos[0] + 1, tail.pos[1])))

        elif dx == 0 and dy == 1:#dół
            self.body.append(Cube((tail.pos[0], tail.pos[1] - 1)))

        elif dx == 0 and dy == -1:#góra
            self.body.append(Cube((tail.pos[0], tail.pos[1] + 1)))
        

        # ustalamy kierunek poruszania sie ostatniej kostki

        self.body[-1].dirnx = dx
        self.body[-1].dirny = dy


    def draw(self, surface):
        for i, c in enumerate(self.body):
            if i == 0:
                c.draw(surface, True)  # oczy
            else:
                c.draw(surface)


def draw_grid(w, rows, surface):

    #rysowanie lini aby powstala siatka
    size_between = w // rows    # dzielenie do rownej liczby
    x = 0
    y = 0
    for l in range(rows):
        x=x+size_between
        y=y+size_between
        pygame.draw.line(surface, (255,255,255), (x,0), (x,w))
        pygame.draw.line(surface, (255,255,255), (0,y), (w,y))



def draw_window(surface):
    surface.fill((0,255,0))
    s.draw(surface)
    draw_grid(size, rows, surface)
    apple.draw(surface) #jablko to jest wciaz kostka wiec mozemy ja rysowac
    pygame.display.update()


def random_apple(snake):
    positions = snake.body

    while True:

        x = random.randrange(rows)
        y = random.randrange(rows)
        #zwraca przefiltrowana liste ktora sprawdza czy ktoras z pozycji x lub y znajduje sie
        # w positions czyli tam gdzie znajduje sie cialo węża

        if len(list(filter(lambda z: z.pos == (x,y), positions))) > 0:
            continue
        else:
            break
    return (x,y)



def main():
    global size, rows, s, apple, pos, points
    size = 500  #plansza snake
    rows = 20
    pos = 20

    window = pygame.display.set_mode((size, size))

    s = snake((0,0,0), (10,10))
    apple = Cube(random_apple(s), color=(255,0,0))
    #jesli argument jest prawdziwy to gra działa
    flag = True
    clock = pygame.time.Clock()


    while flag:

        # spowolnienie gry
        pygame.time.delay(50)
        clock.tick(10)
        s.move()
        s.reset()

        if s.body[0].pos == apple.pos:
            s.eat()

            apple = Cube(random_apple(s), color=(255,0,0))
        draw_window(window)



main()
2

No to stwórz sobie kilka obiektów? Nikt ci nie broni. Dodatkowo jakąś zmienna, w której będziesz przechowywać ilość zjedzonych jabkek i kiedy wąż zje będziesz ją inkrementkwac.

1

Kiedyś sklepałem na kolanie snake w js'ie.

https://yourfrog.github.io/js-snake
https://github.com/YourFrog/js-snake/blob/main/src/snake.js

Za kod się nie wstydzę bo całość od pomysłu do zakończenia zajęła mi godzinę więc jakość kodu jaka jest taka jest. Może Ci się przyda?

Co do problemu z "przeszkodą" to robisz je tak samo jak zjadanie jabłek z tym że akcja kolizji jest inna. Jabłko podbija jakąś liczbę oraz usuwa obiekt z planszy, a "kolec" kończy rozgrywkę czyli przestawia jakiś stan gry.

0

@YourFrog2: jeszcze takie pytanko jak dodać do ekranu ten licznik stworzyłem zmienna points i inkrementuje ją elegancko ale nie wiem jak dodać do ekranu widoczność licznika

1 użytkowników online, w tym zalogowanych: 0, gości: 1