Pygame, move a rectangle and remove the old rectangle in precedent position - python

I'm writing this code because I want to move a rectangle using the arrow keys.
It works, but the loop cycle doesn't move the rectangle, instead it creates a new one every time. The result is like a contrail. You can see it in the pic:the result of the code after some key pressure
Here the code I wrote:
import sys
import pygame
pygame.init()
pygame.display.set_caption('SAGA')
clock=pygame.time.Clock()
FPS=30
#the initial position
POS_X=300
POS_Y=300
ship = pygame.image.load("fighter_0.png")
while True:
#if cycle for detect the key pressure
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key ==pygame.K_UP:
POS_Y=POS_Y-10
if event.type == pygame.KEYDOWN:
if event.key ==pygame.K_DOWN:
POS_Y=POS_Y+10
if event.type == pygame.KEYDOWN:
if event.key ==pygame.K_RIGHT:
POS_X=POS_X+10
if event.type == pygame.KEYDOWN:
if event.key ==pygame.K_LEFT:
POS_X=POS_X-10
#here i draw the rectangle
pygame.draw.rect(screen,(255,255,255),(POS_X,POS_Y,30,30))
clock.tick(FPS)
pygame.display.update()
pygame.quit()
I think I don't understand some principle of pygame, but honestly I don't know which one.

It's doing exactly what you told it to do: draw a new rectangle each time. Computers are frustrating that way. You used draw instead of moving an object.
To fix this, you have two basic alternatives:
In each iteration, first obliterate the previous rectangle with one that matches the background (black). Then draw the new rectangle.
Use a movable object, such as a sprite, and update your game with the move method instead of redrawing. If you search StackOverflow or the internet for "pygame move object" you'll likely find a lot of code you can adapt for this purpose.

Each time you run your loop, you draw over the old screen's image. So in your case you are drawing rectangles on top of the previous rectangles. You need to clear the screen of what was there on the previous iteration of the loop. The easiest way to do this is to fill the screen with a single colour or image:
import sys
import pygame
# Colours
black = [0, 0, 0]
pygame.init()
screen = pygame.display.set_mode((640,480))
pygame.display.set_caption('SAGA')
clock=pygame.time.Clock()
FPS=30
#the initial position
POS_X=300
POS_Y=300
ship = pygame.image.load("fighter_0.png")
while True:
#if cycle for detect the key pressure
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key ==pygame.K_UP:
POS_Y=POS_Y-10
if event.type == pygame.KEYDOWN:
if event.key ==pygame.K_DOWN:
POS_Y=POS_Y+10
if event.type == pygame.KEYDOWN:
if event.key ==pygame.K_RIGHT:
POS_X=POS_X+10
if event.type == pygame.KEYDOWN:
if event.key ==pygame.K_LEFT:
POS_X=POS_X-10
#here i draw the rectangle
screen.fill(black) # Fill the entire screen with black
pygame.draw.rect(screen,(255,255,255),(POS_X,POS_Y,30,30))
clock.tick(FPS)
pygame.display.update()
pygame.quit()

Related

Confused with movement in pygame

I am trying to make a small game in pygame. The player is the left hand red rectangle (if you run it) and I am just trying to make the rocket variable move to the left quickly. Whenever I run the program if I press any key or move my mouse it moves the rocket.
Here is the code:
import pygame,sys,random
pygame.init()
pygame.key.set_repeat(1, 100)
size=width,height=1280,830
screen = pygame.display.set_mode(size)
black = [0, 0, 0]
white = [255, 255, 255]
sky_blue = ((0,255,255))
red = ((255,0,0))
font = pygame.font.SysFont("Arial",14)
rocket=pygame.Rect(1200,350,150,50)
player= pygame.Rect(250,350,250,50)
hull=100
player_speed=100
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type==pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
player_speed=player_speed+100
if event.key == pygame.K_LEFT:
player_speed=player_speed-100
if event.key == pygame.K_UP:
player.top=player.top-50
if event.key == pygame.K_DOWN:
player.top=player.top+50
if player_speed>1000:
player_speed=1000
if player_speed<100:
player_speed=100
if player.top<0:
player.top=0
elif player.bottom>height:
player.bottom=height
#rocket code
if player.colliderect(rocket):
hull=hull-100
if player_speed>99:
rocket.right=rocket.right-5
screen.fill(sky_blue)
pygame.draw.rect(screen,red,player)
pygame.draw.rect(screen,red,rocket)
renderedText = font.render("Speed: "+str(player_speed),1,black)
screen.blit(renderedText, (width/2+50,10))
if hull<1:
renderedText = font.render("GAME OVER",1,black)
screen.blit(renderedText, (width/2+500,500))
pygame.display.flip()
pygame.time.wait(10)
You indentation is incorrect which is causing a logic error.
if player_speed>1000:
...
rocket.right=rocket.right-5
The code between these lines need to be one indent lower. Else this code will only be run when there is a event. Since the for loop will skip execution of any code within if there is no events.

