10
\$\begingroup\$

I just made my first pygame program, ChickenDodger, and I would like to know how I could make my code better. I think I did pretty good for my first time, except the way I added the 2nd egg. I do not like the way I added it. Any advice?

(I made a lot of comments for my younger brother, so he understands it easier, I think some comments are unnecessary)

import pygame
import time
import random
#Initialize pygame
pygame.init()
#Initialize the screen
screenwidth = 960
screenheigth = 640
screen = pygame.display.set_mode((screenwidth,screenheigth))
#Get the color codes
white = (255,255,255)
black = (0,0,0)
#Get the chicken image and scale it
chickenwidth = 50
chickenheigth = 100
chicken = pygame.image.load("chicken.jpg")
chicken = pygame.transform.scale(chicken, (chickenwidth, chickenheigth))
#Get the egg image and scale it
eggwidth = 50
eggheigth = 50
egg = pygame.image.load("egg.jpg")
egg = pygame.transform.scale(egg, (eggwidth, eggheigth))
#Get the second egg image and scale it
egg2width = 50
egg2heigth = 50
egg2 = pygame.image.load("egg.jpg")
egg2 = pygame.transform.scale(egg2, (egg2width, egg2heigth))
#Change the title
pygame.display.set_caption("Chicken Dodger")
#Set the clock
clock = pygame.time.Clock()
#Define the chicken's starting location
def chickenplace(chickenx, chickeny):
 screen.blit(chicken, (chickenx, chickeny))
#Define the egg's starting location
def eggplace(eggx, eggy):
 screen.blit(egg, (eggx, eggy))
#Define the second egg's starting location
def egg2place(egg2x, egg2y):
 screen.blit(egg2, (egg2x, egg2y))
#Define the gameloop
def gameloop():
 #Wait 2 seconds before starting the function
 time.sleep(2)
 dead = False
 #Set the counter for the dodged eggs
 eggcounter = 0
 #Place the chicken and define its xchange
 chickenx = (screenwidth * 0.5)
 chickeny = (screenheigth * 0.8)
 chickenxchange = 0
 #Place the egg and define its speed
 eggx = random.randint(0,910)
 eggy = -200
 eggspeed = 7
 #Place the second egg and define its speed
 egg2x = random.randint(0,910)
 egg2y = -200
 egg2speed = 14
 while not dead:
 for event in pygame.event.get():
 #Make a quit option
 if event.type == pygame.QUIT:
 dead = True
 #Move chicken
 if event.type == pygame.KEYDOWN:
 if event.key == pygame.K_LEFT:
 chickenxchange = -10
 elif event.key == pygame.K_RIGHT:
 chickenxchange = 10
 if event.type == pygame.KEYUP:
 if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
 chickenxchange = 0
 #Change the chickenx and the eggy
 chickenx += chickenxchange
 eggy += eggspeed
 #Fill the screen
 screen.fill(white)
 #Place the chicken and the egg
 chickenplace(chickenx, chickeny)
 eggplace(eggx, eggy)
 egg2place(egg2x, egg2y)
 #Set the boundaries for the chicken
 if chickenx > screenwidth - chickenwidth:
 chickenx = screenwidth - chickenwidth
 chickenplace(chickenx, chickeny)
 if chickenx < 0:
 chickenx = 0
 chickenplace(chickenx, chickeny)
 #Make the egg come back
 if eggy > screenheigth:
 eggy = -200
 eggx = random.randint(0,910)
 #Make the second egg come back
 if egg2y > screenheigth:
 egg2y = -200
 egg2x = random.randint(0,910)
 #Add 1 point for every egg avoided, if the egg hits the chicken, reset the counter to 0
 if eggy == chickeny + 2:
 if eggx > chickenx + 50 or eggx < chickenx - 50:
 eggcounter += 1
 else:
 eggcounter = 0
 time.sleep(2)
 gameloop()
 #Do not add a point if the second egg gets avoided, if the second egg hits the chicken, reset the counter to 0
 if egg2y == chickeny + 2:
 if egg2x > chickenx + 50 or egg2x < chickenx - 50:
 eggcounter = eggcounter
 else:
 eggcounter = 0
 time.sleep(2)
 gameloop()
 #Display the counter
 countertext = pygame.font.SysFont(None, 20)
 counterlabel = countertext.render("Counter:" + str(eggcounter), True, black)
 screen.blit(counterlabel, (20, 20))
 #Double the egg's speed when you have dodged 5 eggs
 if eggcounter > 5:
 eggspeed = 14
 #Make a second egg fall when you have dodged 15 eggs
 if eggcounter > 15:
 egg2y += egg2speed
 egg2place(egg2x, egg2y)
 #Display a "You won!" when you dodged the first egg 30 times
 if eggcounter == 30:
 wintext = pygame.font.SysFont(None, 60)
 winlabel = wintext.render("You won!", True, black)
 screen.blit(winlabel, (200, 200))
 time.sleep(1)
 dead = True
 pygame.display.update()
 clock.tick(60)
gameloop()
pygame.quit()
quit()
asked May 5, 2016 at 18:11
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

First of all, the name "Chicken Dodger" made me laugh, that's a good one!

Quitting

Quitting is handled like this:

while not dead:
 for event in pygame.event.get():
 #Make a quit option
 if event.type == pygame.QUIT:
 dead = True
 # ... more code
 # ... a lot more code

After you set dead to True, still a lot more code will get executed in the outer while not dead loop. I'm not sure if that's intentional. If it isn't, then it looks like that you can simply return from the function.

Use more elif

In these conditions:

#Make a quit option
if event.type == pygame.QUIT:
 dead = True
#Move chicken
if event.type == pygame.KEYDOWN:
 if event.key == pygame.K_LEFT:
 chickenxchange = -10
 elif event.key == pygame.K_RIGHT:
 chickenxchange = 10
if event.type == pygame.KEYUP:
 if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
 chickenxchange = 0

event.type can only have one of these values. For example if event.type == pygame.QUIT, then there's no need to evaluate the other conditions. This is what elif is designed for:

if event.type == pygame.QUIT:
 # ...
elif event.type == pygame.KEYDOWN:
 # ...
elif event.type == pygame.KEYUP:
 # ...

The same goes here:

if chickenx > screenwidth - chickenwidth:
 chickenx = screenwidth - chickenwidth
 chickenplace(chickenx, chickeny)
if chickenx < 0:
 chickenx = 0
 chickenplace(chickenx, chickeny)

The second if should be an elif, because if the first condition was true, the second cannot be true, so there's no need to evaluate it.

Review the entire program, and look for conditions that are mutually exclusive as in these examples.

Variable span

It's good to move references to a variable close together as much as possible. Consider this:

dead = False
# ... a lot of code
while not dead:

You initialized dead early on, wrote a lot of code before actually using that variable in the while loop. By the time I read the while loop, I don't remember where dead was initialized. I also have to quickly scan the code between the initialization and the loop, to see that its value was never changed before the loop begins. If you move the initialization line down to right before the loop start, the code becomes a little bit easier to read.

answered May 7, 2016 at 8:41
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.