0

The cube is only moving once.

import time
import pygame

pygame.init()


class Window(object):
    def __init__(self, width, height, bg):
        self.width = width
        self.height = height
        self.bg = bg

    def create(self):
        return pygame.display.set_mode((self.width, self.height))

The problem is somewhere here

class Cube(object):
    def __init__(self, surface, x, y, width, height, color):
        self.surface = surface
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.color = color

    def move(self, lead_x_change=0, lead_y_change=0):
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                lead_x_change = -20
            elif event.key == pygame.K_RIGHT:
                lead_x_change = 20
            elif event.key == pygame.K_UP:
                lead_y_change = -20
            elif event.key == pygame.K_DOWN:
                lead_y_change = 20
        self.x += lead_x_change
        self.y += lead_y_change

    def draw(self):
        pygame.draw.rect(self.surface, self.color, (self.x, self.y, self.width, self.height))


window = Window(800, 600, (0, 0, 0))
surface = window.create()

head = Cube(surface, 400, 300, 20, 20, (255, 255, 255))

starting gameloop

gameloop = True
while gameloop:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()

        head.move()

        surface.fill((0, 0, 0))
        head.draw()
        pygame.display.update()

The Cube moves, but only one time after a keypress. it should continiously move in one direction though, after pressing the direction. I dont know how to make it move continiously, even watched ton of videos about it and still dont understand.

Yosuf
  • 3
  • 1
  • 2
  • Your keypress should set a flag or raise an event, and the rendering code that draws the movement should handle that event or read the flag and change direction. The rendering loop should just run continuously, moving in the last set direction. –  Jan 21 '19 at 16:44

3 Answers3

0

Maybe because when you are calling the method

head.move()

and have in the method parameters set lead changes to 0. and when it is called it's always 0.

Try changing

def move(self, lead_x_change=0, lead_y_change=0):

to

def move(self, lead_x_change, lead_y_change):

I'm not 100% sure this will work.

Let me know!

Jože Strožer
  • 663
  • 1
  • 6
  • 14
0

In the main loop, when you call pygame.event.get(), the program is waiting until a new event occurs. In pygame, only a new key press qualifies as an "event"; holding a key down will not continuously fire an "event".

Instead, you will need to call a different function. As per this question, pygame.key.get_pressed() is probably more what you are looking for. You will want to modify your main loop so it runs even when an event is not present, like so:

gameloop = True
while gameloop:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    # Note the next line is un-indented, so it executes anyway
    head.move()
    surface.fill((0, 0, 0))
    head.draw()
    pygame.display.update()

And also fix the move() method to be structured like:

keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
    lead_x_changed = -1    # Will move much faster now
elif keys[pygame.K_RIGHT]:
...
BradzTech
  • 2,755
  • 1
  • 16
  • 21
  • 1
    its better, but i want to press the key only once to let the snake move in a direction forever until i press another key. – Yosuf Jan 21 '19 at 17:43
0

Based on the comment that OP wants the movement to occur until another key is pressed, as opposed to whether a key is held down, there is an entirely separate solution involved. Instead, the code must be refactored to instead include a variable for the last direction that was pressed, and a timed loop to continuously move in that direction.

In the Cube's __init__ method, add:

self.lastDir = null

Make a new method in the Cube class for handling the key event:

def updateDir(self, event):
    if event.type == pygame.KEYDOWN and event.key in [pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN]:
        self.lastDir = event.key

Modify the move method to instead be based on self.lastDir instead of event.key:

if self.lastDir != null:
    if self.lastDir == pygame.K_LEFT:
        lead_x_change = -20
...

And finally, modify the main loop to call the move method on a regular basis, as opposed to waiting for a new move:

gameloop = True
while gameloop:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
        head.updateDir(event)
    head.move()
    surface.fill((0, 0, 0))
    head.draw()
    pygame.display.update()
    # Insert time.sleep(seconds) here if too fast
BradzTech
  • 2,755
  • 1
  • 16
  • 21