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
Related
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.
This question already has answers here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Sometimes the ball doesn't bounce off the paddle in pong game
(1 answer)
Closed 2 years ago.
I'm failly new to programming in general and this is my second game ever so sorry in advance.
I made a pong game with only one paddle for now, but the ball keeps bouncing even when it's not hitting the paddle.
This is my draw ball function:
def draw_ball(self):
self.sc.blit(ball, (self.bx,self.by))
self.bx += self.speedx
self.by += self.speedy
if self.bx >= 1000:#check goals
self.bx = 250
self.by = 340
if self.bx <= 38: #check coalision
self.speedx *= -1
if self.by<= 12:
self.speedy *= -1
if self.by>= 725:
self.speedy *= -1
#check coalision with the paddle
#px and py are the coordinates of the paddle
if self.bx > (self.px - 35) and (self.by < (self.py + 196) and (self.by + 38) > self.py) :
self.speedx *= -1
Here is the main loop:
#global variables
WIN_HEIGHT = 1024
WIN_WIDTH = 768
SPEED = 5
PX = 956
PY = 320
MOVEMENT = 5
BALL = Ball(550, 60, screen, .5, .4, PX, PY)
running = True
while running:
redraw_screen()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
mouse_pos = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONDOWN and START_BUTTON.is_clicked(mouse_pos):
running = False
playing = True
while playing:
screen.fill((0,0,0))
BALL.draw_ball()
PLAYER.draw_player()
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
playing = False
Thanks for your help.
I recommend to use pygame.Rect objects and the method .colliderect()
Define rectangles for the ball, paddle and screen or get the rectangles from a pygame.Surface by .get_rect():
ball_rect = ball.get_rect(topleft = (self.bx, self.by))
right_paddle_rect = pygame.Rect(self.px, self.py, 38, 196)
screen_rect = self.sc.get_rect()
Test the collision of the ball and the borders of the screen:
if ball_rect.top < screen_rect.top or ball_rect.bottom > screen_rect.bottom:
self.speedy *= -1
if ball_rect.left < screen_rect.left:
self.speedx *= -1
if ball_rect.right > screen_rect.right:
self.bx = 250
self.by = 340
Be carful when you test the collision between the ball and the paddle. See Sometimes the ball doesn't bounce off the paddle in pong game:
if ball_rect.colliderect(right_paddle_rect):
self.speedx = -abs(self.speedx)
Complete method draw_ball:
def draw_ball(self):
self.sc.blit(ball, (self.bx, self.by))
self.bx += self.speedx
self.by += self.speedy
ball_rect = ball.get_rect(topleft = (self.bx, self.by))
right_paddle_rect = pygame.Rect(self.px, self.py, 38, 196)
screen_rect = self.sc.get_rect()
if ball_rect.top < screen_rect.top or ball_rect.bottom > screen_rect.bottom:
self.speedy *= -1
if ball_rect.left < screen_rect.left:
self.speedx *= -1
if ball_rect.right > screen_rect.right:
self.bx = 250
self.by = 340
if ball_rect.colliderect(right_paddle_rect):
self.speedx = -abs(self.speedx)
Minimal example:
import pygame
class Game:
def __init__(self, screen):
self.sc = screen
self.bx, self.by = 250, 340
self.speedx, self.speedy = 5, 5
self.px, self.py = 700, 200
def draw_ball(self):
self.sc.blit(ball, (self.bx, self.by))
self.bx += self.speedx
self.by += self.speedy
ball_rect = ball.get_rect(topleft = (self.bx, self.by))
right_paddle_rect = pygame.Rect(self.px, self.py, 38, 196)
screen_rect = self.sc.get_rect()
if ball_rect.top < screen_rect.top or ball_rect.bottom > screen_rect.bottom:
self.speedy *= -1
if ball_rect.left < screen_rect.left:
self.speedx *= -1
if ball_rect.right > screen_rect.right:
self.bx = 250
self.by = 340
if ball_rect.colliderect(right_paddle_rect):
self.speedx = -abs(self.speedx)
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
ball = pygame.Surface((38, 38), pygame.SRCALPHA)
pygame.draw.circle(ball, (255, 255, 255), (19, 19), 19)
game = Game(screen)
run = True
while run:
clock.tick(60)
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
print(pygame.key.name(event.key))
keys = pygame.key.get_pressed()
pspeed = 5
if keys[pygame.K_UP]:
game.py = max(0, game.py - pspeed)
if keys[pygame.K_DOWN]:
game.py = min(screen.get_height()-196, game.py + pspeed)
screen.fill(0)
game.draw_ball()
pygame.draw.rect(screen, (255, 255, 255), (game.px, game.py, 38, 196))
pygame.display.flip()
My teacher gave us this code to analyze and I am not sure why he put 27 there for collision.. I asked him he said if the distance between the player and the enemy is less than 27 then I will call it a collision, but I still don't understand, can someone please kindly explain it to me in simpler terms. I don't understand where the number 27 comes from.. when my dimensions are so big?
import math
import random
import pygame
# Intialize the pygame
pygame.init()
# create the screen
screen = pygame.display.set_mode((1000, 700))
# Background
background = pygame.image.load('undersea.png')
# Player
playerImg = pygame.image.load('space-invaders.png')
playerX = 500
playerY = 600
playerX_change = 0
# Enemy
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 5
for i in range(num_of_enemies):
enemyImg.append(pygame.image.load('plastic.png'))
enemyX.append(random.randint(0, 636))
enemyY.append(random.randint(50, 150))
enemyX_change.append(4)
enemyY_change.append(40)
# Bullet
# Ready - You can't see the bullet on the screen
# Fire - The bullet is currently moving
bulletImg = pygame.image.load('bullet (1).png')
bulletX = 0
bulletY = 480
bulletX_change = 0
bulletY_change = 10
bullet_state = "ready"
# Score
score_value = 0
font = pygame.font.Font('freesansbold.ttf', 32)
textX = 10
testY = 10
# Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)
def show_score(x, y):
score = font.render("Score : " + str(score_value), True, (255, 255, 255))
screen.blit(score, (x, y))
def game_over_text():
over_text = over_font.render("GAME OVER", True, (255, 255, 255))
screen.blit(over_text, (200, 250))
def player(x, y):
screen.blit(playerImg, (x, y))
def enemy(x, y, i):
screen.blit(enemyImg[i], (x, y))
def fire_bullet(x, y):
global bullet_state
bullet_state = "fire"
screen.blit(bulletImg, (x + 16, y + 10))
def isCollision(enemyX, enemyY, bulletX, bulletY):
distance = ((enemyX - bulletX) ** 2 + (enemyY - bulletY) ** 2)
distance = math.sqrt(distance)
print(distance)
if distance < 27:
return True
else:
return False
# Game Loop
running = True
while running:
# RGB = Red, Green, Blue
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 whether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -5
if event.key == pygame.K_RIGHT:
playerX_change = 5
if event.key == pygame.K_SPACE:
if bullet_state is "ready":
# Get the current x cordinate of the spaceship
bulletX = playerX
fire_bullet(bulletX, bulletY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# 5 = 5 + -0.1 -> 5 = 5 - 0.1
# 5 = 5 + 0.1
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 636:
playerX = 636
# Enemy Movement
for i in range(num_of_enemies):
# Game Over
if enemyY[i] > 440:
for j in range(num_of_enemies):
enemyY[j] = 2000
game_over_text()
break
enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = 4
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = -4
enemyY[i] += enemyY_change[i]
# Collision
collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
bulletY = 480
bullet_state = "ready"
score_value += 1
enemyX[i] = random.randint(0, 736)
enemyY[i] = random.randint(50, 150)
enemy(enemyX[i], enemyY[i], i)
# Bullet Movement
if bulletY <= 0:
bulletY = 480
bullet_state = "ready"
if bullet_state is "fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
show_score(textX, testY)
pygame.display.update()
The value is 27, because you compute the Euclidean distance between (enemyX, enemyY) and (bulletX, bulletY) in the function isCollision:
def isCollision(enemyX, enemyY, bulletX, bulletY):
distance = ((enemyX - bulletX) ** 2 + (enemyY - bulletY) ** 2)
distance = math.sqrt(distance)
print(distance)
The Euclidean distance between 2 points (Ax, Ay) and (Bx, By) is
d = sqrt((Bx-Ax)**2 + (By-Ay)**2) = hypot(Bx-Ax, By-Ay)
In 2 dimensional space this is the same as the Pythagorean theorem. The length of the diagonal in a square with a side length of 19 is approximately 27.
Try changing the '27' to a small no. like '5' and you will see that the collision is happening too late on screen. OR if you replace the enemy/bullet image you are loading with some other small/large image you will notice that you will have to change you '27' to some other number to make things work as intended.
Simple Words
The reason for the hard-coding '27' could be because the width of enemy image and the width of bullet image you load in your code seem to touch (collide) eachother at the distance '27' from the point where they are drawn.
Explanation
When we load an image pygame draws it from top-left corner. For Example your background image is so large in code but when you ask your code where is this 'background' located it well tell you it is on (0,0) although it's on your full screen not a single point.
Infered from screen.blit(background, (0, 0)) line in your code
Same for the images/sprites of enemy and bullets. The position you use in collision enemyX, enemyY, bulletX, bulletY are the top-left coordinates. Now to show them actually touching/colliding you may have to tell the code that 'My enemy is more than one pixel on the position. So I want to take care of it by using the constant '27' (depends on width of enemy/bullet). As soon as the both positions have a Euclidean distance of '27' this means they are colliding on my screen hence proceed as true.
If you are still confused about the positioning issue and how center of image or top-left of image matters read these, it will help.
https://stackoverflow.com/a/51182238/11672352
Why is the pygame rect not in the right place?
It seems to me like the game triggers the collision once the bullet enters a circle of radius 27 pixels around the enemy. Although your enemy may not be a perfect circle, it is a lot simpler to treat them as if they were when calculating collisions as it is relatively easy to check whether a point has collided with a circle, in this case, the bullet with the enemy.
the lines:
distance = ((enemyX - bulletX) ** 2 + (enemyY - bulletY) ** 2)
distance = math.sqrt(distance)
are used to calculate the distance between the middle of the enemy and the bullet by using Pythagoras' theorem (a^2 + b^2 = c^2 where a and b are two different sides of a right angled triangle and c is your hypotenuse, aka the longest side)
The value 27 is likely used because the enemy is likely around 52 pixels (27 * 2) wide and tall
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)
What I am trying to do here is make my collision detect allow me to jump on a square but it doesn't seem to work. Its a the very bottom of the main loop.
# --- COLLISION is at the bottom of main loop
# ------
# this is a pygame module that I imported
import pygame
pygame.init()
# this is just my screen I created win defines it
win = pygame.display.set_mode((500,500))
# this is my caption for my game
pygame.display.set_caption("Just Tryna learn Something")
# these are my coordinates for my enemy where it will spawn
cordx = 300
cordy = 300
heights = 70
widths = 70
# my Player Coordinate and its speed and and its Jump
x = 200
y = 200
height = 40
width = 40
speed = 5
isJump = False
jumpCount = 10
# main loop
# main loop for my game
running = True
while running:
pygame.time.delay(100)
win.fill((0,0,0))
#-----------------------------------------------------------------------------------------
# this here draws my player in my window
Player = pygame.draw.rect(win, (140, 0,150), (x, y, height, width))
#-----------------------------------------------------------------------------------------
# this here draws my enemy
Enemy = pygame.draw.rect(win, (90,90,90), (cordx, cordy, heights, widths))
#=-------------------------------------------------------------------------------------
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#-------------------------------------------------------------------
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= speed
if keys[pygame.K_RIGHT]:
x += speed
# this here is my functions for movement and Jumping
if not(isJump):
if keys[pygame.K_UP]:
y -= speed
if keys[pygame.K_DOWN]:
y += speed
if keys[pygame.K_SPACE]:
isJump = True
else:
if jumpCount >= -10:
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False
# COLLISION here is my collision detect and collision
its suppose to make me stand on the square with my little box when I jump on it
but it doesnt seem to work (Enemy) is the big box and (Player) is the little box
if Player.colliderect(Enemy):
pygame.draw.rect(win, (150,0,140), (50, 50, 20, 70))
if Player.top >= 375 and Player.top <= 370:
x = 375
# ---------------------------------------------------------
pygame.display.update()
pygame.quit()
Continuously let the player fall down. Add a variable fall = 0 and the variable to y and increment fall in every frame, if the player is not jumping. A jump ends, if the player reaches the maximum jump height (jumpCount == 0):
if not isJump:
y += fall
fall += 1
# [...]
else:
if jumpCount > 0:
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False
Limit the player to the bottom of the window (500), and the top of the block by setting the y coordinate of the player:
Player.topleft = (x, y)
collide = False
if Player.colliderect(Enemy):
y = Enemy.top - Player.height
collide = True
if Player.bottom >= 500:
y = 500 - Player.height
collide = True
It is only allowed to jump, if the player stands on the ground or on the block:
if collide:
if keys[pygame.K_SPACE]:
isJump = True
fall = 0
Furthermore use pygame.time.Clock() and tick(), instead of pygame.time.delay() for a smooth movement. Control the speed by the flops per second (FPS):
FPS = 60
clock = pygame.time.Clock()
running = True
while running:
clock.tick(FPS)
#pygame.time.delay(100)
See the example:
# --- COLLISION is at the bottom of main loop
# ------
# this is a pygame module that I imported
import pygame
pygame.init()
# this is just my screen I created win defines it
win = pygame.display.set_mode((500,500))
# this is my caption for my game
pygame.display.set_caption("Just Tryna learn Something")
# these are my coordinates for my enemy where it will spawn
cordx = 300
cordy = 350
heights = 70
widths = 70
# my Player Coordinate and its speed and and its Jump
x = 200
y = 200
height = 40
width = 40
speed = 5
isJump = False
jumpCount = 10
fall = 0
FPS = 60
clock = pygame.time.Clock()
# main loop
# main loop for my game
running = True
while running:
clock.tick(FPS)
#pygame.time.delay(100)
win.fill((0,0,0))
#-----------------------------------------------------------------------------------------
# this here draws my player in my window
Player = pygame.draw.rect(win, (140, 0,150), (x, y, height, width))
#-----------------------------------------------------------------------------------------
# this here draws my enemy
Enemy = pygame.draw.rect(win, (90,90,90), (cordx, cordy, heights, widths))
#=-------------------------------------------------------------------------------------
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#-------------------------------------------------------------------
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= speed
if keys[pygame.K_RIGHT]:
x += speed
# this here is my functions for movement and Jumping
if not isJump:
y += fall
fall += 1
Player.topleft = (x, y)
collide = False
if Player.colliderect(Enemy):
collide = True
y = Enemy.top - Player.height
if Player.right > Enemy.left and Player.left < Enemy.left:
x = Enemy.left - Player.width
if Player.left < Enemy.right and Player.right > Enemy.right:
x = Enemy.right
if Player.bottom >= 500:
collide = True
y = 500 - Player.height
if collide:
if keys[pygame.K_SPACE]:
isJump = True
fall = 0
else:
if jumpCount > 0:
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False
pygame.display.update()
pygame.quit()