Python Forum
[PyGame] sound effect delay and program laggy
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] sound effect delay and program laggy
#11
This breaks the snake from getting larger but it is more of an illustration of using clock and time....not time delay more than anything else. Notice the FPS is at 60 and you can slow it down just be changing a single number. You can speed up the snake by reducing the delay, or slow it down by increasing the delay

import random
import pygame
pygame.init()
 
screenWidth=500
screenHeight=500
 
mainWindow=pygame.display.set_mode((screenWidth,screenHeight))
pygame.display.set_caption("Snake")
 
x=250
y=250
snakeSize=50
move="down"
length=0
path=[]
clock = pygame.time.Clock()
run=True

 
def frandxy():
    global posx
    global posy
    posx=snakeSize*(random.randint(0,screenWidth/snakeSize-1))
    posy=snakeSize*(random.randint(0,screenWidth/snakeSize-1))
    if (posx,posy) in path or x==posx and y==posy:
            frandxy()
         
def game():
    global run
    global x
    global y
    global move
    global length
    global path
    
    global clock
    timer = 0.0
    delay = 175
    
    while run:
         
        #pygame.time.delay(200)
         
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                closeGame()
 
        key=pygame.key.get_pressed()
        if key[pygame.K_UP] and move != "down":
            move="up"
        if key[pygame.K_DOWN] and move != "UP":
            move="down"
        if key[pygame.K_RIGHT] and move != "left":
            move="right"
        if key[pygame.K_LEFT] and move != "right":
            move="left"
 
        path.insert(0,(x,y))
        
        if pygame.time.get_ticks()-timer > delay:
            timer = pygame.time.get_ticks()
            #move snake
            if move=="down" and y<=screenHeight-snakeSize:
                y+=snakeSize
            if move=="down" and y>=screenHeight:
                y=0
            if move=="up" and y>=0:
                y-=snakeSize
            if move=="up" and y<0:
                y=screenHeight-snakeSize
            if move=="right" and x<=screenWidth-snakeSize:
                x+=snakeSize
            if move=="right" and x>=screenWidth:
                x=0
            if move=="left" and x>=0:
                x-=snakeSize
            if move=="left" and x<0:
                x=screenWidth-snakeSize

            if x==posx and y==posy:
                length+=1
                frandxy()
            if (x,y) in path:
                #loseGame()
                print("You lose. Your length was", length)
                pygame.quit()
                break
            if length>=100:
                print("You won! The snake filled up the whole screen!")
                pygame.quit()
                break

        mainWindow.fill((0,0,0))
        #draw snake
        if length>0:
            for i in range(length):
                pygame.draw.rect(mainWindow, (0,255,0),(path[i][0],path[i][1], snakeSize,snakeSize))
        pygame.draw.rect(mainWindow, (0,255,0),(x, y, snakeSize, snakeSize))
        #draw food
        pygame.draw.rect(mainWindow, (255,0,0),(posx,posy, snakeSize, snakeSize))
        if len(path)>length:
            path=path[:(length)]
        clock.tick(60)
        pygame.display.update()
frandxy()
game()
I dont have much time today other than that.
Recommended Tutorials:
#12
Is there really anyway I can keep my program from running insanely fast without messing up other things? Right now I'm really thinking of taking my professor's advice and just abandoning python and learning Java instead. It seems python is just too limiting and glitchy. And I'm getting sick of using functions whose actual workings I have to figure out through trial and error. As for my sound generator, it does weird things to the sounds when I change the duration and I have no clue why, because I don't know how the equations of these scipy functions actually work, and I have no way of seeing them. What I want is the source code of the things I'm using. Honestly, I would be just programming everything in assembly language if I could.
#13
(Sep-28-2019, 12:17 AM)xBlackHeartx Wrote: Is there really anyway I can keep my program from running insanely fast without messing up other things?
If all your code is based off of frames per second, and you change the FPS...everything is going to have to be re-modified to adjust to the change. Its just a part of programming. You made your code wrong basically. And all animation has to be readjusted to the change. You should of started your program at 60 FPS, but instead made all calculations based on it being 7. I will leave that to you since you didnt use classes and are using nested loops for games states which conflicts with my programming structure.

