Pygame: Image/Sprite not appearing on moving background - python

The image I uploaded is not appearing onto the moving background. However, when the background was still it showed up normally (i was able to see the character and make it jump using the space key). Have been trying to figure out the error for days, please help - thank you!!!!
The following is the portion of code used for the character and moving background.
background = pygame.image.load('background.png')
backgroundX = 0
backgroundX2 = background.get_width()
homeScreen = pygame.image.load('home_screen.png')
def redrawGameWindow():
screen.blit(background, (0, 0))
man.draw(screen)
# background images for right to left moving screen
screen.blit(background, (backgroundX, 0))
screen.blit(background, (backgroundX2, 0))
pygame.display.update()
# create class for character (object)
class player(object):
def __init__(self, x, y, width, height): # initialize attributes
self.x = x
self.y = y
self.width = width
self.height = height
self.left = True
self.right = True
self.isJump = False
self.stepCount = 0
self.jumpCount = 10
self.standing = True
def draw(self, screen):
if self.stepCount + 1 >= 27: # 9 sprites, with 3 frames - above 27 goes out of range
self.stepCount = 0
if not self.standing:
if self.left:
screen.blit(leftDirection[self.stepCount // 5], (self.x, self.y), man.pos)
self.stepCount += 1
elif self.right:
screen.blit(rightDirection[self.stepCount // 5], (self.x, self.y), man.pos)
self.stepCount += 1
else:
if self.right:
screen.blit(rightDirection[0], (self.x, self.y)) # using index, include right faced photo
else:
screen.blit(leftDirection[0], (self.x, self.y))
class enlargement(object):
def __init__(self, x, y, radius, color, facing):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.facing = facing
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius, 1)
# main loop
speed = 30 # NEW
man = player(200, 410, 64, 64) # set main character attributes
run = True
while run:
clock.tick(speed) # NEW
backgroundX -= 1.4 # Move both background images back
backgroundX2 -= 1.4
if backgroundX < background.get_width() * -1: # If our background is at the -width then reset its position
backgroundX = background.get_width()
if backgroundX2 < background.get_width() * -1:
backgroundX2 = background.get_width()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
man.left = True
man.right = False
man.standing = False # false, because man is walking
# verify that character is within window parameters
elif keys[pygame.K_RIGHT]:
man.right = True
man.left = False
man.standing = False # false, because man is walking
else:
man.standing = True
man.stepCount = 0
if not man.isJump:
if keys[pygame.K_SPACE]:
man.isJump = True # when jumping, man shouldn't move directly left or right
man.right = False
man.left = False
man.stepCount = 0
else:
if man.jumpCount >= -10:
neg = 1
if man.jumpCount < 0:
neg = -1
man.y -= (man.jumpCount ** 2) * 0.5 * neg # to jump use parabola
man.jumpCount -= 1
else:
man.isJump = False
man.jumpCount = 10

Your probably just redrawing the background last ,thus it covers your sprite every time, I've had the issue in Visual Studio's C# (the old MonoGame library). By the way that's just a guess without completely going over your code. Good luck!

Related

pygame Layers, pygame.sprite [duplicate]

This question already has answers here:
Pygame sprite disappearing with layeredUpdates at a certain Y coordinate
(2 answers)
pygame.sprite.LayeredUpdates.move_to_front() does not work
(1 answer)
Closed 1 year ago.
I have started making a simple 2D game in python.
Thats my code
import clock
import time
import inspect
import itertools
import threading
import sys
pygame.init()
# defining the game window
gameDisplay = pygame.display.set_mode((1280, 640))
# displaying the game window
pygame.display.set_caption("Game")
background = pygame.image.load("images/background.jpg")
right = [pygame.image.load("images/animate/a1_r.png"), pygame.image.load("images/animate/a2_r.png"),
pygame.image.load("images/animate/a3_r.png"), pygame.image.load("images/animate/a4_r.png")]
standing = pygame.image.load("images/animate/standing.png") # 65x87 px
shaking = pygame.image.load("images/animate/shaking.png")
crouching = pygame.image.load("images/animate/crouching.png")
left = [pygame.image.load("images/animate/a1_l.png"), pygame.image.load("images/animate/a2_l.png"),
pygame.image.load("images/animate/a3_l.png"), pygame.image.load("images/animate/a4_l.png")]
shop_img = pygame.image.load("images/shop.png") # 230x140 px
clock = pygame.time.Clock()
isJump = False
jumpCount = 10
height = 87
width = 65
def border(x):
if x <= 0 and keys[pygame.K_a]:
return False
elif x >= 1225 and keys[pygame.K_d]:
return False
else:
return True
class StickMan(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 7
self.steps = 0
self.left = False
self.right = False
self.crouching = False
self.shaking = False
self.hitbox = (self.x + 20, self.y, 70, 60)
def draw(self):
if self.steps + 1 >= 20:
self.steps = 0
if self.left:
gameDisplay.blit(left[self.steps // 5], (self.x, self.y))
self.steps += 1
elif self.right:
gameDisplay.blit(right[self.steps // 5], (self.x, self.y))
self.steps += 1
elif self.shaking:
gameDisplay.blit(shaking, (self.x, self.y))
elif self.crouching:
gameDisplay.blit(crouching, (self.x, self.y))
else:
gameDisplay.blit(standing, (self.x, self.y))
self.steps = 0
def move(self):
if self.vel > 0:
self.x += self.vel
def current_width(self):
self.width = 65
def current_height(self):
if not keys[pygame.K_s]:
self.height = 87
else:
self.height = 50
class shop(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
def draw(self):
gameDisplay.blit(shop_img, (self.x, self.y))
Shop = shop( 200, 410, 230, 140)
Player = StickMan( 100, 470, 65, 87)
def draw():
gameDisplay.blit(background, (0, 0))
Player.draw()
Shop.draw()
run = True
# main Loop
while run:
for event in pygame.event.get():
pygame.display.update()
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and border(Player.x):
Player.x -= Player.vel
Player.left = True
Player.right = False
if keys[pygame.K_d] and border(Player.x):
Player.x += Player.vel
Player.left = False
Player.right = True
if not keys[pygame.K_d] and not keys[pygame.K_a]:
Player.left = False
Player.right = False
if keys[pygame.K_s]:
Player.crouching = True
else:
Player.crouching = False
if keys[pygame.K_q]:
Player.shaking = True
else:
Player.shaking = False
if not isJump:
if keys[pygame.K_SPACE]:
isJump = True
else:
if jumpCount >= -10:
Player.y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False
pygame.display.flip()
draw()
pygame.display.update()
clock.tick(60)
I've got problem with layers. - My character is running behind the shop. I was trying to fix this by using pygame.sprite (http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Sprite) but after many trials my man still runs behind the shop. Have you got any ideas how can I fix it ?

Repeat drawing in pygame

I am making a BrickBreaker/Breakout game using pygame. I want my game to create rows of bricks until the a brick hits the paddle but I can't figure out how to do so. Currently it only creates 1 row of bricks. I also want to make the bricks dissappear when the ball hits them. Currently when the bricks are hit they just move off the screen, but I want them to get permanently deleted.
Thanks!
My current code:
# Brick Breaker Game
import pygame
import random
# Initialize the pygame
pygame.init()
# create the screen
screen = pygame.display.set_mode((800, 600))
# background
background = pygame.image.load("realBackground.png")
# Title and Icon
pygame.display.set_caption("Brick Breaker")
icon = pygame.image.load("Brick Breaker Icon.png")
pygame.display.set_icon(icon)
# Paddle
paddleImage = pygame.image.load("scaledPaddle.png")
paddleX = 335
paddleY = 550
paddleX_change = 0
# BrickCoordinates
brickX = []
brickY = []
brickX_change = []
brickY_change = []
numOfBricks = 6
brickXValue = 15
for i in range(numOfBricks):
brickX.append(brickXValue)
brickY.append(0)
brickX_change.append(0.3)
brickY_change.append(0)
# Add 120 if thick lines in middle bricks
# Add 110 if uniform thickness
brickXValue += 130
#Bricks
yellowBrickImage = pygame.image.load("yellowBrick.png")
greenBrickImage = pygame.image.load("greenBrick.png")
blueBrickImage = pygame.image.load("blueBrick.png")
pinkBrickImage = pygame.image.load("pinkBrick.png")
# ball
ballImage = pygame.image.load("Ball.png")
ballX = 380
ballY = 280
ballX_change = 1.5
ballY_change = 1.5
#Score
scoreValue = 0
font = pygame.font.Font("Neufreit-ExtraBold.otf",24)
textX = 10
textY = 10
def showScore(x,y):
score = font.render("Score : " + str(scoreValue), True, (255,255,255))
screen.blit(score,(x,y))
def paddle(x, y):
screen.blit(paddleImage, (x, y))
def yellowBrick(x, y, i):
screen.blit(yellowBrickImage, (x, y))
def greenBrick(x, y, i):
screen.blit(greenBrickImage, (x, y))
def blueBrick(x, y, i):
screen.blit(blueBrickImage, (x, y))
def pinkBrick(x, y, i):
screen.blit(pinkBrickImage, (x, y))
def ball(x, y):
screen.blit(ballImage, (x, y))
#To pick random brick colours
colourOfBrick = []
for i in range(numOfBricks):
colourOfBrick.append(random.randint(1,4))
# Game Loop (makes sure game is always running)
running = True
while running:
# To change background colour
screen.fill((128, 128, 128))
# 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 whether left or right
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
paddleX_change = -5
if event.key == pygame.K_RIGHT:
paddleX_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
paddleX_change = 0
# Checking boudries of paddle
paddleX += paddleX_change
if paddleX <= 0:
paddleX = 0
elif paddleX >= 669:
paddleX = 669
#Draw Rectangles around bricks
brickRect = []
for i in range(numOfBricks):
brickRect.append(pygame.draw.rect(screen, (0, 0, 0), (brickX[i], brickY[i], 120, 42),1))
# Brick Movement
for i in range(numOfBricks):
brickY[i] += brickY_change[i]
if brickY[i] <= 0:
brickY_change[i] = 0.3
elif brickY[i] >= 500:
brickY_change[i] = -0.3
# Makes brick show up on screen
if colourOfBrick[i] == 1:
yellowBrick(brickX[i], brickY[i], i)
elif colourOfBrick[i] == 2:
greenBrick(brickX[i], brickY[i], i)
elif colourOfBrick[i] == 3:
blueBrick(brickX[i], brickY[i], i)
elif colourOfBrick[i] == 4:
pinkBrick(brickX[i], brickY[i], i)
# Ball Movement and boundary checking
ballX += ballX_change
if ballX <= 0:
ballX_change *= -1
elif ballX >= 760:
ballX_change *= -1
ballY += ballY_change
if ballY <= 0:
ballY_change *= -1
elif ballY >= 560:
ballX = 380
ballY = 280
# Paddle and Ball Collision
if ballY > 530 and ballY < 535 and (ballX+20) < paddleX + 131 and (ballX+20) > paddleX:
ballY_change *= -1
paddle(paddleX, paddleY)
ballCircle = pygame.draw.circle(screen, (255,0,0), (int(ballX+20),int(ballY+20)) ,20)
ball(ballX, ballY)
#Ball and Brick Collision
for i in range (numOfBricks):
if ballCircle.colliderect(brickRect[i]):
if abs(ballCircle.top - brickRect[i].bottom < 10) and ballY_change < 0:
brickX[i] = -400
ballY_change *= -1
scoreValue += 1
showScore(textX,textY)
pygame.display.update()
In your code all bricks have brickY.append(0) so all bricks are in one row. You have to create bricks with different Y values to create other rows.
You may need nested for-loops for this - like this
row_number = 3
brickYValue = 0
for row in range(row_number):
brickXValue = 15
for column in range(numOfBricks):
brickX.append(brickXValue)
brickY.append(brickYValue)
brickX_change.append(0.3)
brickY_change.append(0)
brickXValue += 130
# after `for column`
brickYValue += 15 # row height
But it will create more bricks then numOfBricks - you will have numOfBricks*row_number bricks so you would have to change other for-loops and use range(numOfBricks*row_number) instead of range(numOfBricks)
Or you should learn how to use for-loop without range()
brickRect = []
for x, y in zip(brickX, brickY):
brickRect.append(pygame.draw.rect(screen, (0, 0, 0), x, y, 120, 42),1))
BTW: you should also learn how to use pygame.Rect() to keep size and position of brick, paddle and ball. Rect() has methods to check collisions and you would no need long if ... and ... and ...
EDIT: I added rows in this code but I made many other changes so it may not be good example.
I draw surfaces instead of loading images so everyone can run it without images.
import pygame
import random
# --- classes ---
class Brick():
def __init__(self, x, y, image):
self.image = image
self.rect = self.image.get_rect(x=x, y=y)
self.x = x
self.y = y
self.x_change = 0
self.y_change = 1
def draw(self, screen):
self.rect.x = int(self.x)
self.rect.y = int(self.y)
screen.blit(self.image, self.rect)
pygame.draw.rect(screen, (0, 0, 0), self.rect, 1)
def update(self):
self.y += self.y_change
self.rect.y = int(self.y)
if self.rect.y <= 0:
self.y_change = 1
elif self.rect.y >= 500:
self.y_change = -1
class Ball():
def __init__(self):
#self.image = pygame.image.load("Ball.png")
self.image = pygame.Surface((16, 16)).convert_alpha()
self.image.fill((0,0,0,0)) # transparent background
pygame.draw.circle(self.image, (255,255,255), (8, 8), 8)
self.rect = self.image.get_rect(centerx=380, centery=280)
self.x = 380
self.y = 280
self.x_change = 3
self.y_change = 3
def reset(self):
self.x = 380
self.y = 280
def draw(self, screen):
self.rect.centerx = int(self.x)
self.rect.centery = int(self.y)
screen.blit(self.image, self.rect)
def update(self):
# Ball Movement and boundary checking
self.x += self.x_change
self.rect.centerx = int(self.x)
if self.rect.left <= 0:
self.x_change *= -1
elif self.rect.right >= 800:
self.x_change *= -1
self.y += self.y_change
self.rect.centery = int(self.y)
if self.rect.top <= 0:
self.y_change *= -1
elif self.rect.bottom >= 600:
self.reset()
class Paddle():
def __init__(self):
#self.image = pygame.image.load("scaledPaddle.png")
self.image = pygame.Surface((100, 30))
self.image.fill((255,0,0))
self.rect = self.image.get_rect(x=335, y=550)
self.x_change = 0
self.y_change = 0
def reset(self):
self.rect.x = 335
self.rect.y = 550
def draw(self, screen):
screen.blit(self.image, self.rect)
def update(self):
# Checking boudries of paddle
self.rect.x += self.x_change
if self.rect.left <= 0:
self.rect.left = 0
elif self.rect.right >= 800:
self.rect.right = 800
class Score():
def __init__(self):
#self.font = pygame.font.Font("Neufreit-ExtraBold.otf", 24)
self.font = pygame.font.SysFont(None, 24)
self.value = 0
self.x = 10
self.y = 10
def reset(self):
self.value = 0
def draw(self, screen):
self.image = self.font.render("Score : " + str(self.value), True, (255,255,255))
self.rect = self.image.get_rect(x=self.x, y=self.y)
screen.blit(self.image, self.rect)
# --- functions ---
# empty
# --- main ---
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Brick Breaker")
#icon = pygame.image.load("Brick Breaker Icon.png")
#pygame.display.set_icon(icon)
# Background Image
#background_image = pygame.image.load("realBackground.png")
background_image = pygame.Surface((800,600))
for y in range(5, 600, 25):
for x in range(5, 800, 25):
color = random.choice([(255,128,128), (128,255,128), (128,128,255)])
background_image.fill(color, [x,y,15,15])
# Brick Images
#brick_images = [
# pygame.image.load("yellowBrick.png"),
# pygame.image.load("greenBrick.png"),
# pygame.image.load("blueBrick.png"),
# pygame.image.load("pinkBrick.png"),
#]
brick_images = [
pygame.Surface((100, 30)),
pygame.Surface((100, 30)),
pygame.Surface((100, 30)),
pygame.Surface((100, 30)),
pygame.Surface((100, 30)),
pygame.Surface((100, 30)),
]
brick_images[0].fill((255,0,0))
brick_images[1].fill((0,255,0))
brick_images[2].fill((0,0,255))
brick_images[3].fill((255,255,0))
brick_images[4].fill((255,0,255))
brick_images[5].fill((0,255,255))
# Objects
paddle = Paddle()
ball = Ball()
score = Score()
# bricks
rows_number = 5
cols_number = 7
all_bricks = []
y = 0
for row in range(rows_number):
x = 50
for col in range(cols_number):
color_image = random.choice(brick_images)
brick = Brick(x, y, color_image)
all_bricks.append(brick)
x += 100
y += 30
# Game Loop
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# If keystroke is pressed check whether left or right
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
paddle.x_change = -5
if event.key == pygame.K_RIGHT:
paddle.x_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
paddle.x_change = 0
# --- updates ---
paddle.update()
ball.update()
# Bricks Update
for brick in all_bricks:
brick.update()
# Ball and Paddle Collision
if ball.rect.colliderect(paddle):
ball.y_change *= -1
# Ball and Bricks Collision
for brick in all_bricks:
if ball.rect.colliderect(brick):
brick.x = -400
ball.y_change *= -1
score.value += 1
# --- draws ---
# To change background colour
# screen.fill((128, 128, 128)) # you don't need it if background fill all screen
# background image
screen.blit(background_image, (0, 0))
for brick in all_bricks:
brick.draw(screen)
paddle.draw(screen)
ball.draw(screen)
score.draw(screen)
pygame.display.flip()
clock.tick(60) # 60 FPS (Frames Per Second) on all computers
# --- end ---
pygame.quit()

Why doesn't my sprite move correctly in pygame?

My second game is a platformer. I drew all the spites, drew the background and the platform, but I cant move my character more than 45 pixels one way, even when it is supposed to move 5 pixels. I also copied some code from here and there, so I cant just search it up. This is very puzzling, please help.
Here is the code:
import sys
import pygame
screen = pygame.display.set_mode((1300, 700), pygame.RESIZABLE)
global bg
bg = pygame.image.load('Pictures/badground.png')
w = (0, 0, 0)
screen.fill(w)
screen.blit(bg, (0, 0))
level = 0
walking_l = (pygame.image.load('Pictures/walk_l.png'))
walking_r = (pygame.image.load('Pictures/walk_r.png'))
walking_l_2 = (pygame.image.load('Pictures/_stand.png'))
walking_r_2 = (pygame.image.load('Pictures/stand.png'))
stand = (pygame.image.load('Pictures/rstand.png'))
pf = (pygame.image.load('Pictures/platform.png'))
pygame.display.set_caption('Platformed')
class player(object):
def __init__(self, speed, width, height):
self.speed = speed
self.x = 650
self.y = 350
self.width = width
self.height = height
self.walk_l = False
self.walk_r = False
self.stand = True
self.jump = False
self.walk_count = 0
def reprint_win(self):
screen.fill(w)
screen.blit(bg, (0, 0))
def walk(self):
k = pygame.key.get_pressed()
if k[pygame.K_a]:
self.x -= self.speed
self.stand = False
self.walk_l = True
self.walk_r = False
self.jump = False
print(self.x)
screen.fill(w)
screen.blit(bg, (0, 0))
elif k[pygame.K_d]:
self.x += self.speed
self.stand = False
self.walk_r = True
self.walk_l = False
self.jump = False
print(self.y)
screen.fill(w)
screen.blit(bg, (0, 0))
elif k[pygame.K_w] and self.walk_r and not self.jump:
self.stand = False
self.walk_r = True
self.walk_l = False
self.jump = True
screen.fill(w)
screen.blit(bg, (0, 0))
else:
self.stand = True
self.walk_r = False
self.walk_l = False
self.jump = False
screen.fill(w)
screen.blit(bg, (0, 0))
while True:
for e in pygame.event.get():
man = player(5, 64, 64)
if e.type == pygame.QUIT:
sys.exit()
if e.type == pygame.KEYDOWN:
man.walk()
screen.blit(stand, (man.x, man.y))
pygame.display.update()
elif e.type == pygame.KEYDOWN:
man.walk()
screen.blit(stand, (man.x, man.y))
pygame.display.update()
The method walk() of the class player changes the instance attribute, but id doesn't draw anything.
Add a method draw, which draw the player dependent on the instance attributes:
class player(object):
# [...]
def walk(self):
self.stand, self.walk_l, self.walk_r, self.jump = False, False, False, False
k = pygame.key.get_pressed()
if k[pygame.K_a]:
self.x -= self.speed
self.walk_l = True
elif k[pygame.K_d]:
self.x += self.speed
self.walk_r = True
elif k[pygame.K_w] and self.walk_r and not self.jump:
self.jump = True
else:
self.stand = True
def draw(self, surf):
if self.walk_l:
surf.blit(walking_l, (self.x, self.y))
elif self.walk_r:
surf.blit(walking_r, (self.x, self.y))
else:
surf.blit(stand, (self.x, self.y))
You have to draw the entire scene in every frame. Do the drawing to the application loop rather then the event loop.
Furthermore the instance of palyer has to be created before the application loop and invoke man.mvoe() in every frame.
Use pygame.time.Clock() .tick() to control the frames per second:
man = player(5, 64, 64)
clock = pygame.time.Clock()
FPS = 60
while True:
clock.tick(FPS)
for e in pygame.event.get():
if e.type == pygame.QUIT:
sys.exit()
man.walk()
screen.blit(bg, (0, 0))
man.draw(screen)
pygame.display.update()

Pygame sprite won't show up

I started creating a new game in pygame. first I made the game window and background. I made to backgrounds(bg and fg). I was going to leave fg as it was and make the second backgound, bg, as a scrolling background when my character sprite moves. After that, I pasted in code from a previous pygame project that was just a simple sprite character that could walk and jump in front of a background. When I pasted it in, the window came up and only displayed my backgrounds and did not show my sprite character at all. It also did not throw any errors. what's happening? Is my sprite just hidden?
import pygame
from random import randint, choice
from pygame.locals import *
pygame.init()
#(pasted code start)-----------------------------------------------------------------------------
walkRight = [pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/Examples/Ben-Game/ben characters main/R %s.png' % frame) for frame in range(1, 9)]
walkLeft = [pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/Examples/Ben-Game/ben characters main/L %s.png' % frame) for frame in range(14, 21)]
#(pasted code end)-----------------------------------------------------------------------------
bg = pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/Llama game/Llama imaging/backgrounds concepts/Mountains/PPP_BG1.png')
fg = pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/Llama game/Llama imaging/backgrounds concepts/Mountains/PPP_fg1.png')
screen = pygame.display.set_mode((276, 216), HWSURFACE|DOUBLEBUF|RESIZABLE)
#(pasted code start)---------------------------------------------------------------------------
class player(object):
def __init__(self,x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.velocity = 15
self.isJump = False
self.jumpCount = 7
self.right = False
self.left = False
self.walkCount = 0
self.screen = screen
def draw(self, screen):
if self.walkCount + 1 >= 8:
self.walkCount = 0
if self.left:
self.screen.blit(walkLeft[self.walkCount//1], (self.x, self.y))
self.walkCount += 1
elif self.right:
self.screen.blit(walkRight[self.walkCount//1], (self.x, self.y))
self.walkCount += 1
else:
self.screen.blit(char, (self.x, self.y))
#(pasted code end)-----------------------------------------------------------------------------
pygame.display.set_caption("Game")
screen.blit(pygame.transform.scale(bg,(276, 216)),(0,0))
screen.blit(pygame.transform.scale(fg,(276, 216)),(0,0))
pygame.display.flip()
#while loop for screen resize, fulscreen:
while True:
pygame.event.pump()
event=pygame.event.wait()
if event.type==QUIT:
pygame.quit()
elif event.type==VIDEORESIZE:
screen=pygame.display.set_mode(event.dict['size'],HWSURFACE|DOUBLEBUF|RESIZABLE)
screen.blit(pygame.transform.scale(bg,event.dict['size']),(0,0))
screen.blit(pygame.transform.scale(fg,event.dict['size']),(0,0))
pygame.display.flip()
#(pasted code start)---------------------------------------------------------------------------
#drawing in sprite character
def redrawGamescreen():
ben.screen.blit(bg,(0,0))
ben.screen.blit(fg,(0,0))
ben.draw(ben.screen)
pygame.display.update()
ben = player(50, 279, 64, 64)
run = True
#main loop and character control
while run:
clock.tick(8)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and ben.x > ben.velocity:
ben.x -= ben.velocity
ben.left = True
ben.right = False
elif keys[pygame.K_RIGHT] and ben.x < 735 - ben.width - ben.velocity:
ben.x += ben.velocity
ben.right = True
ben.left = False
else:
ben.right = False
ben.left = False
ben.walkCount = 0
if not(ben.isJump):
if keys[pygame.K_SPACE]:
ben.isJump = True
ben.right = False
ben.left = False
else:
if ben.jumpCount >= -7:
neg = 1
if ben.jumpCount < 0:
neg = -1
ben.y -= (ben.jumpCount ** 2) * 0.5 * neg
ben.jumpCount -= 1
else:
ben.isJump = False
ben.jumpCount = 7
ben.velocity = 15
redrawGamescreen()
#(pasted code end)-----------------------------------------------------------------------------
pygame.quit()
I can't test it but if you better organize code then you should see that you run two while loop. In first loop you display only background. And you never ends first loop so it never run second loop which draws sprite on background. You should remove first loop.

How to make an object "jump" in pygame

I was trying to create something along the lines of mario, this is far from perfect I know. Anyways, while trying to make the "jumping" method I ran into an issue - The jumping doesn't work the way I intended it to work. Whenether I click the space bar my red square moves up and down randomly, I have to press the spacebar and hold it to complete a jump and even then its not perfect. Sometimes when I hold the space bar for too long the red square will continue to jump again. Is there any way to solve this issue? I'd be very thankful for any help, thanks.
import pygame, time, math, random, sys
from pygame.locals import *
background = pygame.image.load("assets/MarioBackground.png")
def events():
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
W, H = 640, 400
HW, HH = W / 2, H / 2
AREA = W * H
FPS = 60
bg_x = 0
isJump = False
jumpCount = 10
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((W,H))
pygame.display.set_caption("Mario")
class Mario():
def __init__(self, x, y):
self.x = x
self.y = y
def draw(self):
pygame.draw.rect(screen, (255,0,0), (self.x, self.y, 40, 40))
def move(self):
global bg_x
if pressed_keys[K_RIGHT] and bg_x > -920:
if self.x > 490:
bg_x -= 5
else:
self.x += 5
if pressed_keys[K_LEFT] and self.x > 5:
self.x -= 5
def jump(self):
global jumpCount, isJump
if pressed_keys[K_SPACE]:
if jumpCount >= -10:
isJump = True
print(jumpCount)
neg = 1
if jumpCount < 0:
neg = -1
self.y -= (jumpCount ** 2) * 0.1 * neg
jumpCount -= 1
else:
isJump = False
jumpCount = 10
mario = Mario(50, 270)
while True:
clock.tick(FPS)
events()
pressed_keys = pygame.key.get_pressed()
screen.blit(background, (bg_x,0))
mario.move()
mario.draw()
mario.jump()
pygame.display.update()
Just check if isJump is true and then execute the jumping code in the jump method. I also recommend adding the isJump and jumpCount as attributes to Mario, so that you don't have to modify global variables.
To prevent the continuous jumping while Space is pressed, you have to handle the key press in the event queue. Then the jump action is triggered only once per key press not while the key is being held down.
import pygame, time, math, random, sys
from pygame.locals import *
background = pygame.Surface((640, 400))
background.fill((30, 90, 120))
W, H = 640, 400
HW, HH = W / 2, H / 2
AREA = W * H
FPS = 60
bg_x = 0
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((W,H))
class Mario():
def __init__(self, x, y):
self.x = x
self.y = y
# isJump and jumpCount should be attributes of Mario.
self.isJump = False
self.jumpCount = 10
def draw(self):
pygame.draw.rect(screen, (255,0,0), (self.x, self.y, 40, 40))
def move(self):
global bg_x
if pressed_keys[K_RIGHT] and bg_x > -920:
if self.x > 490:
bg_x -= 5
else:
self.x += 5
if pressed_keys[K_LEFT] and self.x > 5:
self.x -= 5
def jump(self):
# Check if mario is jumping and then execute the
# jumping code.
if self.isJump:
if self.jumpCount >= -10:
neg = 1
if self.jumpCount < 0:
neg = -1
self.y -= self.jumpCount**2 * 0.1 * neg
self.jumpCount -= 1
else:
self.isJump = False
self.jumpCount = 10
mario = Mario(50, 270)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
# Start to jump by setting isJump to True.
mario.isJump = True
clock.tick(FPS)
pressed_keys = pygame.key.get_pressed()
screen.blit(background, (bg_x,0))
mario.move()
mario.draw()
mario.jump()
pygame.display.update()
You can fix it by implementing the following rules:
you can only begin a jump when you touch the floor
you start a jump by pressing the space bar (set a variable) and stop it, when you touch the floor
you start a jump on keydown (pygame.KEYDOWN) not if pressed.
Some code snippets:
Begin jump
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and self.y == 0:
isJump = True
End jump
if self.y == 0:
isJump = False
With this rules you can only jump, when you're on the floor. You don't need to hold the space bar and you won't jump a second time if you hold the space bar to long

Categories