i'm making a start menu for my game but when i hit the exit button i made in the start menu, it doesn't exit. Is there anything wrong with my code?
I tried making a function for the exit, put it in the code that exit the game with the window exit button, but nothing worked.
import pygame
import os
pygame.mixer.pre_init()
pygame.mixer.init(44100, 16, 2, 262144)
pygame.init()
from pygame.locals import*
pygame.mixer.music.load(os.path.join(os.getcwd(), 'Sounds',
'intro.ogg'))
pygame.mixer.music.set_volume(0.3)
pygame.mixer.music.play(-1)
FPS = 60
white = (255,255,255)
grey = (128,128,128)
black = (0,0,0)
red = (255,0,0)
orange = (255,128,0)
yellow = (255,255,0)
green = (0,255,0)
Lgreen = (128,255,0)
blue = (0,0,255)
Lblue = (0,255,255)
purple = (255,0,255)
pink = (255,0,127)
pygame.display.set_caption('Snake Universe')
Title = pygame.image.load('Graphics/Title.png')
Play = pygame.image.load('Graphics/Play.png')
Option = pygame.image.load('Graphics/Option.png')
Exit = pygame.image.load('Graphics/Exit.png')
LinePX = pygame.image.load('Graphics/LinePX.png')
LineO = pygame.image.load('Graphics/LineO.png')
clock = pygame.time.Clock()
movie = pygame.movie.Movie('Video/bg.mpg')
screen = pygame.display.set_mode((1280, 720))
bgE = pygame.image.load('Graphics/transparent.png')
movie_screen = pygame.Surface(movie.get_size()).convert()
movie.set_display(movie_screen)
movie.play()
y = 235
y1 = 3000
cnt = 0
playing = True
while playing:
cnt+=1
if cnt>=1870:
cnt=0
movie.rewind()
movie.play()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key==pygame.K_RETURN:
if y == 426:
movie.stop()
playing = False
pygame.quit()
quit()
if event.key == pygame.K_UP:
y += 1
if y == 3236:
y = 235
y1 = 3000
if y == 236:
y = 425
y1 = 3000
if y == 426:
y1 =335
y = 3235
if event.key == pygame.K_DOWN:
y += 1
if y == 236:
y = 3235
y1 = 335
if y == 3236:
y1 = 3000
y = 425
if y == 426:
y1 = 3000
y = 235
if event.type == pygame.QUIT:
movie.stop()
playing = False
pygame.quit()
quit()
screen.blit(movie_screen,(0, 0))
screen.blit(Title, (360, 0))
screen.blit(Play, (460, 250))
screen.blit(Exit, (460, 450))
screen.blit(LinePX, (482.5, y))
screen.blit(LineO, (482.5, y1))
screen.blit(Option, (460, 350))
screen.blit(bgE, (-100, 0))
pygame.display.update()
clock.tick(FPS)
i expected it to exit the window but instead it doesn't do anything.
The main loop runs as long as playing is True.
playing = True
while playing:
# [...]
When the pygame.QUIT event is handled, playing is set False the main loop condition is fails:
if event.type == pygame.QUIT:
playing = False
# [...]
Note, pygame.quit() doesn't terminate the loop, but it uninitialize all pygame modules, which will cause an exception in the following, if it is done in the middle of the application.
If you want to quit the application by the keypad enter key pygame.K_KP_ENTER, the you've to do the same when the pygame.KEYDOWN event is handled:
if event.type == pygame.KEYDOWN:
if event.key==pygame.K_KP_ENTER:
playing = False
Or you've to send a pygame.QUIT event by pygame.event.post():
if event.type == pygame.KEYDOWN:
if event.key==pygame.K_KP_ENTER:
pygame.event.post(pygame.event.Event(pygame.QUIT))
Related
I've been trying to make a wild west game in Pygame in which the player duels an NPC, but I can't get the shooting functions to work. I've basically tried to keep it simple, and I have a series of functions to make the bullet go across the screen, but they aren't working. Here's the code:
import pygame, time
pygame.init()
display_width = 800
display_height = 600
win = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('The Old Wild West')
black = (0,0,0)
white = (255,255,255)
clock = pygame.time.Clock()
dead = False
avatar = pygame.image.load('cowboy.jfif')
avatar2 = pygame.image.load('enemy.jfif')
bullet = pygame.image.load('bullet.png')
bx2 = 330
bx3 = 440
bx4 = 550
bx = 220
by = 220
bspeed = 165
x = 50
ex = 550
ey = 225
y = 200
x_change = 0
speed = 0
def cowboy(x,y):
win.blit(avatar, (x,y))
def enemy(ex, ey):
win.blit(avatar2, (ex, ey))
def shootframe1():
win.blit(bullet, (bx, by))
def antiframe1():
pygame.draw.rect(win, (255, 255, 255), (bx, by, 50, 150))
def shootframe2():
win.blit(bullet, (bx2, by))
def antiframe2():
pygame.draw.rect(win, (255, 255, 255), (bx2, by, 50, 150))
def shootframe3():
win.blit(bullet, (bx3, by))
def antiframe3():
pygame.draw.rect(win, (255, 255, 255), (bx3, by, 50, 150))
def shootframe4():
win.blit(bullet, (bx4, by))
def antiframe4():
pygame.draw.rect(win, (255, 255, 255), (bx4, by, 50, 150))
while not dead:
for event in pygame.event.get():
if event.type == pygame.QUIT:
dead = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
if event.type == pygame.K_SPACE:
if event.key == pygame.K_SPACE:
shootframe1()
time.sleep(0.5)
antiframe1()
shootframe2()
time.sleep(0.5)
antiframe2()
shootframe3()
time.sleep(0.5)
antiframe3()
shootframe4()
time.sleep(0.5)
antiframe4()
x += x_change
win.fill(white)
cowboy(x,y)
enemy(ex, ey)
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
Here is cowboy.jfif, enemy.jfif and bullet.png:
bullet.png
cowboy.jfif
enemy.jfif
Please help me out with this confusion.
I updated your code drastically, I tried to comment everything pretty well so it's clear what is happening.
First, you were filling the screen white after drawing the bullet onto the screen so it never showed up.
Second, the space bar key didn't fire because you were checking if the space bar was an event type. So I moved it under the event.type == pygame.KEYDOWN
Third, using time.sleep(0.5) makes the game window freeze and stutter a lot so I would avoid doing that.
If you have any questions about the changes feel free to ask.
import pygame, time
pygame.init()
display_width = 800
display_height = 600
win = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('The Old Wild West')
black = (0,0,0)
white = (255,255,255)
clock = pygame.time.Clock()
dead = False
avatar = pygame.image.load('cowboy.jfif')
avatar2 = pygame.image.load('enemy.jfif')
bullet = pygame.image.load('bullet.png')
bx2 = 330
bx3 = 440
bx4 = 550
bx = 220
by = 220
bspeed = 165
x = 50
ex = 550
ey = 225
y = 200
x_change = 0
speed = 0
def cowboy(x,y):
win.blit(avatar, (x,y))
def enemy(ex, ey):
win.blit(avatar2, (ex, ey))
# A single shoot function that appends a new bullet to our bullet list below.
def shoot():
bullet_list.append(Bullet(bx, by))
# A bullet class that holds information about a single bullet
class Bullet:
def __init__(self, x, y):
# Initializing variables for the bullet
self.x = x
self.y = y
self.image = pygame.image.load('bullet.png')
self.bullet_speed = 165
# Moves the bullet accross the screen by updating the x variable after each draw()
def _move_bullet(self):
self.x += self.bullet_speed
def draw(self):
# Get the surface (window)
surface = pygame.display.get_surface()
# Blit the bullet to the screen
surface.blit(self.image, (self.x, self.y))
# Update its position with the function above
self._move_bullet()
bullet_list = [] # Since the user can have multiple bullets firing, we need to keep track of them
while not dead:
win.fill(white) #Move this to the top so you're filling the screen before drawing anything
for event in pygame.event.get():
if event.type == pygame.QUIT:
dead = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
if event.key == pygame.K_SPACE: # Moved this up here
shoot() # Spawn the bullet
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
x += x_change
cowboy(x,y)
enemy(ex, ey)
# Draw each bullet onto the screen by iterating over the list
for bullet in bullet_list:
# If the bullet has exited the screen we remove it from the list so they are not kept in memory
if bullet.x > display_width:
bullet_list.remove(bullet)
# Draw the bullet (called from the Class)
bullet.draw()
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
Shooting one bullet works but i can only shoot one and after that it stops working. I've tried to change my "bullet_fire" to False after KEYUP but this doesnt work either since then the bullet is only visible while i hold the arrow up key while the problem remain. How should i solve this problem?
Here is the code:
import pygame
pygame.init()
# Skärm
Screen = pygame.display.set_mode((1600, 900))
# Title och Logo
pygame.display.set_caption("Fjärt Spel")
icon = pygame.image.load('planet.png')
pygame.display.set_icon(icon)
# backround
backround = pygame.image.load("0000.png")
# player
playerIMG = pygame.image.load("soldier.png")
playerX = 350
playerY = 836
playerX_Change = 0
playerY_Change = 30
# enemy
enemyIMG = pygame.image.load("terrorist2.png")
enemyX = 500
enemyY = 810
enemyX_Change = 0
enemyY_Change = 0
# bullet
bulletIMG = pygame.image.load("pung(32x32).png")
bulletX = playerX
bulletY = playerY
bulletX_Change = 50
bulletY_Change = 0
bullet_fire = False
offScreen = 1600, 900
def player(x, y):
Screen.blit(playerIMG, (x, y))
def enemy(x, y):
Screen.blit(enemyIMG, (x, y))
Running = True
while Running:
Screen.fill((0, 0, 0))
# backround
Screen.blit(backround, (0, 0))
if bullet_fire == True:
Screen.blit(bulletIMG, (bulletX + 100, playerY))
bulletX += bulletX_Change
if bulletX > 1600:
bullet_fire == False
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 = -10
if event.key == pygame.K_RIGHT:
playerX_Change = 10
if event.key == pygame.K_SPACE:
playerY_Change = -70
if event.key == pygame.K_UP:
bullet_fire = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_SPACE:
playerX_Change = 0
playerY_Change = 30
# Ha player innan fill!!
playerX += playerX_Change
playerY += playerY_Change
if playerX <= 0:
playerX = 0
elif playerX >= 1436:
playerX = 1436
if playerY <= 0:
playerY = 0
elif playerY >= 836:
playerY = 836
player(playerX, playerY)
enemy(enemyX, enemyY)
pygame.display.update()
if bulletX > 1600:
bullet_fire == False
# ^^
This appears to want to set bullet_fire to False when it reaches a certain ordinate but, in reality, is comparing the two and throwing away the result. That means the first bullet you've fired is still going, has left the screen, and is probably halfway to Jupiter by now :-)
By way of example, this is similar to the following transcript:
>>> a = 7
>>> if a == 7:
... a == 14
... print(a)
...
False
7
You need to use == for comparison and = for assignment.
Keep in mind that's the likely cause of your issue. Since your question does not contain the code that decides whether a new bullet should be generated, it's a little hard to tell for sure. I'm therefore basing it on the assumption that one bullet at a time is all that's permitted (as in quite a few arcade games). Hence, if you never "destroy" the current bullet, you'll never be able to fire another one.
If that turns out to not be the case, you probably need to post more code so we can do an exhaustive analysis.
As an aside, I'm a little concerned about the physics involved in:
Screen.blit(bulletIMG, (bulletX + 100, playerY))
This appears to draw the bullet at the players current Y position meaning that, after the bullet is fired, it will track the player in some weird Einsteinian "spooky action at a distance" manner. While that makes the game a lot easier since you can direct the bullets after firing, I'm not convinced it will get a high score in the realism category :-)
'''There's a minor bug in this Space Invaders Code, everything works fine and well at the start , until all of a sudden sometimes, mostly at the end of the game, some of the enemy spaceships suddenly moves extremely fast and wayy faster than the other enemies, but follows the same path as the others..If I manage to shoot down the fast spaceships, more of them start moving at the very same fast speed, how it that??I have attached the code down below:'''
import pygame
import random
import math
from pygame import mixer
# Initialize and create a Game Window
pygame.init()
screen = pygame.display.set_mode(size=(800,600))
#Caption and Icon
pygame.display.set_caption('Space Invaders')
icon = pygame.image.load('ufo.png')
pygame.display.set_icon(icon)
#Background
background = pygame.image.load('background.png')
#BackgroundSound
mixer.music.load('background.wav')
mixer.music.play(-1)
#Player
playerImg = pygame.image.load('player.png')
playerX=360
playerY=470
playerX_change = 0
#Enemy
enemyImg=[]
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies=6
for i in range(num_of_enemies):
enemyImg.append(pygame.image.load('enemy.png'))
enemyX.append(random.randint(0,736))
enemyY.append(random.randint(40,120))
enemyX_change.append(4)
enemyY_change.append(20)
#Bullet
bulletImg = pygame.image.load('bullet.png')
bulletX=0
bulletY=480
bulletX_change = 0
bulletY_change = -10
bulletstate = 'ready' # Bullet is 'ready' if its ready to shoot and 'fire' means a bullet is fired
#Number of Bullets
no_of_bullets=0
#Score
score_value=0
Score_font = pygame.font.Font("freesansbold.ttf" , 32)
textX=10
textY=10
#Number of bullets
def Show_score(x,y):
score=Score_font.render("Score: " + str(score_value) , True , (255,255,255))
screen.blit(score , (x,y))
def player(x,y):
screen.blit(playerImg , (playerX , playerY))
def enemy(x, y, i):
screen.blit(enemyImg[i] , (enemyX[i] , enemyY[i]))
def bullet_fire(x,y):
global bulletstate
bulletstate='fire'
screen.blit(bulletImg ,(x+16 , y+10))
def Collision(bulletX , bulletY , enemyX , enemyY):
distance=math.sqrt((math.pow(enemyX-bulletX,2)) + (math.pow(bulletY-enemyY,2)))
if distance<29:
return True
else:
return False
def game_over():
font1 = pygame.font.Font("BUBBLEGUMS.ttf" , 68)
gameover=font1.render("GAME OVER " , True , (255,255,255))
screen.blit(gameover , (100,200))
def numberofbullets():
font2=pygame.font.Font("blow.ttf",35)
number_of_bullets=font2.render("Number of Bullets Shot: " + str(no_of_bullets) , True , (0,255,255))
screen.blit(number_of_bullets , (170,375))
#Game Loop
running=True
while running:
# BackgroundImage
screen.blit(background ,(0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#Keystroke
if event.type == pygame.KEYDOWN:
if event.key ==pygame.K_LEFT:
playerX_change -=6
if event.key == pygame.K_RIGHT:
playerX_change +=6
if bulletstate=='ready':
if event.key == pygame.K_SPACE:
no_of_bullets+=1
bulletX=playerX
bullet_fire(bulletX,bulletY)
bullet_sound = mixer.Sound('laser.wav')
bullet_sound.play()
if event.type ==pygame.KEYUP:
if event.key ==pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change=0
#Checking for Boundaries of Spaceship
playerX +=playerX_change
if playerX>=736:
playerX=736
elif playerX<=0:
playerX=0
# Enemy Movement
for i in range(num_of_enemies):
if enemyY[i]>440:
for j in range(num_of_enemies):
enemyY[j]=2000
game_over()
numberofbullets()
break
enemyX[i] +=enemyX_change[i]
if enemyX[i]>735:
enemyX_change[i]+=-4
enemyY[i] +=enemyY_change[i]
elif enemyX[i]<0:
enemyX_change[i]+=4
enemyY[i] +=enemyY_change[i]
#Collision
collision = Collision(bulletX, bulletY, enemyX[i], enemyY[i])
if collision:
collision_sound = mixer.Sound('explosion.wav')
collision_sound.play()
bulletY=480
bulletstate='ready'
enemyX[i]=random.randint(0,800)
enemyY[i]=random.randint(40,120)
score_value+=100
enemy(enemyX[i],enemyY[i] ,i)
#Bullet Movement
if bulletY<=0:
bulletY=480
bulletstate='ready'
if bulletstate=='fire':
bullet_fire(bulletX, bulletY)
bulletY+=bulletY_change
player(playerX,playerY)
Show_score(textX, textY)
pygame.display.update()
The problem of your code is that when your write this:
enemyX[i] +=enemyX_change[i]
if enemyX[i]>735:
enemyX_change[i]+=-4
enemyY[i] +=enemyY_change[i]
elif enemyX[i]<0:
enemyX_change[i]+=4
enemyY[i] +=enemyY_change[i]
every time the enemy reaches an edge enemyX_change[i] should be set to the opposite of what it was before, not by adding or subtracting 4, but directly by setting it to 4 or -4. Also you should set enemyX[i] to be 735 when the enemy reaches the left side and 0 when he reaches the right side.
If you change that piece of code with this one everything should work fine:
if enemyX[i]>735:
enemyX[i] = 735
enemyX_change[i] = -4
enemyY[i] +=enemyY_change[i]
elif enemyX[i]<0:
enemyX[i] = 0
enemyX_change[i] = 4
enemyY[i] +=enemyY_change[i]
i am new to pygame and wanted to make a game i found a playlist online at https://www.youtube.com/playlistlist=PLQVvvaa0QuDdLkP8MrOXLe_rKuf6r80KO t i followed it but i got a error like this
Traceback (most recent call last):
File "/home/pi/firstgamepyg.py", line 78, in <module>
game_loop()
File "/home/pi/firstgamepyg.py", line 65, in game_loop
things(thing_startx, thing_starty, thing_width, thing_height, black)
File "/home/pi/firstgamepyg.py", line 15, in things
pygame.draw.rect(gamedisplay, color,(thingx, thingy, thingw, thingh))
TypeError: Rect argument is invalid
this is my code
import pygame
import time
import random
pygame.init()
dw = 800
dh = 600
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
cw = 96
gamedisplay = pygame.display.set_mode((dw,dh))
cimg = pygame.image.load('/home/pi/Downloads/car.jpeg')
def things(thingx, thingy, thingw, color, thingh):
#error on next line
pygame.draw.rect(gamedisplay, color,(thingx, thingy, thingw, thingh))
def car(x,y):
gamedisplay.blit(cimg,(x,y))
def text_objects(text, font):
textsurface = font.render(text, True, red)
return textsurface, textsurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf',115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((dw/2),(dh/2))
gamedisplay.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
game_loop()
def crash():
message_display('wasted')
def game_loop():
x = (dw * 0.45)
y = (dh * 0.65)
x_change = 0
thing_startx = random.randrange(0,800)
thing_starty = -600
thing_speed = 7
thing_width = 100
thing_height = 100
pygame.display.set_caption('A bit Racey')
clock = pygame.time.Clock()
gameexit = False
while not gameexit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameexit = True
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key==pygame.K_RIGHT:
x_change = 0
x += x_change
gamedisplay.fill(white)
things(thing_startx, thing_starty, thing_width, thing_height, black)
thing_starty += thing_speed
car(x,y)
if x > dw - cw or x < 0:
crash()
gameexit = True
pygame.display.update()
clock.tick(100)
game_loop()
pygame.quit()
quit()
i was trying to make a game where you are a car and avoid blocks but i cant add the blocks because i get an error
your things function is formatted incorrectly. you have the parameter list as (thingx, thingy, thingw, color, thingh) but then you call it as (thingx, thingy, things, thingh, color). to make the errors go away all that you need to do is in the function definition switch color with thingh
So I made this in order to select an area like in strategy games, however
the screen keeps blinking, is there a way to solve this?
import pygame
from pygame.locals import *
WHITE = (255,255,255)
BLUE = (0,0,255)
pygame.init()
window = pygame.display.set_mode((640, 480))
window.fill(WHITE)
pygame.display.flip()
LEFT_CLIC = 1
mouse_tracking = False
draw_area = False
while True:
for event in pygame.event.get():
if event.type == QUIT:
continuer = 0
if event.type == MOUSEBUTTONDOWN:
if event.button == LEFT_CLIC:
x_start, y_start = event.pos
x_end, y_end = event.pos
mouse_tracking = True
draw_area = True
if event.type == MOUSEMOTION and mouse_tracking:
x_end, y_end = event.pos
if event.type == MOUSEBUTTONUP:
if event.button == LEFT_CLIC:
x_end, y_end = event.pos
mouse_tracking = True
draw_area = False
if draw_area:
width = x_end-x_start
height = y_end-y_start
pygame.draw.rect(window, BLUE, (x_start, y_start, width, height))
pygame.display.flip()
window.fill(WHITE)
pygame.display.flip()
So it's pretty simple, record coordinates when there is a clic, then follow the mouse until the clic is done.
Thanks.
There should be only one pygame.display.flip() call per frame, otherwise you get this flickering, so remove one of them. Also, fill the screen before you draw the rect.
window.fill(WHITE)
if draw_area:
width = x_end-x_start
height = y_end-y_start
pygame.draw.rect(window, BLUE, (x_start, y_start, width, height))
pygame.display.flip()