How do I fix my 'Jump'? - python

I am new to this website and pygame so bear with me. I am experimenting with pygame and made a simple platformer. However, whenever I 'Jump', the block jumps frame by frame, so I have to hold down the spacebar. Any help would be greatly appreciated!
here is my code:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
x = 0
y = 490
width = 10
height = 10
vel = 5
pygame.key.set_repeat(1)
isjump = False
jumpcount = 10
while True:
pygame.time.delay(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x>vel-5:
x -= vel
if keys[pygame.K_d] and x < 500 - width:
x += vel
if not(isjump):
if keys[pygame.K_SPACE]:
isjump = True
else:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= (jumpcount ** 2) /2 * neg
jumpcount -= 1
else:
isjump = False
jumpcount = 10
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
pygame.display.update()
pygame.quit()

You are mixing your keyboard event handling with your jump-logic. I've done two things, change the spacebar detection to trigger isjump and handle the jump logic irregardless of whether there is a key pressed or not:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
x = 0
y = 490
width = 10
height = 10
vel = 5
pygame.key.set_repeat(1)
isjump = False
jumpcount = 10
while True:
pygame.time.delay(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x>vel-5:
x -= vel
if keys[pygame.K_d] and x < 500 - width:
x += vel
# if we're not already jumping, check if space is pressed to start a jump
if not isjump and keys[pygame.K_SPACE]:
isjump = True
jumpcount = 10
# if we're supposed to jump, handle the jump logic
if isjump:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= (jumpcount ** 2) /2 * neg
jumpcount -= 1
else:
isjump = False
jumpcount = 10
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
pygame.display.update()
pygame.quit()

The line keys = pygame.key.get_pressed() and the whole game logic and drawing code should not be in the event loop (for event in pygame.event.get():), otherwise the code gets executed once per event in the queue, and if no events are in the queue, it won't be executed at all.
You could just dedent keys = pygame.key.get_pressed() and all lines beneath.
Alternatively, you could check in the event loop if the space key was pressed (with if event.type == pygame.KEYDOWN:) and then set isjump to True (that means the player will only jump once per keypress).
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
x = 0
y = 490
width = 10
height = 10
vel = 5
isjump = False
jumpcount = 10
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
isjump = True
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > vel - 5:
x -= vel
elif keys[pygame.K_d] and x < 500 - width:
x += vel
if isjump:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= jumpcount**2 / 2 * neg
jumpcount -= 1
else:
isjump = False
jumpcount = 10
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
pygame.display.update()
clock.tick(30)
pygame.quit()
I also recommend adding a pygame.time.Clock instance and call clock.tick(FPS) to regulate the frame rate.
And I'd rather implement the jumping in this way, with a gravity constant which gets added to the y-velocity each frame.

Related

Python, object after jumping doesn't fall down. Fix?

i have a program in which a square is supposed to jump, then fall down. For some reason, the square is jumping but it doesn't fall down. I'm not sure what's the issue is, i hope you could help me fix it. jumping gif
Here i'm displaying the window while the game is being played
#DISPLAY WINDOW
def draw_window(square):
#SCREEEN
WIN.fill(black)
#OBJECTS
#LINE
pygame.draw.line(WIN, white, (0, 400), (900, 400), 10)
#SQUARE
square.draw()
pygame.display.update()
Here i'm defining a square class and it's methods including jumping
#SQUARE
class Square():
def __init__(self):
self.y = 295
self.vel = 10
def draw(self):
pygame.draw.rect(WIN, red, [50, self.y, 100, 100])
def jump(self, jumpCount):
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
self.y -= (jumpCount ** 2) * 0.05 * neg
jumpCount -= 1
else:
jump = False
jumpCount = 10
Here is the main game loop with all functions
def main():
jump = False
jumpCount = 10
square = Square()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#JUMPING
if event.type == pygame.KEYDOWN:
if not jump and event.key == pygame.K_SPACE:
jump = True
if jump:
square.jump(jumpCount)
draw_window(square)
pygame.quit()
Here are some modifications to your code:
In the class Square, draw method should pass in a pygame.Rect as a parameter of pygame.draw.rect.
The jump method of Square created local variable jump and jump_count, changes to these variables will not affect the variable in main(). So you have to return these values and update them in main()
Full Code:
import pygame
clock = pygame.time.Clock()
WIN = pygame.display.set_mode((800, 600))
red = (255, 0, 0)
white = (255, 255, 255)
black = (0, 0, 0)
FPS = 60
class Square():
def __init__(self):
self.y = 295
self.vel = 10
def draw(self):
pygame.draw.rect(WIN, red, pygame.Rect(50, self.y, 100, 100))
def jump(self, jumpCount):
jump = True
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
self.y -= (jumpCount ** 2) * 0.05 * neg
jumpCount -= 1
else:
jump = False
jumpCount = 10
return jump, jumpCount
#DISPLAY WINDOW
def draw_window(square):
#SCREEEN
WIN.fill(black)
#OBJECTS
#LINE
pygame.draw.line(WIN, white, (0, 400), (900, 400), 10)
#SQUARE
square.draw()
pygame.display.update()
def main():
jump = False
jumpCount = 10
square = Square()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#JUMPING
if event.type == pygame.KEYDOWN:
if not jump and event.key == pygame.K_SPACE:
jump = True
if jump:
jump, jumpCount = square.jump(jumpCount)
draw_window(square)
pygame.quit()
main()
Output:

Pygame character jump speed problems

I'm currently trying to make my first game. I am trying to make my character jump, but my code doesn't have errors but when my character jump it just happens to fast. I don't know which part to change. I have not been able to figure this out on my own as I am still learning. Here is my code:
import pygame
pygame.init()
screen = pygame.display.set_mode((1200, 600))
WinHeight = 600
WinWidth = 1200
# player
player = pygame.image.load("alien.png")
x = 50
y = 450
vel = 0.3
playerSize = 32
# title
pygame.display.set_caption("First Game")
# Jump
isJump = False
jumpCount = 10
running = True
while running:
screen.fill((255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
break
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > vel:
x -= vel
if keys[pygame.K_d] and x < WinWidth - vel - playerSize:
x += vel
if not (isJump):
if keys[pygame.K_w] and y > vel:
y -= vel
if keys[pygame.K_s] and y < WinHeight - vel - playerSize:
y += vel
if keys[pygame.K_SPACE]:
isJump = True
else:
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
y -= (jumpCount ** 2) * 0.5 * neg
jumpCount -= 1
else:
isJump = False
jumpCount = 10
screen.blit(player, (x, y))
pygame.display.update()
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()
running = True
while running:
clock.tick(60)
# [...]

Pygame jump animation not working - though walking is

Okay, so I was able to add walking animations to the right and the left on my main file, but when I basically copy/pasted/changed the names for adding jump, it doesn't work.
I went ahead and made a copy of my main file, just without the walking animations. I went ahead and tried just doing the jump animation, and even though I copied everything from the same tutorial as I used for the walking, it still doesn't work.
I've been trying to figure this out since last night from like 8 pm. Is there a different way for jump animations to work? See below for the code of THE COPY, so no walking animations. I get no errors, the player can walk left and right, and jump as well.
import pygame
import os
x = 90
y = 60
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x, y)
def player_jump_animation():
"""Adding collision block to each right jump animation"""
new_player = player_frames_jump[player_jump_index]
new_player_rect = new_player.get_rect(
center=(player_rect.centerx, player_rect.centery))
return new_player, new_player_rect
pygame.init()
screen = pygame.display.set_mode((1000, 1000))
clock = pygame.time.Clock()
player_movement = 720
isJump = False
jumpCount = 10
bg_surface = pygame.image.load('assets/camp_bg.png').convert()
bg_surface = pygame.transform.scale2x(bg_surface)
player_idle = pygame.transform.scale2x(pygame.image.load(
'assets/IDLE_000.png').convert_alpha())
player_jump0 = pygame.transform.scale2x(
pygame.image.load('assets/JUMP_000.png').convert_alpha())
player_jump1 = pygame.transform.scale2x(
pygame.image.load('assets/JUMP_001.png').convert_alpha())
player_jump2 = pygame.transform.scale2x(
pygame.image.load('assets/JUMP_002.png').convert_alpha())
player_jump3 = pygame.transform.scale2x(
pygame.image.load('assets/JUMP_003.png').convert_alpha())
player_jump4 = pygame.transform.scale2x(
pygame.image.load('assets/JUMP_004.png').convert_alpha())
player_jump5 = pygame.transform.scale2x(
pygame.image.load('assets/JUMP_005.png').convert_alpha())
player_jump6 = pygame.transform.scale2x(
pygame.image.load('assets/JUMP_006.png').convert_alpha())
player_frames_jump = [player_jump0, player_jump1, player_jump2,
player_jump3, player_jump4, player_jump5, player_jump6]
player_jump_index = 3
player_surface = player_frames_jump[player_jump_index]
player_rect = player_surface.get_rect(center=(300, 512))
PLAYERJUMP = pygame.USEREVENT
pygame.time.set_timer(PLAYERJUMP, 120)
run = True
while run:
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == PLAYERJUMP:
if player_jump_index < 6:
player_jump_index += 1
else:
player_jump_index = 0
# Setting jump animation
player_jump, player_rect = player_jump_animation()
if keys[pygame.K_LEFT] and player_rect.centerx > 0 + 35:
# If I speed up, player looks like sliding
player_rect.centerx -= 5
if keys[pygame.K_RIGHT] and player_rect.centerx < 1000 - 35:
# If I speed up, player looks like sliding
player_rect.centerx += 5
if not(isJump):
if keys[pygame.K_UP]:
isJump = True
else:
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
player_movement -= (jumpCount ** 2) * 0.1 * neg
jumpCount -= 0.5
# This will execute when jump is finished
else:
# Resetting Variables
jumpCount = 10
isJump = False
pygame.display.update()
clock.tick(60)
screen.blit(bg_surface, (0, 0))
player_rect.centery = player_movement
screen.blit(player_idle, player_rect)
pygame.quit()
You have to draw the Surface referenced by player_jump, if the player is jumping:
while run:
# [...]
screen.blit(bg_surface, (0, 0))
player_rect.centery = player_movement
if isJump:
screen.blit(player_jump, player_rect)
else:
screen.blit(player_idle, player_rect)
# [...]

PyGame is Choppy

im new at pygame and im watching some tutorials in how to get started with it, I wrote this basic code that it only has movement and a jump "function" but it is really choppy, I do not think its my hardware (Macbook Pro 2018). Do someone has any idea of whats happening?
HereĀ“s the code:
import pygame
pygame.init()
win_width = 500
win_height = 500
win = pygame.display.set_mode((win_width,win_height))
pygame.display.set_caption("First PyGame")
width = 40
height = 60
x = win_width/2
y = win_height/2
vel = 10
isJump = False
jumpCount = 10
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("adios putito")
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel:
x -= vel
if keys[pygame.K_RIGHT] and x < win_width - width - vel:
x+= vel
if not (isJump):
if keys[pygame.K_UP] and y > vel:
y -= vel
if keys[pygame.K_DOWN]and y < win_height - height - vel:
y += vel
if keys[pygame.K_SPACE]:
isJump = True
else:
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
y -= (jumpCount ** 2) * 0.5 * neg
jumpCount -= 1
else:
isJump = False
jumpCount = 10
win.fill((0,0,0))
pygame.draw.rect(win,(255,255,255), (x,y,width,height))
pygame.display.update()
pygame.quit()
The line
pygame.time.delay(100)
is delaying your script that milliseconds, remove that line and it should work just fine!
Result:
import pygame
pygame.init()
win_width = 500
win_height = 500
win = pygame.display.set_mode((win_width,win_height))
pygame.display.set_caption("First PyGame")
width = 40
height = 60
x = win_width/2
y = win_height/2
vel = 10
isJump = False
jumpCount = 10
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("adios putito")
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel:
x -= vel
if keys[pygame.K_RIGHT] and x < win_width - width - vel:
x+= vel
if not (isJump):
if keys[pygame.K_UP] and y > vel:
y -= vel
if keys[pygame.K_DOWN]and y < win_height - height - vel:
y += vel
if keys[pygame.K_SPACE]:
isJump = True
else:
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
y -= (jumpCount ** 2) * 0.5 * neg
jumpCount -= 1
else:
isJump = False
jumpCount = 10
win.fill((0,0,0))
pygame.draw.rect(win,(255,255,255), (x,y,width,height))
pygame.display.update()
pygame.quit()
It's still a good idea to have a game clock that delays your program enough to keep a persistent framerate. You can use pygame's pygame.time.Clock object and use its tick() method to delay your game. The tick method takes an integer which represents the FPS you want your game to cap at. If your game runs slower than the FPS value you put in, no delay will happen.
import pygame
pygame.init()
win_width = 500
win_height = 500
win = pygame.display.set_mode((win_width,win_height))
pygame.display.set_caption("First PyGame")
clock = pygame.time.Clock()
width = 40
height = 60
x = win_width/2
y = win_height/2
vel = 10
isJump = False
jumpCount = 10
run = True
while run:
# Delay your game to try and keep 60 FPS.
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("adios putito")
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel:
x -= vel
if keys[pygame.K_RIGHT] and x < win_width - width - vel:
x+= vel
if not (isJump):
if keys[pygame.K_UP] and y > vel:
y -= vel
if keys[pygame.K_DOWN]and y < win_height - height - vel:
y += vel
if keys[pygame.K_SPACE]:
isJump = True
else:
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
y -= (jumpCount ** 2) * 0.5 * neg
jumpCount -= 1
else:
isJump = False
jumpCount = 10
win.fill((0,0,0))
pygame.draw.rect(win,(255,255,255), (x,y,width,height))
pygame.display.update()
pygame.quit()

jumping too fast?

I am messing around with pygame, and trying to create a simple jumping function (no physics yet).
For some reason my "jumps" are not visible in the display, even though the values I am using print out and seem to be working as intended. What could I be doing wrong?
isJump = False
jumpCount = 10
fallCount = 10
if keys[pygame.K_SPACE]:
isJump = True
if isJump:
while jumpCount > 0:
y -= (jumpCount**1.5) / 3
jumpCount -= 1
print(jumpCount)
while fallCount > 0:
y += (fallCount**1.5) / 3
fallCount -= 1
print(fallCount)
else:
isJump = False
jumpCount = 10
fallCount = 10
print(jumpCount, fallCount)
win.fill((53, 81, 92))
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.update()
I shortened the amount of code, but I think this is all that is related to the problem.
You've to turn the while loops to if conditions. You don't want to do the complete jump in a single frame.
You've to do a single "step" of the jump per frame. Use the main application loop to perform the jump.
See the example:
import pygame
pygame.init()
win = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
isJump = False
jumpCount, fallCount = 10, 10
x, y, width, height = 200, 300, 20, 20
run = True
while run:
clock.tick(20)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
isJump = True
if isJump:
if jumpCount > 0:
y -= (jumpCount**1.5) / 3
jumpCount -= 1
print(jumpCount)
elif fallCount > 0:
y += (fallCount**1.5) / 3
fallCount -= 1
print(fallCount)
else:
isJump = False
jumpCount, fallCount = 10, 10
print(jumpCount, fallCount)
win.fill((53, 81, 92))
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.flip()

Categories

Resources