Можно ли переместить спрайт в Pygame? - PullRequest
0 голосов
/ 13 мая 2018

Я хочу использовать необработанный пользовательский ввод с терминала для перемещения спрайта с помощью pygame вместо использования прослушивателей ключевых событий. В конечном итоге я хочу иметь возможность контролировать спрайт с помощью команд выдачи терминала, таких как «двигаться вверх», «двигаться влево» и так далее. Я пытаюсь сделать приложение интерактивного терминала, которое создает окно Pygame при вводе команд в командной строке, чтобы вы могли видеть, как все работает. Это возможно? Вот что я пытался:

#!/usr/bin/env python3
# draw a world
# add a player and player control
# add player movement

# GNU All-Permissive License
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.  This file is offered as-is,
# without any warranty.

import pygame
import sys
import os
import time

'''
Objects
'''

class Player(pygame.sprite.Sprite):
    '''
    Spawn a player
    '''
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.movex = 0
        self.movey = 0
        self.frame = 0
        self.image = pygame.image.load(os.path.join('Images','character_sized.png'))
        self.rect  = self.image.get_rect()



    def control(self,x,y):
        '''
        control player movement
        '''
        self.movex += x
        self.movey += y

    def update(self):
        '''
        Update sprite position
        '''

        self.rect.x = self.rect.x + self.movex
        self.rect.y = self.rect.y + self.movey



'''
Setup
'''
worldx = 960
worldy = 720

fps = 40        # frame rate
ani = 4        # animation cycles
clock = pygame.time.Clock()
pygame.init()
main = True

BLUE  = (25,25,200)
BLACK = (23,23,23 )
WHITE = (254,254,254)
ALPHA = (0,255,0)

world = pygame.display.set_mode([worldx,worldy])
backdrop = pygame.image.load('Images/grass-pattern.png')
backdropbox = world.get_rect()
player = Player()   # spawn player
player.rect.x = 0
player.rect.y = 0
player_list = pygame.sprite.Group()
player_list.add(player)
steps = 10      # how fast to move
userInput = " "

'''
Main loop
'''
while main == True:
    userInput = raw_input(">>>")
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            pygame.quit(); sys.exit()
            main = False

        # Cuando aprietas la tecla
        if userInput == 'l':
            player.control(-steps,0)
            time.sleep(2)    # Esto es lo que hace que se mueva el character a la izquierda.
        if userInput == 'r':
            player.control(steps*2,0)   # Esto es lo que hace que se mueva el character a la derecha.
            time.sleep(2)
        if userInput == 'u':
            print('jump')
            time.sleep(2)

        # # Cuando levantas la tecla.
        # if event.key == pygame.K_LEFT or event.key == ord('a'):
        #     player.control(steps,0)

        # if event.key == pygame.K_RIGHT or event.key == ord('d'):
        #     player.control(-steps,0)
        # if event.key == ord('q'):
        #     pygame.quit()
        #     sys.exit()
        #     main = False

#    world.fill(BLACK)
    world.blit(backdrop, backdropbox)
    player.rect.clamp_ip(backdropbox)
    player.update()
    player_list.draw(world) #refresh player position
    pygame.display.flip()
    clock.tick(fps)

1 Ответ

0 голосов
/ 13 мая 2018

Модуль curses имеет метод getch, который вы можете использовать для этой цели.Пользователи Windows должны устанавливать проклятия.

Сначала введите stdscr.nodelay(1), чтобы метод getch не блокировал, затем используйте его в главном цикле while, чтобы получить нажатую клавишу и объединить ее со строковой переменной (здесь она называется command) и используйте stdscr.addstr для его отображения.

Когда пользователь нажимает ввод, проверьте, равна ли введенная команда 'move left' или 'move right', и переместите игровой объект в соответствующем направлении.

import curses
import pygame as pg


def main(stdscr):
    stdscr.nodelay(1)  # Makes the `getch` method non-blocking.
    # Use `addstr` instead of `print`.
    stdscr.addstr('Press "Esc" to exit...\n')
    command = ''  # Add the entered characters to this string.

    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    rect = pg.Rect(300, 100, 30, 50)

    while True:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                return

        inpt = stdscr.getch()  # Here we get the pressed key.
        if inpt == 27:  # Esc
            return
        elif inpt in (ord('\n'), ord('\r')):  # Enter pressed.
            # Check which command was entered and move the rect.
            if command == 'move right':
                rect.x += 20
            elif command == 'move left':
                rect.x -= 20
            command = ''  # Reset the command string.
            stdscr.addstr(2, 0, '{}\n'.format(command))  # Write in the second line.
        elif inpt == 8:  # Backspace
            command = command[:-1]
            stdscr.addstr(2, 0, '{}\n'.format(command))
        elif inpt not in (-1, 0):  # ValueErrors if inpt is -1 or 0.
            command += chr(inpt)  # Concatenate the strings.
            stdscr.addstr(2, 0, '{}\n'.format(command))

        screen.fill((30, 30, 30))
        pg.draw.rect(screen, (0, 120, 250), rect)
        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    # Use the curses.wrapper to start the program. It handles
    # exceptions and resets the terminal after the game ends.
    curses.wrapper(main)
    pg.quit()

Я неИмею большой опыт работы с проклятиями, поэтому нет гарантий, что все работает правильно.

Модуль msvcrt (Windows) также имеет функцию getch, и я думаю, что termios можно использовать для Linux и MacOS.Это кроссплатформенное решение, кажется, работает, но я никогда не проверял его: https://stackoverflow.com/a/510364/6220679

...