Domanda Problema pygame movimento player

Bynary01

Utente Silver
3 Ottobre 2016
57
32
0
73
Salve ragazzi, è la prima volta che mi approccio a pagane e sto cercando di implementare delle funzioni che mi mendano più comodo il lavoro, diciamo come un "mini Engine".
il problema è il seguente:
quando vado a chiamare il metodo insaziato nella mia classe Entity che dovrebbe servire a far muovere l'Entità, il movimento avviene ma lo Sprite viene ripetuto formando una linea continua diciamo, incollo il codice
Python:
import pygame

screen = pygame.display.set_mode((0, 0))
class Entity():
    def __init__(self, imagePath, pos):
        self.sprite = pygame.image.load(imagePath)
        self.X = pos[0]
        self.Y = pos[1]
        self.init_pos = (self.X, self.Y )

    def spawn(self):
        screen.blit(self.sprite, self.init_pos)

    def moove(self,event,velocity):
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                self.X += velocity
                screen.blit(self.sprite, (self.X,self.Y))

Python:
import pygame
from models import *

pygame.init()
screen = pygame.display.set_mode([800, 600])

run = True
tree = Entity('tree.png',[300, 300])

while run == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            r = False

    tree.moove(event, 1)
    tree.spawn()
    pygame.display.update()
Messaggio unito automaticamente:

ho dimenticato di aggiungere che per creare l'entità tree, il programma si va a cercare un file chiamato 'tree.png' nella root dir
 
Premetto che NON ho mai usato Pygame, ho creato un gioco 2D molto semplice in C++ e Java in passato..
Il problema che hai descritto lo avevamo anche noi quando non aggiornavamo correttamente il display (quindi scrivevamo la sprite nella posizione giusta, senza cancellare e riscrive l'area, quindi andavamo a sovrapporla).
Tu come stai gestendo la cosa al momento? (Cerchiamo in caso di trovare una soluzione ragionando, anche se non conosco la libreria)
E' l'unico aiuto che posso offrirti al momento

Inoltre ho trovato questo: https://opensource.com/article/17/12/game-python-moving-player
 
Premetto che NON ho mai usato Pygame, ho creato un gioco 2D molto semplice in C++ e Java in passato..
Il problema che hai descritto lo avevamo anche noi quando non aggiornavamo correttamente il display (quindi scrivevamo la sprite nella posizione giusta, senza cancellare e riscrive l'area, quindi andavamo a sovrapporla).
Tu come stai gestendo la cosa al momento? (Cerchiamo in caso di trovare una soluzione ragionando, anche se non conosco la libreria)
E' l'unico aiuto che posso offrirti al momento
ciao, innanzitutto ti ringrazio per la risposta, attualmente se leggi nel primo file, creo una classe chiamata Entity che inizializza un oggetto con uno Sprite e una posizione, nel metodo spawn della classe poi faccio "spawnare" l'entity che ho creato utilizzando screen.blit(Sprite, posizione), concretamente quello che fa è semplicemente mostrare a schermo lo Sprite nella posizione data.

il problema arriva quando tento di creare il metodo che dovrebbe far muovere l'entity:

creo un metodo che si chiama moove che prende in input l'evento (pressione della freccia destra) e una velocità, a questo punto non faccio altro che aggiungere la velocità alla coordinata X dell'entity ogni volta che si verifica l'evento ed utilizzo screen.blit( con le nuove coordinate.

spiegato a parole è molto più strano ma se provi a dare un occhiata al codice riesci a capire anche se non sai nulla di python.
il secondo pezzo di codice è effettivamente il 'game-loop'
 
Perfetto, il bug, nelle tue parole, e' presente: "a questo punto non faccio altro che aggiungere la velocità alla coordinata X dell'entity ogni volta che si verifica l'evento ed utilizzo screen.blit() con le nuove coordinate. "

Tu, come dcevo prima, stai scrivendo l'oggetto nella nuova posizione, ma non stai "ricreando" l'area (cancellandola e riscrivendola)

Generalmente quello che si fa e':
- avere una mappa logica
- ogni ciclo si cancella tutto il diplay e si ridisegna seguendo la mappa logica

- Quando possibile NON si cancella tutto il display, ma solo la porzione da aggiornare.

Come mai hai due screen?
 
va bene ti ringrazio, se dai un occhio al game-loop potrebbe trovarsi li l'errore dato che è quello che effettivamente "disegna la scena" e non è altro che una serie di chiamate a funzioni

comunque ho due screen perché nel file delle classi c'è bisogno dell'oggetto screen (che in quel caso inizializzo con dimensione (0,0) aleatoriamente) e poi ne cambio semplicemente le dimensioni quando lo vado effettivamente ad utilizzare nel main file
 
Ora diro' una cosa sulla quale ti consiglio di fare test, perche' non vorrei dir boiate:
immagino quelli siano due file, tu inizializzi due volte una variabile screen (con stesso nome), ma che assume valori diversi e fa riferimento a due variabili diverse.
Sicuro che lo screen del primo file sia lo stesso del secondo?
 
Come ha detto fisica-all, il problema è che non stai cancellando e ridisegnando, ma stai disegnando su uno schermo sporco. Non è pulitissima, ma prova a dare un'occhiata a sta roba:
Python:
import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))

def vecsum(a, b):
    return tuple(x + y for x,y in zip(a,b))

class Entity():
    def __init__(self, imagePath, position):
        self.sprite = pygame.image.load(imagePath)
        self.position = position
        self.direction = (0, 0)
    def draw(self):
        self.position = vecsum(self.position, self.direction)
        screen.blit(self.sprite, self.position)
    def move(self, event, speed):
        if event.type == pygame.KEYDOWN or event.type == pygame.KEYUP:
            if event.type == pygame.KEYUP: speed = -speed 
            if event.key == pygame.K_RIGHT: self.direction = vecsum(self.direction, (speed, 0))
            if event.key == pygame.K_LEFT:  self.direction = vecsum(self.direction, (-speed, 0))
            if event.key == pygame.K_UP:    self.direction = vecsum(self.direction, (0, -speed))
            if event.key == pygame.K_DOWN:  self.direction = vecsum(self.direction, (0, speed))

tree = Entity('tree.png', (300, 300))

run = True
while run: 
    # pulisci lo schermo (i.e., riempilo di bianco)
    screen.fill((255,255,255))          
    # gestisci gli eventi
    for event in pygame.event.get():
        if event.type == pygame.QUIT: run = False
        tree.move(event, 1)
    # disegna gli sprites
    tree.draw()                         
    # aggiorna lo schermo
    pygame.display.update()
 
  • Grazie
Reazioni: fisica-all