Behind the scenes PyGame game works but image won't move - python

I am trying to make my own own game. Before, the car image would move really well but then and put my loop in a "def" thing so that the game could restart when the car crash in the wall and when you win. Now, everything works only the game doesn't seem to update to the screen because the car won't move. The game still seems to work behind the screen because when I make the car crash without seeing it move it plays the crash segment. PyGame doesn't say day is an error. this is kind of new to me and I really don,t understand what the problem.
here is part of my code:
#Setting and variables
display_width = 1570
display_height = 450
car_width = 98
car_height = 66
clock = pygame.time.Clock()
wn = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('My own game')
finish_line = pygame.image.load('myOwnFinishreal.png')
carImg = pygame.image.load('myOwnRGame.png')
carY = 192
carX = 10
Xchange = 0
Ychange = 0
Xfin = 1480
Yfin = 0
carY = 192
carX = 10
#racecar
def car(x,y):
wn.blit(carImg, (carX, carY))
#finish line
def finish():
wn.blit(finish_line, (Xfin, Yfin))
#Crashing
def textObjects(text, font):
textSurface = font.render(text, True, red)
return textSurface, textSurface.get_rect()
def displayMessage(text):
textFont1 = pygame.font.Font('freesansbold.ttf', 32)
textSurf, textRect = textObjects(text, textFont1)
textRect.center = ((display_width/2),(display_height/2))
while True:
wn.blit(textSurf, textRect)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
pygame.quit()
if event.key == pygame.K_SPACE:
gameLoop()
pygame.display.update()
def crash():
displayMessage('You crashed!Press X to quit, _SPACE_ to restart!')
def win():
displayMessage('Bravo! You are the best car runner! Press X to quit _SPACE_ to restart.')
#Game loop
def gameLoop():
carY = 192
carX = 10
Xchange = 0
Ychange = 0
alive = True
losing = True
while alive and losing:
carX += Xchange
carY += Ychange
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
pygame.quit()
if event.key == pygame.K_UP:
Xchange = 0
Ychange = 0
Xchange = 2.5
elif event.key == pygame.K_LEFT:
Xchange = 0
Ychange = 0
time.sleep(0.85)
Ychange = -3
elif event.key == pygame.K_RIGHT:
Xchange = 0
Ychange = 0
time.sleep(0.85)
Ychange = 3
elif event.key == pygame.K_DOWN:
Xchange = 0
Ychange = 0
time.sleep(0.85)
Xchange = -3
if carY <= -15 or carY >= display_height - 15:
Xchange = 0
Ychange = 0
crash()
if carX >= display_width:
Xchange = 0
Ychange = 0
win()
if carX <= 0:
carX = 10
#350 250 120 30
wn.fill(grey)
finish()
carX += Xchange
carY += Ychange
car(carX, carY)
pygame.display.update()
clock.tick(60)
pygame.quit()
gameLoop()
Looking forward for your help and bid thanks!

You have to use the arguments x and y rather than carX and carY in the function car:
def car(x,y):
wn.blit(carImg, (x, y))

Related

K_SPACE bug pygame [duplicate]