To be honest, your code is quite spaghetti anyways. It wouldn't hurt to rewrite the code a few more times to better understand organization. 250 lines is not that much. Imagine if you wrote a game in spaghetti code at 20,000 lines and had to rewrite it. Thats why I push for people to write good code no matter how short it is. You can write spaghetti code in any language. You can create bottlenecks as well in any language. Learning structure in any language is persistent across all languages. I write my c++ games the same way as i write my python games....i just hate writing code in c++ as it takes too long.

Said functions have documentation. The point of creating those libraries is to not have to re-invent the wheel. That is a lot about Python in general. Why create a new library when one is already created for you for the same purpose? You just have to learn how to use that library. Which is much less time that it would be to create your own. OF course you are free to do that if you want of course. But Python users are prone to use an existing library if one is available.

Like i said for the scipy thing, you are probably going to have to ask them directly. I have never made a sound generator, nor have ever even used scipy module so i know nothing about it.

(Sep-28-2019, 12:17 AM)xBlackHeartx Wrote: It seems python is just too limiting and glitchy.
Python is not glitchy. Python and Pygame can handle a 2D game. It is how you structure your code. A lot of people dis Python for being slow....but most of the time it is because of bad coding. The only time it truly is too slow is if you are creating a graphics driver or something in which you really need to be low level.

(Sep-28-2019, 12:17 AM)xBlackHeartx Wrote: What I want is the source code of the things I'm using
The documentation will explain how to use it better than seeing the source code. But if you insist on seeing the source code of scipy you can look at it. The path defers based on what operating system your on and python version of course. This is linux. The path on Windows would be the same under site-packages for the installed python version of scipy.
metulburr@ubuntu:/usr/local/lib/python3.6/site-packages/scipy$ ls
_build_utils          HACKING.rst.txt  LICENSE.txt  __pycache__  stats
cluster               __init__.py      linalg       setup.py     THANKS.txt
__config__.py         INSTALL.rst.txt  linalg.pxd   signal       version.py
conftest.py           integrate        misc         sparse
constants             interpolate      ndimage      spatial
_distributor_init.py  io               odr          special
fftpack               _lib             optimize     special.pxd
Recommended Tutorials:
#14
I actually didn't plan to limit it when I started, I only did so when I first started testing it out and found it ran too fast. And what was when all I had was a green square moving across the screen. Speaking of which, I decided to up the fps to 60 just to see what would happen; it was quite amusing to watch.

And I have heard that python has a reputation for taking up more processing power than an equivalent program written in something lower-level like c++. Though part of that is compiling errors brought about by the conveniences of the language, such as not having to tell the program where it begins and ends. And yes, I also found it annoying how much typing you had to do, and I took it in the same semester I took c++ (and yes, I got the two languages mixed up at one point).

And honestly, I don't see how my code is 'spaghetti code', if anything, that class-based example you linked to looks like spaghetti to me.

My code doesn't look that elaborate if you map it out. First, there's the start menu, which leads into the game. The game has two possible exits: a victory and a loss screen. Each one of these leads into another screen asking to play again. There's actually only one; the background color changes depending on whether you won or lost. Though come to think of it, I could possibly condense the victory and loss screens into one the same way. The last loop is the one that places the food onto the screen. Its a do-while loop, and only runs when you start up a game and when the snake eats food. You'll notice I run that function right before the game() loop in every place it appears.

And I'm not planning on becoming a professional programmer, so why does it matter if my code doesn't follow standard? Its not like pygame is used by professional companies anyway. Besides, my professor claimed its common for free-lance programmers to intentionally make spaghetti code to make sure that their employers won't hire a rival programmer if they need more work done on it.

And other than my lag issue, my program runs fine and I do play it regularly. The only glitches I've found were the program placing the food directly on the snake, and being able to move down when moving up (I accidentally set the line that checks for that to see if the movement was set to 'Up' rather than 'up'). And why would using classes speed it up anyway? And I can't even begin to imagine how to make this game using classes. Now, I have made custom classes and used them (even if they are rather ineptly designed, such as requiring over a dozen parameters), but I can't figure out how to use classes for this program.

