Im doing this game for school and it's supposed to be finished real soon and then of course al the problems start coming up, the game now crashes, sometimes after a few seconds and sometimes directly on start. Don't really know why, a thought is that its doing to much at the same time, or doing something it doesent need to do. The code is verry badly done, should use classes and functions but I have really goten in to that since im really new to this (first game im doing on my own). So please, if anyone could help I would appreciate it, give me tips on what to improve and if someone could fix my problem that would be great!

The pics will be attached to this post

import time
import pygame
from pygame.locals import*

pygame.init()
screenWidth = 1018
screenHeight = 720
screen = pygame.display.set_mode((screenWidth,screenHeight))
facingLeft = False
#Player

Player = pygame.image.load('GoodGuyFramPng.png')
PlayerRect = Player.get_rect()

#Boss
BossIm = pygame.image.load('Boss.png')
Boss = BossIm.get_rect()

#Shot for use later
#shotIm = pygame.image.load('Bullet.png')
#shot = shotIm.get_rect()


counter = 1
secondsPerFrame = 1.0/30
done = False
#Player var
x = 0
y = 0
vx = 0
vy = 0
g = 2

onGround = False
jumping = False
moving = False


#Boss var
bx = 560
by = 0
goingLeft = True
goingRight = False
bvx = 0
bvy = 0
radius = 10
BonGround = False
Bjumping = False


while not done:
    delayTime = time.clock()

    #Comands
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        #Shoot
        if event.type == KEYDOWN and event.key == K_LCTRL:
            print('shoot')
        #jump
        if event.type == KEYDOWN and event.key == K_SPACE and onGround:
            vy = -20
            onGround = False
            jumping = True
        if event.type == KEYUP and event.key == K_SPACE and not onGround and vy < 0:
            vy = 0
            jumping = False


    pressedKeys = pygame.key.get_pressed()
    #walk/run
    if pressedKeys[K_LEFT]:
        PlayerRect.x -= (4 + pressedKeys[K_LSHIFT] * 8)
        facingLeft = True
        moving = True
        Player = pygame.image.load('GubbeVanster.png')
        if PlayerRect.left < 0:
            PlayerRect.x += (4 + pressedKeys[K_LSHIFT] * 8)
    if pressedKeys[K_RIGHT]:
        PlayerRect.x += (4 + pressedKeys[K_LSHIFT] * 8)
        facingLeft = False
        moving = True
        Player = pygame.image.load('GubbeSidan.png')
        if PlayerRect.right > screenWidth:
            PlayerRect.right -= (4 + pressedKeys[K_LSHIFT] * 8)
    if event.type == KEYUP:
        if event.key == K_RIGHT or event.key == K_LEFT:
            moving = False

    if pressedKeys[K_ESCAPE]:
        done = True

    if not moving:
        Player = pygame.image.load('GoodGuyFramPng.png')

    #Physics

    PlayerRect.y += vy
    PlayerRect.x += vx

    vy = min(vy + g, 20)

    onGround = False

    #Check colition with floor
    if vy > 0 and PlayerRect.bottom >= screenHeight:
        if PlayerRect.bottom >= screenHeight and PlayerRect.bottom < screenHeight + vy:
            PlayerRect.bottom = screenHeight
            vy = 0
            onGround = True

    #--------Bossen------------------------------------------------------------

    #Walk
    if goingLeft:
        Boss.x -= 4
        if Boss.left <= 0:
            goingLeft = False
            goingRight = True
    if goingRight:
        Boss.x += 4
        if Boss.right >= screenWidth:
            goingRight = False
            goingLeft = True

    #Physics
    Boss.y += bvy
    Boss.x += bvx

    bvy = min(bvy + g, 20)

    BonGround = False

    #check colition with floor
    if bvy > 0 and Boss.bottom >= screenHeight:
        if Boss.bottom >= screenHeight and Boss.bottom < screenHeight + bvy:
            Boss.bottom = screenHeight
            bvy = 0
            BonGround = True
    #-----------------------------------------------------------------------
    jumping = jumping and vy < 0
    Bjumping = Bjumping and bvy < 0

    #draw stuff

    #Backgrund drawn once
    for i in range (1):     
        background = pygame.image.load('bakgrund.jpg')
        screen.blit(background, (0,0))      

    #Player
    screen.blit(BossIm,Boss)
    screen.blit(Player,PlayerRect)

    pygame.display.flip()

    counter += 1
    time.sleep(secondsPerFrame - (time.clock() - delayTime))

