The left paddle works fine it moves up and down no problem. But the right is okay when I don't move but when I do it moves to the directions I coded to but doesn't erase the previously drawn location which in the end just draws a straight line. Trying to make my first ever game with no tutorial and I'm kind of stuck
Here's the code
import pygame
pygame.init()
screen_width = 1280
screen_height = 720
window = pygame.display.set_mode((screen_width, screen_height),0,0)
pygame.display.set_caption("PongGame")
clock = pygame.time.Clock()
#background
background = pygame.image.load("C:/Users/teamb/Desktop/PythonWorkspace/myGame/background.png")
#paddle image
paddle = pygame.image.load("C:/Users/teamb/Desktop/PythonWorkspace/myGame/paddle.png")
paddle_size = paddle.get_rect().size
#left paddle
left_paddle_width = paddle_size[0]
left_paddle_height = paddle_size[1]
left_paddle_xpos = 10
left_paddle_ypos = (screen_height/2 - left_paddle_height/2)
to_x = 0
to_y = 0
character_speed = 10
#right paddle
right_paddle_width = paddle_size[0]
right_paddle_height = paddle_size[1]
right_paddle_xpos = screen_width - right_paddle_width - 10
right_paddle_ypos = (screen_height/2 - left_paddle_height/2)
to_y_2 = 0
# ball
ball = pygame.image.load("C:/Users/teamb/Desktop/PythonWorkspace/myGame/ball.png")
running = True
while running:
dt = clock.tick(60)
print("fps : " + str(clock.get_fps()))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#left paddle
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
to_y -= character_speed
elif event.key == pygame.K_s:
to_y += character_speed
if event.type == pygame.KEYUP:
if event.key == pygame.K_w or event.key == pygame.K_s:
to_y = 0
#right paddle
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
to_y_2 -= character_speed
elif event.key == pygame.K_DOWN:
to_y_2 += character_speed
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
to_y_2 = 0
left_paddle_ypos += to_y
right_paddle_ypos += to_y_2
if left_paddle_ypos < 0:
left_paddle_ypos = 0
if left_paddle_ypos > screen_height - left_paddle_height:
left_paddle_ypos = screen_height - left_paddle_height
window.blit(background,(0,0))
window.blit(paddle, (left_paddle_xpos,left_paddle_ypos))
window.blit(paddle, (right_paddle_xpos, right_paddle_ypos))
window.blit(ball, (640, 360))
pygame.display.update()
pygame.quit()
Moste likely the background Surface (background) has a smaller width than the display Surface (window).
Clear the display before drawing the scene:
while running:
# [...]
window.fill(0) # <--- clear display
window.blit(background,(0,0))
window.blit(paddle, (left_paddle_xpos,left_paddle_ypos))
window.blit(paddle, (right_paddle_xpos, right_paddle_ypos))
window.blit(ball, (640, 360))
pygame.display.update()
Or scale the background image by pygame.transform.smoothscale:
background = pygame.image.load("C:/Users/teamb/Desktop/PythonWorkspace/myGame/background.png")
background = pygame.transform.smoothscale(background, window.get_size())
This line is redrawing your background on every movement:
window.blit(background,(0,0))
However, I suppose your background image is actually smaller than your play field, so you are not redrawing the background on that side. You can either make your background image larger, or draw it again using an offset, or even draw it stretched. The idea is cover the entire play field when you are drawing the background.
It is worth pointing out this is not necessarily the most optimized way to do that. Ideally, you would redraw only the parts that had changed, but this is way more complex. Drawing the entire background is an easy fix.
Related
Does anybody see the problem in this code? Trying to make the ball/bullet come out of the left paddle and disappear once it hits the right paddle but when I try running the code I don't see the ball in general. I think its hidden behind the left paddle but its not moving either when I'm space. I am trying to make a game where the left player would should bullets and the right player would try to dodge them. Now I'm stuck at the bullet. Please help. Thanks!
import pygame
pygame.init()
screen_width = 1280
screen_height = 720
window = pygame.display.set_mode((screen_width, screen_height),0,0)
pygame.display.set_caption("PongGame")
clock = pygame.time.Clock()
#background
background = pygame.image.load("C:/Users/teamb/Desktop/PythonWorkspace/myGame/background.png")
#paddle image
paddle = pygame.image.load("C:/Users/teamb/Desktop/PythonWorkspace/myGame/paddle.png")
paddle_size = paddle.get_rect().size
#left paddle
left_paddle_width = paddle_size[0]
left_paddle_height = paddle_size[1]
left_paddle_xpos = 10
left_paddle_ypos = (screen_height/2 - left_paddle_height/2)
to_x = 0
to_y = 0
character_speed = 10
#right paddle
right_paddle_width = paddle_size[0]
right_paddle_height = paddle_size[1]
right_paddle_xpos = screen_width - right_paddle_width - 10
right_paddle_ypos = (screen_height/2 - left_paddle_height/2)
to_y_2 = 0
# ball
bullet = pygame.image.load("C:/Users/teamb/Desktop/PythonWorkspace/myGame/ball.png")
bullet_size = bullet.get_rect().size
bullet_width = bullet_size[0]
#make the bullet be able to shoot multiple at the same time
bullets = []
#bulllet speed
bullet_speed = 15
running = True
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#left paddle
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
to_y -= character_speed
elif event.key == pygame.K_s:
to_y += character_speed
elif event.key == pygame.K_SPACE:
bullet_ypos = left_paddle_ypos
bullet_xpos = left_paddle_xpos
bullets.append([bullet_xpos, bullet_ypos])
if event.type == pygame.KEYUP:
if event.key == pygame.K_w or event.key == pygame.K_s:
to_y = 0
#right paddle
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
to_y_2 -= character_speed
elif event.key == pygame.K_DOWN:
to_y_2 += character_speed
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
to_y_2 = 0
left_paddle_ypos += to_y
right_paddle_ypos += to_y_2
bullets = [ [w[0] - bullet_speed, w[1]] for w in bullets] #shoot the bullet
bullets = [ [w[0], w[1]] for w in bullets if w[0] == right_paddle_xpos and w[1] == right_paddle_ypos]
#barrier for the paddles to not go outside the screen.
if left_paddle_ypos < 0:
left_paddle_ypos = 0
if left_paddle_ypos > screen_height - left_paddle_height:
left_paddle_ypos = screen_height - left_paddle_height
window.blit(background,(0,0))
window.blit(paddle, (left_paddle_xpos,left_paddle_ypos))
window.blit(paddle, (right_paddle_xpos, right_paddle_ypos))
for bullet_xpos, bullet_ypos in bullets:
window.blit(bullet, (bullet_xpos, bullet_ypos))
pygame.display.update()
pygame.quit()
Two changes required:
Remove this line. It clears the bullet list before the bullets are shown.
#bullets = [ [w[0], w[1]] for w in bullets if w[0] == right_paddle_xpos and w[1] == right_paddle_ypos]
Change this line (- to +). It sends the bullets in the wrong direction.
bullets = [ [w[0] + bullet_speed, w[1]] for w in bullets] #shoot the bullet
Trying to make the ball/bullet... disappear once it hits the right paddle
So, I assume this is the line intended to have that effect:
bullets = [ [w[0], w[1]] for w in bullets if w[0] == right_paddle_xpos and w[1] == right_paddle_ypos]
Read it more carefully: for each of the bullet positions, we will check if it is positioned exactly where the right paddle is (i.e., top-left corners coincide!), and if so, keep that one unmodified; everything else is discarded.
You need to use proper collision logic, and you need to keep bullets that have not collided with the absorber.
Incidentally:
elif event.key == pygame.K_SPACE:
bullet_ypos = left_paddle_ypos
bullet_xpos = left_paddle_xpos
bullets.append([bullet_xpos, bullet_ypos])
How exactly did you want new bullets to be positioned, relative to the left paddle? How does this code say they will be positioned?
bullets = [ [w[0] - bullet_speed, w[1]] for w in bullets] #shoot the bullet
Which way do you want the bullet to move, if its speed is positive? Which way will it actually move, according to this logic?
For a school project I am building a recreation of Among Us in python with Pygame. I have already set up all the server and client side code and that's all working fine. I'm now in the process of making the camera follow the player. Only I can't get it to work.
My idea was: when a player moves, everything in his surroundings has to move in the opposite direction. But when you have a multiplayer game this doesn't work. Because then the other player moves as well which breaks the system.
If anyone has any idea how to make such a code, please let me know.
Thank you in advance
You don't have to move the background and object rects around the player, you can just move the player around and have a scroll offset value that keeps track of how much the blitted objects have to be offset. You don't apply the scroll value to the rect position because the rect position isn't relative to the window like the blit objects are. Here is an example of how you could achieve this.
import pygame, sys
clock = pygame.time.Clock()
from pygame.locals import *
pygame.init()
pygame.display.set_caption("Scrolling example")
WINDOW_SIZE = (600, 400)
screen = pygame.display.set_mode(WINDOW_SIZE, 0, 32)
scroll = [0, 0]
player = pygame.Rect(100, 100, 10, 10)
up = False
down = False
left = False
right = False
blocks = [pygame.Rect(250,250,50,50)]
while True:
screen.fill((0, 0, 0))
scroll[0] += (player.x - scroll[0] - (WINDOW_SIZE[0]/2)) // 20
scroll[1] += (player.y - scroll[1] - (WINDOW_SIZE[1]/2)) // 20
player_movement = [0, 0]
if right == True:
player_movement[0] += 2
if left == True:
player_movement[0] -= 2
if up == True:
player_movement[1] -= 2
if down == True:
player_movement[1] += 2
player.x += player_movement[0]
player.y += player_movement[1]
player_scroll_rect = player.copy()
player_scroll_rect.x -= scroll[0]
player_scroll_rect.y -= scroll[1]
pygame.draw.rect(screen, (255,255,255), player_scroll_rect)
for block in blocks:
scroll_block = block.copy()
scroll_block.x = scroll_block.x - scroll[0]
scroll_block.y = scroll_block.y - scroll[1]
pygame.draw.rect(screen, (0,0,255), scroll_block)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_RIGHT:
right = True
if event.key == K_LEFT:
left = True
if event.key == K_UP:
up = True
if event.key == K_DOWN:
down = True
if event.type == KEYUP:
if event.key == K_RIGHT:
right = False
if event.key == K_LEFT:
left = False
if event.key == K_UP:
up = False
if event.key == K_DOWN:
down = False
pygame.display.update()
clock.tick(60)
If you want a solution for using images, ask me.
Also, you can find more about scrolling here: https://www.youtube.com/watch?v=5q7tmIlXROg
#enable pygame mode
import pygame
pygame.init()
#create screen
screen = pygame.display.set_mode((1000,600))
#Title + Logo
pygame.display.set_caption("Space Invader")
icon = pygame.image.load("chicken.png")
pygame.display.set_icon(icon)
#Player icon
player_icon = pygame.image.load("spaceship.png")
playerX = 400
playerY = 500
player_changeX = 0
player_changeY = 0
def player(x, y):
screen.blit(player_icon, (x, y))
surface.blit(image,((1920/2)-(image.get_width()/2),(1080/2)-
(image.get_height()/2)))
#game loop
running = True
while running:
# backround colour RGB
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#If key pressed check wether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_changeX = -1
if event.key == pygame.K_RIGHT:
player_changeX = 1
if event.key == pygame.K_UP:
player_changeY = -1
if event.key == pygame.K_DOWN:
player_changeY = 1
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key ==pygame.K_RIGHT:
player_changeX = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
player_changeY = 0
# If player reaches boarder
if playerX >= 936:
player_changeX = -1
if playerX <= 0:
player_changeX = 1
if playerY <= 0:
player_changeY = 1
if playerY >= 550:
player_changeY = -1
#Player change in coordinates
playerX += player_changeX
playerY += player_changeY
player(playerX, playerY)
pygame.display.update()
I am creating a simple game as i just got into programing and I was wondering if you could make the game screen appear in the centre of your own screen as when I run it it keeps appearing on the bottom of my screen and I then have to manually move it into the centre. If you can please tell me how. Hope my question was formated good enough. Thank you for any help.
It depends; if it's a image you can do:
surface.blit(image,((screenwidth/2)-(image.get_width()/2),(screenheight/2)-(image.get_height()/2)))
Please tell me it it's different
Before this I used the code to say 'every button press it moves' but now I have changed it to 'when you press the button it moves in one direction until further instructions', but now the colliderect doesn't work. It worked before, and I'm still new to pygame. I have found a few similar issues but I think I've done what the people asking the questions have done. Any help at all is accepted.
import pygame, sys, random
from pygame.locals import *
from time import sleep
pygame.init()
def render():
windowSurface.fill(black)
player = pygame.Rect(225 + xmod,450 - ymod,30,30)
pygame.draw.rect(windowSurface,white,player)
pygame.draw.rect(windowSurface,white,wall_1)
pygame.draw.rect(windowSurface,white,wall_2)
pygame.display.update()
black = (0,0,0)
white = (255,255,255)
windowSurface = pygame.display.set_mode((500, 500),0,32)
windowSurface.fill(black)
xmod = 0
ymod = 0
direction = 'none'
player = pygame.Rect(225 + xmod,450 - ymod,30,30)
wall_1 = pygame.Rect(0,225,250,50)
wall_2 = pygame.Rect(300,250,200,50)
render()
while True:
render()
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_LEFT:
direction = 'left'
if event.key == K_RIGHT:
direction = 'right'
if event.key == K_UP:
direction = 'up'
if event.key == K_DOWN:
direction = 'down'
if event.type == QUIT:
pygame.quit()
sys.exit()
if player.colliderect(wall_1) or player.colliderect(wall_2):
xmod = 0
ymod = 0
player = pygame.Rect(225 + xmod,450 - ymod,30,30)
render()
print('again')
if direction == 'left':
xmod -= 1
sleep(0.004)
if direction == 'right':
xmod += 1
sleep(0.004)
if direction == 'up':
ymod += 1
sleep(0.004)
if direction == 'down':
ymod -= 1
sleep(0.004)
You never update the global player variable, so it stays at its original coordinates. In the render function you create a new rect and assign it to a local player variable, but it is not the same as the global player which you use for the collision detection.
I suggest adding variables for the velocity speed_x, speed_y and adding them to the player.x and .y attributes every frame to move the rect directly.
The local player rect in the render function can be removed.
import sys
import pygame
from pygame.locals import *
pygame.init()
def render():
windowSurface.fill(black)
pygame.draw.rect(windowSurface, white, wall_1)
pygame.draw.rect(windowSurface, white, wall_2)
pygame.draw.rect(windowSurface, white, player)
pygame.display.update()
black = (0,0,0)
white = (255,255,255)
windowSurface = pygame.display.set_mode((500, 500),0,32)
clock = pygame.time.Clock() # A clock to limit the frame rate.
player = pygame.Rect(225, 450, 30, 30)
wall_1 = pygame.Rect(0,225,250,50)
wall_2 = pygame.Rect(300,250,200,50)
speed_x = 0
speed_y = 0
while True:
# Handle events.
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_LEFT:
speed_x = -5
speed_y = 0
elif event.key == K_RIGHT:
speed_x = 5
speed_y = 0
elif event.key == K_UP:
speed_y = -5
speed_x = 0
elif event.key == K_DOWN:
speed_y = 5
speed_x = 0
# Add the speed to the x and y attributes to move the rect.
player.x += speed_x
player.y += speed_y
# Game logic.
if player.colliderect(wall_1) or player.colliderect(wall_2):
player = pygame.Rect(225, 450, 30, 30)
print('again')
# Render everything.
render()
clock.tick(60) # Limit the frame rate to 60 FPS.
I'm quite new to pygame so forgive me if I appear stupid, but I am having problems trying to get a bordered scrolling system - i.e. one that stops when the edge of the background is reached instead of continuously scrolling around.
This is what I have:
import pygame
import math
import sys
import random
from pygame.locals import *
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((1024, 728),0,0)
pygame.display.set_caption("Modern Politics")
b1 = "Blank.png"
back = pygame.image.load(b1).convert()
back1 = pygame.image.load(b1).convert()
x=0
y=0
screenWidth = 1024
screenHeight = 728
while True:
screen.blit(back, (x,y))
screen.blit(back1, (x-screenWidth,y-screenHeight))
for event in pygame.event.get():
if not hasattr(event, "key"): continue
if event.key == K_RIGHT:
x=x-10
elif event.key == K_LEFT:
x=x+10
elif event.key == K_UP:
y=y+10
elif event.key == K_DOWN:
y=y-510
elif event.key == K_ESCAPE:
sys.exit(0)
if x == screenWidth:
x=0
if y == screenHeight:
y=0
msElapsed = clock.tick(100)
pygame.display.flip()
But that just comes up with a whole heap of problems, as shown in this gif:
https://gyazo.com/f734c9955d52b0fed1e89766013f4122
The (unfinished) picture I am trying to scroll is this 1920x1080 image:
https://www.dropbox.com/s/fh2e99nw5jh7eqc/Blank.png?dl=1
How can I make it so that the image stops scrolling and will not scroll when the end of the image is reached? It needs to work both vertically and horizontally.
(By the way I am using Python 3.4)
I think it is similar to "following camera" so you could use camera offset if you have more objects on the screen but here I use something different.
You need to compare left,right,top,bottom image border with left,right,top,bottom screen border to stop scrolling
# left borders
if x > 0:
x = 0
# top borders
if y > 0:
y = 0
# right borders
if x+image_width < screen_width:
x = screen_width
# bottom borders
if y+image_height < screen_height:
y = screen_height
I use pygame.Rect to use rect.left instead of x and rect.right instead of x+width (and rect.top instead of y and rect.bottom instead of y+height)
#!/usr/bin/env python3
# pygame (simple) template
import pygame
# === CONSTANTS === (UPPER_CASE names)
SCREEN_WIDTH = 1024
SCREEN_HEIGHT = 728
# === CLASSES === (CamelCase names)
# empty
# === FUNCTIONS === (lower_case names)
# empty
# === MAIN ===
# --- init ---
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
screen_rect = screen.get_rect()
pygame.display.set_caption("Modern Politics")
# --- objects ---
image_name = "Blank.png"
image = pygame.image.load(image_name).convert()
image_rect = image.get_rect()
speed = 20
change_x = 0
change_y = 0
# --- mainloop ---
clock = pygame.time.Clock()
running = True
while running:
# --- events ---
for event in pygame.event.get():
# --- global events ---
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
# --- player events ---
# KEYDOWN/KEYUP event occurs when key is going down/up (short-time event),
# not when key is held down/up (long-time event)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
change_x -= speed
elif event.key == pygame.K_LEFT:
change_x += speed
elif event.key == pygame.K_DOWN:
change_y -= speed
elif event.key == pygame.K_UP:
change_y += speed
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
change_x += speed
elif event.key == pygame.K_LEFT:
change_x -= speed
elif event.key == pygame.K_DOWN:
change_y += speed
elif event.key == pygame.K_UP:
change_y -= speed
# --- updates (without draws) ---
# move object
image_rect.x += change_x
image_rect.y += change_y
# check borders
# right borders (SCREEN_WIDTH)
if image_rect.right < screen_rect.right:
image_rect.right = screen_rect.right
# left borders (0)
if image_rect.left > screen_rect.left:
image_rect.left = screen_rect.left
# bottom borders (SCREEN_HEIGTH)
if image_rect.bottom < screen_rect.bottom:
image_rect.bottom = screen_rect.bottom
# left borders (0)
if image_rect.top > screen_rect.top:
image_rect.top = screen_rect.top
# --- draws (without updates) ---
screen.blit(image, image_rect)
# human eyes need at least 25FPS to see animation,
# monitors mostly refresh screen with 60Hz - it means 60FPS.
clock.tick(30)
pygame.display.flip()
# --- the end ---
pygame.quit()