How can I end this game - python

I am trying to make a game wherein when the player icon collides with meowth the game ends and screen shows the text "GAME OVER" persitently. However when i run this program there is a short blink and the game continues. What changes should I make to the given code? Also when i click the quit button of the game window it simply hangs there and the game window/screen does not close. I would relly appreciate any help or inputs or any further suggestons to this game by you guys.
import random
import pygame
import math
from pygame import mixer
pygame.init()
mixer.init()
# create the screen
screen=pygame.display.set_mode((800,600))
#icon and title
pygame.display.set_caption("pokecapture")
icon=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\pokeball.png")
pygame.display.set_icon(icon)
#background
bg=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\background.png")
# player
playerImg=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\pokeball.png")
playerX=374
playerY=536
playerX_change=0
def player(x,y):
screen.blit(playerImg,(x,y))
#sound
mixer.music.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\bgsound.wav")
mixer.music.play(-1)
#score
score=0
font=pygame.font.SysFont('inkfree.ttf',40)
textX=10
textY=10
def show_score():
score1=font.render('SCORE:'+str(score),True, (0,0,0))
screen.blit(score1,(30,30))
#pokemons
bullbasaur=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\bullbasaur.png")
charmander=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\charmander.png")
dratini=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\dratini.png")
eevee=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\eevee.png")
jigglypuff=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\jigglypuff.png")
meowth=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\meowth (2).png")
pikachu=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\pikachu.png")
psyduck=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\psyduck.png")
snorlax=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\snorlax.png")
squirtle=pygame.image.load("C:\\users\\khuhan rawat\\Desktop\\pokemon\\squirtle.png")
poke=[bullbasaur,charmander,dratini,eevee,jigglypuff,meowth,pikachu,psyduck,snorlax,squirtle]
pokeImg=[meowth,pikachu]
pokeX=[]
pokeY=[]
pokeY_change=[1,1]
for i in range(8):
n=random.randint(0,9)
poke1=poke[n]
pokeImg.append(poke1)
pokeX.append(random.randint(0,768))
pokeY.append(random.randint(-80,400))
pokeY_change.append(1)
for i in range (2):
pokeX.append(random.randint(0,768))
pokeY.append(random.randint(-80,400))
def pokemon(x,y,i,l):
screen.blit(l[i],(x,y))
#collision
def collision(x,y,playerX,playerY):
dist=math.sqrt((math.pow(x-playerX,2))+(math.pow(y-playerY,2)))
if dist<=27:
return True
#game over
over_font=pygame.font.SysFont('inkfree.ttf',60)
def gameover():
overtext=over_font.render("GAME OVER",True,(0,0,0))
screen.blit(overtext,(20,300))
#game loop
running=True
while running:
screen.fill((0,0,0))
screen.blit(bg,(0,0))
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_LEFT:
playerX_change=-3
if event.key==pygame.K_RIGHT:
playerX_change=3
if event.type==pygame.KEYUP:
playerX_change=0
playerX+=playerX_change
if playerX<=0:
playerX=0
elif playerX>=736:
playerX=736
player(playerX,playerY)
#show score
for i in range(10):
pokeY[i]+=pokeY_change[i]
pokemon(pokeX[i],pokeY[i],i,pokeImg)
col=collision(pokeX[i],pokeY[i],playerX,playerY)
if pokeY[i]>=600:
pokeY[i]=random.randint(-20,40)
pokeX[i]=random.randint(0,768)
if col:
char=pokeImg[i]
if char==pikachu:
np=random.randint(0,9)
pokeX[i]=random.randint(0,736)
pokeY[i]=random.randint(0,40)
pokemon(pokeX[i],pokeY[i],np,poke)
cap=mixer.Sound("C:\\users\\khuhan rawat\\Desktop\\pokemon\\capture.wav")
cap.play()
score+=5
elif char==meowth:
for i in range(10):
pokeY[i]=2000
screen.fill((34,34,34))
gameover()
break
else:
np=random.randint(0,9)
pokeX[i]=random.randint(0,736)
pokeY[i]=random.randint(0,40)
pokemon(pokeX[i],pokeY[i],np,poke)
cap=mixer.Sound("C:\\users\\khuhan rawat\\Desktop\\pokemon\\capture.wav")
cap.play()
score+=5
np=random.randint(0,9)
pokeX[i]=random.randint(0,736)
pokeY[i]=random.randint(0,40)
pokemon(pokeX[i],pokeY[i],np,poke)
cap=mixer.Sound("C:\\users\\khuhan rawat\\Desktop\\pokemon\\capture.wav")
cap.play()
show_score()
pygame.display.update()