This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
Closed 1 year ago.
from pygame.locals import *
import random
import pygame
from pygame.constants import K_RIGHT
# Initialize the pygame
pygame.init
# create the screen
screen = pygame.display.set_mode((800, 600))
# background
background = pygame.image.load('bg.png')
# Title and Icon
pygame.display.set_caption("Space Invaders")
icon = pygame.image.load('ufo.png')
pygame.display.set_icon(icon)
# Player
playerImg = pygame.image.load('player.png')
playerX = 370
playerY = 480
playerX_change = 0
def player(x, y):
screen.blit(playerImg, (x, y))
# Enemy
enemyImg = pygame.image.load('alien.png')
enemyX = random.randint(0, 736)
enemyY = 50
enemyX_change = 1
enemyY_change = 40
def enemy(x, y):
screen.blit(enemyImg, (x, y))
# Bullet
# ready - you can't see bullet
# fire - you can see bullet and it's moving
bulletImg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bulletX_change = 1
bulletY_change = 10
bullet_state = "ready"
def fire_bullet(x, y):
global bullet_state
bullet_state = "fire"
screen.blit(bulletImg, (x+16, y+10))
# Game Loop
running = True
while running:
# Changing RGB of background
screen.fill((0, 0, 0))
# Background image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# if keystroke is pressed check wheter its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
fire_bullet(playerX, bulletY)
if event.key == pygame.K_LEFT:
playerX_change = -3
if event.key == pygame.K_RIGHT:
playerX_change = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# bounds
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# enemy movement
enemyX += enemyX_change
if enemyX <= 0:
enemyX_change = 1
enemyY += enemyY_change
elif enemyX >= 736:
enemyX_change = -1
enemyY += enemyY_change
# bullet movement
if bullet_state is "fire":
fire_bullet(playerX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
enemy(enemyX, enemyY)
pygame.display.update()
I'm working on a tutorial project for begginers in PyGame. It is a copy of Space Inviders. When i'm pressing space nothing is happening, but when i press ctrl + shift + space it reacts as space, also after changing K_SPACE to K_LSHIFT or K_UP it is working but with other buttons it is not, I've tried changing "fire" and "ready" to True or False but it didn't fixed my problem
It is a matter of Indentation. You have to evaluate the events in the event loop instead of the application loop:
#Game Loop
running = True
while running:
# Changing RGB of background
screen.fill((0, 0, 0))
# Background image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# INDENTATION
#-->|
# if keystroke is pressed check wheter its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
fire_bullet(playerX, bulletY)
if event.key == pygame.K_LEFT:
playerX_change = -3
if event.key == pygame.K_RIGHT:
playerX_change = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0

Why wont this blit on my screen?

I know this is going to be (hopefully) an easy fix, but I cannot get the gameover screen to blit on my screen. I have thought through this for the past two hours, and none of my tweaks are working. Any help would be greatly appreciated!
This file contains the main file loop as while as sprite group
updates and general updates/renders for the program
import pygame, sys
import player
import random
import math
from constants import *
from bullet import *
from block import *
pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption("Open")
clock = pygame.time.Clock()
def main():
moveX = 0
moveY = 0
sprite_list = pygame.sprite.Group()
bullet_list = pygame.sprite.Group()
block_list = pygame.sprite.Group()
main_player = player.Player()
sprite_list.add(main_player)
main_player.rect.x = 400
main_player.rect.y = 550
for i in range(1,10):
blocks = Block()
blocks.center_x = random.randrange(760)
blocks.center_y = random.randrange(400)
blocks.radius = random.randrange(10,200)
blocks.angle = random.random() * 4 * math.pi
blocks.speed = 0.04
block_list.add(blocks)
sprite_list.add(blocks)
font = pygame.font.Font(None, 36)
game_over = False
score = 0
level = 1
gameLoop = True
while gameLoop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
moveX = 5
if event.key == pygame.K_LEFT:
moveX = -5
if event.key == pygame.K_DOWN:
moveY = 5
if event.key == pygame.K_UP:
moveY = -5
if event.key == pygame.K_SPACE:
bullets = Bullet()
bullets.rect.x = main_player.rect.x + 16
bullets.rect.y = main_player.rect.y + 16
sprite_list.add(bullets)
bullet_list.add(bullets)
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT and moveX >= 0:
moveX = 0
if event.key == pygame.K_LEFT and moveX <= 0:
moveX = 0
if event.key == pygame.K_DOWN and moveY >= 0:
moveY = 0
if event.key == pygame.K_UP and moveY <= 0:
moveY = 0
for bullets in bullet_list:
block_hit_list = pygame.sprite.spritecollide(bullets, block_list, True)
for block in block_hit_list:
score += 1
bullet_list.remove(bullets)
sprite_list.remove(bullets)
if bullets.rect.y < 0:
bullet_list.remove(bullets)
sprite_list.remove(bullets)
if pygame.sprite.spritecollide(main_player, block_list, True):
gameLoop = False
game_over = True
sprite_list.update()
screen.fill(BLACK)
sprite_list.draw(screen)
main_player.rect.x += moveX
main_player.rect.y += moveY
score_text = font.render("Score: "+str(score), True, WHITE)
screen.blit(score_text,[10,10])
level_text = font.render("Level: "+str(level), True, WHITE)
screen.blit(level_text,[115,10])
if game_over == True:
you_lose_text = font.render("YOU SUCK", True, RED)
screen.blit(you_lose_text, [300,300])
pygame.time.wait(1000)
break
clock.tick(60)
pygame.display.update()
pygame.quit()
if __name__ == "__main__":
main()
HERE IS MY ISSUE:
if game_over == True:
you_lose_text = font.render("YOU SUCK", True, RED)
screen.blit(you_lose_text, [300,300])
pygame.time.wait(1000)
break
I am getting no error, and the pygame.time.wait function is working correctly? Why is it just skipping over displaying the text?
Maybe it is not the best solution but your code doesn't need better.
blit draws in buffer. You have to use update before wait to send data from buffer to screen.
if game_over == True:
you_lose_text = font.render("YOU SUCK", True, RED)
screen.blit(you_lose_text, [300,300])
pygame.display.update() # send on screen
pygame.time.wait(1000)
break
clock.tick(60)
pygame.display.update()
pygame.quit()

Pygame Help Trying to add apples in Snakegame

import pygame
import random
import time
pygame.init()
display_width = 800
display_height = 600
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('slither')
white = (255, 255, 255)
black = (0,0,0)
red = (252,25,25)
blue = (20,20,250)
purple = (90,33,146)
movement_size = 10
block_size = 20
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 25)
def message_to_screen(msg,colour):
screen_text = font.render(msg, True, colour)
gameDisplay.blit(screen_text, [display_width/2, display_height/2])
def gameLoop():
gameExit = False
gameOver = False
lead_x = display_width/2.0
lead_y = display_height/2.0
lead_x_change = 0
lead_y_change = 0
randAppleX = random.randrange(0, display_width-block_size)
randAppleY = random.randrange(display_height-block_size, 0)
while not gameExit:
while gameOver == True:
gameDisplay.fill(purple)
message_to_screen("Game Over, Press 'C' to play again or 'Q' to Quit", red)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameExit = True
gameOver = False
if event.key == pygame.K_c:
gameLoop()
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
lead_x_change -= movement_size
lead_y_change = 0
elif event.key == pygame.K_RIGHT:
lead_x_change += movement_size
lead_y_change= 0
elif event.key == pygame.K_UP:
lead_y_change -= movement_size
lead_x_change= 0
elif event.key == pygame.K_DOWN:
lead_y_change += movement_size
lead_x_change= 0
if lead_x >= 782 or lead_x < 0 or lead_y >= 582 or lead_y < 0:
gameOver = True
lead_x += lead_x_change
lead_y += lead_y_change
gameDisplay.fill(white)
pygame.draw.rect(gameDisplay, red, [randAppleX, randAppleY, block_size, block_size])
pygame.draw.rect(gameDisplay, black, [lead_x, lead_y, block_size, block_size])
pygame.display.update()
clock.tick(11)
pygame.quit()
quit()
gameLoop()
I was trying to add 'apples' in my snake game. However I was troubled in doing so. Any help debugging code would be very much appreciated! I'm getting some error on lines; 94,42 and 218 something has gone horribly wrong with the randrange stuff.
http://i63.tinypic.com/1h4ggj.png <----- To See
the error happens in
randAppleY = random.randrange(display_height-block_size, 0)
As the error stack trace indicates that randrange function got parameters start=580, stop=0. From inspecting the source file for this function shows that the default value for step is 1.
This is causing the problem as 0 is less than 580 and connot be reached by adding 1 (step parameter) any number of times.
What you can do to fix this is either pass step parameter as -1
randAppleY = random.randrange(display_height-block_size, 0, -1)
Or pass the smaller value as start and larger value as stop parameter
randAppleY = random.randrange(0, display_height-block_size)
import pygame
import random
import time
pygame.init()
display_width = 800
display_height = 600
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('slither')
white = (255, 255, 255)
black = (0,0,0)
red = (252,25,25)
blue = (20,20,250)
purple = (90,33,146)
movement_size = 10
block_size = 20
clock = pygame.time.Clock()
gameExit = gameOver = False
font = pygame.font.SysFont(None, 25)
def message_to_screen(msg,colour):
screen_text = font.render(msg, True, colour)
gameDisplay.blit(screen_text, [display_width/2, display_height/2])
def gameLoop():
gameExit = False
gameOver = False
lead_x = display_width/2.0
lead_y = display_height/2.0
lead_x_change = 0
lead_y_change = 0
randAppleX = random.randint(0, display_width-block_size)
randAppleY = random.randint(0,display_height-block_size)
while not gameExit:
while gameOver:
gameDisplay.fill(purple)
message_to_screen("Game Over, Press 'C' to play again or 'Q' to Quit", red)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameExit = True
gameOver = False
if event.key == pygame.K_c:
gameLoop()
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
lead_x_change -= movement_size
lead_y_change = 0
elif event.key == pygame.K_RIGHT:
lead_x_change += movement_size
lead_y_change= 0
elif event.key == pygame.K_UP:
lead_y_change -= movement_size
lead_x_change= 0
elif event.key == pygame.K_DOWN:
lead_y_change += movement_size
lead_x_change= 0
if lead_x >= 782 or lead_x < 0 or lead_y >= 582 or lead_y < 0:
gameOver = True
lead_x += lead_x_change
lead_y += lead_y_change
gameDisplay.fill(white)
pygame.draw.rect(gameDisplay, red, [randAppleX, randAppleY, block_size, block_size])
pygame.draw.rect(gameDisplay, black, [lead_x, lead_y, block_size, block_size])
pygame.display.update()
clock.tick(11)
pygame.quit()
quit()
gameLoop()

