How do I move one singular object in Pygame - python

So I've been trying to move only one cube using user input, but when I try I move both cubes in unison, not one, which is my goal. How do I move one cube (using user input) instead of both at the same time? Thanks :^)
import pygame
pygame.init()
pygame.display.set_caption('Crash!')
win = pygame.display.set_mode((800, 600))
x = 150
y = 300
width = 100
height = 60
scHeight = 600
scWidth = 800
vel = 0.5
running = True
while running:
keys = pygame.key.get_pressed()
if keys[pygame.K_UP] and y > vel:
y -= vel
if keys[pygame.K_DOWN] and y < scHeight - height - vel:
y += vel
win.fill((0, 0, 0))
plane = pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
meteor = pygame.draw.rect(win, (255, 255, 0), (700, y, width, height))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

Use individual positions for the cubes:
x1, y1 = 150, 300
x2, y2 = 700, 300
So the position of each cube can be changed individually. e.g. one cube can be moved by the arrow key, while the other one can be moved by w and s
keys = pygame.key.get_pressed()
if keys[pygame.K_UP] and y2 > vel:
y2 -= vel
if keys[pygame.K_DOWN] and y2 < scHeight - height - vel:
y2 += vel
if keys[pygame.K_w] and y1 > vel:
y1 -= vel
if keys[pygame.K_s] and y1 < scHeight - height - vel:
y1 += vel
Each object is id draw at is own position:
plane = pygame.draw.rect(win, (255, 0, 0), (x1, y1, width, height))
meteor = pygame.draw.rect(win, (255, 255, 0), (x2, y2, width, height))

PyGame just draws the shapes you want it to draw, at the coords you tell it.
So, if we look at both pygame.draw.rect() calls, we can see that both have y in them, so when you update the y value on user input, you "move" both rectangles.

Related

How do I make a bullet shoot and hit system? [duplicate]

This question already has answers here:
How can i shoot a bullet with space bar?
(1 answer)
How do I detect collision in pygame?
(5 answers)
How do I stop more than 1 bullet firing at once?
(1 answer)
Closed 1 year ago.
This program currently makes two squares appear on the screen when you press start, the one on the left is controlled using WASD whilst the one on the right is controlled using the arrow keys. I want to make it so that when you click spacebar, the square on the left shoots a red rectangle (the bullet) to the right of the screen and if it hits the other square, then the health goes down by one. If it doesn't hit the other square, the bullet hits the edge of the screen and disappears (I would also like the other square to do this too but the other way around and instead of pressing space you press right control). The health variable for both squares is on lines 9 and 10. Can somebody please tell me how to do this?
Full Code (The two key presses that I would like to make the chosen character shoot are lines 60 and 72):
import pygame
import sys
import os
pygame.init()
FPS = 60
HEALTH_L = 3
HEALTH_R = 3
start_smallfont = pygame.font.SysFont('Corbel', 45)
start_text = start_smallfont.render('Start', True, (255, 255, 255))
rect_smallfont = pygame.font.SysFont('Corbel', 33)
rect_text = rect_smallfont.render('You', True, (255, 255, 255))
x = 630
y = 325
x2 = 170
y2 = 325
vel = 0.1
startWIDTH, startHEIGHT = 170, 80
screenWIDTH, screenHEIGHT = 800, 720
WIN = pygame.display.set_mode((screenWIDTH, screenHEIGHT))
pygame.display.set_caption(":D")
def main():
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
if 800/2-85 <= mouse[0] <= 800/2-85+startWIDTH and 720/2-40 <= mouse[1] <= 720/2-40+startHEIGHT:
clock.tick(FPS)
run = False
while True:
global x, y, x2, y2, movingx
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
WIN.fill((0, 0, 0))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel:
x -= vel
if keys[pygame.K_RIGHT] and x < screenWIDTH - 50 - vel:
x += vel
if keys[pygame.K_UP] and y > vel:
y -= vel
if keys[pygame.K_DOWN] and y < screenHEIGHT - 50 - vel:
y += vel
if keys[pygame.K_SPACE]:
#PUT BULLET FUNCTION HERE
if keys[pygame.K_a] and x2 > vel:
x2 -= vel
if keys[pygame.K_d] and x2 < screenWIDTH - 50 - vel:
x2 += vel
if keys[pygame.K_w] and y2 > vel:
y2 -= vel
if keys[pygame.K_s] and y2 < screenHEIGHT - 50 - vel:
y2 += vel
if keys[pygame.K_RCTRL]:
#PUT BULLET FUNCTION HERE
pygame.draw.rect(WIN, (255, 0, 0), (x, y, 50, 50))
pygame.draw.rect(WIN, (255, 0, 0), (x2, y2, 50, 50))
pygame.display.update()
mouse = pygame.mouse.get_pos()
if 800/2-85 <= mouse[0] <= 800/2-85+startWIDTH and 720/2-40 <= mouse[1] <= 720/2-40+startHEIGHT:
pygame.draw.rect(WIN, (255, 91, 91), (800/2-85, 720/2-40, startWIDTH, startHEIGHT))
else:
pygame.draw.rect(WIN, (255, 0, 0), (800/2-85, 720/2-40, startWIDTH, startHEIGHT))
WIN.blit(start_text, (800/2-85+42,720/2-40+20))
pygame.display.update()
if __name__ == "__main__":
main()

