Pygame loop not running - python

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.

Related

How can I end this game

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.

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

pygame.event.set_grab remains turned on after exception / crash and makes program "unkillable"

I am creating a game with pygame and I am using pygame.event.set_grab(True) to keep cursor locked in the game window (it keeps all keyboard input in the window also), but when the program crashes (either because of syntax error or some other exception) the set_grab stays turned on and it is impossible to turn off the program afterwards. (fortunately I am using Linux so i can access console that overrides everything so i can turn it off manually)
I am wondering if it is possible to make some error handling which will turn it off (or kills the program) or if there is a better way to keep just mouse inputs in the window. (so it is possible to alt+f4)
import pygame
pygame.init()
size = (600, 700)
monitor=pygame.display.Info()
screen = pygame.display.set_mode(size)#pygame.FULLSCREEN)
pygame.display.set_caption("Meteor Galaxy 3")
done = False
clock = pygame.time.Clock()
pygame.mouse.set_visible(0)
pygame.event.set_grab(True) #this is turned on with the initialization
#(doesnt have to be) of the game
When the game crashes it transforms into the usual black window with the exception you cant do anything.
Thank you.
Edit:
The full code:
#coding: utf-8
import pygame
import random
random.randint(0,2)
#TODO:
#Vymyslieť systém na čakanie framov
#Upraviť zmenu rýchlosti hráčovho náboja
##Pygame init
pygame.init()
size = (600, 700)
possible_sizes=[[600,700],[900,1050],[1200,1400],[1800,2100]] #ASI 1200,1400 obrázky a potom downscale?? (ak vôbec zmena rozlisenia..)
monitor=pygame.display.Info()
screen = pygame.display.set_mode(size)#pygame.FULLSCREEN)
pygame.display.set_caption("Meteor Galaxy 3")
done = False
clock = pygame.time.Clock()
pygame.mouse.set_visible(0)
pygame.event.set_grab(True)
#<VARIABLES>
##<COLORS>
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
##</COLORS>
##<IMAGES> #"../meteo_data/img/"
bg1=[pygame.image.load("../meteo_data/img/bg1.png"),700-5770,True]
#backgrounds.append([pygame.image.load("img/bg2.png"),[600,1924]])
#backgrounds.append([pygame.image.load("img/bg3.png"),[600,1924]])
img_crosshair=pygame.image.load("../meteo_data/img/crosshair.png").convert()
#Ships
img_player=pygame.image.load("../meteo_data/img/ships/player.png").convert()
img_enemy1=pygame.image.load("../meteo_data/img/ships/enemy1.png").convert()
#Bullets
img_b1=pygame.image.load("../meteo_data/img/bullets/bullet.png").convert()
img_player.set_colorkey(BLACK)
img_enemy1.set_colorkey(BLACK)
img_crosshair.set_colorkey(BLACK)
##</IMAGES>
##<SOUNDS>
##</SOUNDS>
menu_game=1 #Nula pre menu , jedna pre hru?? , medzi nula a jedna ostatné??
esc_menu=False
fire=False
level=-1
level_ended=True
## def=0 def=0
##<BULLET TYPES> #[IMAGE,DAMAGE,SPEED,PENETRATION,relX,relY] /relX a relY vziať z relX a relY lode.
B_default=[img_b1,3,4,False,0,0]
##</BULLET TYPES>
##<SHIP TYPES> #[IMAGE,HEALTH,SPEED,RELOAD,X,Y,relX,relY,BULLET_TYPE] /relX a relY je pre bullet
##</SHIP TYPES>
##<LEVELS>
level1=[bg1]
master_level=[level1]
##</LEVELS>
#</VARIABLES>
#<FUNCTIONS>
##<SPRITES>
class bullet(pygame.sprite.Sprite):
def __init__(self,bullet_type):
pygame.sprite.Sprite.__init__(self)
self.image=bullet_type[0]
self.dmg=bullet_type[1]
self.speed=bullet_type[2]
self.penetration=bullet_type[3] ##Prestrelí viac ENIMÁKOV ? True/False
self.rect = self.image.get_rect()
self.rect.x=bullet_type[4] ##Vypočítať pri vystrelení (ship pos -/+ ship.bullet_x(y)) (pre každý typ lode zvlášť)
self.rect.y=bullet_type[5]
self.image.set_colorkey(BLACK)
class ship(pygame.sprite.Sprite):
def __init__(self,ship_type):
pygame.sprite.Sprite.__init__(self)
self.image=ship_type[0]
self.hp=ship_type[1]
self.speed=ship_type[2] ##0 Pre hráča
self.reload=ship_type[3] ##Rýchlosť streľby (koľko framov čakať) 0 = každý frame bullet
self.rect=self.image.get_rect()
self.rect.x=ship_type[4]
self.rect.y=ship_type[5]
self.bullet_x=ship_type[6]
self.bullet_y=ship_type[7]
self.b_type=ship_type[8]
self.image.set_colorkey(BLACK)
class barrier(pygame.sprite.Sprite):
def __init__(self,coord):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface([700,40])
self.image.fill(WHITE)
self.rect=self.image.get_rect()
self.rect.x=coord[0]
self.rect.y=coord[1]
bullets=pygame.sprite.Group()
ships=pygame.sprite.Group()
barriers=pygame.sprite.Group()
player_b_type=B_default
player_b_type[2]=player_b_type[2]*(-1)
player=ship([img_player,100,0,10,279,650,15,3,player_b_type]) ##PLAYER SHIP
wait=player.reload
barrier_top=barrier([-50,-400])
barrier_bottom=barrier([-50,900])
barriers.add(barrier_top)
barriers.add(barrier_bottom)
##</SPRITES>
#</FUNCTIONS>
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button==1:
fire=True
elif event.type == pygame.MOUSEBUTTONUP:
if event.button==1:
fire=False
elif event.type==pygame.KEYDOWN:
if event.key==pygame.K_ESCAPE:
if not esc_menu:
esc_menu=True
pygame.event.set_grab(False)
else:
esc_menu=False
pygame.event.set_grab(True)
coord=pygame.mouse.get_pos()
if menu_game==0:
screen.fill(WHITE) #BG
elif menu_game==1:
#GAME LOGIC
if level_ended:
level=level+1
bg1_y=master_level[level][0][1]
level_ended=False
bg1_y=bg1_y+2
player.rect.x=coord[0]-20
pygame.sprite.groupcollide(barriers,bullets,False,True)
pygame.sprite.groupcollide(barriers,ships,False,True)
if fire:
if wait==0:
bullet_modified=player.b_type
bullet_modified[4]=player.rect.x+player.bullet_x
bullet_modified[5]=player.rect.y+player.bullet_y
b=bullet(bullet_modified)
bullets.add(b)
wait=player.reload
else:
wait=wait-1
#RENDERING
screen.fill(BLACK)
screen.blit(master_level[level][0][0],[0,bg1_y]) #BG
screen.blit(player.image,player.rect)
for naboj in bullets:
screen.blit(naboj.image,naboj.rect)
naboj.rect.y=naboj.rect.y+naboj.speed
screen.blit(img_crosshair,[coord[0]-10,coord[1]-10])
pygame.display.flip() #FRAMY
clock.tick(60)
pygame.quit()
#NOTES:
# Dlzka lvl sa urci vyskou bg (5760 px == 48 sec - 1. lvl)
#189 -
#
So, the problem there is that if some exception happens in the middle of that code, pygame.quit() is never called.
All you have to do is to set a try ... fynaly block around your Pygame code, and put the pygame.quit() call on the finally block.
For that I suggest some reformatting which will also improve the modularity of your code, which is to enclose all that code you put on the module level inside a function.
So:
...
def main():
done = False
while not done:
...
for naboj in bullets:
...
screen.blit(img_crosshair,[coord[0]-10,coord[1]-10])
pygame.display.flip() #FRAMY
clock.tick(60)
try:
main()
finally:
pygame.quit()
In this way, any unhandled exception within the code run in main (or in any other function called from it), as well as well behaved main-loop termination, will immediately run the code within the finally block: Pygame is shut down, along with its event handling, and you get the error traceback on the terminal enabling you to fix the code.
update the finally hint is also essential for anyone making a game with pygame that uses fullscreen, regardless of event_grab.

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.