Concerning this 'classes' thing, honestly I can't understand how they actually work. I know functions are loaded into separate places in RAM from the main program, allowing the computer to switch between them by just changing the memory location its reading. But what's a class doing? What's actually going on inside the machine? And yes, I do have some understanding how computers work. I know that strings are actually arrays, and that graphics and sound work by inserting data directly into reserved ram chips, which causes a chain reaction that results in the appropriate output. Honestly, I do wish at times that I could directly insert data in memory locations like that. Oh, and I watch the 8-bit guy all the time. I actually figured out a way to draw sprites without the .blit command by watching a video he uploaded talking about how computers used to draw sprites. My code was directly inspired by how it used to be done, though mine allows each individual pixel to have its own color. Before my eureka moment, I was actually focusing on figuring out how to make an art program before I continued figuring out more games, but I quickly realized that such a program would be far more advanced than what I was planning to start with. Looking at my to-do list, I was apparently planning on making a space invaders clone next, which I still haven't gotten around to doing (still figuring out how to do it, right now I'm trying to figure out how to make destructible barriers).
#15
(Sep-28-2019, 04:56 AM)xBlackHeartx Wrote: if anything, that class-based example you linked to looks like spaghetti to me.
Using nested loops to make states is what makes it spaghetti the worst. For example when you are looking for draw methods, you have to look in every loop. Same for logic. So code is all over the entire source file instead of being contained in one area. It makes it hard to find related code.
(Sep-28-2019, 04:56 AM)xBlackHeartx Wrote: And I'm not planning on becoming a professional programmer, so why does it matter if my code doesn't follow standard?
One reason is because it makes it that much hard to help. Aside from being organized
for your own sake.

(Sep-28-2019, 04:56 AM)xBlackHeartx Wrote: Besides, my professor claimed its common for free-lance programmers to intentionally make spaghetti code to make sure that their employers won't hire a rival programmer if they need more work done on it.
Python strives to make code readable. Making spaghetti code is not ideal in any situation because you yourself might not understand it if your are making it hard for someone else to. Especially if you come back to the code at a later date. Why make everything spaghetti then? If your boss instructs you to make it spaghetti, then whatever...its their code. But why make your code a constant spaghetti mess?
(Sep-28-2019, 04:56 AM)xBlackHeartx Wrote: And other than my lag issue, my program runs fine and I do play it regularly.
Spaghetti code can run perfectly fine. But it also can easily hide hard to diagnose bugs and bottlenecks.

(Sep-28-2019, 04:56 AM)xBlackHeartx Wrote: And why would using classes speed it up anyway?
I didnt use classes to speed up your game. I used pygame time ticks on your existing code without creating classes.

(Sep-28-2019, 04:56 AM)xBlackHeartx Wrote: And I can't even begin to imagine how to make this game using classes. Now, I have made custom classes and used them (even if they are rather ineptly designed, such as requiring over a dozen parameters)
If you need a dozen parameters for a class, then you are most likely building it wrong. That is one benefit to using classes is the reduction of parameters all over the code.

A Space Invaders is a good example that would use classes. Each invader would be the result of a single class creating numerous objects. A modified invader can be made by inheriting from that class to make a new class with a slight variation of logic or data. Since classes are a collection of logic and data, anytime you want to view your code of anything relating to the invaders, you simply look in the class. My eureka moment in OOP was when i was forced to use classes. Before that i thought the same, that classes made it more complex. In reality they simplify it.
Recommended Tutorials:
#16
How is my code 'all over the place'? Its grouped by the screen its associated with! There's the start screen, the main game screen (where most of the code is), then the loss, victory, and playAgain screens. The whole structure of my program is this:

start()
game()
loss()
playAgain()
win()
playAgain()

Of course, bc my functions all call each other, I have to declare them in reverse order, which let's honest doesn't really add much to complexity:

frandxy()
closegame()
playAgain()
loseGame()
winGame()
game()
start()

And even my main game loop follows an obvious pattern:

check to see if the 'close' button is being pressed
check to see which arrow key is being pressed and update the 'move' variable accordingly
change x,y coordinates of the snake based on what 'move' is set to
check to see if the snake's head has collided with food, if so, run frandxy
check for loss and victory conditions
draw the screen, which is sub-divided into drawing the background, drawing the snake, drawing the food

Concerning drawing the screen, I learned by trial and error that the order you have the program draw things determines layering, so everything is ordered from back to front. First the background, and then everything in front of the background. That's why it uses the order it does. As for that, it was fortunate that I drew the food AFTER the snake, because otherwise when it spawned the food in on top of the snake, it would've just looked like it had disappeared until the snake was no longer on top of it. Another lesson learned.

The last line of code, which shortens the list I use to draw the snake's tail, was put there because my program kept slowing down as the game progressed, and rather quickly. I was able to resolve that by actually putting a limit on how long the 'path' list could get. As you see, I limited it to the value of 'length'. This is actually a change I made before I made it so the snake couldn't cross its own path. And yes, even if I didn't eat food the game would still continue to slow down. In fact, what I did in-game made no difference. That's how I figured out it must be the 'path' list, since it continuously grows longer regardless of whether or not the snake grows.

As for my variables, yeah, I declared them a bit randomly. I just added them in as I got to them. Though that hasn't really caused me any problems. Besides, if I really need to I could just add comments to all of them explaining what they do. And of course, group them up in a more logical order (such as the variables for the snake's graphics, which includes x, y, path, length, and snakeSize). Though looking at, I just now noticed that I declare the posx and posy variables (which are the x,y coordinates for the food) in the food's main loop! Oops.