The break in the gameover condition only breaks the for loop, not the outer while loop.
elif char==meowth:
for i in range(10):
pokeY[i]=2000
screen.fill((34,34,34))
gameover()
running = False
break
Setting the running flag to False should solve the issue.

Related

Pygame loop not running

I am trying to create a qr code generator as a small project. Currently it should only print 2 lines on the top of the screen. but the second for loop doesnt run at all. i changed the variables and such. I dont understand why the for loop doesnt activate at all.
import pygame,random,os
pygame.init()
rand=random.Random()
#use https://www.qr-code-generator.com/
#Setup
WIDTH,HEIGHT=210,210
WIN=pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("QR code generator")
WIN.fill((255,255,255))
x=0
y=0
dothisthing=True
d=0
f=0
def doit(xm,ym):
pygame.draw.rect(WIN, (0,0,0), pygame.Rect(xm,ym,10,10))
for l in range(6):
doit(d,f)
pygame.display.update()
d+=10
d=14
f=0
for y in range(6):
doit(d,f)
pygame.display.update()
d+=10
run=True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run=False
pygame.display.update()
I was using 14 instead of 140. This caused the boxes to overlap. The only help I got was to limit cpu usage and update game states, so.

How to integrate 'MENU' code for my game with the actual gaming code?

I have created a basic game. Now I want to expand on the basic game and add a video game menu to it. I have two programs:
Basic game code
MENU code
I want to integrate both codes into one so that my game becomes more functional. I am just a beginner and need directions on how to do that. Thanks for helping.
BASIC GAME CODE:
import pygame
import random
import sys
pygame.init()
w=800
h=600
red=(251,63,75)
blue=(104,41,171)
yellow=(255,255,0)
player_size=25
player_pos=[w/2,h-(2*player_size)]
enemy_size=25
enemy_pos=[random.randint(0,w-enemy_size),0]
enemy_list=[ ]
bg_color=(0,0,0)
screen=pygame.display.set_mode((w,h))
game_over=False
speed=10
score=0
clock=pygame.time.Clock()
myFont=pygame.font.SysFont("monospace",35)
def set_level(score,speed):
if score<10:
speed=5
elif score<20:
speed=6
elif score<30:
speed=8
elif score<40:
speed=10
elif score<50:
speed=13
elif score<200:
speed=15
else:
speed=20
return speed
def drop_enemies(enemy_list):
delay=random.random()
if len(enemy_list)<6 and delay<0.1:
x_pos=random.randint(0,w-enemy_size)
y_pos=0
enemy_list.append([x_pos,y_pos])
def draw_enemies(enemy_list):
for enemy_pos in enemy_list:
pygame.draw.rect(screen,blue,
(enemy_pos[0],enemy_pos[1],enemy_size,enemy_size))
def update_enemy_pos(enemy_list,score):
for idx,enemy_pos in enumerate(enemy_list):
if enemy_pos[1]>=0 and enemy_pos[1]<h:
enemy_pos[1]+=speed
else:
enemy_list.pop(idx)
score+=1
return score
def detect_collision(player_pos,enemy_pos):
p_x=player_pos[0]
p_y=player_pos[1]
e_x=enemy_pos[0]
e_y=enemy_pos[1]
if (e_x>=p_x and e_x<(p_x+player_size)) or (p_x>=e_x and p_x<(e_x+enemy_size)):
if (e_y>=p_y and e_y<(p_y+player_size)) or (p_y>=e_y and p_y<(e_y+enemy_size)):
return True
return False
def collision_check(enemy_list,player_pos):
for enemy_pos in enemy_list:
if detect_collision(enemy_pos,player_pos):
return True
return False
while not game_over:
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()
if event.type==pygame.KEYDOWN:
x=player_pos[0]
y=player_pos[1]
if event.key==pygame.K_LEFT:
x-=player_size
elif event.key==pygame.K_UP:
y-=player_size
elif event.key==pygame.K_RIGHT:
x+=player_size
elif event.key==pygame.K_DOWN:
y+=player_size
player_pos=[x,y]
screen.fill(bg_color)
drop_enemies(enemy_list)
score=update_enemy_pos(enemy_list,score)
speed=set_level(score,speed)
text='Your Score is:' + str(score)
label=myFont.render(text,1,yellow)
screen.blit(label,(w/2,h-40))
if collision_check(enemy_list,player_pos):
game_over=True
break
draw_enemies(enemy_list)
pygame.draw.rect(screen,red,
(player_pos[0],player_pos[1],player_size,player_size))
clock.tick(30)
pygame.display.update()
pygame.display.flip()
GAME MENU CODE:
import pygame
import random
import sys
pygame.init()
w=800
h=600
bg_color=(34,139,34)
red=(255,0,0)
blue=(0,0,125)
bright_blue=(0,0,255)
font_size=35
b1_pos=[w/2-50,h/2]
b1_size=[105,50]
screen=pygame.display.set_mode((w,h))
myFont=pygame.font.SysFont("freesansbold.tff",font_size)
def button(b1_pos,b1_size):
mouse_pos=pygame.mouse.get_pos()
click=pygame.mouse.get_pressed()
if (b1_pos[0]<mouse_pos[0]<(b1_pos[0]+b1_size[0])) and (b1_pos[1]<mouse_pos[1]<(b1_pos[1]+b1_size[1])):
pygame.draw.rect(screen,bright_blue,(b1_pos[0],b1_pos[1],b1_size[0],b1_size[1]))
if click[0]==1:
print("Left click")
else:
pygame.draw.rect(screen,blue,(b1_pos[0],b1_pos[1],b1_size[0],b1_size[1]))
text='START'
label=myFont.render(text,1,red)
screen.blit(label,(w/2-38,h/2+5))
game_over=False
while not game_over:
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()
screen.fill(bg_color)
button(b1_pos,b1_size)
pygame.display.update()
When creating a game you need something called The MainLoop. All the code that needs to be updated in every frame goes inside this loop. This loop runs forever until the game is terminated. Check these video tutorials and this
Let me give you an example:
import pygame
#Import literals such as QUIT
from pygame.locals import *
pygame.init()
w = 800
h = 600
screen = pygame.display.set_mode((w,h))
running = True
def MenuCode():
pass
def GameCode():
pass
#This is the Game Loop.
while running:
#Events are used to check if a key has
#been pressed or a mouse button or a mouse movement.
for event in pygame.event.get():
#If the user pressed the x button.
#terminate the while loop.
if event.type == QUIT:
running = False
break;
#In every frame you must clean the window with a color
#in order to draw anythin else above it.
screen.fill((0,0,0))
#Here draw anything you like
#Also somewhere here call all the code that needs to be
#called every frame (Menu code, Game code, etc)
MenuCode()
GameCode()
#Lastly you must update the display.
#The most important thing that this does
#is called buffer swapping, check it out.
pygame.display.update()
#When the loop terminates, terminate pygame.
pygame.quit()
If you want to learn what the update() method does check about double buffering