how to stop movement if the object hits the boundary in pygame

import pygame
import random
pygame.init()
black = (0,0,0)
red = (255,0,0)
display_width = 800
display_height = 600
FPS = 20
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("The Space Jumpers")
img = pygame.image.load('starship2.png')
spritesize = 50
boundlimit = 200
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 25)
def gameLoop():
gameExit = False
gameOver = False
lead_x = display_width / 2
lead_y = display_height / 2
xchange = 0
ychange = 0
randBlockX = random.randrange(0,boundlimit+1)
randBlockY = random.randrange(0,575)
while not gameExit:
gameDisplay.blit(img, [lead_x,lead_y])
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
xchange = -spritesize / 2
ychange = 0
if event.key == pygame.K_RIGHT:
xchange = spritesize / 2
ychange = 0
if event.key == pygame.K_UP:
ychange = -spritesize / 2
xchange = 0
if event.key == pygame.K_DOWN:
ychange = spritesize / 2
xchange = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
xchange = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
ychange = 0
lead_x += xchange
lead_y += ychange
gameDisplay.fill(black)
pygame.draw.rect(gameDisplay,red, [randBlockX, randBlockY, 600, 25])
if (lead_x+spritesize < randBlockX and randBlockY<lead_y<randBlockY+25) :
randBlockX = random.randrange(0,boundlimit+1)
randBlockY = random.randrange(0,575)
elif (lead_x+spritesize < randBlockX and randBlockY<lead_y<randBlockY+25 ):
randBlockX = random.randrange(0,boundlimit+1)
randBlockY = random.randrange(0,575)
elif (lead_x > randBlockX+600 and randBlockY<lead_y<randBlockY+25):
randBlockX = random.randrange(0,boundlimit+1)
randBlockY = random.randrange(0,575)
elif (lead_x > randBlockX+600 and randBlockY<lead_y<randBlockY+25):
randBlockX = random.randrange(0,boundlimit+1)
randBlockY = random.randrange(0,575)
clock.tick(FPS)
pygame.quit()
quit()
gameLoop()
This is my current code and in this code when the object(sprite) hits the boundary, it keeps on moving but what I want to do is, I want to stop the movement of the object when it hits the boundary, for example when the object hits the left boundary it shouldnt move left anymore. You kind of get the idea, its a simple game
Instead of using two variables (lead_x, lead_y) to store the position of the object, use a Rect. It's as simple as
gameDisplay = pygame.display.set_mode((display_width,display_height))
gameDisplay_rect = gameDisplay.get_rect()
img = pygame.image.load('starship2.png')
img_rect = img.get_rect(center=gameDisplay_rect.center)
To draw you object, simply do:
gameDisplay.blit(img, img_rect)
Now, to move your object, instead of
lead_x += xchange
lead_y += ychange
you can do
img_rect.move_ip(lead_x, lead_y)
img_rect.clamp_ip(gameDisplay_rect)
clamp_ip will then prevent your object from leaving the screen.
I think this will work:
try changing your if statement(if pygame.key == pygame.K_LEFT:) to(if pygame.key == pygame.K_LEFT and x > 0:)
i have been struggling with the same thing for a school project and have gotten it so that it stops the sprite if you touch the border, but if you spam that button you can get through. I currently have an if statement saying(If x < 0: x_change = 0), but i have not tried the one i suggested. i hope it works.
sloth's method is for sure better in many ways, but if you still want to keep your old lead_x, lead_y structure you could just add a separate statements outside of the event loop:
if lead_x <= 0:
lead_x += 10 # just use any small distance to push you back to place every frame
elif lead_x >= display_width:
lead_x -= 10
and so on for every direction.

