What I'am trying to do is once a car has crossed the finish line I would want it to say which car won the race but how could I add that to my game? The code works fine just trying to see how I could add some more features to it like a signal or some type of notification saying which car passed the finish line first.
import pygame
pygame.init()
#Setting up our colors that we are going to use
GREEN = (20, 255, 140)
GREY = (210, 210, 210)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
PURPLE = (255, 0, 255)
BLACKWHITE =(96, 96, 96)
SCREENWIDTH = 400
SCREENHEIGHT = 500
size = (SCREENWIDTH, SCREENHEIGHT)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Car Racing")
Icon = pygame.image.load("image/redca_iconr.png")
pygame.display.set_icon((Icon))
# This will be a list that will contain all the sprites we intend to use in our game.
#all_sprites_list = pygame.sprite.Group()
#player
playerIMG = pygame.image.load("image/red_racecar.png")
playerX = 250
playerY = 450
playerCar_position = 0
#player2
playerIMG_two = pygame.image.load("image/greencar.png")
playerX_two = 150
playerY_two = 450
playerCar_position_two = 0
#player3
playerIMG_three = pygame.image.load("image/Orangecar.png")
playerX_three = 50
playerY_three = 450
playerCar_position_three = 0
#player4
playerIMG_four = pygame.image.load("image/yellow_car.png")
playerX_four = 200
playerY_four = 450
playerCar_position_four = 0
#Putting cars to the screen
def player(x, y):
screen.blit(playerIMG, (x, y))
def player_two(x, y):
screen.blit(playerIMG_two, (x, y))
def player_three(x, y):
screen.blit(playerIMG_three, (x, y))
def player_four(x, y):
screen.blit(playerIMG_four, (x, y))
# Main game loop
run = True
clock = pygame.time.Clock()
#TIP - lots of our actions take place in our while loop cause we want the function/program to run consistently
while run:
# Drawing on Screen
screen.fill(GREEN)
# Draw The Road
pygame.draw.rect(screen, GREY, [40, 0, 300, 500])
# Draw Line painting on the road
pygame.draw.line(screen, WHITE, [185, 0], [185, 500], 5)
#Finish line
pygame.draw.rect(screen, BLACKWHITE, [50, 50, 280, 40])
pygame.draw.line(screen, WHITE, [65, 70], [300, 70], 5)
font = pygame.font.SysFont("Papyrus", 45)
text = font.render("Finish line!", 1, (150, 50, 25))
screen.blit(text, (195 - (text.get_width() / 2), 15))
**Here is where the finish line code is at just want too add some type of notafication saying which car has crossed the finsh line first!**
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# Number of frames per secong e.g. 60
clock.tick(60)
keys = pygame.key.get_pressed()
if keys[pygame.K_1]:
playerCar_position = -0.1
if keys[pygame.K_q]:
playerCar_position = 0.1
if keys[pygame.K_2]:
playerCar_position_two = -0.1
if keys[pygame.K_w]:
playerCar_position_two = 0.1
if keys[pygame.K_3]:
playerCar_position_three = -0.1
if keys[pygame.K_e]:
playerCar_position_three = 0.1
# our functions
playerY += playerCar_position
playerY_two += playerCar_position_two
playerY_three += playerCar_position_three
player(playerX, playerY)
player_two(playerX_two, playerY_two)
player_three(playerX_three, playerY_three)
player_four(playerX_four, playerY_four)
# Refresh Screen
pygame.display.flip()
pygame.quit()
Imagine the finish line is actually a rectangle. Given the finish line goes from [65, 70] to [300, 70], this gives us a rectangle at (65,70) that's 235 pixels wide. Just to make things a bit safer, we can use a much wider rectangle for the line, in case a car is moving many pixels in an update... just so it can't "jump" the line without ever entering it.
finish_line_rect = pygame.Rect( 65,70, 235,32 ) # but 32 pixels wide
Then when each car moves, you can use pygame.Rect.collidepoint() with the x,y of each car to see if it overlaps with the finish_line_rect.
For example:
# Move the Players' cars
playerY += playerCar_position
playerY_two += playerCar_position_two
playerY_three += playerCar_position_three
# Draw the Players' cars
player(playerX, playerY)
player_two(playerX_two, playerY_two)
player_three(playerX_three, playerY_three)
player_four(playerX_four, playerY_four)
# Did anyone cross the line?
if ( finish_line_rect.collidepoint( playerX, playerY ) ):
print( "Player (one) has crossed into finish rectangle" )
if ( finish_line_rect.collidepoint( playerX_two, playerY_two ) ):
print( "Player two has crossed into finish rectangle" )
# ETC.
First off, I think you should create a "car" class as to not duplicate so much code and make it easier to work with. Regarding the finish line, I would do the following:
#Create an array with all cars X value
CarPositions = [Car1_x, Car2_x, Car3_x, Car4_x]
#Define X value of Finishline
Finishline = 600
def CheckPosition(CarPositions, Finishline):
for i in range(len(CarPositions)):
if CarPositions[i] >= Finishline:
return CarPositions[i]
You should have your array of X positions in numerical order i.e. Car 1 is before Car 2 in the array. That way the i in the for loop represents which number car has passed.
Related
so I am making a code where there is a character(A rectangle) and and Balloon(A circle) and the character has to catch the balloons before it hits the ground. Everything worked fine until I tried making the game look a little better and used the blit function to add an image. For some reason my text keeps buffering now.
Code:
import random
import pygame
from pygame.locals import *
pygame.init()
#Variables
white = (255, 255, 255)
blue = (70,130,180)
black = (0,0,0)
red = (255,0,0)
x = 400
y = 450
score = 0
cooly = 100
randomx = random.randint(100,800)
clock = pygame.time.Clock()
#screen stuff
screenwidth = 800
screenheight = 600
screen = pygame.display.set_mode((screenwidth, screenheight))
pygame.display.set_caption("Balloon Game!")
#end of screen stuff
#Initializing font
def show_text(msg, x, y, color,size):
fontobj= pygame.font.SysFont("freesans", size)
msgobj = fontobj.render(msg,False,color)
screen.blit(msgobj,(x, y))
#Game loop
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
exit()
# Draw Character
screen.fill(blue)
character = pygame.draw.rect(screen, red, (x, y, 60, 60))
#End of Drawing Character
#Draw Balloons
balloon = pygame.draw.circle(screen, (black), (randomx, cooly), 30, 30)
cooly = cooly + 2
# Making Arrow Keys
keyPressed = pygame.key.get_pressed()
if keyPressed[pygame.K_LEFT]:
x -= 3
if keyPressed[pygame.K_RIGHT]:
x += 3
#Drawing Cool Stuff
Cloud = pygame.image.load('Cloud.png')
screen.blit(Cloud,(100,75))
pygame.display.update()
#End of making arrow keys
show_text("Score:",130,0,black,50)
show_text(str(score),250,0,black,50)
#Collision
if balloon.colliderect(character):
randomx = random.randint(100,800)
cooly = 100
score = score + 1
#end of collision
#Ending
if cooly >= 600:
screen.fill(blue)
show_text("Game Over!", 200, 250, black, 100)
show_text("Score :", 200, 350, black, 75)
show_text(str(score), 400, 350, black, 75)
#Polishing
if score == score + 5:
cooly += 1
x += 3
pygame.display.update()
clock.tick(250)
The problem is caused by multiple calls to pygame.display.update(). An update of the display at the end of the application loop is sufficient. Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering.
Remove all calls to pygame.display.update() from your code, but call it once at the end of the application loop.
Do not create the font object and do not load the images in the application loop. This are very expensive operatios, because the filed have to be read and interpreted:
fontobj= pygame.font.SysFont("freesans", size) #<-- INSERT
def show_text(msg, x, y, color,size):
# fontobj= pygame.font.SysFont("freesans", size) <-- DELET
msgobj = fontobj.render(msg,False,color)
screen.blit(msgobj,(x, y))
Cloud = pygame.image.load('Cloud.png') #<-- INSERT
# [...]
while True:
# [...]
# Cloud = pygame.image.load('Cloud.png') <-- DELETE
screen.blit(Cloud,(100,75))
# pygame.display.update() <-- DELETE
# [...]
pygame.display.update()
clock.tick(250)
I've tried to add gravity using the quadratic formula but didn't seem to work and I tried to turn it into a function and that still didn't seem to work. I tried using a class but I don't quite understand how they work so can someone help me add gravity to my platformer. I've tried many videos but didn't seem to help so any help would be much appreciated
import pygame
from pygame.locals import *
from pygame import mixer
from typing import Tuple
import pickle
from os import path
import time
import sys
import os
pygame.init()
white = 255,255,255
black = 0,0,0
green = 0, 255, 0
blue = 0,0,255
font = pygame.font.SysFont('Comic Sans MS', 50, 70)
screen_width = 650
screen_height = 800
screen = pygame.display.set_mode([screen_width,screen_height])
screen.fill((white))
pygame.display.set_caption("Darsh's Game")
pygame.display.update()
pygame.draw.rect(screen,white,(200,150,100,50))
running = 1
speed = 1
x = 25
y = 669
isJump = False
jumpCount = 10
left = False
right = True
def draw_text(text, font, text_col, x, y):
img = font.render(text, True, text_col)
screen.blit(img, (x, y))
def draw_rect():
rect1 = pygame.Rect(0, 0, 25, 800)
pygame.draw.rect(screen, black, rect1)
rect2 = pygame.Rect(625, 0, 25, 800)
pygame.draw.rect(screen, black, rect2)
rect3 = pygame.Rect(0, 775, 650, 25)
pygame.draw.rect(screen, green, rect3)
pygame.display.flip()
def direction(left, right):
if left == True:
screen.blit(mainleft_img, (x, y))
elif right == True:
screen.blit(mainright_img, (x, y))
draw_rect()
draw_text("George is dumb", font, green, 100, 400)
pygame.display.update()
mainright_img = pygame.image.load('newgameimg/mainright.png')
mainleft_img = pygame.image.load('newgameimg/mainleft.png')
screen.blit(mainright_img, (300, 400))
run = True
while run:
draw_text("George is dumb", font, green, 100, 400)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > speed - 16:
x -= speed
left = True
right = False
draw_text("George is dumb", font, green, 100, 400)
pygame.display.update()
if keys[pygame.K_d] and x < screen_width - speed - 89:
x += speed
left = False
right = True
draw_text("George is dumb", font, green, 100, 400)
pygame.display.update()
if keys[pygame.K_ESCAPE]:
pygame.quit()
if not (isJump):
if keys[pygame.K_SPACE]: # jumping code
isJump = True
else:
if jumpCount >= -10:
time.sleep(0.02)
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False # jumping code
screen.fill(white)
direction(left, right)
draw_text("George is dumb", font, green, 100, 400)
draw_rect()
pygame.display.update()
You don't need the quadratic formula to get a simple gravity going; a simple gravity variable increasing every frame should do the trick.
...
gravity = 0
while run:
...
...
if keys[pygame.K_SPACE]:
gravity += 1
y -= gravity
...
Note that I don't speak your language; I mainly code in JavaScript, but I did try python once and I got the syntax down pretty quick. Hopefully this suits your needs, with a bit of tweaking of course.
Add a variable fall = 0. Increment the variable if the player does not jump (fall += 0.2). Change the y coordinate of the player through the variable fall in each frame. Get the bounding rectangle of the player with pygame.Surface.get_rect(). If the bottom of the rectangle reaches the floor then stop falling, and restricting the bottom of the rectangle on the floor. Set fall = 0 if the player starts to jump:
while run:
# [...]
if not (isJump):
fall += 0.2
y += fall
player_rect = mainleft_img.get_rect(topleft = (x, y))
if player_rect.bottom > 775:
player_rect.bottom = 775
y = player_rect.top
fall = 0
if keys[pygame.K_SPACE]: # jumping code
isJump = True
fall = 0
else:
# [...]
Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering. Remove all calls to pygame.display.update() from your code, but call it once at the end of the application loop.
In addition, draw each object only once.
Do not delay, wait or sleep. Use pygame.time.Clock to control the frames per second and thus the game speed.
The method tick() of a pygame.time.Clock object, delays the game in that way, that every iteration of the loop consumes the same period of time. See pygame.time.Clock.tick():
This method should be called once per frame.
That means that the loop:
clock = pygame.time.Clock()
run = True
while run:
clock.tick(60)
runs 60 times per second.
See pygame.time.Clock.tick():
This method should be called once per frame. It will compute how many milliseconds have passed since the previous call.
Complete example:
import pygame
from pygame.locals import *
pygame.init()
white = 255,255,255
black = 0,0,0
green = 0, 255, 0
blue = 0,0,255
screen_width = 650
screen_height = 800
screen = pygame.display.set_mode([screen_width,screen_height])
pygame.display.set_caption("Darsh's Game")
font = pygame.font.SysFont('Comic Sans MS', 50, 70)
running = 6
speed = 2
fall = 0
x = 25
y = 669
isJump = False
jumpCount = 10
left = False
right = True
def draw_text(text, font, text_col, x, y):
img = font.render(text, True, text_col)
screen.blit(img, (x, y))
def draw_rect():
rect1 = pygame.Rect(0, 0, 25, 800)
pygame.draw.rect(screen, black, rect1)
rect2 = pygame.Rect(625, 0, 25, 800)
pygame.draw.rect(screen, black, rect2)
rect3 = pygame.Rect(0, 775, 650, 25)
pygame.draw.rect(screen, green, rect3)
def direction(left, right):
if left == True:
screen.blit(mainleft_img, (x, y))
elif right == True:
screen.blit(mainright_img, (x, y))
draw_text("George is dumb", font, green, 100, 400)
mainright_img = pygame.image.load('newgameimg/mainright.png')
mainleft_img = pygame.image.load('newgameimg/mainleft.png')
clock = pygame.time.Clock()
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > speed - 16:
x -= speed
left = True
right = False
if keys[pygame.K_d] and x < screen_width - speed - 89:
x += speed
left = False
right = True
if keys[pygame.K_ESCAPE]:
pygame.quit()
if not (isJump):
fall += 0.2
y += fall
player_rect = mainleft_img.get_rect(topleft = (x, y))
if player_rect.bottom > 775:
player_rect.bottom = 775
y = player_rect.top
fall = 0
if keys[pygame.K_SPACE]: # jumping code
isJump = True
fall = 0
else:
if jumpCount >= -10:
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False # jumping code
screen.fill(white)
draw_rect()
direction(left, right)
pygame.display.update()
So what am trying to get is a text to pop up after a car crosses the finish line for example “Game over first car won” but everything I done so far hasn’t worked and was hoping I can get some assistance here.
import pygame, random
import time
pygame.init()
# music/sounds
CarSound = pygame.mixer.Sound("image/CAR+Peels+Out.wav")
CarSound_two = pygame.mixer.Sound("image/racing01.wav")
CarSound_three = pygame.mixer.Sound("image/RACECAR.wav")
CarSound_four = pygame.mixer.Sound("image/formula+1.wav")
music = pygame.mixer.music.load("image/Led Zeppelin - Rock And Roll (Alternate Mix) (Official Music Video).mp3")
pygame.mixer.music.play(-1)
bg = pygame.image.load('image/Crowds.png')
#Setting up our colors that we are going to use
GREEN = (20, 255, 140)
GREY = (210, 210, 210)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
PURPLE = (255, 0, 255)
BLACKWHITE =(96, 96, 96)
SCREENWIDTH = 400
SCREENHEIGHT = 500
size = (SCREENWIDTH, SCREENHEIGHT)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Car Racing")
Icon = pygame.image.load("image/redca_iconr.png")
pygame.display.set_icon((Icon))
# This will be a list that will contain all the sprites we intend to use in our game.
#all_sprites_list = pygame.sprite.Group()
#player
playerIMG = pygame.image.load("image/red_racecar.png")
playerX = 250
playerY = 450
playerCar_position = 0
#player2
playerIMG_two = pygame.image.load("image/greencar.png")
playerX_two = 150
playerY_two = 450
playerCar_position_two = 0
#player3
playerIMG_three = pygame.image.load("image/Orangecar.png")
playerX_three = 50
playerY_three = 450
playerCar_position_three = 0
#player4
playerIMG_four = pygame.image.load("image/yellow_car.png")
playerX_four = 200
playerY_four = 450
playerCar_position_four = 0
#Putting cars to the screen
def player(x, y):
screen.blit(playerIMG, (x, y))
def player_two(x, y):
screen.blit(playerIMG_two, (x, y))
def player_three(x, y):
screen.blit(playerIMG_three, (x, y))
def player_four(x, y):
screen.blit(playerIMG_four, (x, y))
finish_text = ""
font2 = pygame.font.SysFont("Papyrus", 45)
players_finished = 0
placings = ["1st", "2nd", "3rd", "4th"]
def text_objects(text, font):
textSurface = font.render(text, True, RED)
return textSurface, textSurface.get_rect()
def message_display(text):
largText =pygame.font.Font("Mulish-Regular.ttf", 15)
TextSurf, TextRect = text_objects(text, largText)
TextRect.center = ((SCREENWIDTH / 1), (SCREENHEIGHT / 1))
screen.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
screen.blit(bg, (0, 0))
pygame.display.flip()
# Main game loop
run = True
clock = pygame.time.Clock()
#TIP - lots of our actions take place in our while loop cause we want the function/program to run consistently
while run:
# Drawing on Screen
screen.fill(GREEN)
# Draw The Road
pygame.draw.rect(screen, GREY, [40, 0, 300, 500])
# Draw Line painting on the road
pygame.draw.line(screen, WHITE, [185, 0], [185, 500], 5)
#Finish line
pygame.draw.rect(screen, BLACKWHITE, [50, 50, 280, 40])
pygame.draw.line(screen, WHITE, [50, 70], [330, 70], 5)
font = pygame.font.SysFont("Impact", 35)
text = font.render("Finish line!", 4, (150, 50, 25))
screen.blit(text, (180 - (text.get_width() / 2), -8))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# Number of frames per secong e.g. 60
clock.tick(60)
keys = pygame.key.get_pressed()
if keys[pygame.K_1]:
CarSound.play()
playerCar_position = -0.1
if keys[pygame.K_q]:
playerCar_position = 0.1
if keys[pygame.K_2]:
CarSound_two.play()
playerCar_position_two = -0.1
if keys[pygame.K_w]:
playerCar_position_two = 0.1
if keys[pygame.K_3]:
CarSound_three.play()
playerCar_position_three = -0.1
if keys[pygame.K_e]:
playerCar_position_three = 0.1
if keys[pygame.K_4]:
CarSound_four.play()
playerCar_position_four = -0.1
if keys[pygame.K_r]:
playerCar_position_four = 0.1
# our functions
playerY += playerCar_position
playerY_two += playerCar_position_two
playerY_three += playerCar_position_three
playerY_four += playerCar_position_four
player(playerX, playerY)
player_two(playerX_two, playerY_two)
player_three(playerX_three, playerY_three)
player_four(playerX_four, playerY_four)
finish_line_rect = pygame.Rect(50, 70, 235, 32)
Here is where I been trying to see if I can get my text to pop up but haven’t had any luck I do get an output of which player crosses the line from first to last car but am trying to get a text that says “Whichever car crosses first won Game over” as soon the car crosses the line
# Did anyone cross the line?
if (finish_line_rect.collidepoint(playerX, playerY)):
if finish_text[:8] != "Player 1": # so it doesnt do this every frame the car is intersecting
finish_text = "Player 1 is " + placings[players_finished]
players_finished += 1
print("Player (one) has crossed into finish line!")
elif (finish_line_rect.collidepoint(playerX_two, playerY_two)):
if finish_text[:8] != "Player 2":
print("Player one has crossed into finish line first other car lost!")
finish_text = "Player 2 is " + placings[players_finished]
players_finished += 1
elif (finish_line_rect.collidepoint(playerX_three, playerY_three)):
if finish_text[:8] != "Player 3":
print("Player two has crossed into finish line first other car lost!")
finish_text = "Player 3 is " + placings[players_finished]
players_finished += 1
elif (finish_line_rect.collidepoint(playerX_four, playerY_four)):
if finish_text[:8] != "Player 4":
print("Player two has crossed into finish line first other car lost!")
finish_text = "Player 4 is " + placings[players_finished]
players_finished += 1
#print("Player two has crossed into finish line first other car lost!")
#finish_text = "Player 4 is " + placings[players_finished]
pygame.display.flip()
pygame.quit()
Try something like this. At the end of the loop, if there is a finisher, blit the text to the screen the same way you wrote "Finish Line!"
if (players_finished and finish_text):
font = pygame.font.SysFont("Impact", 35)
text = font.render(finish_text, 4, (150, 250, 25))
screen.blit(text, (180 - (text.get_width() / 2), -8))
If you want the 'popup' to be temporary, you will need add a timer or counter to clear the finish_text so it stops being drawn.
I am trying to get a text to say "Game Over" for 5 seconds once a car reaches the finish line.
import pygame, random
from time import sleep
pygame.init()
# music/sounds
CarSound = pygame.mixer.Sound("image/CAR+Peels+Out.wav")
CarSound_two = pygame.mixer.Sound("image/racing01.wav")
CarSound_three = pygame.mixer.Sound("image/RACECAR.wav")
CarSound_four = pygame.mixer.Sound("image/formula+1.wav")
music = pygame.mixer.music.load("image/Led Zeppelin - Rock And Roll (Alternate Mix) (Official Music Video).mp3")
pygame.mixer.music.play(-1)
bg = pygame.image.load('image/Crowds.png')
#Setting up our colors that we are going to use
GREEN = (20, 255, 140)
GREY = (210, 210, 210)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
PURPLE = (255, 0, 255)
BLACKWHITE =(96, 96, 96)
SCREENWIDTH = 400
SCREENHEIGHT = 500
size = (SCREENWIDTH, SCREENHEIGHT)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Car Racing")
Icon = pygame.image.load("image/redca_iconr.png")
pygame.display.set_icon((Icon))
# This will be a list that will contain all the sprites we intend to use in our game.
#all_sprites_list = pygame.sprite.Group()
#player
playerIMG = pygame.image.load("image/red_racecar.png")
playerX = 250
playerY = 450
playerCar_position = 0
#player2
playerIMG_two = pygame.image.load("image/greencar.png")
playerX_two = 150
playerY_two = 450
playerCar_position_two = 0
#player3
playerIMG_three = pygame.image.load("image/Orangecar.png")
playerX_three = 50
playerY_three = 450
playerCar_position_three = 0
#player4
playerIMG_four = pygame.image.load("image/yellow_car.png")
playerX_four = 200
playerY_four = 450
playerCar_position_four = 0
#Putting cars to the screen
def player(x, y):
screen.blit(playerIMG, (x, y))
def player_two(x, y):
screen.blit(playerIMG_two, (x, y))
def player_three(x, y):
screen.blit(playerIMG_three, (x, y))
def player_four(x, y):
screen.blit(playerIMG_four, (x, y))
finish_text = ""
font2 = pygame.font.SysFont("Papyrus", 65)
players_finished = 0
placings = ["1st", "2nd", "3rd", "4th"]
def text_objects(text, font):
textSurface = font.render(text, True, RED)
return textSurface, textSurface.get_rect()
def message_display(text):
largText =pygame.font.Font("Mulish-Regular.ttf", 15)
TextSurf, TextRect = text_objects(text, largText)
TextRect.center = ((SCREENWIDTH / 1), (SCREENHEIGHT / 1))
screen.blit(TextSurf, TextRect)
screen.blit(bg, (0, 0))
pygame.display.flip()
**Here is the function on where am trying to show the text temporary on the screen**
def Game_over():
if (players_finished):
clock.tick(1)
pygame.time.delay(5000)
font = pygame.font.SysFont("Impact", 25)
text = font.render("Game over!", 4, (0, 66, 37))
screen.blit(text, (185 - (text.get_width() / 2), 120))
pygame.display.flip()
# Main game loop
run = True
clock = pygame.time.Clock()
#TIP - lots of our actions take place in our while loop cause we want the function/program to run consistently
while run:
# Drawing on Screen
screen.fill(GREEN)
# Draw The Road
pygame.draw.rect(screen, GREY, [40, 0, 300, 500])
# Draw Line painting on the road
pygame.draw.line(screen, WHITE, [185, 0], [185, 500], 5)
#Finish line
pygame.draw.rect(screen, BLACKWHITE, [50, 50, 280, 40])
pygame.draw.line(screen, WHITE, [50, 70], [330, 70], 5)
font = pygame.font.SysFont("Impact", 35)
text = font.render("Finish line!", 4, (150, 50, 25))
screen.blit(text, (180 - (text.get_width() / 2), -8))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# Number of frames per secong e.g. 60
clock.tick(60)
keys = pygame.key.get_pressed()
if keys[pygame.K_1]:
CarSound.play()
playerCar_position = -0.1
if keys[pygame.K_q]:
playerCar_position = 0.2
if keys[pygame.K_2]:
CarSound_two.play()
playerCar_position_two = -0.1
if keys[pygame.K_w]:
playerCar_position_two = 0.2
if keys[pygame.K_3]:
CarSound_three.play()
playerCar_position_three = -0.1
if keys[pygame.K_e]:
playerCar_position_three = 0.2
if keys[pygame.K_4]:
CarSound_four.play()
playerCar_position_four = -0.1
if keys[pygame.K_r]:
playerCar_position_four = 0.2
# our functions
playerY += playerCar_position
playerY_two += playerCar_position_two
playerY_three += playerCar_position_three
playerY_four += playerCar_position_four
player(playerX, playerY)
player_two(playerX_two, playerY_two)
player_three(playerX_three, playerY_three)
player_four(playerX_four, playerY_four)
finish_line_rect = pygame.Rect(50, 70, 235, 32)
# Did anyone cross the line?
if (finish_line_rect.collidepoint(playerX, playerY)):
if finish_text[:8] != "Player 1": # so it doesnt do this every frame the car is intersecting
finish_text = "Player 1 is " + placings[players_finished]
players_finished += 1
print("Player (one) has crossed into finish line!")
elif (finish_line_rect.collidepoint(playerX_two, playerY_two)):
if finish_text[:8] != "Player 2":
print("Player one has crossed into finish line first other car lost!")
finish_text = "Player 2 is " + placings[players_finished]
players_finished += 1
elif (finish_line_rect.collidepoint(playerX_three, playerY_three)):
if finish_text[:8] != "Player 3":
print("Player two has crossed into finish line first other car lost!")
finish_text = "Player 3 is " + placings[players_finished]
players_finished += 1
elif (finish_line_rect.collidepoint(playerX_four, playerY_four)):
if finish_text[:8] != "Player 4":
print("Player two has crossed into finish line first other car lost!")
finish_text = "Player 4 is " + placings[players_finished]
players_finished += 1
if (players_finished and finish_text):
font = pygame.font.SysFont("Impact", 25)
text = font.render(finish_text, 4, (0, 66, 37))
screen.blit(text, (185 - (text.get_width() / 2), 90))
Game_over()
pygame.display.update()
#print("Player two has crossed into finish line first other car lost!")
#finish_text = "Player 4 is " + placings[players_finished]
pygame.display.flip()
pygame.quit()
add a variable at the start of your code with the name tick_var and if you want a fixed tickrate remove it from the parameter of the function if not change your code and att the tickrate as a paramter of the function when used.
def Game_over(tickrate):
global tick_var
tick_var +=1
if(tick_var>5*tickrate):
if (players_finished):
clock.tick(tickrate)
font = pygame.font.SysFont("Impact", 25)
text = font.render("Game over!", 4, (0, 66, 37))
screen.blit(text, (185 - (text.get_width() / 2), 120))
pygame.display.flip()
I had an earlier post deleted because there are similar posts. I appreciate that but because I am so inexperienced with pygame (I literally began using it last week), I cant make heads or tails of the code. Also, I am finding it difficult to apply to my game. Firstly, I do not need it to relate to a moving player character as they will always travel from a set position (400, 450). Also, I preferably need it to do this when the left mouse button is pressed but if it is easier to use a key then that is fine. I simply do not have the expertise to use past posts and apply it to my program. Thanks. Just to clarify, my game is going to be a duck hunt-like target shooter game.
#Setting window dimensions and caption (Module 1)
pygame.init()
window = pygame.display.set_mode((800, 575))
pygame.display.set_caption("TARGET PRACTICE")
#Colour variables (Module 1)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (200, 0, 0)
GREEN = (0, 200, 0)
BLUE = (0, 0, 200)
exec = True
#Target class created (Module 5)
class Target:
def __init__(self, x, y, h, w, v):
self.x = x
self.y = y
self.h = h
self.w = w
self.v = v
#Instantiation of targets (Module 5)
target_1 = Target(0, 80, 60, 40, 0.5)
target_2 = Target(0, 100, 60, 40, 0.5)
target_3 = Target(0, 50, 60, 40, 0.5)
target_4 = Target(0, 75, 60, 40, 0.5)
target_5 = Target(0, 45, 60, 40, 0.5)
target_6 = Target(0, 85, 60, 40, 0.5)
#Declaring variables to be used in the while loop (Module 5)
clock = 0
target_2_threshold = 500
target_3_threshold = 1000
target_4_threshold = 1500
target_5_threshold = 2000
target_6_threshold = 2500
#Setting player sprite dimension variables (Module 6)
player_sprite_x = 357.5
player_sprite_y = 450
player_sprite_h = 125
player_sprite_w = 85
while exec:
pygame.time.delay(1)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exec = False
#Defines movement of targets and sets delay between drawings (Module 5)
clock += 1
target_1.x += target_1.v
if clock > target_2_threshold:
target_2.x += target_2.v
if clock > target_3_threshold:
target_3.x += target_3.v
if clock > target_4_threshold:
target_4.x += target_4.v
if clock > target_5_threshold:
target_5.x += target_5.v
if clock > target_6_threshold:
target_6.x += target_6.v
#Fill the background (Module 5)
window.fill(RED)
#Redraw each target in every frame (Module 5)
pygame.draw.rect(window, BLUE, (target_1.x, target_1.y, target_1.h, target_1.w))
if clock > target_2_threshold:
pygame.draw.rect(window, BLUE, (target_2.x, target_2.y, target_2.h, target_2.w))
if clock > target_3_threshold:
pygame.draw.rect(window, BLUE, (target_3.x, target_3.y, target_3.h, target_3.w))
if clock > target_4_threshold:
pygame.draw.rect(window, BLUE, (target_4.x, target_4.y, target_4.h, target_4.w))
if clock > target_5_threshold:
pygame.draw.rect(window, BLUE, (target_5.x, target_5.y, target_5.h, target_5.w))
if clock > target_6_threshold:
pygame.draw.rect(window, BLUE, (target_6.x, target_6.y, target_6.h, target_6.w))
#Draw the player sprite (Module 6)
pygame.draw.rect(window, BLUE, (player_sprite_x, player_sprite_y, player_sprite_w, player_sprite_h))
pygame.display.update()
pygame.quit()
Here are some brief notes to get you pointed in the right direction. People often write questions that amount to "Gimme teh codez!", so very open and broad questions are often greeted (quite rightly) with negativity.
So...
First you need to grab the mouse cursor. This is achieved by handling the mouse events in your main event-loop:
while exec:
#pygame.time.delay(1) # <-- DON'T DO THIS
for event in pygame.event.get():
if event.type == pygame.QUIT:
exec = False
elif event.type == pygame.MOUSEBUTTONUP: # mouse button released
mouse_position = pygame.mouse.get_pos()
# TODO: handle mouse click at <mouse_position>
Note: I like to use MOUSEBUTTONUP rather than DOWN, because this is how modern GUIs tend to work - on-screen operations activate on release, but it's up to you.
Now you have the click-position, how do you launch a bullet from the bottom-centre of the screen to the mouse co-ordinates?
Well, first what is bottom-centre? It's half the width of the window, and maybe some factor from the bottom. In PyGame the top-left corner of the screen is (0, 0), and the bottom-left is ( 0, window_height-1 ). I always store the window size in variables, so computing this position is easy, and it frees the code from having to be modified if the window/screen size changes.
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 575
# Firing position is 98% bottom, middle of the window/screen.
start_position = ( ( WINDOW_WIDTH // 2, int( WINDOW_HEIGHT * 0.98 ) )
So then given a mouse-click, the code needs to make the bullet travel from start_position to mouse_position. This can be calculated, by working out an x and y speed which should be applied, each update, to the projectile. Obviously a projectile travelling straight down has a speed of ( 0, something ), and a projectile going directly right has a speed of ( something, 0 ). Obviously if travelling up or left, the something would be negative because of the way PyGame lays-out its co-ordinates. The point is that there are separate components of change: x for the horizontal movement, and y for the vertical .
To calculate this x and y speed (technically a velocity vector), the code needs to determine the line from start to end, and then normalise it (a fancy way of saying "divide it by it's length").
I'm assume you know the line-length formula already, so this part should be easy. It makes the calculations simpler if the code temporarily offsets both points as-if the origin was at (0,0), since the direction is still the same.
Once the code has the velocity vector (x, y), each animation update-cycle simply add these component-speeds to the co-ordinate of the projectile. You may need to store the co-ordinates as real numbers, since adding small amounts (e.g.: 0.2) to an integer tends to throw away the change. This is because some-integer + 0.2 -> some-integer.
Anyway, see how you go with this information. If trouble persists ... ask another question!
Use event pygame.MOUSEBUTTONDOWN to get mouse click and its position.
You can use pygame.math.Vector2() to create vector between mouse and player. And then you can use normalize() to create value which you can use as bullet's direction.
And keep in variable or list bullet's position and bullet's direction
all_bullets = []
while exec:
pygame.time.delay(1)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exec = False
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
print("[shoot!] mouse position:", event.pos)
dx = event.pos[0] - (player_sprite_x+ player_sprite_w//2)
dy = event.pos[1] - player_sprite_y
direction = pygame.math.Vector2(dx, dy).normalize()
bullet = {'x': player_sprite_x+42, 'y': player_sprite_y, 'direction': direction}
all_bullets.append(bullet)
Later you can use for-loop to move every bullet on list and keep only bullets which are still on screen
all_bullets_keep = []
for item in all_bullets:
item['x'] += item['direction'][0] # item['direction'][0] * 2
item['y'] += item['direction'][1] # item['direction'][1] * 2
# keep bullet if it is still on screen
if 0 < item['x'] < 800 and 0 < item['y'] < 575:
all_bullets_keep.append(item)
all_bullets = all_bullets_keep
#print(len(all_bullets), end='\r')
Finally you can use for-loop to draw all bullets
for item in all_bullets:
pygame.draw.rect(window, BLUE, (item['x']-5, item['y']-5, 10, 10))
It still need to check collision with targets but it would be easier if you would keep targets on list and use pygame.Rect()` to keep position and size because it has special methods to check collisions.
So now you have work to use lists with tagets and pygame.Rect()
import pygame
pygame.init()
window = pygame.display.set_mode((800, 575))
pygame.display.set_caption("TARGET PRACTICE")
#Colour variables (Module 1)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (200, 0, 0)
GREEN = (0, 200, 0)
BLUE = (0, 0, 200)
exec = True
#Target class created (Module 5)
class Target:
def __init__(self, x, y, h, w, v):
self.x = x
self.y = y
self.h = h
self.w = w
self.v = v
#Instantiation of targets (Module 5)
target_1 = Target(0, 80, 60, 40, 0.5)
target_2 = Target(0, 100, 60, 40, 0.5)
target_3 = Target(0, 50, 60, 40, 0.5)
target_4 = Target(0, 75, 60, 40, 0.5)
target_5 = Target(0, 45, 60, 40, 0.5)
target_6 = Target(0, 85, 60, 40, 0.5)
#Declaring variables to be used in the while loop (Module 5)
clock = 0
target_2_threshold = 500
target_3_threshold = 1000
target_4_threshold = 1500
target_5_threshold = 2000
target_6_threshold = 2500
#Setting player sprite dimension variables (Module 6)
player_sprite_x = 357.5
player_sprite_y = 450
player_sprite_h = 125
player_sprite_w = 85
all_bullets = []
while exec:
pygame.time.delay(1)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exec = False
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
print("[shoot!] mouse position:", event.pos)
dx = event.pos[0] - (player_sprite_x+ player_sprite_w//2)
dy = event.pos[1] - player_sprite_y
direction = pygame.math.Vector2(dx, dy).normalize()
bullet = {'x': player_sprite_x+42, 'y': player_sprite_y, 'direction': direction}
all_bullets.append(bullet)
#Defines movement of targets and sets delay between drawings (Module 5)
clock += 1
target_1.x += target_1.v
if clock > target_2_threshold:
target_2.x += target_2.v
if clock > target_3_threshold:
target_3.x += target_3.v
if clock > target_4_threshold:
target_4.x += target_4.v
if clock > target_5_threshold:
target_5.x += target_5.v
if clock > target_6_threshold:
target_6.x += target_6.v
all_bullets_keep = []
for item in all_bullets:
item['x'] += item['direction'][0] # item['direction'][0] * 2
item['y'] += item['direction'][1] # item['direction'][1] * 2
# keep bullet if it is still on screen
if 0 < item['x'] < 800 and 0 < item['y'] < 575:
all_bullets_keep.append(item)
all_bullets = all_bullets_keep
#print(len(all_bullets), end='\r')
#Fill the background (Module 5)
window.fill(RED)
#Redraw each target in every frame (Module 5)
pygame.draw.rect(window, BLUE, (target_1.x, target_1.y, target_1.h, target_1.w))
if clock > target_2_threshold:
pygame.draw.rect(window, BLUE, (target_2.x, target_2.y, target_2.h, target_2.w))
if clock > target_3_threshold:
pygame.draw.rect(window, BLUE, (target_3.x, target_3.y, target_3.h, target_3.w))
if clock > target_4_threshold:
pygame.draw.rect(window, BLUE, (target_4.x, target_4.y, target_4.h, target_4.w))
if clock > target_5_threshold:
pygame.draw.rect(window, BLUE, (target_5.x, target_5.y, target_5.h, target_5.w))
if clock > target_6_threshold:
pygame.draw.rect(window, BLUE, (target_6.x, target_6.y, target_6.h, target_6.w))
for item in all_bullets:
pygame.draw.rect(window, BLUE, (item['x']-5, item['y']-5, 10, 10))
#Draw the player sprite (Module 6)
pygame.draw.rect(window, BLUE, (player_sprite_x, player_sprite_y, player_sprite_w, player_sprite_h))
pygame.display.update()
pygame.quit()