akgr1154
akgr1154

Reputation: 19

Pygame moving issues

When I use the move code in python pygame, it won't load the code when I run.

#right to repestic creatovrs



import pygame, random, time, sys, pyscroll, pytmx
from Bruh import *
from pygame.locals import *
from pytmx.util_pygame import load_pygame

pygame.init()
width, height = 800, 600
backgroundColor = 255,  0,  0
screen = pygame.display.set_mode((width, height))

blue = (0, 0, 255)
darkblue = (20, 20, 70)
white = (255, 255, 255)
lightwhite = (170, 170, 170)
skin = (236, 188, 180)
floorcolor = (229,164,14)
sun = (250,255,63) 


#the four numbers go x axis, y axis, width, and then height
def drawLevel1(window):
  img = pygame.image.load("Overlay.png")
  window.blit(img, (0, 0))
def drawLevel2(window):
  img2 = pygame.image.load("Overlay2.png")
  window.blit(img, (0, 0))     

pygame.key.set_repeat(100,100)

Character = Bruh(35, 367)

Bruh.draw(Character, screen)

drawLevel1(screen)
'''
while True:
      for event in pygame.event.get():
          if event.type==QUIT or (event.type==KEYUP and event.key==K_ESCAPE):
            pygame.quit()
            sys.exit()
          elif event.type==KEYDOWN:

            if event.key==K_DOWN: 
                Character.moveUp()

            elif event.key==K_UP:
                Character.moveDown()

            elif event.key==K_LEFT:
                Character.moveLeft()

            elif event.key==K_RIGHT:
                Character.moveRight()

for event in pygame.event.get():
  if event.type==QUIT or (event.type==KEYUP and event.key==K_ESCAPE):
    pygame.quit()
    sys.exit()
  if event.key==K_DOWN:
    Character.moveUp()
  if event.key==K_UP:
    Character.moveDown()
  if event.key==K_LEFT:
    Character.moveLeft()
  if event.key==K_RIGHT:
    Character.moveRight
either of these won't work for some reason. it just wont load the game once these are placed in the code
'''
pygame.display.update()

while (True):
    for event in pygame.event.get() :
         if ( event.type == pygame.QUIT or (event.type==pygame.KEYDOWN and event.key==pygame.K_ESCAPE)):
              pygame.quit(); 
              sys.exit();

and the code from bruh.py:

import pygame
from pygame.locals import *

class Bruh:
    def __init__(self, newX, newY):
        self.x = newX
        self.y = newY
        self.img = pygame.image.load("Bruh.png")
    def draw(self, window):
        window.blit(self.img, (self.x,self.y))
    def moveLeft(self):
        self.x = self.x - 5
    def moveRight(self):
      self.x = self.x + 5
    def moveUp(self):
        self.y = self.y + 5
    def moveDown(self):
        self.y = self.y - 5
    def getRec(self):
        myRec = self.img.get_rect()
        return (self.x, self.y, myRec[2], myRec[3])      

those are all the .py files, and they must be causing some issue. I don't get any error message, it just won't load when i press run. I can't figure out why. If anyone has some help that would be great

Upvotes: 1

Views: 280

Answers (1)

QuinnF
QuinnF

Reputation: 2149

I think pygame is a little less smart than you are expecting it to be. In your while loop, you are moving your character, but all you are doing when you are "moving" that character is updating a number on that object. You are not telling pygame that anything has changed and you are not re-drawing the screen. It's not smart enough to know to do that on its own. There are frameworks that will keep track of your values and try to update the display to stay synced with them (mostly for web development) but that's not how pygame works.

Instead, real-time videogames usually follow this pattern:

while running:
    handle_events()  # check which keys have been pressed
    loop()           # handle, physics, AI, logic, etc
    render()         # re-draw a new version of the screen based on the new state of the world

See this tutorial for more.

In your case, that might look like:

pygame.key.set_repeat(100, 100)
character = Bruh(35, 367)

while True:
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()
        elif event.type == KEYDOWN:
            if event.key == K_DOWN:
                character.moveUp()
            elif event.key == K_UP:
                character.moveDown()
            elif event.key == K_LEFT:
                character.moveLeft()
            elif event.key == K_RIGHT:
                character.moveRight()

    screen.fill((0, 0, 0))
    drawLevel1(screen)
    character.draw(screen)

    pygame.display.update()

Actually, though, that's not a great way to do things. The line pygame.key.set_repeat(100, 100) means that you will only get a KEYDOWN event every 100ms (10 times/sec). But, the while loop will run many many more times than that. This means that your character movement will only happen at 10FPS, but you will be burning the resources to run your game much faster.

Instead, I would do something like this:

# make a clock to help us run at a consistent framerate
clock = pygame.time.Clock()

# a dictionary to help us keep track of which keys are currently held down
keys_down = {
    K_DOWN: False,
    K_UP: False,
    K_LEFT: False,
    K_RIGHT: False,
}

while True:
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()
        elif event.type == KEYDOWN:
            # when the user presses a key, we keep track of the fact
            # that that key is down until they release it
            if event.key in keys_down:
                keys_down[event.key] = True
        elif event.type == KEYUP:
            # when the user releases a key, it's not down anymore
            if event.key in keys_down:
                keys_down[event.key] = False

    # This code will run *every loop*, regardless of
    # whether the user has pressed or released a key recently
    if keys_down[K_DOWN]:
        character.moveDown()
    if keys_down[K_UP]:
        character.moveUp()
    if keys_down[K_LEFT]:
        character.moveLeft()
    if keys_down[K_RIGHT]:
        character.moveRight()

    # Then, clear the screen and re-draw everything in the scene
    screen.fill((0, 0, 0))
    # drawLevel1(screen)
    character.draw(screen)
    pygame.display.update()

    # clock.tick gets the number of `ticks` (milliseconds) since the
    # last time it was called. If you specify a number like tick(30),
    # then it will also wait an amount of time equal to 30 minus that
    # number. Effectively it will limit you to 30fps.
    clock.tick(30)

Actually, even this isn't ideal. Really, you should run as fast as you can and update your game logic to take into account the framerate (i.e. move farther each frame if you are getting fewer fps) so your character always moves a consistent speed even if you get a dip in framerate. Even better, let your logic and rendering run asynchronously. This is getting into some advanced stuff, though.


Edit:

As @Kingsley pointed out, pygame has this functionality built in. The above example can by simplified like this:

import pygame
from pygame.locals import *

clock = pygame.time.Clock()

while True:
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()

    # This line handles all the KEYUP and KEYDOWN events
    # instead of doing it manually
    keys_down =  pygame.key.get_pressed()

    if keys_down[K_DOWN]:
        character.moveDown()
    if keys_down[K_UP]:
        character.moveUp()
    if keys_down[K_LEFT]:
        character.moveLeft()
    if keys_down[K_RIGHT]:
        character.moveRight()

    screen.fill((0, 0, 0))
    drawLevel1(screen)
    character.draw(screen)
    pygame.display.update()

    clock.tick(30)

Upvotes: 2

Related Questions