I was trying to make a side scroller game with pygame ( i am quite new to pygame ) and my game works quite fine but once it turns fast it just gets a weird kind of glitch for a few seconds and it happens occasionally i think its some kind of background error of size not being enough but my screen size is 800, 447 but the background png i use is 1920, 1080 ( the black screen is my background ) Here is my code
from pygame.locals import *
import os
import sys
import math
pygame.init()
W, H = 800, 447
win = pygame.display.set_mode((W,H))
pygame.display.set_caption('Side Scroller')
x = 200
y = 200
height = 30
width = 30
bg = pygame.image.load(os.path.join('im','bg.png')).convert()
bgX = 0
bgX2 = bg.get_width()
clock = pygame.time.Clock()
class player(object):
run = [pygame.image.load(os.path.join('im', str(x) + '.png')) for x in range(8,16)]
jump = [pygame.image.load(os.path.join('im', str(x) + '.png')) for x in range(1,8)]
slide = [pygame.image.load(os.path.join('images', 'S1.png')),pygame.image.load(os.path.join('images', 'S2.png')),pygame.image.load(os.path.join('images', 'S2.png')),pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')),pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S3.png')), pygame.image.load(os.path.join('images', 'S4.png')), pygame.image.load(os.path.join('images', 'S5.png'))]
jumpList = [![enter image description here][1]][1][1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4]
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.jumping = False
self.sliding = False
self.slideCount = 0
self.jumpCount = 0
self.runCount = 0
self.slideUp = False
def draw(self, win):
if self.jumping:
self.y -= self.jumpList[self.jumpCount] * 1.2
win.blit(self.jump[self.jumpCount//18], (self.x,self.y))
self.jumpCount += 1
if self.jumpCount > 108:
self.jumpCount = 0
self.jumping = False
self.runCount = 0
elif self.sliding or self.slideUp:
if self.slideCount < 20:
self.y += 1
elif self.slideCount == 80:
self.y -= 19
self.sliding = False
self.slideUp = True
if self.slideCount >= 110:
self.slideCount = 0
self.slideUp = False
self.runCount = 0
win.blit(self.slide[self.slideCount//10], (self.x,self.y))
self.slideCount += 1
else:
if self.runCount > 42:
self.runCount = 0
win.blit(self.run[self.runCount//6], (self.x,self.y))
self.runCount += 1
def redrawwindow():
win.blit(bg, (bgX, 0))
win.blit(bg, (bgX2, 0))
runner.draw(win)
pygame.display.update()
run = True
speed = 30[![enter image description here][1]][1]
pygame.time.set_timer(USEREVENT+1, 500)
runner = player(200, 313, 80, 64)
while run:
bgX -= 1.4
bgX2 -= 1.4
if bgX < bg.get_width() * -1:
bgX = bg.get_width()
if bgX2 < bg.get_width() * -1:
bg2 = bg.get_width()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == USEREVENT+1:
speed +=1
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE] or keys[pygame.K_UP]:
if not (runner.jumping):
runner.jumping = True
if keys[pygame.K_DOWN]:
if not (runner.sliding):
runner.sliding = True
redrawwindow()
clock.tick(speed)
pygame.quit()
looks like you just need to update your screen so the pixels will update properly.
you can add
pygame.display.update()
to the end of your game loop
if this still don't work then try using this command to fill in the background with just the color black just and clearing everything
win.fill((0, 0, 0))
you should put it at the start of the game loop
Related
1) In my code the problem is that my Platform underneath my player class are connected and when the player moves so does the platform and if so the player moves on the platform the entire time. Can someone tell me how to fix that? If you are wondering where to look for all the code and where it is going to be it is all the code here because I didn't Know what was causing the problem in my code.
import math
import os
import sys
# It is importing everything
import pygame
from pygame.locals import *
#The platform class is the problem I'm having
class Platform:
def __init__(self, size, x, y, length, color, velocity):
self.length = length
self.size = size
self.x = x
self.y = y
self.color = color
self.velocity = velocity
self.xVelocity = 0
# This is what the platform class has and what it does
def draw(self):
display = pygame.display.get_surface()
pygame.draw.rect(display, self.color, (int(self.x) - 80, int(self.y) + 225, int(self.x), int(self.y) - 45))
# This is def draw function is showing that how I want my Platform to look like
def do(self):
self.draw()
2) When my player reaches the "end" of the screen it stops but I want to make it a scrolling screen and nothing happens and then there is no game when the player moves and scroll by itself. After someone tells me how to fix my second problem then I want the Background to kill the player if the background goes past the player.
# The def do function is running def draw function
class Player:
def __init__(self, velocity, maxJumpRange, x, y, size):
self.falling = True
self.jumpCounter = 0
self.xVelocity = 0
self.y = y
self.x = x
self.jumping = False
self.velocity = velocity
self.maxJumpRange = maxJumpRange
self.jump_offset = 0
self.size = size
# The player class is making how the Player is going to look and what are his limits
def keys(self):
k = pygame.key.get_pressed()
# The def keys(self): is creating a variable for pygame.key.get_pressed() and underneath is a function to make the player move around
if k[K_LEFT]:
self.xVelocity = -self.velocity
elif k[K_RIGHT]:
self.xVelocity = self.velocity
else:
self.xVelocity = 0
if k[K_SPACE] or k[K_UP] and not self.jumping and not self.falling:
self.jumping = True
self.jumpCounter = 0
# The if k[K_Space] or k[K_UP] is making sure the player has a jump limit and can't continue jumping forever.
def move(self):
self.x += self.xVelocity
# This to make sure that the player can move while he is jumping.
if self.jumping:
self.y -= self.velocity
self.jumpCounter += 1
if self.jumpCounter == self.maxJumpRange:
self.jumping = False
self.falling = True
elif self.falling:
if self.y <= h - 10 <= self.y + self.velocity:
self.y = h - 10
self.falling = False
else:
self.y += self.velocity
def draw(self):
display = pygame.display.get_surface()
pygame.draw.circle(display, White, (int(self.x), int(self.y) - 25), 25, 0)
def do(self):
self.keys()
self.move()
self.draw()
# This Function is doing all of the Functions self.keys(), self.move(), self.draw()
def events():
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
# This is to make sure that you can exit the game is needed
def keys(player):
keys = pygame.key.get_pressed()
if keys[K_UP] or keys[K_SPACE] and player.jumping == False and player.jump_offset == 0:
player.jumping = True
# The function here to make sure that the player can jump
def do_jumping(player):
jump_height = 25
# Def do_jumping(player): is to adjust the jump_height of the player
if player.jumping:
player.jump_offset += 1
if player.jump_offset >= jump_height:
player.jumping = False
elif player.jump_offset > 0 and player.jumping == False:
player.jump_offset -= 1
# The above is showing how the makes sure the player doesn't jump higher then the jump height
w = 576
h = 516
hw = w / 2
hh = h / 2
AREA = w * h
# The above is showing the width the height and Area
os.environ['SDL_VIDEO_WINDOW_POS'] = "50,50"
p = Player(hh, hw, 290, 250, 30)
# the above is showing what the graphics are
pygame.init()
Clock = pygame.time.Clock()
DS = pygame.display.set_mode((w, h)) # This is what the display size is
pygame.display.set_caption("Try to get point B")
FPS = 120
Black = (0, 0, 0, 255)
White = (255, 255, 255, 255)
pl = Platform(290, 250, 50, 70, White, 0)
Red = (255, 0, 0)
Solid_Fill = 0
# Bkgd stands for background
bkgd = pygame.image.load("scroll.png").convert() # scroll.png is the png im using to use as the background
bkgdWidth = bkgd.get_rect().size[0]
print(bkgdWidth)
bkgdHeight = bkgd.get_rect().size
stageWidth = bkgdWidth * 2
StagePosX = 0
startScollingPosx = hw
circleRadius = 25
circlePosX = circleRadius
playerPosX = circleRadius
playerPosY = 377
playerVelocityX = 0
playerVelocityY = 0
platformVelocityX = 0
platformVelocityY = 0
x = 0
# The above is showing the player Velocity, player position y and x and what the stage position is, Ignore platform
# velocity.
# What the while true loop is doing is to make sure that the background moves while the player moves
while True:
events()
k = pygame.key.get_pressed()
if k[K_RIGHT]:
playerVelocityX = 1
pl.xVelocity = 0
elif k[K_LEFT]:
playerVelocityX = -1
pl.xVelocity = 0
else:
playerVelocityX = 0
pl.xVelocity = 0
playerPosX += playerVelocityX
if playerPosX > stageWidth - circleRadius:
playerPosX = stageWidth - circleRadius
if playerPosX < circleRadius:
playerPosX = circleRadius
if playerPosX < startScollingPosx:
circlePosX = playerPosX
elif playerPosX > stageWidth - startScollingPosx:
circlePosX - stageWidth + w
else:
circlePosX = startScollingPosx
StagePosX -= playerVelocityX
# The code below show is working how to balance the Display size and rel x is the easier of saying that
rel_x = StagePosX % bkgdWidth
DS.blit(bkgd, (rel_x - bkgdWidth, 0))
if rel_x < w:
DS.blit(bkgd, (rel_x, 0))
events()
keys(p)
do_jumping(p)
pygame.draw.circle(DS, White, (math.floor(p.x), math.floor(p.y) - math.floor(p.jump_offset)), math.floor(p.size), math.floor(Solid_Fill))
platform_color = Red
pl.color = Red
pl.draw()
if p.jump_offset == 0:
pl.color = White
pl.do()
pygame.display.update()
Clock.tick(FPS)
DS.fill(Black)
3) Lastly sorry for the lack of good code and where to look around the code because I didn't Know what was causing the problem in my code so I had to put out all of it.
I edited your code a bit so fix the problems you had, I did change the image as i didn't have it, but i fixed jumping and standing on platform by making player constantly fall and check if the player collides with the platform. I also added the scrolling background. Got rid of the unnecessary code as mentioned in my comments. changed the player move to do the jump from there. changed the size in platform to a list so it has width and height. got rid of velocity too as platforms didn't move.
import math
import os
import sys
# It is importing everything
import pygame
from pygame.locals import *
class Platform:
def __init__(self, size, x, y, color):
#size is a list, this means it has width and height
self.size = size
self.x = x
self.y = y
self.color = color
# This is what the platform class has and what it does
def draw(self):
display = pygame.display.get_surface()
pygame.draw.rect(display, self.color, (int(self.x), int(self.y), self.size[0], self.size[1]))
# This is def draw function is showing that how I want my Platform to look like
def do(self):
self.draw()
# The def do function is running def draw function
class Player:
def __init__(self, velocity, maxJumpRange, x, y, size):
self.falling = True
self.jumpCounter = 0
self.xVelocity = 0
self.y = y
self.x = x
self.jumping = False
self.velocity = velocity
self.maxJumpRange = maxJumpRange
self.jump_offset = 0
self.size = size
self.TouchedGround = False
# The player class is making how the Player is going to look and what are his limits
def keys(self):
k = pygame.key.get_pressed()
# The def keys(self): is creating a variable for pygame.key.get_pressed() and underneath is a function to make the player move around
if k[K_LEFT]:
self.xVelocity = -self.velocity
elif k[K_RIGHT]:
self.xVelocity = self.velocity
else:
self.xVelocity = 0
if (k[K_SPACE] or k[K_UP]) and not self.jumping and self.TouchedGround:
self.jumping = True
self.jumpCounter = 0
self.TouchedGround = False
# The if k[K_Space] or k[K_UP] is making sure the player has a jump limit and can't continue jumping forever.
def move(self):
self.x += self.xVelocity
# if the player is jumping, change y value
if self.jumping:
self.y -= self.velocity
self.jumpCounter += 1
if self.jumpCounter == self.maxJumpRange:
self.jumping = False
self.falling = True
elif self.falling:
self.y += self.velocity
self.jumpCounter -= 1
def draw(self):
display = pygame.display.get_surface()
pygame.draw.circle(display, White, (int(self.x), int(self.y)), self.size)
def do(self):
self.keys()
self.move()
self.draw()
# This Function is doing all of the Functions self.keys(), self.move(), self.draw()
def events():
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
#window size
w = 576
h = 516
# The above is showing the width the height and Area
os.environ['SDL_VIDEO_WINDOW_POS'] = "50,50"
# the above is showing what the graphics are
#player
p = Player(1, 100, 290, 250, 30)
#start pygame
pygame.init()
Clock = pygame.time.Clock()
DS = pygame.display.set_mode((w, h)) # This is what the display size is
pygame.display.set_caption("Try to get point B")
#variables
FPS = 120
Black = (0, 0, 0, 255)
White = (255, 255, 255, 255)
Red = (255, 0, 0)
# Bkgd stands for background
bkgd = pygame.Surface((w,h)) # didnt have the image so i made it blue
bkgd.fill((0,0,255))
#platforms
pl = Platform([290,20], 250, 350, White)
#this is a list that holds all the platforms
platforms_list = [pl,Platform([200,20], 100, 450, White), Platform([200,20], 400, 250, White)]
#this is how much to scroll the background by
background_scroll = 0
# What the while true loop is doing is to make sure that the background moves while the player moves
while True:
events()
#blit the background, since the image is same size as window blit twice so when scrolls, you dont have blackness
DS.blit(bkgd, (-background_scroll, 0))
DS.blit(bkgd, (w-background_scroll, 0))
#check for x button clicked
events()
#update the player
p.do()
#update platforms and check for collision with player
platform_color = Red
for platform in platforms_list:
platform.color = platform_color
if p.jumping == 0:
platform.color = White
platform.do()
#if bottom of player is in the platform, move the player on top of the platform
if p.y + p.size > platform.y and p.y + p.size < platform.y + platform.size[1]:
if p.x > platform.x and p.x < platform.x + platform.size[0]:
p.y = platform.y - p.size
p.TouchedGround = True
#if the player reaches the side of the screen, move the background and platforms to make it look like it is moving
if p.x + p.size >= w:
p.x = w - p.size
background_scroll += 1
for platform in platforms_list:
platform.x -= 1
if background_scroll == w:
background_scroll = 0
#same but for the left
if p.x - p.size <= 0:
p.x = 0 + p.size
background_scroll -= 1
for platform in platforms_list:
platform.x += 1
if background_scroll == 0:
background_scroll = w
#update screen
pygame.display.update()
Clock.tick(FPS)
DS.fill(Black)
I have been trying to get this code to work for weeks and cannot figure out the issue. I have a list of images, that I am using to animate my character. THe game worked fine at first, but ever since I made the background animate (start moving left to right), my character stopped appearing. Do I have to change the location of some of my code? Really confused. Thank you!!
# create lists with images of character walking left and right
rightDirection = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
leftDirection = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
background = pygame.image.load('background.png')
backgroundX = 0
backgroundX2 = background.get_width()
homeScreen = pygame.image.load('home_screen.png')
# frame rate
clock = pygame.time.Clock()
# use procedure for game window rather than using it within loop
def redrawGameWindow():
man.draw(screen)
# background images for right to left moving screen
screen.blit(background, (backgroundX, 0))
screen.blit(background, (backgroundX2, 0))
pygame.display.update()
# create class for character (object)
class player(object):
def __init__(self, x, y, width, height): # initialize attributes
self.x = x
self.y = y
self.width = width
self.height = height
self.left = True
self.right = True
self.isJump = False
self.stepCount = 0
self.jumpCount = 10
self.standing = True
def draw(self, screen):
if self.stepCount + 1 >= 27: # 9 sprites, with 3 frames - above 27 goes out of range
self.stepCount = 0
if not self.standing:
if self.left:
screen.blit(leftDirection[self.stepCount // 5], (self.x, self.y), )
self.stepCount += 1
elif self.right:
screen.blit(rightDirection[self.stepCount // 5], (self.x, self.y), )
self.stepCount += 1
else:
if self.right:
screen.blit(rightDirection[0], (self.x, self.y)) # using index, include right faced photo
else:
screen.blit(leftDirection[0], (self.x, self.y))
class enlargement(object):
def __init__(self, x, y, radius, color, facing):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.facing = facing
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius, 1)
man = player(200, 313, 64, 64)
# main loop
speed = 30 # NEW
man = player(200, 410, 64, 64) # set main character attributes
run = True
while run:
redrawGameWindow() # call procedure
clock.tick(speed) # NEW
backgroundX -= 1.4 # Move both background images back
backgroundX2 -= 1.4
if backgroundX < background.get_width() * -1: # If our background is at the -width then reset its position
backgroundX = background.get_width()
if backgroundX2 < background.get_width() * -1:
backgroundX2 = background.get_width()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
man.left = True
man.right = False
man.standing = False # false, because man is walking
# verify that character is within window parameters
elif keys[pygame.K_RIGHT]:
man.right = True
man.left = False
man.standing = False # false, because man is walking
else:
man.standing = True
man.stepCount = 0
if not man.isJump:
if keys[pygame.K_SPACE]:
man.isJump = True # when jumping, man shouldn't move directly left or right
man.right = False
man.left = False
man.stepCount = 0
else:
if man.jumpCount >= -10:
neg = 1
if man.jumpCount < 0:
neg = -1
man.y -= (man.jumpCount ** 2) * 0.5 * neg # to jump use parabola
man.jumpCount -= 1
else:
man.isJump = False
man.jumpCount = 10
pygame.quit()
You get anwser in one of previous questions - see https://stackoverflow.com/a/59761318/1832058
You have to draw man AFTER background.
def redrawGameWindow():
# background images for right to left moving screen
screen.blit(background, (backgroundX, 0))
screen.blit(background, (backgroundX2, 0))
# AFTER BACKGROUND !!!!
man.draw(screen)
pygame.display.update()
my code was working fine when i didnt have a moving background. But now, i started making my character move from left to right and it stopped showing up. Ive been trying to figure out what the issue is for days, please help!! Thanks!!!
the following is the line of code i used for the background and character:
# create class for character (object)
class player(object):
def __init__(self, x, y, width, height): # initialize attributes
self.x = x
self.y = y
self.width = width
self.height = height
self.left = True
self.right = True
self.isJump = False
self.stepCount = 0
self.jumpCount = 10
self.standing = True
def draw(self, screen):
if self.stepCount + 1 >= 27: # 9 sprites, with 3 frames - above 27 goes out of range
self.stepCount = 0
if not self.standing:
if self.left:
screen.blit(leftDirection[self.stepCount // 5], (self.x, self.y), )
self.stepCount += 1
elif self.right:
screen.blit(rightDirection[self.stepCount // 5], (self.x, self.y), )
self.stepCount += 1
else:
if self.right:
screen.blit(rightDirection[0], (self.x, self.y)) # using index, include right faced photo
else:
screen.blit(leftDirection[0], (self.x, self.y))
class enlargement(object):
def __init__(self, x, y, radius, color, facing):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.facing = facing
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius, 1)
# main loop
speed = 30 # NEW
man = player(200, 410, 64, 64) # set main character attributes
run = True
while run:
redrawGameWindow() # call procedure
clock.tick(speed) # NEW
backgroundX -= 1.4 # Move both background images back
backgroundX2 -= 1.4
if backgroundX < background.get_width() * -1: # If our background is at the -width then reset its position
backgroundX = background.get_width()
if backgroundX2 < background.get_width() * -1:
backgroundX2 = background.get_width()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
man.left = True
man.right = False
man.standing = False # false, because man is walking
# verify that character is within window parameters
elif keys[pygame.K_RIGHT]:
man.right = True
man.left = False
man.standing = False # false, because man is walking
else:
man.standing = True
man.stepCount = 0
if not man.isJump:
if keys[pygame.K_SPACE]:
man.isJump = True # when jumping, man shouldn't move directly left or right
man.right = False
man.left = False
man.stepCount = 0
else:
if man.jumpCount >= -10:
neg = 1
if man.jumpCount < 0:
neg = -1
man.y -= (man.jumpCount ** 2) * 0.5 * neg # to jump use parabola
man.jumpCount -= 1
else:
man.isJump = False
man.jumpCount = 10
Background removes all from screen - so you have to always draw background before any other elements.
You don't need to draw static background in (0,0) because moving background also remove it.
def redrawGameWindow():
# background
screen.blit(background, (backgroundX, 0))
screen.blit(background, (backgroundX2, 0))
man.draw(screen)
pygame.display.update()
I am trying to make a space invaders/asteroids game where you can shoot in all directions using pygame. Currently, I can move my ship in all directions and shoot in all directions, but as soon as I change directions my bullets that were previously fired will stop moving/move in the direction that the ship is going. Thank you in advance.
import pygame
import random
# intialize the pygame
pygame.init()
# dimensions of the pygame
screen = pygame.display.set_mode((800,600))
# Caption and Icon
pygame.display.set_caption("Saving Earth")
icon = pygame.image.load('ufo.png')
pygame.display.set_icon(icon)
# images
earth_image = pygame.image.load('earth.png')
fly_up = pygame.image.load('spaceshipU.png')
fly_down = pygame.image.load('spaceshipD.png')
fly_left = pygame.image.load('spaceshipL.png')
fly_right = pygame.image.load('spaceshipR.png')
background = pygame.image.load('space.jpg')
clock = pygame.time.Clock()
#Player class
class player(object):
def __init__(self, player_x, player_y, width, height):
self.player_x = player_x
self.player_y = player_y
self.width = width
self.height = height
self.speed = 4
self.left = False
self.right = False
self.up = True
self.down = False
# draws the ship to screen
def draw(self, screen):
if self.left:
screen.blit(fly_left, (self.player_x,self.player_y))
elif self.right:
screen.blit(fly_right, (self.player_x,self.player_y))
elif self.up:
screen.blit(fly_up, (self.player_x,self.player_y))
elif self.down:
screen.blit(fly_down, (self.player_x,self.player_y))
else:
screen.blit(fly_up, (self.player_x,self.player_y))
class Bullet(object):
def __init__(self, bullet_x, bullet_y, radius, color):
self.bullet_x = bullet_x
self.bullet_y = bullet_y
self.radius = radius
self.color = color
self.speed = 6
self.vertfacing = 1
self.hortfacing = 1
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.bullet_x,self.bullet_y), self.radius)
# redraws game screen
def redraw_game_screen():
screen.blit(background, (0,0))
screen.blit(earth_image, (350, 230))
ship.draw(screen)
for bullet in bullets:
bullet.draw(screen)
pygame.display.update()
#Game Loop
ship = player(300, 300, 32, 32)
bullets = []
vertfacing = -1
hortfacing = 1
running = True
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
for bullet in bullets:
if bullet.bullet_x < 800 and bullet.bullet_x > 0 and bullet.bullet_y < 600 and bullet.bullet_y > 0 :
if hortfacing == -1 and ship.left:
bullet.bullet_x -= bullet.speed
elif hortfacing == 1 and ship.right:
bullet.bullet_x += bullet.speed
elif vertfacing == 1 and ship.down:
bullet.bullet_y += bullet.speed
elif vertfacing == -1 and ship.up:
bullet.bullet_y -= bullet.speed
else:
bullets.remove(bullet)
#key commands
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
if ship.left:
hortfacing = -1
elif ship.right:
hortfacing = 1
elif ship.up:
vertfacing = -1
elif ship.down:
vertfacing = 1
if len(bullets) < 100:
bullets.append(Bullet(round(ship.player_x + ship.width //2), round(ship.player_y + ship.height//2), 6, (255,165,0)))
if keys[pygame.K_LEFT] and ship.player_x > ship.speed:
ship.player_x -= ship.speed
ship.left = True
ship.right = False
ship.up = False
ship.down = False
elif keys[pygame.K_RIGHT] and ship.player_x < 800 - ship.speed - ship.width:
ship.player_x += ship.speed
ship.right = True
ship.left = False
ship.up = False
ship.down = False
elif keys[pygame.K_UP] and ship.player_y > ship.speed:
ship.player_y -= ship.speed
ship.up = True
ship.down = False
ship.left = False
ship.right = False
elif keys[pygame.K_DOWN] and ship.player_y < 600 - ship.height - ship.speed:
ship.player_y += ship.speed
ship.down = True
ship.up = False
ship.left = False
ship.right = False
redraw_game_screen()
pygame.quit()
You have to se the attributes vertfacing and hortfacing in the class Bullet:
class Bullet(object):
def __init__(self, bullet_x, bullet_y, radius, color, vertfacing, hortfacing):
self.bullet_x = bullet_x
self.bullet_y = bullet_y
self.radius = radius
self.color = color
self.speed = 6
self.vertfacing = vertfacing
self.hortfacing = hortfacing
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.bullet_x,self.bullet_y), self.radius)
Pass the attributes to the constructor when a Bullet spawns:
if len(bullets) < 100:
bullet = Bullet(round(ship.player_x + ship.width //2),
round(ship.player_y + ship.height//2), 6, (255,165,0),
vertfacing, hortfacing)
bullets.append(bullet)
Use the attributes of bullet (bullet.hortfacing, bullet.vertfacing) when you calculate the new position.
Add a method to the class Bullet that moves it:
class Bullet(object):
# [...]
def move(self):
if self.hortfacing == -1:
self.bullet_x -= self.speed
elif self.hortfacing == 1:
self.bullet_x += self.speed
elif self.vertfacing == 1:
self.bullet_y += self.speed
elif self.vertfacing == -1:
self.bullet_y -= self.speed
Call the method for each bullet:
for bullet in bullets:
if bullet.bullet_x < 800 and bullet.bullet_x > 0 and bullet.bullet_y < 600 and bullet.bullet_y > 0 :
bullet.move()
else:
bullets.remove(bullet)
import math
import random
import pygame
from pygame.locals import *
import sys
def events():
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
pygame.init()
W = 700
H = 400
updater = pygame.time.Clock()
display = pygame.display.set_mode((700, 400))
pygame.display.set_caption("Skating_Game")
x = y = 0
surface = pygame.image.load("man2.png")
pygame.display.set_icon(surface)
class player:
def __init__(self, velocity, maxJumpRange):
self.velocity = velocity
self.maxJumpRange = maxJumpRange
def setLocation(self, x, y):
self.x = x
self.y = y
self.xVelocity = 0
self.jumping = False
self.jumpCounter = 0
self.falling = True
def keys(self):
k = pygame.key.get_pressed()
if k[K_LEFT]:
self.xVelocity = -self.velocity
elif k[K_RIGHT]:
self.xVelocity = self.velocity
else:
self.xVelocity = 0
if k[K_SPACE] and not self.jumping and not self.falling:
self.jumping = True
self.jumpCounter = 0
def move(self):
self.x += self.xVelocity
if self.jumping:
self.y -= self.velocity
self.jumpCounter += 1
if self.jumpCounter == self.maxJumpRange:
self.jumping = False
self.falling = True
elif self.falling:
if self.y <= H - 60 and self.y + self.velocity >= H - 60:
self.y = H - 60
self.falling = False
else:
self.y += self.velocity
def draw(self):
display = pygame.display.get_surface()
character = pygame.image.load("man3.png").convert_alpha()
display.blit(character, (self.x, self.y - 100))
#pygame.draw.circle(display, (255, 255, 255), (self.x, self.y - 25), 25, 0)
def do(self):
self.keys()
self.move()
self.draw()
P = player(3, 50)
P.setLocation(350, 0)
BLACK = ( 0, 0, 0)
g=0
font = pygame.font.SysFont("Plump", 30)
obstacle = pygame.image.load("obstacle.png").convert_alpha()
background = pygame.image.load("Road.png").convert()
x = 0
while True:
events()
rel_x = x % background.get_rect().width
display.blit(background, (rel_x - background.get_rect().width,0))
if rel_x < 700:
display.blit(background, (rel_x, 0))
x -= 1
g += 0.01
pygame.draw.rect(display, (255,255,255,128), [rel_x, 275, 150, 50])
display.blit(obstacle, (rel_x, 250))
text = font.render("Score: "+str(int(g)), True, (255, 255, 255))
display.blit(text, (0,0))
P.do()
if P.rect.collidepoint(self.x,self.y):
pygame.quit()
pygame.display.update()
updater.tick(200)
So if the player collides with the obstacle image the game should stop. How do i do this? I have made a class for the player and the obstacle is just an image which is constantly moving.
I was thinking maybe I could track the x and y coordinate of the player and obstacle and when their radius overlaps the game could stop.
Here's a working (simplified) version of your program with some comments. You have to create rects for the obstacle and the player and then check if the rects collide with the help of the colliderect method.
import sys
import pygame
from pygame.locals import *
pygame.init()
W = 700
H = 400
updater = pygame.time.Clock()
display = pygame.display.set_mode((700, 400))
PLAYER_IMAGE = pygame.Surface((30, 50))
PLAYER_IMAGE.fill(pygame.Color('dodgerblue1'))
class Player:
def __init__(self, x, y, velocity, maxJumpRange):
self.velocity = velocity
self.maxJumpRange = maxJumpRange
self.image = PLAYER_IMAGE # Give the player an image.
# Create a rect with the size of the PLAYER_IMAGE and
# pass the x, y coords as the topleft argument.
self.rect = self.image.get_rect(topleft=(x, y))
self.x = x
self.y = y
self.xVelocity = 0
self.jumping = False
self.jumpCounter = 0
self.falling = True
def keys(self):
k = pygame.key.get_pressed()
if k[K_LEFT]:
self.xVelocity = -self.velocity
elif k[K_RIGHT]:
self.xVelocity = self.velocity
else:
self.xVelocity = 0
if k[K_SPACE] and not self.jumping and not self.falling:
self.jumping = True
self.jumpCounter = 0
def move(self):
self.x += self.xVelocity
if self.jumping:
self.y -= self.velocity
self.jumpCounter += 1
if self.jumpCounter == self.maxJumpRange:
self.jumping = False
self.falling = True
elif self.falling:
if self.y >= H - 160: # Simplified a little.
self.y = H - 160
self.falling = False
else:
self.y += self.velocity
# Update the position of the rect, because it's
# used for the collision detection.
self.rect.topleft = self.x, self.y
def draw(self, display):
# Just draw the image here.
display.blit(self.image, (self.x, self.y))
def do(self):
self.keys()
self.move()
player = Player(350, 0, 3, 50)
obstacle = pygame.Surface((150, 50))
obstacle.fill(pygame.Color('sienna1'))
# Create a rect with the size of the obstacle image.
obstacle_rect = obstacle.get_rect()
g = 0
x = 0
FPS = 60 # Cap the frame rate at 60 or 30 fps. 300 is crazy.
while True:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
# --- Update the game ---
player.do()
rel_x = x % display.get_width()
x -= 7
g += 0.01
obstacle_rect.topleft = rel_x, 250 # Update the position of the rect.
# --- Draw everything ---
display.fill((30, 30, 30))
display.blit(obstacle, (rel_x, 250))
if g > 30:
display.blit(obstacle, (rel_x+350, 250))
# Check if the obstacle rect and the player's rect collide.
if obstacle_rect.colliderect(player.rect):
print("Game over!") # And call pygame.quit and sys.exit if you want.
# Draw the image/surface of the player onto the screen.
player.draw(display)
# Draw the actual rects of the objects (for debugging).
pygame.draw.rect(display, (200, 200, 0), player.rect, 2)
pygame.draw.rect(display, (200, 200, 0), obstacle_rect, 2)
pygame.display.update()
updater.tick(FPS)
Pygame rectangles include a collidepoint and colliderect method that allows you to check to see if something intersects with a rectangle. So you could have rectangles drawn beneath the obstacle and check to see if the player's coordinates intersect with the rectangle. Like this:
if self.rect.collidepoint(self.x,self.y):
pygame.quit()