How do I make the character jump in Pygame? - python

I am trying to make a platformer game and I want the circle to jump, but whenever I try to make a jump, I get the following error, I found various methods of doing the jump, but none of them worked.
I think that the error is whenever I jump, a float number is happening and the draw method can't contain floats, only integers
here is the code for the game:
import pygame
import os
import time
import random
pygame.font.init()
Width, Height = 1280, 720
win = pygame.display.set_mode((Width, Height))
pygame.display.set_caption("Parkour Ball")
BG = pygame.image.load(os.path.join("assets", "Background.jpg"))
class Ball:
def __init__(self, x, y):
self.x = x
self.y = y
def draw(self, window):
pygame.draw.circle(window, (255,0,0), (self.x, self.y), 25)
def main():
run = True
FPS = 60
clock = pygame.time.Clock()
level = 0
lives = 10
main_font = pygame.font.SysFont("comicsans", 50)
lost_font = pygame.font.SysFont("comicsans", 60)
spikes = []
holes = []
hammers = []
platforms = []
enemies = []
player_vel = 5
jump = False
jumpCount = 10
player = Ball(300, 450)
lost = False
lost_popup = 0
def redraw():
win.blit(BG, (0,0))
player.draw(win)
pygame.display.update()
while run:
clock.tick(FPS)
redraw()
if lives == 0:
lost = True
lost_popup += 1
if lost:
if lost_popup > FPS * 3:
run = False
else:
continue
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and player.x - player_vel - 25 > 0:
player.x -= player_vel
if keys[pygame.K_RIGHT] and player.x + player_vel + 25 < Width:
player.x += player_vel
if keys[pygame.K_w]and player.y - player_vel > 0: #up
player.y -= player_vel
if keys[pygame.K_s] and player.y + player_vel < Height: #down
player.y += player_vel
if not(jump):
if keys[pygame.K_SPACE]:
jump = True
else:
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
player.y -= (jumpCount ** 2) / 2 * neg
jumpCount -= 1
main()

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)

Related

Masks Works Like a triangle