How can I add a sprite when no keys are pressed?

How can I add a sprite when no keys are pressed? I have each four directions covered when the arrow keys are pressed but when they are released the sprite goes obviously but cant think of how to add it. I tried adding else statements and other things best thing i got was the standing forward sprite being underneath the others but cant seem to get it to go when one of the arrow keys is pressed and return when they are relased.
Any help appreciated. Thanks in advance.
my code:
import pygame
pygame.init()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (200, 0, 0)
GREEN = (0, 200, 0)
BLUE = (0, 0, 200)
# background
background = pygame.image.load('Playing Game state 2.png')
# character
standingforward = pygame.image.load('standingforward.png')
standingdownward = pygame.image.load('standingdownwards.png')
standingleft = pygame.image.load('standingleft.png')
standingright = pygame.image.load('standingright.png')
# player variables
x = 375
y = 525
w = 50
h = 50
vel = 0.5
screenWidth = 800
screenHeight = 575
screen = pygame.display.set_mode((screenWidth, screenHeight))
pygame.display.set_caption("FROGGER")
sprite = pygame.draw.rect
running = True
while running:
# sprites
screen.blit(background, (0, 0))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
screen.blit(standingleft, (x, y))
if keys[pygame.K_RIGHT]:
screen.blit(standingright, (x, y))
if keys[pygame.K_DOWN]:
screen.blit(standingdownward, (x, y))
if keys[pygame.K_UP]:
screen.blit(standingforward, (x, y))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()
# controls
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if x < 0:
x = 0
if keys[pygame.K_RIGHT]:
x += vel
if x > screenWidth-w:
x = screenWidth-w
if keys[pygame.K_UP]:
y -= vel
if y < 0:
y = 0
if keys[pygame.K_DOWN]:
y += vel
if y > screenHeight-h:
y = screenHeight-h
pygame.quit()
Add a variable that refers to the current image. Change the variable when a key is pressed. Draw the current image in the application loop:
current_image = standingright
running = True
while running:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
current_image = standingleft
if keys[pygame.K_RIGHT]:
current_image = standingright
if keys[pygame.K_DOWN]:
current_image = standingdownward
if keys[pygame.K_UP]:
current_image = standingforward
screen.blit(background, (0, 0))
screen.blit(current_image, (x, y))
# [...]

The character I created doesn't come back to the exact platform after a single trigger press on UP arrow key

