Страницы

Поиск по вопросам

воскресенье, 29 марта 2020 г.

Игра змейка, проблема реализации

#python #python_3x #разработка_игр


Начал писать консольную змейку, сталкивался с многими проблемами, но данную проблему
не могу пока что решить. Проблема в том, что как только игра начинается всё в порядке,
края правильно рисуются, но стоит взять фрукт так сразу происходит какая-то ахинея
и правая сторона уходит на несколько клеточек вправо.

import threading
import random
import os
from pynput import keyboard
from time import sleep


def draw():
    global score
    global fruitX
    global fruitY
    global snake

    os.system("clear")

    # top
    for i in range(0, width + 1):
        print("#", end='')
    print()

    # all mid
    for i in range(0, height):
        for j in range(0, width):
            if (j == 0) or (j == width - 1):
                print("#", end='')
            for k in snake:
                if (i == k[1]) and (j == k[0]):
                    print("G", end='')
                elif (i == fruit[0][1]) and (j == fruit[0][0]):
                    print('*', end='')
                else:
                    print(' ', end='')
        print()

    # bot
    for i in range(0, width + 1):
        print("#", end='')
    print()

    print(f"Total score: {score}")


def input():
    with keyboard.Listener(on_release=on_release) as listener:
        listener.join()


def on_release(key):
    global gameOver
    global snake

    ka = 0

    if key == keyboard.Key.esc:
        gameOver = True

    if key == keyboard.KeyCode.from_char('w'):
        for k in snake:
            snake[ka][1] -= 1
        ka += 1

    if key == keyboard.KeyCode.from_char('s'):
        for k in snake:
            snake[ka][1] += 1
        ka += 1

    if key == keyboard.KeyCode.from_char('d'):
        for k in snake:
            snake[ka][0] += 1
        ka += 1

    if key == keyboard.KeyCode.from_char('a'):
        for k in snake:
            snake[ka][0] -= 1
        ka += 1


def logic():
    global score
    global fruit
    global snake

    # Got a fruit
    if (snake[0][0] == fruit[0][0]) and (snake[0][1] == fruit[0][1]):
        score += 1
        snake.append([snake[0][0] - 1, snake[0][1]])
        fruit.pop()

    if len(fruit) == 0:
        fruit.append((random.randint(1, width - 1),
                      random.randint(1, height - 1)))


if __name__ == "__main__":
    gameOver = False
    width = 20
    height = 20

    snake = [[width / 2 - 1,
              height / 2 - 1]]

    fruit = [(random.randint(1, width - 1),
              random.randint(1, height - 1))]
    score = 0

    t_input = threading.Thread(target=input, name='InputThread')
    t_input.start()

    # Main game
    while not gameOver:
        sleep(0.1)
        draw()
        logic()


Можете не кидать готовый код, можно просто объяснить что не так. Если всё уж так
плохо, то подскажите что переучить заново, или попрактиковаться снова. Учился по книге
Билл Любанович "Простой Python"

    


Ответы

Ответ 1



но стоит взять фрукт так сразу происходит какая-то ахинея и правая сторона уходит на несколько клеточек вправо Смотрите, у вас когда рисуется змейка заодно рисуются фрукт и пустое пространство, что странно -- это ведь разные объекты. ... for k in snake: if (i == k[1]) and (j == k[0]): print("G", end='') elif (i == fruit[0][1]) and (j == fruit[0][0]): print('*', end='') else: print(' ', end='') ... Поэтому, когда змейка берет фрукт, у змеи становится два блока и тот цикл два раза прогоняется и получается в два раза больше пространства Решил другим подходом рисовать поле -- сначала составить матрицу, заполнить ее, а после отрисовать: import threading import random import os from pynput import keyboard from time import sleep def clear(): if os.name == 'posix': os.system('clear') else: os.system('cls') def draw(): global score global snake board = [] for _ in range(width): board.append([' ' for _ in range(height)]) # Top for i in range(width): board[0][i] = "#" # Left for i in range(height): board[i][0] = "#" # Right for i in range(height): board[i][width - 1] = "#" # All mid for i, j in snake: board[j][i] = 'G' for i, j in fruit: board[j][i] = '*' # Bottom for i in range(width): board[height - 1][i] = "#" clear() print() for row in board: print(''.join(row)) print(f"Total score: {score}") def keyboard_listener(): with keyboard.Listener(on_release=on_release) as listener: listener.join() def on_release(key): global gameOver global snake ka = 0 if key == keyboard.Key.esc: gameOver = True if key == keyboard.KeyCode.from_char('w') or key == keyboard.Key.up: for k in snake: snake[ka][1] -= 1 ka += 1 if key == keyboard.KeyCode.from_char('s') or key == keyboard.Key.down: for k in snake: snake[ka][1] += 1 ka += 1 if key == keyboard.KeyCode.from_char('d') or key == keyboard.Key.right: for k in snake: snake[ka][0] += 1 ka += 1 if key == keyboard.KeyCode.from_char('a') or key == keyboard.Key.left: for k in snake: snake[ka][0] -= 1 ka += 1 def logic(): global score global fruit global snake print(f'snake={snake} fruit={fruit}') # Got a fruit if snake[0][0] == fruit[0][0] and snake[0][1] == fruit[0][1]: score += 1 snake.append([snake[0][0] - 1, snake[0][1]]) fruit.pop() if not fruit: fruit.append((random.randint(1, width - 1), random.randint(1, height - 1))) if __name__ == "__main__": gameOver = False width = 20 height = 20 snake = [[width // 2 - 1, height // 2 - 1]] fruit = [(random.randint(1, width - 1), random.randint(1, height - 1))] score = 0 t_input = threading.Thread(target=keyboard_listener, name='InputThread') t_input.start() # Main game while not gameOver: draw() logic() sleep(0.1) PS. Вам нужно будет подумать как движение змейки организовать, пока только голова движется PPS Этот код с этим может выдать странный результат snake = [[width / 2 - 1, height / 2 - 1]] / -- это деление с остатком, после него будет вещественное число. Поэтому, нужно делить через //

Комментариев нет:

Отправить комментарий