list index is out of range for bullets in pygame

So i'm rather new to pygame, and the project i have been working with is making the old alien invasion arcade game. I know i need to clean up my pictures and display and dimensions and stuff so don't worry about that, but the problem i'm struggling with now is firing my bullets, i'm storing them in a list and then deleting them. but i come up with the error "list index out of range". this error shows up on line 50 of this code. Oh and this error only shows up while i have 2 bullets active at a time. for instance i can shoot 1 every second or two just fine, but if i rapid fire a little bit and two are moving on screen at once then i get the error the things to really look at are on lines 42-52, 88-90,and the last 3. also any suggestions on improving the efficiency of my code is greatly appreciated
import pygame
pygame.init()
#keystate variables
keystate={'left':False,'right':False,'up':False,'down':False}
red=(255,0,0)
black=(0,0,0)
green=(0,255,0)
shipX=0
shipY=445
bulletsX=[]
bulletsY=[]
ship=pygame.image.load("ship.png")
ship=pygame.transform.scale(ship,(35,35))
bullet_pic=pygame.image.load("bullet.png")
bullet_pic=pygame.transform.scale(bullet_pic,(25,25))
backdrop=pygame.image.load("backdrop.png")
backdrop=pygame.transform.scale(backdrop,(640,400))
clock=pygame.time.Clock()
screen=pygame.display.set_mode((640,480))
screen.blit(backdrop,(0,0))
# ship movement functions
def moveship_Xneg():
global shipX
if shipX>0:
shipX-=1
def moveship_Xpos():
global shipX
if shipX<605:
shipX+=1
def moveship_Yneg():
global shipY
if shipY<445:
shipY+=1
def moveship_Ypos():
global shipY
if shipY>400:
shipY-=1
#gunfire definitions
def move_bullet():
for bullet in range(len(bulletsX)):
bulletsY[bullet]-=2
screen.blit(bullet_pic,(bulletsX[bullet],bulletsY[bullet]))
pygame.display.update()
def del_bullet():
for bullet in range(len(bulletsX)):
#below this is line 50, realized it didn't show numbers, my bad
if bulletsY[bullet]<=-10:
bulletsY.remove(bulletsY[bullet])
bulletsX.remove(bulletsX[bullet])
# ship movement changes
def start_ship(): #draws the starting position of the ship
screen.blit(ship,(0,445))
pygame.display.update()
def draw_newship(): #draws the new ship and updates the screen
screen.blit(ship,(shipX,shipY))
#screen.blit(backdrop,(shipX
#print(shipX,shipY)
pygame.display.update()
#def del_oldship(): #deletes the old ship
start_ship()
#Main Loop
running=True
while running:
clock.tick(350)
#checks keystroke events
for event in pygame.event.get():
#quits the program
if event.type==pygame.QUIT:
running=False
pygame.quit()
#KEYDOWN CHECKS
if event.type==pygame.KEYDOWN:
#Movement variable changes
if event.key==pygame.K_LEFT:
keystate['left']=True
if event.key==pygame.K_RIGHT:
keystate['right']=True
if event.key==pygame.K_DOWN:
keystate['down']=True
if event.key==pygame.K_UP:
keystate['up']=True
#Action per event
if event.key==pygame.K_SPACE:
bulletsX.append(shipX+17.5)
bulletsY.append(shipY)
#KEYUP CHECKS
if event.type==pygame.KEYUP:
#movement variable changes
if event.key==pygame.K_LEFT:
keystate['left']=False
if event.key==pygame.K_RIGHT:
keystate['right']=False
if event.key==pygame.K_DOWN:
keystate['down']=False
if event.key==pygame.K_UP:
keystate['up']=False
# pygame event processing ends
if running==True:
#performs an action per each loop dependant on keystate variables
if keystate['left']==True:
#del_oldship()
moveship_Xneg()
draw_newship()
if keystate['right']==True:
#del_oldship()
moveship_Xpos()
draw_newship()
if keystate['down']==True:
#del_oldship()
moveship_Yneg()
draw_newship()
if keystate['up']==True:
#del_oldship()
moveship_Ypos()
draw_newship()
if bulletsX!=[]:
del_bullet()
move_bullet()
#for coord in range(len(bulletsX)):
#print(bulletsX[coord],bulletsY[coord])
Actually you can find error in the error message. List index out of range
For example
a = [1]
a.remove(1)
>>>a[0]
`IndexError: list index out of range`
In your code,
if bulletsY[bullet] <= -10
This time may be no elements in bulletsY in the position bullet or list bulletsY may be empty.
So you can try like this
if bulletsY and bulletsY[bullet] <= -10
Hope this helps
Updated
Try this
def del_bullet():
for bullet in range(len(bulletsX)):
#below this is line 50, realized it didn't show numbers, my bad
try:
if bulletsY[bullet]<=-10:
bulletsY.remove(bulletsY[bullet])
bulletsX.remove(bulletsX[bullet])
except:pass

Categories