I'm trying to create a game where you are supposed to land on a platforms in the air, and if you fall under the camera's point of view, you die. You can jump in the air but that consumes fat you build up by eating. I'm not done with the game so you won't see that part, but the problem is with the collisions. I've made many objects and one I'm testing is a wooden box. It works, but the collision works like a triangle instead of a square. Half of the collision doesn't work in the top right, but the bottom left works. I have no clue why that can be the case, so help would come a long way. I will link the file and code.
import pygame, math
from pygame.locals import *
pygame.init()
Screen = pygame.display.set_mode((450, 800))
Running = True
ScreenWidth = Screen.get_width()
ScreenHeight = Screen.get_height()
CharacterSize = 25
Character = pygame.image.load('assets/game/Character.png').convert_alpha()
CharacterJumpPower = 15
JumpCooldown = 0
PlayerX = 0
PlayerY = 0
CameraX = PlayerX
CameraY = PlayerY
CameraSmoothness = 28
Gravity = -0.025
XVelocity = 0
YVelocity = 0
MouseX, MouseY = pygame.mouse.get_pos()
Keyboard = pygame.key.get_pressed()
Clock = pygame.time.Clock()
WoodenBox = pygame.transform.smoothscale(pygame.image.load('assets/game/WoodenBox.png').convert_alpha(), (25, 25))
Obstacles = [[WoodenBox, (400, -400)]]
def UpdateVariables():
global Screen, ScreenWidth, ScreenHeight, CharacterSize, Character, MouseX, MouseY, Keyboard, Clock
ScreenWidth = Screen.get_width()
ScreenHeight = Screen.get_height()
Character = pygame.transform.smoothscale(pygame.image.load('assets/game/Character.png').convert_alpha(), (CharacterSize, CharacterSize))
MouseX, MouseY = pygame.mouse.get_pos()
Keyboard = pygame.key.get_pressed()
Clock = pygame.time.Clock()
def CharacterPhysics():
global Gravity, CharacterSize, XVelocity, YVelocity, MouseX, MouseY, PlayerX, PlayerY, Keyboard, CharacterJumpPower, JumpCooldown, ScreenWidth, ScreenHeight
XVelocity = (MouseX - PlayerX) / 5
YVelocity += CharacterSize * Gravity
if Keyboard[K_SPACE] and CharacterSize > 5 and JumpCooldown == 0:
YVelocity = CharacterJumpPower
CharacterSize -= 1
JumpCooldown = 1
elif not Keyboard[K_SPACE]:
JumpCooldown = 0
if (-PlayerY + CameraY + ScreenHeight / 2) > ScreenHeight:
Dead()
if CheckCollisions():
print("True")
PlayerX += XVelocity
# if CheckCollisions():
# if XVelocity > 0:
# PlayerX -= 1
# else:
# PlayerX += 1
# PlayerX -= XVelocity
# XVelocity = 0
PlayerY += YVelocity
if CheckCollisions():
if YVelocity > 0:
PlayerY -= 1
else:
PlayerY += 1
PlayerY -= YVelocity
YVelocity = 0
def CameraMovement():
global PlayerX, PlayerY, CameraX, CameraY, CameraSmoothness
CameraY += (PlayerY - CameraY) / CameraSmoothness
def Dead():
global Running
print("You Died!")
Running = False
def BlitObstacles():
global Screen, Obstacles, CameraX, CameraY, ScreenWidth, ScreenHeight
for Obstacle in Obstacles:
Screen.blit(Obstacle[0], Obstacle[0].get_rect(center = (Obstacle[1][0] - CameraX, -Obstacle[1][1] + CameraY + ScreenHeight / 2)))
def CheckCollisions():
global Obstacles, PlayerX, PlayerY, Character, CharacterSize
for Obstacle in Obstacles:
if abs((PlayerX + PlayerY) - (Obstacle[1][0] + Obstacle[1][1])) < Obstacle[0].get_size()[0] / 2 + Obstacle[0].get_size()[1] / 2:
PlayerMask = pygame.mask.from_surface(Character)
ObstacleMask = pygame.mask.from_surface(Obstacle[0])
Offset = (PlayerX - Obstacle[1][0], PlayerY - Obstacle[1][1])
if ObstacleMask.overlap(PlayerMask, Offset):
return True
return False
while Running:
Screen.fill((255, 255, 255, 255))
UpdateVariables()
CharacterPhysics()
CameraMovement()
Screen.blit(Character, Character.get_rect(center = (PlayerX - CameraX, -PlayerY + CameraY + ScreenHeight / 2))) # Player
BlitObstacles()
pygame.display.flip()
Clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
Running = False
pygame.quit()
Here is the folder: https://www.dropbox.com/sh/26mmmtxmcwvazdd/AACAlbEpA3bUH5YwJILZ5t8fa?dl=0
The abs( clause in CheckCollisions() looks incorrect. I can't work out why a collision is summing the x and y coordinates of the object. There's no information suggesting specialised game physics, so I assume we're just using plain two-dimensional cartesian coordinate collision.
I think a re-working of your objects would really help. The best way forward would be to convert them to PyGame sprites, allowing use of the built-in collision functionality. But in the short-term, just using a PyGame Rect to hold the size and position would help:
box1_image = pygame.transform.smoothscale(pygame.image.load('assets/game/WoodenBox.png').convert_alpha(), (25, 25))
box1_rect = box1_image.get_rect()
box1_rect.center = ( 400, -400 ) # -400 is off-screen??
Obstacles = [[box1_image, box1_rect]]
def CheckCollisions():
global Obstacles, PlayerX, PlayerY, Character, CharacterSize
player_rect = pygame.Rect( PlayerX, PlayerY, CharacterSize, CharacterSize )
PlayerMask = pygame.mask.from_surface(Character)
for Obstacle in Obstacles:
obs_image, obs_rect = Obstacle
if ( player_rect.colliderect( obs_rect ) ):
print( "Rect-Rect Collide" )
ObstacleMask = pygame.mask.from_surface( obs_image )
Offset = ( player_rect.x - obs_rect.x, player_rect.y - obs_rect.y )
if ObstacleMask.overlap(PlayerMask, Offset):
print( "Mask-Mask Collide" )
return True
return False
Keeping the size+position in a Rect allows the code to use a quick collision-check via colliderect( some_other_rect ). It's worth spending the time to understand the Rect class, it's very very useful.

How to make player stay on moving platform in pygame?

I want to create a program where the player has to jump on horizontally moving platforms to reach their high score. The player can move left and right and can jump.
import pygame
from pygame.locals import *
pygame.init()
run = True
width = 500
height = 500
x = 250
y = 475
vel = 10
x_plat = 100
y_plat = 400
platform_vel = 5
clock = pygame.time.Clock()
isjump = False
jumpcount = 7.5
collision_tolerance = 10
gravity = 8
surface = pygame.display.set_mode((width, height))
rect = Rect(x_plat, y_plat, 150, 20)
player = Rect(x, y, 25, 25)
while run:
clock.tick(30)
if rect.left >= 355 or rect.left < 1:
platform_vel *= -1
rect.left += platform_vel
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > 0:
x -= vel
if keys[pygame.K_RIGHT] and x < (500 - 25):
x += vel
if not(isjump):
if keys[pygame.K_SPACE]:
isjump = True
else:
if jumpcount >= -7.5:
y -= (jumpcount * abs(jumpcount)) * 1
jumpcount -= 1
else:
jumpcount = 7.5
isjump = False
collide = pygame.Rect.colliderect(rect, player)
if collide:
player.bottom = rect.top
player.left += platform_vel
rect.left += platform_vel
pygame.draw.rect(surface, (0, 0, 0), rect)
pygame.draw.rect(surface, (255, 255, 255), player)
pygame.display.update()
surface.fill((255, 222, 173))
for event in pygame.event.get():
if event.type == QUIT:
run = False
If you run my code, when the player jumps onto the moving platform, the platform moves but the player doesn't move with it, making the player float in mid air.
I would really appreciate it if someone could help!
The player didn't move at all with the code provided so I updated x and y references to player.x and player.y, then made some changes to implement gravity and collision checking with the platform and floor.
It's important to note that when on the platform, gravity still moves the player downward into the platform so they collide with the platform each clock tick and the "collide" logic runs. It also allows the player to fall off the platform if moving left or right.
This seems to do what you want:
import pygame
from pygame.locals import *
pygame.init()
run = True
width = 500
height = 500
vel = 10
x_plat = 100
y_plat = 400
platform_vel = 5
clock = pygame.time.Clock()
isjump = False
jumpcount = 7.5
collision_tolerance = 10
gravity = 1
player_vy = 0 # players vertical velocity
surface = pygame.display.set_mode((width, height))
rect = Rect(x_plat, y_plat, 150, 20)
player = Rect(250, 475, 25, 25)
while run:
clock.tick(30)
if rect.left >= 355 or rect.left < 1:
platform_vel *= -1
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and player.x > 0:
player.x -= vel
if keys[pygame.K_RIGHT] and player.x < (500 - 25):
player.x += vel
if not(isjump):
if keys[pygame.K_SPACE]:
isjump = True # suppress spacebar jumping until landing
player_vy = -16 # give upward velocity
player_vy += gravity # accelerate downward due to gravity
player.y += player_vy # compute new height
collide = pygame.Rect.colliderect(rect, player)
if collide and player_vy >= 0: # falling and collide with platform?
player.bottom = rect.top # land on platform.
player_vy = 0 # no longer falling
player.left += platform_vel # move with platform
isjump = False # enable jump
if player.y > 475: # don't fall off bottom of screen.
player.y = 475 # land on bottom of screen
player_vy = 0 # stop falling
isjump = False # allow jumping again
rect.left += platform_vel # move platform
pygame.draw.rect(surface, (0, 0, 0), rect)
pygame.draw.rect(surface, (255, 255, 255), player)
pygame.display.update()
surface.fill((255, 222, 173))
for event in pygame.event.get():
if event.type == QUIT:
run = False

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 ?

How Can I make the restart function in pygame?

import pygame
from pygame.locals import *
pygame.init()
screen_width = 600
screen_height = 500
fpsClock = pygame.time.Clock()
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Pong')
#define font
font = pygame.font.SysFont('None', 30)
#define game variables
margin = 50
cpu_score = 0
player_score = 0
fps = 90
live_ball = False
winner = 0
speed_increase = 0
#define colours
bg = (12, 0, 91)
white = (241, 185, 0)
ball_color = (168, 43, 17)
bar_color = (10, 106, 86)
def draw_board():
screen.fill(bg)
pygame.draw.line(screen, white, (0, margin), (screen_width, margin), 2)
def draw_text(text, font, text_col, x, y):
img = font.render(text, True, text_col)
screen.blit(img, (x, y))
class paddle():
def __init__(self, x, y):
self.x = x
self.y = y
self.rect = Rect(x, y, 20, 100)
self.speed = 5
self.ai_speed = 5
def move(self):
key = pygame.key.get_pressed()
if key[pygame.K_UP] and self.rect.top > margin:
self.rect.move_ip(0, -1 * self.speed)
if key[pygame.K_DOWN] and self.rect.bottom < screen_height:
self.rect.move_ip(0, self.speed)
def draw(self):
pygame.draw.rect(screen, bar_color, self.rect)
def ai(self):
#ai to move the paddle automatically
#move down
if self.rect.centery < pong.rect.top and self.rect.bottom < screen_height:
self.rect.move_ip(0, self.ai_speed)
#move up
if self.rect.centery > pong.rect.bottom and self.rect.top > margin:
self.rect.move_ip(0, -1 * self.ai_speed)
class ball():
def __init__(self, x, y):
self.reset(x, y)
def move(self):
#check collision with top margin
if self.rect.top < margin:
self.speed_y *= -1
#check collision with bottom of the screen
if self.rect.bottom > screen_height:
self.speed_y *= -1
if self.rect.colliderect(player_paddle) or self.rect.colliderect(cpu_paddle):
self.speed_x *= -1
#check for out of bounds
if self.rect.left < 0:
self.winner = 1
if self.rect.left > screen_width:
self.winner = -1
#update ball position
self.rect.x += self.speed_x
self.rect.y += self.speed_y
return self.winner
def draw(self):
pygame.draw.circle(screen, ball_color, (self.rect.x + self.ball_rad, self.rect.y + self.ball_rad), self.ball_rad)
def reset(self, x, y):
self.x = x
self.y = y
self.ball_rad = 8
self.rect = Rect(x, y, self.ball_rad * 2, self.ball_rad * 2)
self.speed_x = -4
self.speed_y = 4
self.winner = 0# 1 is the player and -1 is the CPU
#create paddles
player_paddle = paddle(screen_width - 40, screen_height // 2)
cpu_paddle = paddle(20, screen_height // 2)
#create pong ball
pong = ball(screen_width - 60, screen_height // 2 + 50)
#create game loop
run = True
while run:
fpsClock.tick(fps)
draw_board()
draw_text('CPU: ' + str(cpu_score), font, white, 20, 15)
draw_text('Sihu: ' + str(player_score), font, white, screen_width - 100, 15)
draw_text('BALL SPEED: ' + str(abs(pong.speed_x)), font, white, screen_width // 2 - 100 , 15)
#draw paddles
player_paddle.draw()
cpu_paddle.draw()
if live_ball == True:
speed_increase += 1
winner = pong.move()
if winner == 0:
#draw ball
pong.draw()
#move paddles
player_paddle.move()
cpu_paddle.ai()
else:
live_ball = False
if winner == 1:
player_score += 1
elif winner == -1:
cpu_score += 1
#print player instructions
if live_ball == False:
if winner == 0:
draw_text('CLICK ANYWHERE TO START', font, white, 160, screen_height // 2 -0)
if winner == 1:
draw_text('YOU SCORED!', font, white, 220, screen_height // 2 -100)
draw_text('CLICK ANYWHERE TO START', font, white, 160, screen_height // 2 -0)
if winner == -1:
draw_text('CPU SCORED!', font, white, 220, screen_height // 2 -100)
draw_text('CLICK ANYWHERE TO START', font, white, 160, screen_height // 2 -0)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN and live_ball == False:
live_ball = True
pong.reset(screen_width - 60, screen_height // 2 + 50)
if speed_increase > 500:
speed_increase = 0
if pong.speed_x < 0:
pong.speed_x -= 1
if pong.speed_x > 0:
pong.speed_x += 1
if pong.speed_y < 0:
pong.speed_y -= 1
if pong.speed_y > 0:
pong.speed_y += 1
pygame.display.update()
pygame.quit()
I get the code on YOUTUBE
and edit the code a little bits
but I did not add the restart code
How can I make the restart function in pygame?
I just want to over the game when player get a 5 score in the game.
and want to make the game restart.
When the game is overed, the player can restart the game with the button.
To restart you will need to reset any variables that change during the game. Write a function that sets all objects and variables to its initial state:
def reset():
global player_paddle, cpu_paddle, pong
global cpu_score, player_score
global live_ball, winner, speed_increase
player_paddle = paddle(screen_width - 40, screen_height // 2)
cpu_paddle = paddle(20, screen_height // 2)
pong = ball(screen_width - 60, screen_height // 2 + 50)
cpu_score = 0
player_score = 0
live_ball = False
winner = 0
speed_increase = 0
Call the function when you want to restart the game.
Have the loop it's own method, call it from a main() run, when the game is over and ends, have main() ask the user if they want to play again, and if so recall the main loop after setting everything as its default
or
Just have the part that asks again clear and reinitialize all variables as there defaults and let the loop if the user wants to play again

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