My code isn't that complicated, and I have no problems finding what I need when I do alter it. It just looks complicated to you because you're not used to it. As I pointed out earlier, your OOP code looks like spaghetti to me. Now, I'm sure there is a logic to it, but its not apparent to me. Just because the logic isn't immediately apparent to you doesn't mean its not there.

And yeah, obviously I need to clean up and optimize my code a bit, I'm just saying that I didn't do anything 'wrong' just because I did it differently from how you do it. Besides, I've seen people on youtube arguing AGAINST object-oriented programming.

As for my code, I just had an idea on what I could do fix the delay. As I said, I could move all the screens into a single loop using if-then conditions. If I do that, I could have the program limit the fps to 7 at the start of the 'drawing' section, and then have it set it back when its done. Wonder what that would do? Only one way to find out!

And since I'm going to be overhauling my code, I WILL be saving this as a separate file. I'll probably just call it PySnakeV2.
#17
Well, I moved everything into one main loop, but now I can't leave the start screen for some reason. It just makes a beep sound, then nothing more. The esc key still works though.

import random
import pygame
pygame.init()

screenWidth=500
screenHeight=500

mainWindow=pygame.display.set_mode((screenWidth,screenHeight))
pygame.display.set_caption("PySnake")

#snake's graphics
x=screenWidth/2
y=screenHeight/2
snakeSize=50
move="down"
length=0
path=[]
#food's graphics
posx=0
posy=0
#fps
fps=60
fpsClock=pygame.time.Clock()
#game states
win=True
state='start'
#sound effects
loseGameSound=pygame.mixer.Sound('pysnake_lose_game.wav')
eatSound=pygame.mixer.Sound('pysnake_eat.wav')
bleep=pygame.mixer.Sound('pysnake_bleep.wav')

font=pygame.font.SysFont('arialblack',20)



def frandxy():
    posx=snakeSize*(random.randint(0,screenWidth/snakeSize-1))
    posy=snakeSize*(random.randint(0,screenWidth/snakeSize-1))
    if (posx,posy) in path or (posx,posy)==(x,y):
            frandxy()

def closeGame():
    pygame.quit()
    quit()