I am a Pygame beginner. I started to build a game on jumping dinosaur. The character I created doesn't come back to the exact platform after a single trigger press on UP arrow key. It lands slightly above the platform and its lands perfectly after 2,3 UP arrow presses.
I am a complete beginner.
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
x = 20
y = 400
width = 30
height = 45
vel = 10
black = (0,0,0)
x1 = 20
y1 = 30
white = (255,255,255)
run = True
while run:
pygame.time.delay(20)
win.fill(black)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x>=20:
x -= vel
if keys[pygame.K_RIGHT]and x<=450:
x += vel
if keys[pygame.K_UP] and y>=20:
y -= vel
if keys[pygame.K_DOWN] and y<=390:
y += vel
#gravity
else:
if not keys[pygame.K_UP] and y <= 400:
y += 30
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.draw.line(win,white,[0,472],[472,472],2)
pygame.display.update()
pygame.display.flip()
pygame.quit()
Your gravity application is broken. There is plenty of ways to fix this, my choice here is to always apply gravity but limit y so that it can never go bigger than the height of the character above the ground-plane.
To elaborate on what's actually wrong with your approach: your jumps create upwards motion incremented by vel. Which is only a fraction of gravity. So pushing the character up e.g. 40 pixels, and then pull it down by 30 pixels leaves you 10 pixels above ground. Only if you manage to precisely rise exactly a multiple of gravity, you will fall back.
My solution always falls down but then limits the position to the one where the character is right on the ground level.
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
x = 20
y = 400
width = 30
height = 45
black = (0,0,0)
x1 = 20
y1 = 30
white = (255,255,255)
bottom = 472
gravity = 30
vel = 10 + gravity
run = True
while run:
pygame.time.delay(20)
win.fill(black)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x>=20:
x -= vel
if keys[pygame.K_RIGHT]and x<=450:
x += vel
if keys[pygame.K_UP] and y>=20:
y -= vel
if keys[pygame.K_DOWN] and y<=390:
y += vel
else:
y = min(bottom - height, y + gravity)
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.draw.line(win,white,[0,bottom],[bottom,bottom],2)
pygame.display.update()
pygame.display.flip()
pygame.quit()

Pygame display not working under If condition

I am trying to make my code display a text in the middle of the screen once a square goes past right by 500 pixels, but it does seem to be displaying with my If condition. I dont know what I am doing wrong.
import pygame
pygame.init()
displaywidth=500
displayheight=500
gameDisplay = pygame.display.set_mode((displaywidth, displayheight))
pygame.display.set_caption("First Game")
red = (0,255,0)
font=pygame.font.Font(None, 20)
#Class
def Message(msg, color):
screen_text=font.render(msg,True,color)
gameDisplay.blit(screen_text,[displaywidth/2,displayheight/2])
win = pygame.display.set_mode((displaywidth, displayheight))
x = 50
y = 50
width = 40
height = 40
vel = 5
x1 = 0
y1 = 0
width1 = 40
height1 = 40
vel2 = 100
vel3=100
x2 = 100
y2 = 100
pygame.draw.rect(win, (0, 255, 0), (x, y, width, height))
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel2
elif keys[pygame.K_RIGHT]:
x += vel2
elif keys[pygame.K_UP]:
y1-=vel3
elif keys[pygame.K_DOWN]:
y1+=vel3
if x > 500:
Message("meow", red)
pygame.display.update()
print("pew")
elif x < 0:
x = 50
elif y1 > 500:
y1 = 450
elif y1 < 0:
y1 = 50
print(x)
print(y)
win.fill((0, 0, 0))
meow = pygame.draw.rect(win, (0, 255, 0), (x, y1, width, height))
pygame.draw.rect(win, (160, 0, 0), (x1, y1, width1, height1))
pygame.display.update()
pygame.quit()
My print command appears to be working but I dont know why its not displaying.
The issue is that you've 2 calls to pygame.display.update() in your code, but the display is cleared immediately after the first one:
if x > 500:
Message("meow", red)
pygame.display.update() # <----
print("pew")
# [...]
win.fill((0, 0, 0)) # <----
Clear the display before anything is drawn and do a single pygame.display.update() at the end of the main application loop:
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel2
elif keys[pygame.K_RIGHT]:
x += vel2
elif keys[pygame.K_UP]:
y1-=vel3
elif keys[pygame.K_DOWN]:
y1+=vel3
if x < 0:
x = 50
elif y1 > 500:
y1 = 450
elif y1 < 0:
y1 = 50
# clear dispaly
win.fill((0, 0, 0))
# draw scene
if x > 500:
Message("meow", red)
print("pew")
meow = pygame.draw.rect(win, (0, 255, 0), (x, y1, width, height))
pygame.draw.rect(win, (160, 0, 0), (x1, y1, width1, height1))
# update display
pygame.display.update()