pygame.quit()   
Attachments GubbeSidan.png 6.09 KB bakgrund.jpg 69.69 KB GubbeVanster.png 6.07 KB GoodGuyFramPng.png 8.07 KB Boss.png 0.89 KB

What kind of errors do you get when the game crashes? I ran the game quite a few times and only got it to crash once. When it crashed for me it gave me an error that time.sleep() on line 159 had been passed an invalid argument.

As for improving the code, I think the biggest issues I saw are with variable names and conditionals (aside from the lack of functions/classe). The code would be easier to read if for instance "bvy" was named "boss_y_velocity".

With the conditionals, rather than testing a series of ifs you should probably use if/elif. Like line 116:

if goingLeft:
    [code]
if goingRight:
    [code]

would be better as:

if goingLeft:
    [code]
elif goingRight:
    [code]

That way python doesn't evaluate the elif statement if the first statement is True.

In a few places you use a nested conditionals where you could test all the conditions in one statement. Line 87:

if event.type == KEYUP:
    if event.key == K_RIGHT or event.key == K_LEFT:
        moving = False

would also work as:

if event.type == KEYUP and (event.key == K_RIGHT or event.key == K_LEFT):
    moving = False

Rather than the standard Python time methods, I would recommend using a PyGame Clock object, as the Clock.tick() method is specifically designed for this sort of thing.

I would also take the time out to re-write the code with classes. My own version of this now has a GameObject class and a Player class; I haven't gotten around to the Boss and Bullet classes, yet.

(Is it wrong of me to have completely refactored this program for my own edification?)

Comments
I changed to Clock.tick and now it doesent crash, thanks man
Clock.tick() is perfect for what's needed here.

Necrozze, I managed to get the game to reliably crash a few times. Rather than just telling you what I think the problem is, hopefully showing you how I got the info will help you in debugging future projects.

Everytime I could get the game to crash I got this output in the console:

  File "./necrozze.py", line 159, in <module>
    time.sleep(secondsPerFrame - (time.clock() - delayTime))
IOError: [Errno 22] Invalid argument

At this point, you want to find out what's being passed to time.sleep that's causing a problem. You can use Pythons exceptions to only print out the argument passed to sleep when it has a problem like this:

sleep_time = secondsPerFrame - (time.clock() - delayTime)

try:
    time.sleep(sleep_time)
except:
    print "Failed sleep time was: {}".format(sleep_time)
    pygame.quit()

The format function allows you to print the value of a variable inside a string.

When running the code with this change made, you'll end up getting output like this:

Failed sleep time was: -0.256666666667

A negative value passed to sleep is telling it to go backward in time. I'm really not sure why this is happening. You could use the abs() function, but it's likely that there's an underlying problem in the game's code that's causing the problem.

It may seem daunting, but I'd really recommend taking the time to refactor your code using a little more structure. Once you get using functions/classes I think you'll find that they really are no harder to write than code without. Tutorials Point has a really useful tutorial on Python functions. Their tutorial on Python classes makes it really clear how to create classes. Also, check out Pygame's Clock.tick() as Schol-R-LEA suggested, it's perfect for what you're currently using time.clock and time.sleep for.

I'd also recommend checking out Learn Python the Hard Way by Zed A. Shaw and Think Python by Allen B. Downey. They're both freely available to read and I think do a great job explaining Python.