frandxy()
while True:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            closeGame()

    key=pygame.key.get_pressed()
    if key[pygame.K_ESCAPE]:
        closeGame()

    if state=='start':
        titleFont=pygame.font.SysFont('arialblack',50)
        title=titleFont.render('PySnake',0,(0,255,0))
        enterPrompt=font.render('Press Enter to Start',0,(0,255,0))

        mainWindow.blit(title,(screenWidth/2-title.get_width()/2,screenHeight/2-snakeSize*2))
        mainWindow.blit(enterPrompt,(screenWidth/2-enterPrompt.get_width()/2,screenHeight/2))

        for event in pygame.event.get():
                if event.type==pygame.QUIT:
                    closeGame()

        key=pygame.key.get_pressed()
        if key[pygame.K_RETURN]:
            bleep.play()
            state='game'
    if state=='game':
        for event in pygame.event.get():
                if event.type==pygame.QUIT:
                    closeGame()

        key=pygame.key.get_pressed()
        if key[pygame.K_UP] and move != "down":
            move="up"
        if key[pygame.K_w] and move !="down":
            move="up"
        if key[pygame.K_DOWN] and move != "up":
            move="down"
        if key[pygame.K_s] and move != "up":
            move="down"
        if key[pygame.K_RIGHT] and move != "left":
            move="right"
        if key[pygame.K_d] and move != "left":
            move="right"
        if key[pygame.K_LEFT] and move != "right":
            move="left"
        if key[pygame.K_a] and move != "right":
            move="left"
        if key[pygame.K_ESCAPE]:
            closeGame()
        if key[pygame.K_e]:
            closeGame()

            path.insert(0,(x,y))
            #move snake
            if move=="down" and y<=screenHeight-snakeSize:
                y+=snakeSize
            if move=="down" and y>=screenHeight:
                y=0
            if move=="up" and y>=0:
                y-=snakeSize
            if move=="up" and y<0:
                y=screenHeight-snakeSize
            if move=="right" and x<=screenWidth-snakeSize:
                x+=snakeSize
            if move=="right" and x>=screenWidth:
                x=0
            if move=="left" and x>=0:
                x-=snakeSize
            if move=="left" and x<0:
                x=screenWidth-snakeSize

            if x==posx and y==posy:
                length+=1
                eatSound.play()
                frandxy()
            if (x,y) in path:
                win=False
                state='end'
            if length>=((screenWidth/snakeSize)*(screenHeight/snakeSize))-1:
                state='end'

            mainWindow.fill((0,0,0))
            #draw snake
            fps=6
            if length>0:
                for i in range(length):
                    pygame.draw.rect(mainWindow, (0,255,0),(path[i][0],path[i][1], snakeSize,snakeSize))
            pygame.draw.rect(mainWindow, (0,255,0),(x, y, snakeSize, snakeSize))
            #draw food
            pygame.draw.rect(mainWindow, (255,0,0),(posx,posy, snakeSize, snakeSize))
            fps=60
            if len(path)>length:
                path=path[:(length)]
    if state=='end':
        key=pygame.key.get_pressed()
        if key[pygame.K_ESCAPE]:
            closeGame()
        if key[pygame.K_RETURN]:
            bleep.play()
            state='playAgain'
        if win:
            mainWindow.fill((0,255,0))
            textTop=font.render('Your Snake Filled the Screen!',0,(0,0,0))
            textBottom=font.render(('Congratulations!'),0,(0,0,0))
        if win==False:
            textTop=font.render('GAME OVER',0,(0,0,0))
            textBottom=font.render(('Your Length Was: '+str(length)),0,(0,0,0))

        mainWindow.fill((0,0,0))
        pygame.draw.rect(mainWindow,(0,255,0),(screenWidth/2-snakeSize*3,\
                                               screenHeight/2-snakeSize,\
                                               snakeSize*6,snakeSize*2))
        mainWindow.blit(textTop, (screenWidth/2-textTop.get_width()/2,screenHeight/2-snakeSize))
        mainWindow.blit(textBottom, (screenWidth/2-textBottom.get_width()/2,screenHeight/2))

    if state=='playAgain':
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                closeGame()

        key=pygame.key.get_pressed()
        if key[pygame.K_ESCAPE]:
            bleep.play()
            closeGame()
        if key[pygame.K_y]:
            bleep.play()
            win=True
            x=screenWidth/2
            y=screenHeight/2
            length=0
            move="down"
            path=[]
        if key[pygame.K_n]:
            closeGame()
        if win==False:
            mainWindow.fill((0,0,0))
        if win==True:
            mainWindow.fill((0,255,0))
        pygame.draw.rect(mainWindow,(0,255,0),(screenWidth/2-snakeSize*3,\
                                               screenHeight/2-snakeSize,\
                                               snakeSize*6,snakeSize*2))
        font=pygame.font.SysFont('arialblack',20)
        textTop=font.render('Play Again?',0,(0,0,0))
        textBottom=font.render(('(y)es/(n)o'),0,(0,0,0))

        mainWindow.blit(textTop, (screenWidth/2-textTop.get_width()/2,screenHeight/2-snakeSize))
        mainWindow.blit(textBottom, (screenWidth/2-textBottom.get_width()/2,screenHeight/2))

    pygame.display.update()
    fpsClock.tick(fps)

