How to make an object jump in pygame
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()
How to make a character jump in Pygame?
To make a character jump you have to use the KEYDOWN
event, but not pygame.key.get_pressed()
. pygame.key.get_pressed ()
is for continuous movement when a key is held down. The keyboard events are used to trigger a single action or to start an animation such as a jump. See alos How to get keyboard input in pygame?
pygame.key.get_pressed()
returns a sequence with the state of each key. If a key is held down, the state for the key is True
, otherwise False
. Use pygame.key.get_pressed()
to evaluate the current state of a button and get continuous movement.
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
jump = True
Use pygame.time.Clock
("This method should be called once per frame.") you control the frames per second and thus the game speed and the duration of the jump.
clock = pygame.time.Clock()
while True:
clock.tick(100)
The jumping should be independent of the player's movement or the general flow of control of the game. Therefore, the jump animation in the application loop must be executed in parallel to the running game.
When you throw a ball or something jumps, the object makes a parabolic curve. The object gains height quickly at the beginning, but this slows down until the object begins to fall faster and faster again. The change in height of a jumping object can be described with the following sequence:
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10]
Such a series can be generated with the following algorithm (y
is the y coordinate of the object):
jumpMax = 10
if jump:
y -= jumpCount
if jumpCount > -jumpMax:
jumpCount -= 1
else:
jump = False
A more sophisticated approach is to define constants for the gravity and player's acceleration as the player jumps:
acceleration = 10
gravity = 0.5
The acceleration exerted on the player in each frame is the gravity constant, if the player jumps then the acceleration changes to the "jump" acceleration for a single frame:
acc_y = gravity
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if vel_y == 0 and event.key == pygame.K_SPACE:
acc_y = -acceleration
In each frame the vertical velocity is changed depending on the acceleration and the y-coordinate is changed depending on the velocity. When the player touches the ground, the vertical movement will stop:
vel_y += acc_y
y += vel_y
if y > ground_y:
y = ground_y
vel_y = 0
acc_y = 0
See also Jump
Example 1: replit.com/@Rabbid76/PyGame-Jump
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
rect = pygame.Rect(135, 220, 30, 30)
vel = 5
jump = False
jumpCount = 0
jumpMax = 15
run = True
while run:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if not jump and event.key == pygame.K_SPACE:
jump = True
jumpCount = jumpMax
keys = pygame.key.get_pressed()
rect.centerx = (rect.centerx + (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel) % 300
if jump:
rect.y -= jumpCount
if jumpCount > -jumpMax:
jumpCount -= 1
else:
jump = False
window.fill((0, 0, 64))
pygame.draw.rect(window, (64, 64, 64), (0, 250, 300, 100))
pygame.draw.circle(window, (255, 0, 0), rect.center, 15)
pygame.display.flip()
pygame.quit()
exit()
Example 2: replit.com/@Rabbid76/PyGame-JumpAcceleration
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
player = pygame.sprite.Sprite()
player.image = pygame.Surface((30, 30), pygame.SRCALPHA)
pygame.draw.circle(player.image, (255, 0, 0), (15, 15), 15)
player.rect = player.image.get_rect(center = (150, 235))
all_sprites = pygame.sprite.Group([player])
y, vel_y = player.rect.bottom, 0
vel = 5
ground_y = 250
acceleration = 10
gravity = 0.5
run = True
while run:
clock.tick(100)
acc_y = gravity
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if vel_y == 0 and event.key == pygame.K_SPACE:
acc_y = -acceleration
keys = pygame.key.get_pressed()
player.rect.centerx = (player.rect.centerx + (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel) % 300
vel_y += acc_y
y += vel_y
if y > ground_y:
y = ground_y
vel_y = 0
acc_y = 0
player.rect.bottom = round(y)
window.fill((0, 0, 64))
pygame.draw.rect(window, (64, 64, 64), (0, 250, 300, 100))
all_sprites.draw(window)
pygame.display.flip()
pygame.quit()
exit()
How does this algorithm make the character jump in pygame?
At the started Jumpcount
is set 10.
Jumpcount = 10
The jump runs until Jumpcount
is less or equal -10. Therefore, a jump takes exactly 21 cycles:
if Jumpcount >= -10:
Neg
is "signe" of Jumpcount
. It is 1 if Jumpcount
is greater or equal to zero and -1 otherwise:
Neg = 1
if Jumpcount < 0:
Neg = -1
In each frame, the player's y
coordinate is changed by the quadratic function (Jumpcount ** 2) * 0.5
.
y -= (Jumpcount ** 2) * 0.5 * Neg
Since this term is multiplied by Neg
, it is positive if Jumpcount
is greater than 0, and 0 if Jumpcount
is 0, otherwise it is less than 0.
When the amount of Jumpcount
is large, the change in the y
coordinate is greater than when the amount is small. See the values for (Jumpcount ** 2) * 0.5 * Neg
in the 21 cycles:
50.0, 40.5, 32.0, 24.5, 18.0, 12.5, 8.0, 4.5, 2.0, 0.5, 0.0,
-0.5, -2.0, -4.5, -8.0, -12.5, -18.0, -24.5, -32.0, -40.5, -50.0
At the beginning the values are positive and the player jumps. In the end the values are negative and the player falls down.
The sum of this values is 0. Therefore the y
-coordinate has the same value at the end as at the beginning.
See also How to make a character jump in Pygame?.
How do I make the character jump in Pygame?
The coordinates to pygame.draw.circle()
have to be integral values. round()
the floating point coordinates to integral coordinates:
pygame.draw.circle(window, (255,0,0), (self.x, self.y), 25)
pygame.draw.circle(window, (255,0,0), (round(self.x), round(self.y)), 25)
How to make a jumping in python?
It is a matter of Indentation. You have to do the jump in the application loop. The state jump
is set once when the event occurs. However, the jumping needs to be animated in consecutive frames.
Your event loop is mixed up and you must change the coordinate of the player object instead of usr_y
:
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 40))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.centerx = WIDTH - 360
self.rect.centery = HEIGHT - 200
self.y = self.rect.y # <--- floating point y coordinate
def update(self):
self.rect.y = round(self.y) # <--- update player rectangle
self.speedx = 0
# [...]
jump = False
counter = 30
def make():
global counter, jump
if counter >= -30:
player.y -= counter / 2.5 # <--- change player.y
counter -= 1
else:
counter = 30
jump = False
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.key == K_SPACE:
jump = True
# INDENTATION
#<----------|
if jump:
make()
# [...]
How To Make Object Jump Forward In Pygame?
You have to separate the movement along the x and y axis. Just turn the elif
to if
, in the condition that evaluates if SPACE is pressed:
if keys[pygame.K_a] and playerX > 0:
playerX -= vel_x
elif keys[pygame.K_d] and playerX < 500:
playerX += vel_x
# elif jump == False and keys[pygame.K_SPACE]:
if jump == False and keys[pygame.K_SPACE]:
jump = True
elif jump == True:
playerY -= vel_y * 4
vel_y -= 1
if vel_y < -10:
jump = False
vel_y = 10
Complete example:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
playerX = 250
playerY = 250
vel_x = 10
vel_y = 10
jump = False
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and playerX > 0:
playerX -= vel_x
elif keys[pygame.K_d] and playerX < 500:
playerX += vel_x
if jump == False and keys[pygame.K_SPACE]:
jump = True
elif jump == True:
playerY -= vel_y * 4
vel_y -= 1
if vel_y < -10:
jump = False
vel_y = 10
win.fill((0, 0, 0))
pygame.draw.circle(win, (255, 255, 255), (int(playerX), int(playerY)), 15)
pygame.display.update()
pygame.time.delay(30)
pygame.quit()
Making Sprite Jump in Pygame
There are two things that you should introduce. States and velocity.
In order to make the player fall, we want him to jump only when he is on the ground. So we define 2 states. STANDING
and JUMPING
. Now pressing space would only make the player jump if his state is STANDING
.
To make the player fall like a ball, we introduce velocity
. When the player is on the ground, we have the velocity set to 0. When you press space, you change the velocity to 100.
In each loop, if the player state is JUMPING
, we reduce the velocity
by the Earth's gravity.
The last thing to check, is when the player reaches the ground level, you should set the velocity
to 0 and player state to STANDING
.
How to simulate Jumping in Pygame for this particular code
See How to make a character jump in Pygame?. Add a variable jump
and initialize it by 0, before the main loop:
jump = 0
while run:
# [...]
Only react on pygame.K_SPACE
, if player is allowed to jump and stays on the ground. If this is fulfilled then set jump
to the desired "jump" height:
if keys[pygame.K_SPACE] and Ycord == ScreenLenY - height:
jump = 300
As long as jump
is greater than 0, move the player upwards and decease jump
by the same amount, in the main loop.
If the player is not jumping that let him fall dawn, till he reaches the ground:
if jump > 0:
Ycord -= vel
jump -= vel
elif Ycord < ScreenLenY - height:
Ycord += 1
See the demo, where I applied the suggestions to your code:
import pygame
pygame.init()
ScreenLenX, ScreenLenY = (1000, 500)
win = pygame.display.set_mode((ScreenLenX, ScreenLenY))
pygame.display.set_caption("aman")
Xcord, Ycord = (100, 100)
length, height = (10, 10)
xmove, ymove = (1, 1)
vel = 2
jump = 0
run = True
clock = pygame.time.Clock()
while run:
#clock.tick(60)
for event in pygame.event.get():
print(event)
if event.type ==pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT] and Xcord <= ScreenLenX-length:
Xcord += vel
if keys[pygame.K_LEFT] and Xcord >= 0:
Xcord -= vel
if keys[pygame.K_SPACE] and Ycord == ScreenLenY - height:
jump = 300
if jump > 0:
Ycord -= vel
jump -= vel
elif Ycord < ScreenLenY - height:
Ycord += 1
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 0, 0), (Xcord, Ycord, length, height))
pygame.display.update()
Related Topics
Ruby Equivalent to Python's Help()
Is There a Function That Checks If a Character in a String Is a Letter in the Alphabet? (Swift)
Function Which Returns the Least-Squares Solution to a Linear Matrix Equation
Extract Column Value Based on Another Column Pandas Dataframe
How to Fetch a Non-Ascii Url with Urlopen
Is Python's Sorted() Function Guaranteed to Be Stable
Dead Simple Example of Using Multiprocessing Queue, Pool and Locking
How to Convert a Dictionary into a List of Tuples
Get Protocol + Host Name from Url
Python - Classes and Oop Basics
Translate Every Element in Numpy Array According to Key
How to Operate on a Dataframe with a Series for Every Column
How to Avoid Http Error 429 (Too Many Requests) Python
Efficient Calculation of Fibonacci Series
How to Get Exit Code When Using Python Subprocess Communicate Method
Is Module _File_ Attribute Absolute or Relative
Merge Pandas Dataframes Where One Value Is Between Two Others