Player not moving in pygame [duplicate]

This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
How can I make a sprite move when key is held down
(6 answers)
Closed 2 years ago.
I created a program with pygame. The background and player are appearing but the player is not moving. The program is not giving any errors, can you help me? I am using python 3.8.6. Here is some of my code.
# Game Loop
running = True
while running:
for event in pygame.event.get():
player(playerX, playerY)
pygame.display.update()
# Movment
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
player_x_change -= 10
if event.key == pygame.K_d:
player_x_change += 10
if event.key == pygame.K_w:
player_y_change -= 10
if event.key == pygame.K_s:
player_y_change += 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player_x_change = 0
if event.key == pygame.K_d:
player_x_change = 0
# Close the game
if event.type == pygame.QUIT:
running = False
Your code is just displaying the player, not moving him.
To move the player, you have, in a first step, to define a speed variable. Then you have to get the rectangle of your player. That will allow you to modify player position by using the speed variable you defined.
Also, if you want to move your player, you have to draw the background before drawing the player. Otherwise, every player you draw will not disappear.
And don't forget to define the game speed.
Code
#!/usr/bin/python3
import pygame
# set the game speed
delay = 10
screen = pygame.display.set_mode((800, 600))
# loading player image and get pos
player = pygame.image.load('pixel_ship_yellow.png')
player_pos = player.get_rect()
# define speed variable
speed = [1, 1]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
# drawing background
screen.fill((0,0,0))
# apply speed (position is automatically updated)
player_pos = player_pos.move(speed)
# drawing player
screen.blit(player, player_pos)
pygame.display.flip()
# set the game speed
pygame.time.delay(delay)
You need to check for the event when a user pressed a button to move the character and then update the players position. For example, here's checking if the player pressed the right arrow:
while running:
for event in pygame.event.get():
player(playerX, playerY)
pygame.display.update()
# checking if right arrow is being pressed
if events.type == pygame.KEYDOWN:
if events.key == pygame.K_RIGHT
# update players x position here to move right
# for example, player.x += 2
# Close the game
if event.type == pygame.QUIT:
running = False

My game won't work when I use the controls, how do I fix it?

I can not get the controls to work, I try to press escape to open a menu I made but it will not open and I do not know if I am checking for events correctly, is there a way I am SUPPOSED to do it?
I tried using the functions for checking for different keys and I went to the spread-sheet that displays all the event names so you can map them at pygame.org but it will not open when I use the escape or also known as:
elif event.type == pygame.K_ESCAPE:
Frame.blit('Textures/GUI/loom.png', (0,0))
Heres the full code:
import pygame
#Textures/Blocks/loom_side.png
pygame.init()
Screen = "None"
DB = 0
Width = 800
Height = 600
Frame = pygame.display.set_mode((Width,Height))
pygame.display.set_caption("HypoPixel")
FPS = pygame.time.Clock()
def Raycast(TTR, RayXPos, RayYPos, RaySizeX, RaySizeY):
RaycastThis = pygame.image.load(TTR)
RaycastThis = pygame.transform.scale(RaycastThis,(RaySizeX,RaySizeY))
Frame.blit(RaycastThis, (RayXPos, RayYPos))
Loop = True
Raycast('Textures/Screens/Skybox/Earth.png',0,0,800,600)
while Loop == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.K_ESCAPE:
Frame.blit('Textures/GUI/loom.png', (0,0))
pygame.display.update()
FPS.tick(60)
I expected to get the loom GUI that I made. Once I tried to press escape, nothing happened.
pygame.K_ESCAPE is not event type (see pygame.event), but it is a pygame.key.
First check if a key was pressed by comparing the event type to pygame.KEYDOWN:
event.type == pygame.KEYDOWN
Then check if the event.key, which cause the event, is the pygame.K_ESCAPE key:
event.key == pygame.K_ESCAPE
Furthermore, the parameter to Surface.blit() has to be a Surface object rather than a filename.
first load the image to a Surface, by pygame.image.load(), then blit the Surface:
sprite = pygame.image.load('Textures/GUI/loom.png')
Frame.blit(sprite, (0,0))
Of course the your Raycast function can be called to do so:
Raycast('Textures/GUI/loom.png',0,0,800,600)
Your code should look somehow like this:
while Loop == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
Raycast('Textures/GUI/loom.png',0,0,800,600)

Press and hold for pygame

I'm using pygame and pyautogui to move the mouse around the screen in python 2.7. My code looks like:
import pyautogui
import pygame
pygame.init()
pygame.display.set_mode()
loop = True
while loop:
for event in pygame.event.get():
if event.type == pygame.quit:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
pyautogui.moveRel(-50,0)
My code moves the mouse to the left when I press "a" but I have to repeatedly press the button when I want to move the mouse across the screen. Is there a way to be able to press and hold a and move the mouse across the screen? I've looked at other tutorials on this topic but they seem very project specific.
Basically, what you want to do is set a variable indicating whether the key is down on keydown and update it once key is up.
Here, I updated your code to do just that as it might be easier to understand.
import pyautogui
import pygame
loop = True
a_key_down = False # Added variable
while loop:
for event in pygame.event.get():
if event.type == pygame.quit:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
a_key_down = True # Replaced keydown code with this
if event.type == pygame.KEYUP: # Added keyup
if event.key == pygame.K_a:
a_key_down = False
if a_key_down: # Added to check if key is down
pyautogui.moveRel(-50,0)

