0

I'm working on simple snake game in pygame. Issue I'm facing is when commented lines below are interchanged in Game class under play function. This lines suppose to draw snake (using for loop over array) and draw apple at certain location. As per my understanding order of this calls should not affect program in any way but when self.apple.draw() is called before self.snake.walk() suddenly apple images keeps wiping out of screen whenever it's coming back to main function after completing it's draw function. If I reverse order for this calls everything works. (Apology in advance if this is very basic question, but new to coding)

import pygame,time,random
from pygame.locals import *
SIZE=40

class Apple():
    def __init__(self,surface) -> None:
        self.parent_screen=surface
        self.image=pygame.image.load("resources/apple.jpg").convert()
        self.x=0
        self.y=0
    
    def draw(self):
        self.parent_screen.blit(self.image, (self.x, self.y))
    
    def move(self):
        self.x=random.randint(1,9)*SIZE
        self.y=random.randint(1,9)*SIZE

class Snake():
    def __init__(self,surface,length) -> None:
        self.parent_screen=surface
        self.block=pygame.image.load("resources/block.jpg").convert()   #size of block is 40*40
        self.x,self.y=0,0
        self.direction="down" 
        self.length=length
        self.x=[40]*length
        self.y=[40]*length

    def move_left(self):
        self.direction="left"
    
    def move_right(self):
        self.direction="right"
    
    def move_up(self):
        self.direction="up"
    
    def move_down(self):
        self.direction="down"
    
    def walk(self):
        for i in range(self.length-1,0,-1):
            self.x[i]=self.x[i-1]
            self.y[i]=self.y[i-1]

        if self.direction=="left":
            self.x[0]-=SIZE
        if self.direction=="right":
            self.x[0]+=SIZE
        if self.direction=="up":
            self.y[0]-=SIZE
        if self.direction=="down":
            self.y[0]+=SIZE
        self.draw()

    def draw(self):
        self.parent_screen.fill((110, 110, 5))
        for i in range(self.length):
            self.parent_screen.blit(self.block, (self.x[i], self.y[i]))
    
    def increase_length(self):
        self.length += 1
        self.x.append(-1)
        self.y.append(-1)

class Game():
    def __init__(self) -> None:
        pygame.init()
        self.surface=pygame.display.set_mode((400,400))
        self.snake=Snake(self.surface,5)
        self.apple=Apple(self.surface)
    
    def is_collision(self,x1,y1,x2,y2):
        if (x1==x2 and y1==y2):
            return True
        return False

    def display_score(self):
        font = pygame.font.SysFont('arial',30)
        score = font.render(f"Score: {self.snake.length}",True,(200,200,200))
        self.surface.blit(score,(100,100))
        pygame.display.flip()


    def play(self):
        self.snake.walk()       #This is the first line
        self.apple.draw()       #This is the second line
        pygame.display.flip()
        

        if self.is_collision(self.snake.x[0],self.snake.y[0],self.apple.x,self.apple.y):
            self.snake.increase_length()
            self.apple.move()

        for i in range(2, self.snake.length):
            if self.is_collision(self.snake.x[0], self.snake.y[0], self.snake.x[i], self.snake.y[i]):
                return False
        
        return True

    def run(self):
        running =True

        while running:
            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        running = False
                    if event.key == K_LEFT:
                        self.snake.move_left()

                    if event.key == K_RIGHT:
                        self.snake.move_right()

                    if event.key == K_UP:
                        self.snake.move_up()

                    if event.key == K_DOWN:
                        self.snake.move_down()

            if self.play()==False:
                break
            else:
                time.sleep(.5)
        self.display_score()
        #time.sleep(5)
if __name__=="__main__":
    game=Game()
    game.run()

1 Answer 1

1

You must clear the screen before drawing any object, but not in the draw method of an object:

class Snake():
    # [...]

    def draw(self):

        # self.parent_screen.fill((110, 110, 5))   <--- DELETE

        for i in range(self.length):
            self.parent_screen.blit(self.block, (self.x[i], self.y[i]))
class Game():
    # [...]

    def play(self):
        
        self.surface.fill((110, 110, 5))         # <-- INSERT

        self.apple.draw()
        self.snake.walk()
        pygame.display.flip()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.