Rectangle collision in pygame? (Bumping rectangles into each other)

I decided to move that Squarey game to pygame, and now I have 2 rectangles that can move around and bump into the walls. However, the rectangles can move right through each other. How would I make them bump into each other and stop?
My code:
import pygame
pygame.init()
screen = pygame.display.set_mode((1000, 800))
pygame.display.set_caption("Squarey")
done = False
is_red = True
x = 30
y = 30
x2 = 100
y2 = 30
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
is_red = not is_red
pressed = pygame.key.get_pressed()
if pressed[pygame.K_UP]: y -= 3
if pressed[pygame.K_DOWN]: y += 3
if pressed[pygame.K_LEFT]: x -= 3
if pressed[pygame.K_RIGHT]: x += 3
if pressed[pygame.K_w]: y2 -= 3
if pressed[pygame.K_s]: y2 += 3
if pressed[pygame.K_a]: x2 -= 3
if pressed[pygame.K_d]: x2 += 3
if y < 0:
y += 3
if x > 943:
x -= 3
if y > 743:
y -= 3
if x < 0:
x += 3
if y2 < 0:
y2 += 3
if x2 > 943:
x2 -= 3
if y2 > 743:
y2 -= 3
if x2 < 0:
x2 += 3
screen.fill((0, 0, 0))
if is_red: color = (252, 117, 80)
else: color = (168, 3, 253)
if is_red: color2 = (0, 175, 0)
else: color2 = (255, 255, 0)
rect1 = pygame.draw.rect(screen, color, pygame.Rect(x, y, 60, 60))
rect2 = pygame.draw.rect(screen, color2, pygame.Rect(x2, y2, 60, 60))
pygame.display.flip()
clock.tick(60)
pygame.quit()
Use pygame.Rect.colliderect
if rect1.colliderect(rect2):
print("Collision !!")
BTW: you can create rect1 (and rect2) only once - before main loop - and then you can use rect1.x and rect1.y instead of x, y. And you can use pygame.draw.rect(screen, color, rect1) without creating new Rect all the time.
Rect is usefull
# create
rect1 = pygame.Rect(30, 30, 60, 60)
# move
rect1.x += 3
# check colision with bottom of the screen
if rect1.bottom > screen.get_rect().bottom:
# center on the screen
rect1.center = screen.get_rect().center
To check for collisions, try something like this:
def doRectsOverlap(rect1, rect2):
for a, b in [(rect1, rect2), (rect2, rect1)]:
# Check if a's corners are inside b
if ((isPointInsideRect(a.left, a.top, b)) or
(isPointInsideRect(a.left, a.bottom, b)) or
(isPointInsideRect(a.right, a.top, b)) or
(isPointInsideRect(a.right, a.bottom, b))):
return True
return False
def isPointInsideRect(x, y, rect):
if (x > rect.left) and (x < rect.right) and (y > rect.top) and (y < rect.bottom):
return True
else:
return False
Then, while moving them, you can call
if doRectsOverlap(rect1, rect2):
x -= 3
y -= 3
rect1 = pygame.draw.rect(screen, color, pygame.Rect(x, y, 60, 60))
Or something like that.

Categories

Resources