How I should randomly flip arrow with next arrow?

I am creating simple game through pygame. In the code arrow is flipping randomly with each pygame. Draw but I want it to flip (randomly when next arrow in the game.
This is incomplete code
import pygame
import random
import sys
pygame.init()
h=600
w=800
arrow_pos=[w/2,0]
base_size=[w/2,50]
base_pos=[w/4,h-50]
screen=pygame.display.set_mode((w,h))
bg_color=(0,0,0)
base_color=(255,0,0)
arrow_color=(0,150,255)
clock=pygame.time.Clock()
game_over=False
def updating_arrow(arrow_pos):
if arrow_pos[1]>=0 and arrow_pos[1]<h:
arrow_pos[1]+=10
else:
arrow_pos[1]-=h
return arrow_pos[1]
def draw_arrow(screen,arrow_color,arrow_pos,arrow_size):
pygame.draw.polygon(screen, arrow_color, ((arrow_pos[0],
arrow_pos[1]+10), (arrow_pos[0], arrow_pos[1]+20),
(arrow_pos[0]+arrow_size, arrow_pos[1]+20),
(arrow_pos[0]+arrow_size,
arrow_pos[1]+30), (arrow_pos[0]+(arrow_size)*1.5,
arrow_pos[1]+15),
(arrow_pos[0]+arrow_size, arrow_pos[1]),
(arrow_pos[0]+arrow_size,
arrow_pos[1]+10)),0)
while not game_over:
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()
screen.fill(bg_color)
arrow_pos[1]=updating_arrow(arrow_pos)
arrow_size=random.choice([50,-50])
draw_arrow(screen,arrow_color,arrow_pos,arrow_size)
pygame.draw.rect(screen,base_color,
(base_pos[0],base_pos[1],base_size[0],base_size[1]))
pygame.display.update()
clock.tick(30)
Randomly initialize the arrow_size before the main loop:
arrow_size = random.choice([50,-50])
while not game_over:
for event in pygame.event.get():
if event.type==pygame.QUIT:
sys.exit()
Only change the arrow size, when a new arrow appears at the top of the window. You've to use the global statement to change the value of the globale variable arrow_size in the function updating_arrow:
def updating_arrow(arrow_pos):
global arrow_size
if arrow_pos[1] >= 0 and arrow_pos[1] < h:
arrow_pos[1] += 10
else:
arrow_pos[1] -= h
arrow_size = random.choice([50,-50])
return arrow_pos[1]
Or pass arrow_size to the function by a parameter and return the changed, as you do it with arrow_pos:
def updating_arrow(arrow_pos, arrow_size):
if arrow_pos[1]>=0 and arrow_pos[1]<h:
arrow_pos[1]+=10
else:
arrow_pos[1]-=h
arrow_size = random.choice([50,-50])
return arrow_pos, arrow_size
arrow_pos, arrow_size = updating_arrow(arrow_pos, arrow_size)
# arrow_pos[1]=updating_arrow(arrow_pos) <---- delete
# arrow_size=random.choice([50,-50]) <---- delete

Why is my pygame screen static?

So I'm writing a pygame program in which rectangles fall continuously from the top of the screen, and the player can move their rectangle around to catch them. The problem is, when I run the program, the rectangles don't fall on their own. They only fall when you begin to move the character, or when you enter some form of input. They stop falling when the input ends. Why is this happening? I feel like it might have to do with my FPS settings, but I've done similar programs before without this problem occurring. Can anybody tell me what's going on?
Thanks in advance
`import pygame, sys,random,time
from pygame.locals import*
pygame.init()
mainClock=pygame.time.Clock()
WINDOWWIDTH=400
WINDOWHEIGHT=400
windowSurface=pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT ),0,32)
pygame.display.set_caption('Input with Falling Food')
BLACK=(0,0,0)
GREEN=(0,255,0)
WHITE=(255,255,255)
MOVESPEED=20
FOODSIZEMAX=30
FOODSIZEMIN=10
FOODMOVESPEED=30
foodCounter=0
NEWFOOD=5
player=pygame.Rect(300,100,50,50)
foods=[]
for i in range(10):
FOODSIZE=random.randint(FOODSIZEMIN,FOODSIZEMAX)
foods.append(pygame.Rect(random.randint(0,WINDOWWIDTH-FOODSIZE),0,FOODSIZE,FOODSIZE))
moveLeft=False
moveRight=False
moveUp=False
moveDown=False
while True:
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()
sys.exit()
if event.type==KEYDOWN:
if event.key==K_LEFT or event.key==ord('a'):
moveRight=False
moveLeft=True
if event.key==K_RIGHT or event.key==ord('d'):
moveLeft=False
moveRight=True
if event.key==K_UP or event.key==ord('w'):
moveDown=False
moveUp=True
if event.key==K_DOWN or event.key==ord('s'):
moveUp=False
moveDown=True
if event.type==KEYUP:
if event.key==K_ESCAPE:
pygame.quit()
sys.exit()
if event.key==K_LEFT or event.key==ord('a'):
moveLeft=False
if event.key==K_RIGHT or event.key==ord('d'):
moveRight=False
if event.key==K_UP or event.key==ord('w'):
moveUp=False
if event.key==K_DOWN or event.key==ord('s'):
moveDown=False
if event.key==ord('x'):
player.top=random.randint(0,WINDOWHEIGHT-player.height)
player.left=random.randint(0,WINDOWWIDTH-player.width)
if event.type==MOUSEBUTTONUP:
foods.append(pygame.Rect(event.pos[0],event.pos[1],FOODSIZE,FOODSIZE))
foodCounter+=1
if foodCounter>=NEWFOOD:
foodCounter=0
FOODSIZE=random.randint(FOODSIZEMIN,FOODSIZEMAX)
foods.append(pygame.Rect(random.randint(0,WINDOWWIDTH-FOODSIZE),0,FOODSIZE,FOODSIZE))
windowSurface.fill(BLACK)
if moveDown and player.bottom<WINDOWHEIGHT:
player.top+=MOVESPEED
if moveUp and player.top>0:
player.top-=MOVESPEED
if moveLeft and player.left>0:
player.left-=MOVESPEED
if moveRight and player.right<WINDOWWIDTH:
player.right+=MOVESPEED
pygame.draw.rect(windowSurface,WHITE,player)
for i in range(len(foods)):
foods[i].top+=FOODMOVESPEED
for food in foods[:]:
if player.colliderect(food):
foods.remove(food)
for food in foods[:]:
if food.top>=WINDOWHEIGHT:
foods.remove(food)
for i in range(len(foods)):
pygame.draw.rect(windowSurface,GREEN,foods[i])
pygame.display.update()
#mainClock.tick(40)
#time.sleep(0.02)
You need to break your main loop code out of the for event in pygame.event.get(): loop.
That is, everything you want to run every time the clock ticks (not just when the game receives input events) should be outside that loop, just in the main while loop.
At the very least, for the food to move:
for i in range(len(foods)):
foods[i].top+=FOODMOVESPEED
Needs to be taken out.

Python Basic control flow errors

When I run this code, it enters a while loop and checks every turn whether or not on_title_screen==True. If it is true, the program will continue to check for input, but if it is false, the loop will refresh the screen and begin the game. However, when start is clicked, and on_title_screen=False, the game still captures mouse input, and does not display the bird that it should.
import random
import pygame
from pygame import *
import math
import sys
#Presets for window
size=width,height=500,500
Ag=-9.80665
clock = pygame.time.Clock()
white=(255,255,255)
blue=(0,0,255)
red=(255,0,0)
gray_bgColor=(190,193,212)
#Initialise pygame Surface as screen
pygame.init()
pygame.font.init()
screen=pygame.display.set_mode(size)
pygame.display.set_caption("Flappy Kid")
#Game Presets
vY=0
xPos,yPos=200,100
score=0
on_title_screen=True
def falling_loop():
for event in pygame.event.get():
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_UP:
vY=-10
if yPos>height-50:
yPos=100
vY+=1
yPos+=vY
class graphics():
#Holds the methods for loading/displaying graphics
def load_images(self):
#Loads the background and sprite images
self.background_image=pygame.image.load("flappy_background.png").convert()
self.bird_image=pygame.image.load("flappy_sprite.jpg").convert()
screen.set_colorkey(white)
self.birdHitBox=self.bird_image.get_rect()
def show_background(self):
#blits the background
screen.blit(self.background_image,[0,0])
def refresh_display(self):
#updates the display
screen.blit(self.background_image,[xPos,yPos],self.birdHitBox)
falling_loop()
screen.blit(self.bird_image,[xPos,yPos])
class titleScreen():
#Holds the methods for the title screen/menu
def title(self):
#Sets up the title
titleText="Flappy Game"
titlePos=(0,0)
currentFont=pygame.font.SysFont("arialms",30,bold=True,italic=True)
renderTitle=currentFont.render(titleText,1,blue,gray_bgColor)
self.titlex,self.titley=currentFont.size(titleText)
screen.blit(renderTitle,titlePos)
def start(self):
#Sets up the start Button
startText="Start Game"
self.startPos=(0,self.titley)
currentFont=pygame.font.SysFont("arialms",25,bold=False,italic=False)
renderStart=currentFont.render(startText,1,blue,gray_bgColor)
self.startx,self.starty=currentFont.size(startText)
self.start_rect = pygame.Rect(self.startPos[0],self.titley,self.startx,self.starty)
screen.blit(renderStart,self.startPos)
def quit(self):
#Sets up the quit button
quitText="Quit"
self.quitPos=(0,self.starty+self.titley)
currentFont=pygame.font.SysFont("arialms",25,bold=False,italic=False)
renderQuit=currentFont.render(quitText,1,red,gray_bgColor)
self.quitx,self.quity=currentFont.size(quitText)
self.quit_rect = pygame.Rect(self.quitPos[0],self.titley+self.starty,self.quitx,self.quity)
screen.blit(renderQuit,self.quitPos)
def get_click(self):
#Gets mouse click and processes outcomes
for event in pygame.event.get():
if event.type==pygame.MOUSEBUTTONDOWN:
x,y=pygame.mouse.get_pos()
#Tests for start:
if self.start_rect.collidepoint(x,y):
print("start")
on_title_screen=False
elif self.quit_rect.collidepoint(x,y):
print("quit")
sys.exit()
titleC=titleScreen()
graphicsC=graphics()
def setupTitle():
#bundles all title_screen functions
titleC.title()
titleC.start()
titleC.quit()
def main():
graphicsC.load_images()
graphicsC.show_background()
setupTitle()
while True:
clock.tick(30)
if on_title_screen==False:
graphicsC.refresh_display()
elif on_title_screen==True:
titleC.get_click()
pygame.display.flip()
main()
I think #TessellatingHeckler is right, on_title_screen is a shadow variable, not the same.
In this code, there is nowhere that on_title_screen (global) could ever be set to False.
A more powerful answer though is to explain how to find the problem. I strongly recommend using pdb or ipdb. In this case, I would put one just inside of the while loop and make sure that the variables are what I think they should be.

Categories