Decided to just try and see if I could change the fps back and forth mid-program in my original code. It didn't work at all.
#18
Still haven't resolved the issue. It would seem there's just no way of getting rid of it.

Really thinking I shouldn't be bothering with python at all. From what I can tell, the whole language sucks. You have little to no control over anything, your programs always lag badly even if you're running your game on a high-end game pc. Sadly, I hate c++, and I'd rather not bother with Java after what happened to Flash.

I'm getting the impression that my game creation career has ended before I even really got started. So I wasted 3 years of college for NOTHING. And I had no way of knowing what I was getting myself into before I started the degree, with all the lies that's on the internet today. I essentially just took a chance, and got unlucky. Now, I've wasted 5 pell grants for a degree I'll never ever make use of. FML.
#19
(Oct-01-2019, 09:03 AM)xBlackHeartx Wrote: Still haven't resolved the issue. It would seem there's just no way of getting rid of it.

Really thinking I shouldn't be bothering with python at all. From what I can tell, the whole language sucks. You have little to no control over anything, your programs always lag badly even if you're running your game on a high-end game pc. Sadly, I hate c++, and I'd rather not bother with Java after what happened to Flash.

I'm getting the impression that my game creation career has ended before I even really got started. So I wasted 3 years of college for NOTHING. And I had no way of knowing what I was getting myself into before I started the degree, with all the lies that's on the internet today. I essentially just took a chance, and got unlucky. Now, I've wasted 5 pell grants for a degree I'll never ever make use of. FML.
Your attitude is just one of the issues. The way you speak makes people not want to help. Saying a language sucks because you dont understand it is not an ideal way to obtain help. I can understand why you dont want to touch Java or C++. After starting Python i never looked back. And i am grateful for finding Python. If i was stuck with C++ i would of abandoned it and never programmed at all. But it takes years and years to get fluent in any language, even Python. When your in college, your all over the place and unable to focus on learning a language. Especially the language you want. I was lucky and they taught Python in college. College in my opinion just gets the concepts down. You have to do more work after to really understand and get a reality check. You may need to take a break if your getting stressed out. I would surely at least finish your degree if you havent yet (depending on financial situations). Its always better to have that piece of paper for the job interview.

PS i have been really busy and thus not able to respond to your gaming questions. But to be honest your attitude doesnt really make me want to help. Still dont have time to code, but can answer quick responses that take no thought.

You basically converted your game from def -> if conditions. It didnt really change the game mechanics at all, thus retaining all the problems from before. I would strongly suggest to just pause your game and and delve into OOP to the point where feel very comfortable using classes. I would go through my tutorials for game making that use OOP and thoroughly understand it before moving to the next series. There are links to github repos such as mekires examples as well in the tutorials. After awhile of understanding OOP, i bet you would look at your code differently. Save it. You can see your progress of learning by looking back at your code. Every so often i look back in github at code as the years progress and they look different. Especially the first 5 years was pretty bad.
Recommended Tutorials:
#20
I made a quick version of the snake game, it unfinished with some bugs, but it's just an example to show different ways to shorten code and prevent it from becoming spaghetti code. Dictionaries are a big way to shorten code. Especially in the main loop, there are dictionaries that I used to shorten the amount of if statements that could have been there.
import random, pygame, sys, time

#Start up
pygame.init()
screen = pygame.display.set_mode((500, 500))

#Constants
fps = 60
clock = pygame.time.Clock()

#ScreenDisplay
def TextDisplay(screen, text, size, color, centerX, centerY):
    font = pygame.font.SysFont('arial', size)
    textSurface = font.render(text, True, color)
    TextRect = textSurface.get_rect()
    TextRect.center = ((centerX),(centerY))
    screen.blit(textSurface, TextRect)