Invent With Python has a couple freely available books on programming games using Python/Pygame. I haven't read all of the book, but it seems like a pretty good resource based on what I have read.

(Is it wrong of me to have completely refactored this program for my own edification?)

Not at all, though sharing your refactor with him wouldn't be cool as it's a homework assignment. I plan on refactoring it because I've yet to use Pygame and I need more practice working with other peoples' code.

Edited 3 Years Ago by chris.stout: Forgot links to free python books

For me it doesent give an error it just stops working, but I will make changes after what you guys just told me, I really appreciate the help and I will let you know if it works.

and feel free to take the code and do what you want with it :) it's only for a school project and Im the onlyone in my group of 5 that does the programming, the rest arent doing much, exept the one who drew the pictures.

So after changeing to clock.tick() it doesen't crash, so thanks for that. Have another question if you are interested.

at line 87 I have this to

    if not moving:
        Player = pygame.image.load('GoodGuyFramPng.png')

and at line 94

if event.type == KEYUP and (event.key == K_RIGHT or event.key == K_LEFT):
    moving = False

so this basicly makes the player face the screen when you arent moving, but the problem is if you are walking to the right and you press the left key to go to the left before you release the right. Then when you release the right key the character is facing the screen but walking to the left. It's not weird since the code is created that way, but I can't come up with a way to make it not do that. You have any sugestions on how to fix it?

One thing I would recommend also: you don't need to read the image files each time you want to change the image or BLIT it; you can save the images in variables and simply copy it to the current variable when you need to. In my version, I have it initialize the master cpoies at the time when the class is built, and then simply pass a reference to it to each of the individual objects, The relevant part of the Enemy class, for example, is

class Enemy(GameObject):
    front_src = "Boss.png"

    def __init__(self, screen):
        try:
            front = pygame.image.load(Enemy.front_src)
        except:
            print("Could not load enemy image")
            exit(-1)

The object in front is passed to the c'tor of the parent GameObject class, which stores it for later use. It uses a little more memory, but cuts down on the disk accesses, making the game more efficient. The Player class extends this with image_right and image_left members:

    def __init__(self, screen):
        try:
            front = pygame.image.load(Player.front_src)
        except:
            print("Could not load player front image")
            exit(-1)
        try:
            self.image_left = pygame.image.load(Player.left_src)
        except:
            print("Could not load player left image")
            exit(-1)
        try:
            self.image_right = pygame.image.load(Player.right_src)
        except:
            print("Could not load player right image")
            exit(-1)

        new_y = screen.get_rect().bottom - front.get_rect().top

        GameObject.__init__(self, screen, front, 0, new_y, 0, 0, False)

Even without using classes, you can simply have (for example) Player_front_img, Player_right_img and Player_left_img variables holding the image data, without having to read the file every time.

Edited 3 Years Ago by Schol-R-LEA

Comments
That's a really great tip actually, will deffinetly use it! Didn't think of it that way

putting images in variables was a great idé, and it worked perfectly without calsses, I will probably not make this game with classes cause I should be done with this project in like 2 - 3 weeks, so will focus on that it works first hand. But my next game I will deffinetly try working with classes

OK, though I would consider this: It only took me about four hours to re-write the code to use classes for the whole program, including the changes to the event handling and the movement. More importantly, I wrote the base class for all the game objects in about 20 minutes, and then extended that for the Player class in most of the rest of that time (that being the most complex of the classes). Once I had that, the Enemy class took about 10 minutes, because the majority of it was already present in the parent class.

I know it would take longer for you, since you aren't familiar with classes, but I assure you, they would end up saving you a lot of headaches, time, and effort.

Oh wow, the biggest problem I have with classes is that I can't really figure out what to put in wich class, but I guess that in my time frame I could probably learn that and get it working if it only tok you about four hours.

Edited 3 Years Ago by Necrozze: bad grammar

This question has already been answered. Start a new discussion instead.