How can I make the movement smoother?

I'm developing a very basic engine, basing myself on tutorials from Pygame, and I'm having a little problem with "smoothness". How do I make my player walk "smoother"?
My event handler is pretty basic, pretty standard, nothing new, and I even figured out how to make a "boost" (run) for test. But the thing is, at the pygame.KEYUP, those lots of zeros destroy the "smoothness" of my little player, and I don't want that, but I don't want it to walk ad infinitum.
import pygame
import gfx
# Main Class
class Setup:
background = gfx.Images.background
player = gfx.Images.player
pygame.init()
# Configuration Variables:
black = (0,0,0)
white = (255,255,255)
green = (0,255,0)
red = (255,0,0)
title = "Ericson's Game"
# Setup:
size = [700,700]
screen = pygame.display.set_mode(size)
pygame.display.set_caption(title)
done = False
clock = pygame.time.Clock()
# Logic Variables
x_speed = 0
y_speed = 0
x_speed_boost = 0
y_speed_boost = 0
x_coord = 350
y_coord = 350
screen.fill(white)
# Main Loop:
while done == False:
screen.blit(background,[0,0])
screen.blit(player,[x_coord,y_coord])
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
done = True
if event.key == pygame.K_a:
x_speed = -6
x_speed_boost = 1
if event.key == pygame.K_d:
x_speed = 6
x_speed_boost = 2
if event.key == pygame.K_w:
y_speed = -6
y_speed_boost = 1
if event.key == pygame.K_s:
y_speed = 6
y_speed_boost = 2
if event.key == pygame.K_LSHIFT:
if x_speed_boost == 1:
x_speed = -10
if x_speed_boost == 2:
x_speed = 10
if y_speed_boost == 1:
y_speed = -10
if y_speed_boost == 2:
y_speed = 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
x_speed = 0
x_speed_boost = 0
if event.key == pygame.K_d:
x_speed = 0
x_speed_boost = 0
if event.key == pygame.K_w:
y_speed = 0
y_speed_boost = 0
if event.key == pygame.K_s:
y_speed = 0
y_speed_boost = 0
x_coord = x_coord + x_speed
y_coord = y_coord + y_speed
pygame.display.flip()
pygame.display.update()
clock.tick(20)
pygame.quit()
Code will be simpler/clearer using keystate polling for your use. If other parts of the game use 'on press' logic, you can use event handling. So your movement would be:
If you are calling pygame.display.flip() then you don't use pygame.display.update(). Infact it will probably slow it down to use both.
I used your x_coord variable. But it would simplify things to use a tuple or vector for player location. You can use a float, for smoother precision for movement. Then it blits as an int to screen.
while not done:
for event in pygame.event.get():
# any other key event input
if event.type == QUIT:
done = True
elif event.type == KEYDOWN:
if event.key == K_ESC:
done = True
vel_x = 0
vel_y = 0
speed = 1
if pygame.key.get_mods() & KMOD_SHIFT
speed = 2
# get key current state
keys = pygame.key.get_pressed()
if keys[K_A]:
vel_x = -1
if keys[K_D]:
vel_x = 1
if keys[K_W]:
vel_y = -1
if keys[K_S]:
vel_y = 1
x_coord += vel_x * speed
y_coord += vel_y * speed
You are ticking the clock at a rate of 20 frames per second. This is probably causing the choppiness. Change it to something bigger like 70:
clock.tick(70)

Categories