#Snake Class
class Body():
    def __init__(self, rect, direction, first=False):
        self.rect = pygame.Rect(rect[0], rect[1], 20, 20)
        self.direction = direction
        self.first = first

    def draw(self):
        pygame.draw.rect(screen, [20, 20, 210], self.rect)

    def move(self, direction):
        directionDict = {'up' : [0, -20], 'down' : [0, 20], 'right' : [20, 0], 'left' : [-20, 0]}
        returnDirection = self.direction
        self.direction = direction
        additive = directionDict[direction]
        self.rect[0] += additive[0]
        self.rect[1] += additive[1]
        return returnDirection

def StartScreen():
    TextDisplay(screen, 'Snake Game', 50, [20, 210, 20], 250, 150)
    TextDisplay(screen, 'Press Enter/Return to start', 30, [20, 210, 20], 250, 300)
    pygame.display.update()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    return True

def Main():
    if StartScreen():
        keyDict = {pygame.K_w : 'up', pygame.K_a : 'left', pygame.K_d : 'right', pygame.K_s : 'down',
                   pygame.K_UP : 'up', pygame.K_LEFT : 'left', pygame.K_RIGHT : 'right', pygame.K_DOWN : 'down'}
        opposites = {'up' : 'down', 'left' : 'right', 'right' : 'left', 'down' : 'up'}
        firstDirectionAdditive = {'down' : [0, -40], 'up' : [0, 40], 'left' : [40, 0], 'right' : [-40, 0]}
        mainDirectionAdditive = {'down' : [0, -20], 'up' : [0, 20], 'left' : [20, 0], 'right' : [-20, 0]}
        BodyList = []
        BodyList.append(Body([240, 0], 'down', True))
        FoodRect = pygame.Rect(random.randint(10, 490), random.randint(250, 490), 10, 10)
        score = 0
        direction = 'down'
        followingDirection = None
        debounceTime = time.time() - 1
        playing = True
        while playing:
            keysPressed = pygame.key.get_pressed()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return
            #Draw
            if time.time() - debounceTime >= 1:
                debounceTime = time.time()
                screen.fill([210, 20, 20])
                TextDisplay(screen, f'Score: {score}', 30, [20, 210, 20], 250, 25)
                pygame.draw.rect(screen, [255, 255, 255], FoodRect)
                for body in BodyList:
                    if body.first:
                        followingDirection = body.move(direction)
                        if body.rect[0] < 0 or body.rect[0] > 500 or body.rect[1] < 0 or body.rect[1] > 500:
                            return
                        if FoodRect.colliderect(body.rect):
                            FoodRect[0] = random.randint(10, 490)
                            FoodRect[1] = random.randint(75, 490)
                            if len(BodyList) == 1:
                                additive = firstDirectionAdditive[direction]
                            else:
                                additive = mainDirectionAdditive[direction]
                            BodyList.append(Body([BodyList[len(BodyList) - 1].rect[0] + additive[0], BodyList[len(BodyList) - 1].rect[1] + additive[1]], BodyList[len(BodyList) - 1].direction))
                            score += 1
                    else:
                        followingDirection = body.move(followingDirection)
                    body.draw()

            #Check for movement
            for key in keyDict:
                if keysPressed[key]:
                    if opposites[keyDict[key]] != direction:
                        direction = keyDict[key]
                        break
            
            #Tick and update
            clock.tick(fps)
            pygame.display.update()

if __name__ == '__main__':
    Main()
    pygame.quit()
    sys.exit()


Possibly Related Threads…
Thread Author Replies Views Last Post
  Laggy Game Movement game_slayer_99 12 4,323 Oct-05-2022, 11:34 AM
Last Post: metulburr
Music [PyGame] Chopper wash effect efficiency questions. michael1789 9 4,426 Jan-19-2021, 07:12 PM
Last Post: michael1789
  Appropriately delay this PyGame code kleynah22 2 4,388 Nov-09-2017, 02:00 PM
Last Post: Windspar
  [PyGame] My program is very laggy GamePlanet 6 7,046 Aug-15-2017, 03:00 PM
Last Post: nilamo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020