pygame Layers, pygame.sprite [duplicate] - python

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 ?

Related

Blit is not detecting my Player classes self.pos

My code:
import pgzrun, pgzero, pygame, math, time, random, os
from pgzero.builtins import Actor, animate, keyboard
screen = pgzero.screen.Screen
# screen
WIDTH = 800
HEIGHT = 600
pygame.init()
pygame.mouse.set_visible(False)
os.chdir("c:/Users/carter.breshears/Documents/CSPVSC/Final/Images")
font = pygame.font.Font("Minecraft.ttf", 30)
# player images
playerIdle = pygame.image.load("playerIdle.png")
playerWalkImages = [pygame.image.load("playerRun1.png"), pygame.image.load("playerRun2.png"), pygame.image.load("playerRun3.png"), pygame.image.load("playerRun4.png")]
#variables
# gameloop
gameover = False
# classes
class Player:
def __init__(self, x, y):
self.x = x
self.y = y
self.animationCount = 0
self.movingRight = False
self.movingLeft = False
self.movingUp = False
self.movingDown = False
def main(self, screen):
if self.animationCount + 1 >= 24:
self.animationCount = 0
self.animationCount += 1
if self.movingRight or self.movingUp or self.movingDown:
screen.blit(pygame.transform.scale(playerWalkImages[self.animationCount//6], (40,74)), (self.x, self.y))
elif self.movingLeft:
screen.blit(pygame.transform.scale(pygame.transform.flip(playerWalkImages[self.animationCount//6], True, False), (40,74)), (self.x, self.y))
else:
screen.blit(pygame.transform.scale(playerIdle, (40,74)), (self.x, self.y)) ##### This line!
self.movingRight = False
self.movingLeft = False
self.movingUp = False
self.movingDown = False
class PlayerBullet:
def __init__(self, x, y, mouseX, mouseY):
self.x = x
self.y = y
self.mouseX = mouseX
self.mouseY = mouseY
speed = 6
self.angle = math.atan2(y - mouseY, x - mouseX)
self.x_vel = math.cos(self.angle) * speed
self.y_vel = math.sin(self.angle) * speed
def main(self, screen):
self.x -= int(self.x_vel)
self.y -= int(self.y_vel)
print("bang")
pygame.draw.circle(screen, "yellow", (self.x+16, self.y+16), 5)
class InvaderEnemy:
def __init__(self, x, y):
self.x = x
self.y = y
self.greenAnimationImages = [pygame.image.load("virus g.png"), pygame.image.load("virus g2.png")]
self.yellowAnimationImages = [pygame.image.load("virus y.png"), pygame.image.load("virus y2.png")]
self.blueAnimationImages = [pygame.image.load("virus b.png"), pygame.image.load("virus b2.png")]
self.redAnimationImages = [pygame.image.load("virus r.png"), pygame.image.load("virus r2.png")]
self.animationCount = 0
self.velocity = 1
self.lerpFactor = 0.05
def main(self, screen):
if self.animationCount + 1 == 8:
self.animationCount = 0
self.animationCount += 1
spawnPos = (random.randint(-1000, 1000), random.randint(-1000, 1000))
targetVector = pygame.math.Vector2(player.x, player.y)
enemyVector = pygame.math.Vector2(spawnPos.x, spawnPos.y)
newEnemyVector = pygame.math.Vector2(spawnPos.x, spawnPos.y)
distance = enemyVector.distance_to(targetVector)
minDistance = 25
maxDistance = 1000
if distance > minDistance:
directionVector = (targetVector - enemyVector)/2
self.minStep = max(0, distance - maxDistance)
self.maxStep = distance - minDistance
self.stepDistance = self.minStep + (self.maxStep - self.minStep) * self.lerpFactor
newEnemyVector = enemyVector + directionVector * self.stepDistance
return(newEnemyVector.x, newEnemyVector.y)
# player
player = Player(400,300)
displayScroll = [0,0]
# shooting
playerBullets = []
# invader
invaders = []
invaderEnemy = InvaderEnemy(100,100)
invaderSpawnRate = 1
# functions
def update():
# movement
keys = pygame.key.get_pressed()
if keys[pygame.K_a]:
displayScroll[0] -= 2
player.movingLeft = True
for bullet in playerBullets:
bullet.x += 2
if keys[pygame.K_d]:
displayScroll[0] += 2
player.movingRight = True
for bullet in playerBullets:
bullet.x -= 2
if keys[pygame.K_w]:
displayScroll[1] -= 2
player.movingUp = True
for bullet in playerBullets:
bullet.y += 2
if keys[pygame.K_s]:
displayScroll[1] += 2
player.movingDown = True
for bullet in playerBullets:
bullet.y -= 2
player.main(screen)
# shooting
mouseX, mouseY = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
playerBullets.append(PlayerBullet(player.x, player.y, mouseX, mouseY))
for bullet in playerBullets:
PlayerBullet.main(screen)
#enemies
global spawnPos
if time.perf_counter() - invaderSpawnRate > 1:
invaders.append(InvaderEnemy(spawnPos.x, spawnPos.y))
for invader in invaders:
InvaderEnemy.main(screen)
# run
pgzrun.go()
I've tried everything I know of, Im new to this. I know that it worked before because I tested this on my home computer but whenever I downloaded the file on my school computer it stopped working so something must have changed between python versions.

Why does Pygame crashing from list index error?

I am working on a game in Pygame and the window crashes a few seconds into execution. I traced it back to the list I used for the "enemy" sprite walking animation. I still cannot find what it is that it is having trouble within my list. I did the same exact thing with my player walking animations.
here is the error it threw:
Traceback (most recent call last):
File "/Users/luke.redwine/Documents/Python/PyGame/fivr code/basic >platformer/basic_platformer.py", line 188, in <module>
redrawGameWindow()
File "/Users/luke.redwine/Documents/Python/PyGame/fivr code/basic >platformer/basic_platformer.py", line 111, in redrawGameWindow
goblin.draw(ben.window)
File "/Users/luke.redwine/Documents/Python/PyGame/fivr code/basic >platformer/basic_platformer.py", line 85, in draw
window.blit(self.walkRight[self.walkCount //3], (self.x, self.y))
IndexError: list index out of range
I've commented out the player and enemy classes and lists for walking; "walkRight, "walkLeft".
import sys
import pygame
pygame.init()
pygame.display.set_caption("Ben Meitzen")
#player walking lists
walkRight = [pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/fivr code/basic platformer/sprites/tile%s.png' % frame) for frame in range(17, 24)]
walkLeft = [pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/fivr code/basic platformer/sprites/tile%s.png' % frame) for frame in range(9, 16)]
bg = pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/fivr code/basic platformer/skybackground.png')
char = pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/fivr code/basic platformer/sprites/tile1.png')
clock = pygame.time.Clock()
#player class
class player(object):
def __init__(self,x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.velocity = 11
self.isJump = False
self.jumpCount = 7
self.right = False
self.left = False
self.walkCount = 0
self.window = pygame.display.set_mode((860,538))
self.standing = True
def draw(self, window):
if self.walkCount + 1 >= 8:
self.walkCount = 0
if not (self.standing):
if self.left:
self.window.blit(walkLeft[self.walkCount//1], (self.x, self.y))
self.walkCount += 1
elif self.right:
self.window.blit(walkRight[self.walkCount//1], (self.x, self.y))
self.walkCount += 1
else:
if self.right:
window.blit(walkRight[0], (self.x, self.y))
else:
window.blit(walkLeft[0], (self.x, self.y))
class projectile(object):
def __init__(self, x, y, radius, color, facing):
self.x = x
self.y = y
self.color = color
self.facing = facing
self.velocity = 40 * facing
self.radius = radius
def draw(self, window):
pygame.draw.circle(window, self.color, (self.x, self.y), self.radius)
#enemy class
class enemy(object):
#enemy walking lists
walkRight = [pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/fivr code/basic platformer/enemy sprites/enemy%s.png' % frame) for frame in range(17, 24)]
walkLeft = [pygame.image.load('/Users/luke.redwine/Documents/Python/PyGame/fivr code/basic platformer/enemy sprites/enemy%s.png' % frame) for frame in range(9, 16)]
def __init__(self, x, y, width, height, end):
self.x = x
self.y = y
self.width = width
self.height = height
self.end = end
self.walkCount = 0
self.velocity = 3
self.path = [self.x, self.end]
def draw(self, window):
self.move()
if self.walkCount + 1 >= 8:
self.walkcount = 0
if self.velocity > 0:
window.blit(self.walkRight[self.walkCount //3], (self.x, self.y))
self.walkCount += 1
else:
window.blit(self.walkLeft[self.walkCount //3], (self.x, self.y))
self.walkCount += 1
def move(self):
if self.velocity > 0:
if self.x + self.velocity < self.path[1]:
self.x += self.velocity
else:
self.velocity = self.velocity * -1
self.walkcount = 0
else:
if self.x - self.velocity > self.path[0]:
self.x += self.velocity
else:
self.velocity = self.velocity * -1
self.walkcount = 0
#game window-------------------------------------------------------------------------------------------------------------------------------------------------
def redrawGameWindow():
ben.window.blit(bg,(0,0))
ben.draw(ben.window)
goblin.draw(ben.window)
for bullet in bullets:
bullet.draw(ben.window)
pygame.display.update()
##main loop##------------------------------------------------------------------------------------------------------------------------------------------------
goblin = enemy(100, 460, 70, 70, 700)
ben = player(30, 460, 64, 64)
bullets = []
run = True
while run:
clock.tick(8)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
for bullet in bullets:
if bullet.x < 860 and bullet.x > 0:
bullet.x += bullet.velocity
else:
bullets.pop(bullets.index(bullet))
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
if ben.left:
facing = -1
else:
facing = 1
if len(bullets) < 5:
bullets.append(projectile(round(ben.x + ben.width //2), round(ben.y + ben.height -30 //2), 6, (0,0,0), facing))
if keys[pygame.K_LEFT] and ben.x > ben.velocity:
ben.x -= ben.velocity
ben.left = True
ben.right = False
ben.standing = False
elif keys[pygame.K_RIGHT] and ben.x < 860 - ben.width - ben.velocity:
ben.x += ben.velocity
ben.right = True
ben.left = False
ben.standing = False
else:
ben.standing = True
ben.walkCount = 0
if not(ben.isJump):
if keys[pygame.K_UP]:
ben.isJump = True
ben.right = False
ben.left = False
else:
if ben.jumpCount >= -7:
neg = 0.5
if ben.jumpCount < 0:
neg = -0.5
ben.y -= (ben.jumpCount **2) * 1.5 * neg
ben.jumpCount -= 2
else:
ben.isJump = False
ben.jumpCount = 7
ben.velocity = 11
redrawGameWindow()
#-----------------------------------------------------------------------------------------------
pygame.quit()
In this part of the code:
if self.walkCount + 1 >= 8:
self.walkcount = 0
self.walkCount is written as self.walkcount (lowercase c). So, the actual walkCount is not being reset to zero, thus the list index out of range error.

How do I make the character jump in Pygame?

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)

These hit boxes are crossing over even though they are literally not with if statements

I am trying to get my pieces to collide and and when I jump up into the air the characters should not collide.
Here is a video explaining the problem:
https://drive.google.com/file/d/1a26Vmd6TF4C3dJ0DpnFLTR1d3a_lEfn4/view?usp=sharing
The collision is with the goblin.
Furthermore, we can see that the goblin is colliding even though the boxes aren't touching and when on top of the hitbox.
I have tried to change the condition of the loop for example changed the ">" around to "<" and tried making the jump higher. Both of these did not resolve the problem and I am not an experienced coder.
Here is the main problem:
if (adventurer.hitbox_running[0] > attacker.hitbox[0] and adventurer.hitbox_running[0] < attacker.hitbox[0]+70) or (adventurer.hitbox_running[0]+70 > attacker.hitbox[0] and adventurer.hitbox_running[0]+90 < attacker.hitbox[0]+70):
if (adventurer.hitbox_running[1] > attacker.hitbox[1] and adventurer.hitbox_running[1] < attacker.hitbox[1]+70) or (adventurer.hitbox_running[1]+90 > attacker.hitbox[1] and adventurer.hitbox_running[1]+90 < attacker.hitbox[1]+70):
window.fill((255,255,255))
death()
pygame.display.update()
s(0.1)
print("hit")
Here is the entire code with all of the classes and everything:
from time import sleep as s
import random
import pygame
import time
#Loads and plays the music
pygame.mixer.pre_init(44100,16,2,4096)
pygame.init()
pygame.mixer.music.load("Music.mp3")
pygame.mixer.music.set_volume(0.0)
pygame.mixer.music.play(-1)
score = 0
#sets the dimension of the window and loads in the background
window = pygame.display.set_mode((1000, 500))
pygame.display.set_caption("Practice Game")
background = pygame.image.load('pixel6.png')
#Transforms the background to desired dimensions
background = pygame.transform.scale(background, (1000, 500))
#Loads all the jump animation
jumpv1 = [pygame.image.load('adventurer-jump-00.png'),pygame.image.load('adventurer-jump-01.png'),pygame.image.load('adventurer-jump-02.png'),pygame.image.load('adventurer-jump-03.png'), pygame.image.load('adventurer-smrslt-00.png'),pygame.image.load('adventurer-smrslt-01.png'),pygame.image.load('adventurer-smrslt-02.png'),pygame.image.load('adventurer-smrslt-03.png')]
jumpv2 = [pygame.image.load('adventurer-smrslt-00.png'),pygame.image.load('adventurer-smrslt-01.png'),pygame.image.load('adventurer-smrslt-02.png'),pygame.image.load('adventurer-smrslt-03.png')]
jumpv3 = [pygame.image.load('adventurer-smrslt-00.png'),pygame.image.load('adventurer-smrslt-01.png'),pygame.image.load('adventurer-smrslt-02.png'),pygame.image.load('adventurer-smrslt-03.png')]
jumpv4 = [pygame.image.load('adventurer-smrslt-00.png'),pygame.image.load('adventurer-smrslt-01.png'),pygame.image.load('adventurer-smrslt-02.png'),pygame.image.load('adventurer-smrslt-03.png')]
jump = jumpv1+jumpv2+jumpv3+jumpv4
#running animation
run = [pygame.image.load('adventurer-run-00.png'), pygame.image.load('adventurer-run-01.png'),pygame.image.load('adventurer-run-02.png'),pygame.image.load('adventurer-run-03.png')]
#sliding animation
slide = [pygame.image.load('adventurer-slide-00.png'),pygame.image.load('adventurer-slide-01.png'),pygame.image.load('adventurer-stand-00.png'),pygame.image.load('adventurer-stand-01.png'),pygame.image.load('adventurer-stand-02.png')]
#attacking animation
firstattack = [pygame.image.load('adventurer-attack3-00.png'),pygame.image.load('adventurer-attack3-01.png'),pygame.image.load('adventurer-attack3-02.png'),pygame.image.load('adventurer-attack3-03.png'),pygame.image.load('adventurer-attack3-04.png'),pygame.image.load('adventurer-attack3-05.png')]
secondattack = [pygame.image.load('adventurer-attack2-00.png'),pygame.image.load('adventurer-attack2-01.png'),pygame.image.load('adventurer-attack2-02.png'),pygame.image.load('adventurer-attack2-03.png'),pygame.image.load('adventurer-attack2-04.png'),pygame.image.load('adventurer-attack2-05.png')]
thirdattack = [pygame.image.load('adventurer-attack1-00.png'),pygame.image .load('adventurer-attack1-01.png'),pygame.image.load('adventurer-attack1-02.png'),pygame.image.load('adventurer-attack1-03.png'), pygame.image.load('adventurer-attack1-04.png')]
attack = firstattack+secondattack+ thirdattack
#falling animation
falling = [pygame.image.load('adventurer-fall-00.png'), pygame.image.load('adventurer-fall-01.png')]
score = 0
run_program = True
#resizes all the adventuruer images to specified dimensions
for i in range (20):
jump[i] = pygame.transform.scale(jump[i],(90,90))
for i in range(3):
run[i] = pygame.transform.scale(run[i],(90,90))
for i in range (4):
slide[i] = pygame.transform.scale(slide[i],(90,90))
for i in range (1):
falling[i] = pygame.transform.scale(falling[i],(90,90))
for i in range(16):
attack[i] = pygame.transform.scale(attack[i],(90,90))
background_x = 0
background_2 = background.get_width()
clock = pygame.time.Clock()
ghost_image = pygame.image.load('imgg.png')
def text_objects(text, font):
textSurface = font.render(text, True, (0,0,0))
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf',115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((1000/2),(500/2))
window.blit(TextSurf, TextRect)
pygame.display.update()
def death():
message_display('You DIED')
class ghost(object):
ghost_animation = [pygame.image.load('imgg.png'),pygame.image.load('imgg.png')]
def __init__(self, x,y,height):
self.x = x
self.y =y
self.height = height
self.hitbox = (x,y,100,100)
self.count = 0
def draw(self, window):
self.hitbox = (self.x, self.y, 45, 60)
if self.count >=1:
self.count = 0
self.count +=1
window.blit(pygame.transform.scale(self.ghost_animation[self.count], (45,60)), (self.x, self.y))
pygame.draw.rect(window, (255,0,0), self.hitbox, 2)
def hit(self):
print ("hit")
class eye(object):
eye_load = pygame.image.load('obstc2.png')
def __init__(self, x,y,width2, height2):
self.x = x
self.y =y
self.hitbox_enemy = (x,y,200,100)
self.count1 = 0
def draw(self, window):
self.hitbox_enemy = (self.x, self.y, 65, 65)
window.blit(pygame.transform.scale(self.eye_load, (65,65)), (self.x, self.y))
pygame.draw.rect(window, (255,0,0), self.hitbox_enemy, 2)
class player(object):
def __init__(self, x,y):
self.vel = 0.5
self.running = True
self.jumping = True
self.sliding = True
self.attacking = True
self.isJump = False
self. jumps = True
self.fall = True
self.player_x = 40
self.player_y = 378
self.x = 40
self.y = 378
self.width = 378
self.speed = 0.6
self.jumpcount = 10
self.jumpingcount = 0
self.runcount = 0
self.attackcount = 0
self.slidecount = 0
self.fallspeed = 0.3
self.fallingcount = 0
self.hitbox_running = (self.player_x,self.player_y,90,90)
self.hitbox_sliding = (45,self.player_y+47,65,45)
self.hitbox_falling = (self.player_x+30,self.player_y,35,80)
self.hitbox_jumping = (self.player_x+20,self.player_y+20,52,55)
self.hitbox_attacking = (58,405,47,70)
self.hitbox_sword = (108, 405, 20, 50)
def movement(self, window):
pygame.time.delay(20)
if self.runcount >= 3:
self.runcount = 0
if self.running == True:
window.blit(run[self.runcount],(int(self.player_x),int(self.player_y)))
self.runcount +=1
self.hitbox_running = (self.player_x+30,self.player_y+20,48,70)
pygame.draw.rect(window,(255,0,0),self.hitbox_running, 2)
if (keys[pygame.K_DOWN]) or ((keys[pygame.K_DOWN]) and keys[pygame.K_p]):
if self.player_y == 378:
self.running = False
if self.slidecount >= 4:
self.slidecount = 0
if self.sliding:
window.blit(slide[self.slidecount],(int(self.player_x),int(self.player_y)))
self.slidecount +=1
pygame.draw.rect(window,(255,0,0),self.hitbox_sliding, 2)
if event.type == pygame.KEYDOWN:
if (event.key == pygame.K_DOWN )and self.player_y < self.width:
self.running = False
self.jumping = False
self.fallspeed += 0.2
if self.fallingcount >= 1:
self.fallingcount = 0
if self.fall:
window.blit(falling[self.fallingcount], (int(self.player_x),int(self.player_y)))
self.hitbox_falling = (self.player_x+30,self.player_y,35,80)
pygame.draw.rect(window,(255,0,0),self.hitbox_falling, 2)
self.fallingcount +=1
if keys[pygame.K_UP] and keys[pygame.K_p] :
self.fallspeed = 0.3
self.running = False
self.jumping = False
self.sliding = False
if self.attackcount >= 16:
self.attackcount = 0
if self.attacking:
window.blit(attack[self.attackcount],(int(self.player_x),int(self.player_y)))
self.attackcount += 1
self.hitbox_attacking = (self.player_x+30,self.player_y+20,38,70)
self.hitbox_sword = (self.player_x+72, self.player_y+20, 20, 50)
pygame.draw.rect(window,(255,0,0),self.hitbox_attacking, 2)
pygame.draw.rect(window,(255,0,0),self.hitbox_sword, 2)
if self.jumpingcount >= 20:
self.jumpingcount = 0
if self.jumping and self.player_y < self.width:
window.blit(jump[self.jumpingcount],(int(self.player_x),int(self.player_y)))
self.hitbox_jumping = (int(self.player_x+20),int(self.player_y+20),52,55)
pygame.draw.rect(window,(255,0,0),self.hitbox_jumping, 2)
self.jumpingcount +=1
self.fallspeed = 0.3
if keys[pygame.K_UP]:
self.fallspeed = 0.3
self.running = False
if self.jumpingcount >= 20:
self.jumpingcount = 0
if self.jumping and self.player_y < self.width:
window.blit(jump[self.jumpingcount],(int(self.player_x),int(self.player_y)))
self.hitbox_jumping = (int(self.player_x+20),int(self.player_y+20),52,55)
pygame.draw.rect(window,(255,0,0),self.hitbox_jumping, 2)
self.jumpingcount +=1
self.fallspeed = 0.3
if keys[pygame.K_p] and not keys[pygame.K_UP]:
self.running = False
self.jumping = False
self.sliding = False
if self.attackcount >= 16:
self.attackcount = 0
if self.attacking:
self.hitbox_attacking = (self.player_x+30,self.player_y+20,38,70)
self.hitbox_sword = (self.player_x+72, self.player_y+20, 20, 50)
window.blit(attack[self.attackcount],(int(self.player_x),int(self.player_y)))
self.attackcount += 1
pygame.draw.rect(window,(255,0,0),self.hitbox_attacking, 2)
pygame.draw.rect(window,(255,0,0),self.hitbox_sword, 2)
if keys[pygame.K_DOWN] and keys[pygame.K_UP]:
self.running = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
self.running = True
self.jumping = True
self.fallspeed = 0.3
if event.key == pygame.K_UP:
self.running=True
if event.key == pygame.K_p:
self.running = True
self.jumping = True
self.sliding = True
class enemy(object):
walkright = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'), pygame.image.load('R3E.png'), pygame.image.load('R4E.png'), pygame.image.load('R5E.png'), pygame.image.load('R6E.png'), pygame.image.load('R7E.png'), pygame.image.load('R8E.png'), pygame.image.load('R9E.png'), pygame.image.load('R10E.png'), pygame.image.load('R11E.png')]
walkleft = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'), pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'), pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png'), pygame.image.load('L10E.png'), pygame.image.load('L11E.png')]
for i in range (10):
walkright[i] = pygame.transform.scale(walkright[i],(70,70))
for i in range(10):
walkleft[i] = pygame.transform.scale(walkleft[i],(70,70))
def __init__(self,enemy_x,enemy_y, end):
self.x = enemy_x
self.y = enemy_y
self.end = end
self.path = [self.x,self.end]
self.walkcount = 0
self.vel = 7
self.hitbox = (self.x,self.y-15,90,90)
def draw_enemy(self,window):
self.move()
if self.walkcount+1 >= 33:
self.walkcount = 0
self.vel+=0.2
#walking right
if self.vel > 0:
window.blit(self.walkleft[self.walkcount//3], (self.x,self.y-15))
self.walkcount += 1
#walking left
if self.vel < 0:
## window.blit(self.walkleft[self.walkcount//3], (self.x,self.y))
self.walkcount -= 1
if self.x < -100:
self.x = 1050
self.hitbox = (self.x+25,self.y-15,41,70)
pygame.draw.rect(window, (255,0,0),self.hitbox,2)
def move(self):
if self.vel > 0:
#see if position + movement space is < the end, then it is able to move
if self.x + self.vel < self.path[1]:
self.x -= self.vel
#past end point and turns 180
else:
self.vel = self.vel*-1
self.walkcount = 0
#see if position is smaller than starting position
else:
if self.x - self.vel > self.path[0]:
#vel is already negative
self.x += self.vel
else:
#Truns 180 agian
self.vel = self.vel* -1
self.walkcount = 0
class wizard(object):
walkleft = [pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_05.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_05.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_05.gif'),pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'),pygame.image.load('wizard-fly-forward_05.gif')]
for i in range(16):
walkleft[i] = pygame.transform.scale(walkleft[i],(70,70))
def __init__(self,enemy_x,enemy_y, end):
self.x = enemy_x
self.y = enemy_y
self.end = end
self.path = [self.x,self.end]
self.walkcount = 0
self.vel = 7
self.hitbox = (self.x,self.y-15,90,90)
def draw_enemy(self,window):
self.move()
if self.walkcount >= 16:
self.walkcount = 0
#walking left
if self.vel > 0:
window.blit(self.walkleft[self.walkcount], (self.x,self.y-15))
self.walkcount += 1
self.vel+=0.002
if self.x < -120:
self.x = 1100
self.hitbox = (self.x+25,self.y-15,41,70)
pygame.draw.rect(window, (255,0,0),self.hitbox,2)
def move(self):
if self.vel > 0:
#see if position + movement space is < the end, then it is able to move
if self.x + self.vel < self.path[1]:
self.x -= self.vel
#past end point and turns 180
else:
self.vel = self.vel*-1
self.walkcount = 0
#see if position is smaller than starting position
else:
if self.x - self.vel > self.path[0]:
#vel is already negative
self.x += self.vel
else:
#Truns 180 agian
self.vel = self.vel* -1
self.walkcount = 0
class dragon(object):
walkleft = [pygame.image.load('dragon_1.gif'), pygame.image.load('dragon_2.gif'), pygame.image.load('dragon_3.gif'), pygame.image.load('dragon_4.gif'), pygame.image.load('dragon_5.gif'), pygame.image.load('dragon_6.gif')]
for i in range (6):
walkleft[i] = pygame.transform.scale(walkleft[i],(200,176))
def __init__(self,enemy_x,enemy_y, end):
self.x = enemy_x
self.y = enemy_y
self.end = end
self.path = [self.x,self.end]
self.walkcount = 0
self.vel = 7
self.hitbox = (self.x,self.y-15,90,90)
def draw_enemy(self,window):
self.move()
if self.walkcount >= 6:
self.walkcount = 0
#walking left
if self.vel > 0:
window.blit(self.walkleft[self.walkcount], (self.x,300))
self.walkcount += 1
self.vel+=0.002
if self.x < -120:
self.x = 1100
self.hitbox = (self.x+25,self.y-15,41,70)
pygame.draw.rect(window, (255,0,0),self.hitbox,2)
def move(self):
if self.vel > 0:
#see if position + movement space is < the end, then it is able to move
if self.x + self.vel < self.path[1]:
self.x -= self.vel
#past end point and turns 180
else:
self.vel = self.vel*-1
self.walkcount = 0
#see if position is smaller than starting position
else:
if self.x - self.vel > self.path[0]:
#vel is already negative
self.x += self.vel
else:
#Truns 180 agian
self.vel = self.vel* -1
self.walkcount = 0
ghost_list = []
eye_list = []
def keepdrawing():
window.blit(background, (background_x,0))
window.blit(background, (background_2,0))
for draw_ghost in ghost_list:
draw_ghost.draw(window)
for draw_eye in eye_list:
draw_eye.draw(window)
adventurer.movement(window)
attacker.draw_enemy(window)
wizard.draw_enemy(window)
dragon.draw_enemy(window)
score_text = score_font.render("score: " + str(score), 1, (0,0,0))
window.blit(score_text,(470,10))
pygame.display.update()
score_font = pygame.font.SysFont("Arial",30,True)
attacker = enemy(950,407,951)
adventurer = player(40,387)
wizard = wizard(905,407,951)
dragon = dragon(905,407, 951)
vel_background = 2
pygame.time.set_timer(pygame.USEREVENT+1,random.randint(1000, 2000))
pygame.time.set_timer(pygame.USEREVENT+2,random.randint(2000, 3000))
while run:
while run_program:
clock.tick(60)
background_x -= vel_background
background_2 -= vel_background
if background_x < background.get_width() * -1:
background_x = background.get_width()
if background_2 < background.get_width() * -1:
background_2 = background.get_width()
keys = pygame.key.get_pressed()
if (adventurer.hitbox_running[0] > attacker.hitbox[0] and adventurer.hitbox_running[0] < attacker.hitbox[0]+70) or (adventurer.hitbox_running[0]+70 > attacker.hitbox[0] and adventurer.hitbox_running[0]+90 < attacker.hitbox[0]+70):
if (adventurer.hitbox_running[1] > attacker.hitbox[1] and adventurer.hitbox_running[1] < attacker.hitbox[1]+70) or (adventurer.hitbox_running[1]+90 > attacker.hitbox[1] and adventurer.hitbox_running[1]+90 < attacker.hitbox[1]+70):
window.fill((255,255,255))
death()
pygame.display.update()
s(0.1)
print("hit")
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
exit()
if event.type == pygame.USEREVENT+1:
vel_background+=0.2
if event.type == pygame.USEREVENT+2:
r = random.randint(0,1)
if r==0:
new_eye = eye(1050, 390, 64,64)
eye_list.append(new_eye)
if r==1:
new_ghost = ghost(1050,390,64)
ghost_list.append(new_ghost)
if not(adventurer.isJump):
if keys[pygame.K_UP]:
adventurer.isJump =True
else:
if adventurer.jumpcount >= -10:
neg=1
if adventurer.player_y > adventurer.width:
adventurer.player_y = adventurer.width
if adventurer.jumpcount <0:
neg = -1
## s(0.01)
adventurer.player_y -= (adventurer.jumpcount**2)*adventurer.fallspeed*neg*2
## s(0.01)
adventurer.jumpcount -=1
if adventurer.player_y > adventurer.width:
adventurer.player_y=adventurer.width
else:
adventurer.isJump = False
adventurer.jumpcount = 10
if adventurer.player_y > adventurer.width:
player_y = adventurer.width
adventurer.fallspeed = 0.05
keepdrawing()
The expected results should be that the output should not be shit if the hit boxes are not in contact.
The major issue is that you've different "hitboxis, which have different meanings at different states of the game, but you use adventurer.hitbox_running for the collison test event if adventurer is .running or .falling.
The best solution would be the set one .hitbox attribute, which always contains the proper location of adventurer in the method player.movement.
But it is also possible the choose the proper hit box:
if adventurer.running:
hitbox = adventurer.hitbox_running
elif adventurer.jumping:
hitbox = adventurer.hitbox_jumping
elif adventurer.falling:
hitbox = adventurer.hitbox_falling
Further I recommend to use pygame.Rect objects and .colliderect() for the collision test:
rect_adventurer = pygame.Rect(*hitbox)
rect_attacker = pygame.Rect(*attacker.hitbox)
if rect_adventurer.colliderect(rect_attacker):
window.fill((255,255,255))
death()
pygame.display.update()
s(0.1)
print("hit")

Pygame, keep jumping and glitching through the "ground"

My character won't jump properly, he keeps glitching through the ground. If i hold key up, my character won't stop going higher. Do you have some ideas for how I could fix it?
import pygame,sys
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((1200, 800))
screen.fill((0,0,0))
pygame.display.set_caption('Jump and Run')
BLACK = (0,0,0)
WHITE = (250, 250,250)
RED = (250, 0, 0)
BLUE = (0,0,250)
direction = 'right'
way = 0
jump_high = 0
class Hero():
def __init__(self, x, y):
self.x = x
self.y = y
self.image = pygame.image.load('hero.bmp')
self.groundcontact = True
self.vy = 0
alive = True
def check_pos(self):
if self.y >= 400:
self.groundcontact = True
elif self.y <= 400:
self.groundcontact = False
def load_picture(self,surface):
surface.blit(self.image,(self.x, self.y))
def check_input(self):
key = pygame.key.get_pressed()
if key[pygame.K_RIGHT]:
self.x += 10
elif key[pygame.K_LEFT]:
self.x -= 10
elif key[pygame.K_UP]:
self.y -= 50
if not self.groundcontact:
self.vy += 1 #max(min(2,200), -200)
#self.y += self.vy
print "not self.groundcontact"
else:
self.vy = 0
#self.y += self.vy
self.y += self.vy
class Monster():
def __init__(self, x, y):
self.x = x
self.y = y
self.image = pygame.image.load('monster.bmp')
self.collision = False
self.alive = True
def load_picture(self,surface):
surface.blit(self.image,(self.x, self.y))
def walk(self):
global direction
global way
if direction == "right":
self.x += 4
way += 1
if way == 100:
direction = "left"
elif direction == "left":
self.x -= 4
way -= 1
if way == 0:
direction = "right"
monster2 = Monster( 200, 333)
monster1 = Monster(400, 450)
hero = Hero(0, 400)
clock = pygame.time.Clock()
pygame.draw.rect(screen, WHITE,(0,500, 1200, 50))
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
hero.check_pos()
monster1.walk()
monster2.walk()
hero.check_input()
screen.fill(BLACK)
hero.load_picture(screen)
monster1.load_picture(screen)
monster2.load_picture(screen)
pygame.draw.rect(screen, WHITE,(0,500, 1200, 50))
pygame.display.update()
clock.tick(40)
Regarding my comment above, changing the Hero class to somthing like this:
JUMP_POWER = 10
class Hero():
...
def check_input(self):
key = pygame.key.get_pressed()
...
elif key[pygame.K_UP]:
if self.groundcontact:
self.vy -= JUMP_SPEED

Categories