My python character only moves 1 pixel at a time

I am making a small little Parkour Minigame where the character jumps from platform to platform, but I can't seem to get the character to move properly. I made another game and it worked correctly, but this one doesn't. When I hold down the left/right arrow key it only moves 1 pixel at a time. Here are the V
Parkour_MoveLeft=Parkour_MoveRight=Parkour_Jump='no'
Parkour_Speed=1
Parkour_X=0
Parkour_Y=0
Parkour_Rows=0
Parkour_Col=0
Now here is my code for the part of the game I am having trouble with :
if location=='Parkour':
Window.fill(Black)
WindowW = 700
WindowH = 700
Window=pygame.display.set_mode((WindowW, WindowH),0, 32)
pygame.draw.rect(Window, Blue, Parkour_Character)
num=0
for point in Parkour_Grids:
mat=Parkour_Lvl_1[num]
num+=1
if mat=='a':
point['collide']='no'
if mat=='p':
pygame.draw.rect(Window, Green, point['rect'])
point['collide']='yes'
for point in Parkour_Grids:
if point['collide']=='yes':
if Parkour_Character.colliderect(point['left']):
Parkour_MoveRight='no'
if Parkour_Character.colliderect(point['right']):
Parkour_MoveLeft='no'
if Parkour_Character.colliderect(point['bottom']):
Parkour_MoveUp='no'
if Parkour_Character.colliderect(point['top']):
Parkour_MoveDown='no'
Parkour Movement
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_RIGHT:
Parkour_MoveRight='yes'
if event.key == K_LEFT:
Parkour_MoveLeft='yes'
if event.type == KEYUP:
if event.key == K_RIGHT:
Parkour_MoveRight='no'
if event.key == K_LEFT:
Parkour_MoveLeft='no'
if Parkour_MoveLeft=='yes':
Parkour_Character.right-=Parkour_Speed
if Parkour_MoveRight=='yes':
Parkour_Character.right+=Parkour_Speed
Level Map
Parkour_Lvl_1=['a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','p','p','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','p','p','p','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a']
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
Parkour_Grids.append({'rect':pygame.Rect(Parkour_X, Parkour_Y, 80, 30),'right':1,'left':1,'top':1,'bottom':1,'type':'air','collide':'yes'})
Parkour_X+=80
Parkour_Col+=1
if Parkour_Col==40:
Parkour_Col=0
Parkour_X=0
Parkour_Y+=70
Parkour_Rows+=1
if Parkour_Rows==10:
break
for point in Parkour_Grids:
point['right']=pygame.Rect(point['rect'].left+70,point['rect'].top , 6, 70)
point['left']=pygame.Rect(point['rect'].right-76,point['rect'].top , 6, 70)
point['top']=pygame.Rect(point['rect'].left+6,point['rect'].top-15 , 58, 6)
point['bottom']=pygame.Rect(point['rect'].left+6,point['rect'].bottom+6 , 58,6)
Anyone have any help on what I can do? It's the exact same code at another game I made (with different variables), but this one doesn't seem to work.
You need to raise Parkour_Speed. It is set to one, and because it does not look like you have ever multiplied it or implemented a movement twice, that is exactly how many pixels it will move. Upping this number will make it move more pixels at one time. However, while it isn't explicitly clear if this is your issue, it is also possible that it is not moving continuously when you press the button. If the event finder is not being run constantly, this will definitely happen, however because checking events is implemented at the same time, this is probably not the case (with more code it would be easier to know). Another thing that you must repeatedly implement to continuously move your sprite across the screen is where you sync Parkour_X and Y with the screen. I do not see where you do this in the code, but I think it should be easiest to use the move_ip function to solve your problems. Provided that the screen is being updated, this modification to your code should solve your issues:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_RIGHT:
Parkour_MoveRight='yes'
if event.key == K_LEFT:
Parkour_MoveLeft='yes'
if event.type == KEYUP:
if event.key == K_RIGHT:
Parkour_MoveRight='no'
if event.key == K_LEFT:
Parkour_MoveLeft='no'
if Parkour_MoveLeft=='yes':
Parkour_Character.move_ip(-Parkour_Speed,0)
if Parkour_MoveRight=='yes':
Parkour_Character.move_ip(Parkour_Speed,0)
If this also does not solve your problem, everything else seems fine, so it may be useful to include even more code. I know you have a lot of code up already, but simple features in graphical programs such as this one tend to be very interconnected.

Categories