I just want to move a block left and right but don't now why the keydown code isn't getting through. When I open the program it just shows the the 'tank' in its position but you can't move it with left or right keys.
import pygame, sys
from pygame.locals import *
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
TANK_SIZE = 20
BLACK = (0 ,0 ,0 )
WHITE = (255,255,255)
def drawArena():
DISPLAYSURF.fill(BLACK)
def drawTank(tank):
pygame.draw.rect(DISPLAYSURF, WHITE, tank)
def main():
pygame.init()
global DISPLAYSURF
DISPLAYSURF = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('Tanks')
tankX = 200
tankY = 200
tank = pygame.Rect(tankX, tankY, TANK_SIZE, TANK_SIZE)
drawArena()
drawTank(tank)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
tankX -= 20
if event.key == pygame.K_RIGHT:
tankX += 20
drawArena()
drawTank(tank)
pygame.display.update()
if __name__ == '__main__':
main()
this is because updated tankX values do not affect the tank object. there are many ways to make it work. for example, inserting a re-initialization of tank in the while True loop:
import pygame, sys
from pygame.locals import *
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
TANK_SIZE = 20
BLACK = (0 ,0 ,0 )
WHITE = (255,255,255)
def drawArena():
DISPLAYSURF.fill(BLACK)
def drawTank(tank):
pygame.draw.rect(DISPLAYSURF, WHITE, tank)
def main():
pygame.init()
global DISPLAYSURF
DISPLAYSURF = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('Tanks')
tankX = 200
tankY = 200
tank = pygame.Rect(tankX, tankY, TANK_SIZE, TANK_SIZE)
drawArena()
drawTank(tank)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
tankX -= 20
if event.key == pygame.K_RIGHT:
tankX += 20
tank = pygame.Rect(tankX, tankY, TANK_SIZE, TANK_SIZE)
drawArena()
drawTank(tank)
pygame.display.update()
if __name__ == '__main__':
main()
You should not update the tankX and tankY variables as this doesn't affect the tank Rect object. You don't need to re-initialize the tank object as this is probably a waste of resources. A more efficient way is to just directly update the x and y values of the tank object using it's move_ip() function.
In your main loop...
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
tank.move_ip(-20, 0)
if event.type == pygame.K_RIGHT:
tank.move_ip(20, 0)
drawArena()
drawTank(tank)
pygame.display.update()
Related
import pygame, sys
pygame.init()
display_width = 800
display_height = 500
white = (255, 255, 255)
display = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Pong')
clock = pygame.time.Clock()
platform_y = display_height * 0.38
def platform(color, x, y):
global platform_y
pygame.draw.rect(display, color, (x, y, 25, 100))
pygame.display.update()
clock.tick(80)
def ball():
pygame.draw.circle(display, white, (400, 250), 12)
pygame.display.update()
def game():
global platform_y
y_change = 0
while True:
platform(white, 100, platform_y)
platform(white, 675, platform_y)
ball()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit(0)
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
sys.exit(0)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change -= 2
if event.key == pygame.K_DOWN:
y_change += 2
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
platform_y += y_change
pygame.display.update()
clock.tick(80)
if __name__ == '__main__':
game()
I guess it's not the best code but I've been messing around with pygame and got to the point when I have to create Pong, although I'm not sure why the rectangles (platforms) are just getting higher instead of going up and down (I know that both platforms will rise together, will fix that, this is just for test)
You had couple of issues with your code:
You have to call pygame.display.update only once, not after every pygame.draw,
clock.tick is set in main game loop, not in other places,
You have to clear the screen before drawing.
Here is what will probably work as you expect:
import pygame, sys
pygame.init()
display_width = 800
display_height = 500
white = (255, 255, 255)
display = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Pong')
clock = pygame.time.Clock()
platform_y = display_height * 0.38
def platform(color, x, y):
global platform_y
pygame.draw.rect(display, color, (x, y, 25, 100))
def ball():
pygame.draw.circle(display, white, (400, 250), 12)
def game():
global platform_y
y_change = 0
while True:
platform(white, 100, platform_y)
platform(white, 675, platform_y)
ball()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit(0)
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
sys.exit(0)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change -= 2
if event.key == pygame.K_DOWN:
y_change += 2
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
platform_y += y_change
pygame.display.update()
clock.tick(80)
display.fill((0, 0, 0))
if __name__ == '__main__':
game()
Couple of advices:
Don't use global! It's smells on bad code. There are certainly better ways to achieve what you wanted without using it.
Try to avoid a lot of conditions nesting. It's very hard to read, and will require much mental energy to read after day or two.
Happy coding!
I am making a Pong game in Python. To do this, I am using pygame. I am trying to make an image move continuously on a keypress. I have tried multiple methods, but none have worked. here is my code for the movement:
import pygame, sys
from pygame.locals import *
import time
try: #try this code
pygame.init()
FPS = 120 #fps setting
fpsClock = pygame.time.Clock()
#window
DISPLAYSURF = pygame.display.set_mode((1000, 900), 0, 32)
pygame.display.set_caption('Movement with Keys')
WHITE = (255, 255, 255)
wheatImg = pygame.image.load('gem4.png')
wheatx = 10
wheaty = 10
direction = 'right'
pygame.mixer.music.load('overworld 8-bit.WAV')
pygame.mixer.music.play(-1, 0.0)
#time.sleep(5)
#soundObj.stop()
while True: #main game loop
DISPLAYSURF.fill(WHITE)
bign = pygame.event.get()
for event in bign:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
pygame.mixer.music.stop()
keys_pressed = key.get_pressed()
if keys_pressed[K_d]:
wheatx += 20
#events = pygame.event.get()
#for event in events:
# if event.type == pygame.KEYDOWN:
# if event.key == pygame.K_p:
# pygame.mixer.music.stop()
# time.sleep(1)
# pygame.mixer.music.load('secondscreen.wav')
# pygame.mixer.music.play()
DISPLAYSURF.blit(wheatImg, (wheatx, wheaty))
pygame.display.update()
fpsClock.tick(FPS)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
Indentation is normal, I am new to stackoverflow! I have an except, which is why the try is there. Thanks for the help!
This code will move the image down upon the down arrow key being pressed and up if the up arrow key is pressed (should you not be changing the Y-axis and wheaty if the user presses the down key rather than altering wheatx ?). Do similar for the other arrow keys.
while True:
DISPLAYSURF.fill(WHITE)
bign = pygame.event.get()
for event in bign:
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
pygame.mixer.music.stop()
if event.key == pygame.K_DOWN:
wheaty +=20
elif event.key == pygame.K_UP:
wheaty -= 20
DISPLAYSURF.blit(wheatImg, (wheatx, wheaty))
pygame.display.update()
fpsClock.tick(FPS)
I have the game come up and the rectangle rendered.
When I press my KEYDOWN it doesn't move the rectangle, it just makes it longer.
I have tried tons of stuff. I am new to Pygame.
Any help would be amazing.
Here is the code:
import pygame
import time
import random
import math
import sys
pygame.init()
display_width = 1200
display_height = 800
white = (255,255,255)
black = (0,0,0)
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Vertical Pong')
clock = pygame.time.Clock()
def pongBoard(x,y,):
pygame.draw.rect(gameDisplay,white,(x,y,250,25))
def gameLoop():
x = 325
y = 750
xChange = 0
inGame = True
while inGame:
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_a or event.key == pygame.K_LEFT:
xChange = -5
print("Left")
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
xChange = 5
print("Right")
if event.type == pygame.KEYUP:
if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
xChange = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_LEFT:
xChange = 0
pongBoard(x,y)
x += xChange
pygame.display.update()
clock.tick(60)
gameLoop()
pygame.quit()
quit()
So the problem is this:
The rectangle is being constantly redrawn at a different coord, but the screen is not being drawn over the rectangle to cover up the part that is not supposed to be there. In simpler terms, we need to constantly draw the background.
So now the code in the main game loop:
while inGame:
#This code below draws the background
pygame.draw.rect(gameDisplay, black, (0, 0, display_width, display_height))
That is it! The background will constantly cover up the pong ball, and the pong ball will be constantly blitted to a new position!
P.S, there is a better way to do arrow key movement here: How to get keyboard input in pygame?
it actualy does move it, but the old one just stays there, making it look like it does not move but just grows. one way to change that would be to change the old ones color to the background color
try this code it works :-)
import pygame
import time
import random
import math
import sys
pygame.init()
display_width = 1200
display_height = 800
white = (255,255,255)
black = (0,0,0)
red = (123,11,45)
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Vertical Pong')
clock = pygame.time.Clock()
def pongBoard(x,y,xold):
pygame.draw.rect(gameDisplay,white,[x,y,250,25])
pygame.draw.rect(gameDisplay,red,[xold,y,250,25])
def gameLoop():
x = 325
y = 750
xChange = 0
inGame = True
while inGame:
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_a or event.key == pygame.K_LEFT:
xChange = -50
pongBoard(x,y,xold)
print("Left")
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
xChange = 50
pongBoard(x,y,xold)
print("Right")
if event.type == pygame.KEYUP:
if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
xChange = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_LEFT:
xChange = 0
xold = x
x += xChange
xold = x-xChange
pygame.display.update()
clock.tick(60)
gameLoop()
pygame.quit()
quit()
I did a bit of research to see if i could solve the issue that way, but didn't seem to find anything to solve my problem. I found both of these : Why isn't my pygame display displaying anything? and Confused at why PyGame display's a black screen. I tried to solve my problem with what was adviced in the comments but it didn't work, or the reason for the problem was different than mine.
When i run the code the pygame window shows, but is just completely black, but no errors are called.
so here is the code (might be a bit long).
import pygame
import time
import random
pygame.init()
display_width = 700
display_height = 900
player_width = 140
player_height = 100
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Baby shower')
clock = pygame.time.Clock()
greenkidimg = pygame.image.load('kid green.png')
bluekidimg = pygame.image.load('kid blue.png')
redkidimg = pygame.image.load('kid red.png')
catcherimg = pygame.image.load('catcher.png')
background = pygame.image.load('background.png')
#image loads
def player(x,y):
gameDisplay.blit(catcherimg,(x,y))
def bluekid(bluex, bluey, bluew, blueh):
gameDisplay.blit(bluekidimg, (bluex, bluey))
def redkid(redx, redy, redw, redh):
gameDisplay.blit(redkidimg, (redx,redy))
def greenkid(greenx, greeny, greenw, greenh):
gameDisplay.blit(greenkidimg(greenx, greeny))
def game_loop():
x = (display_width*0.45)
y = (display_height*0.8)
x_change = 0
blue_width = 66
bluex_start = random.randrange (0, display_width-blue_width)
bluey_start = -600
blue_speed = 15
blue_height = 78
green_width = 66
greenx_start = random.randrange (0, display_width-green_width)
greeny_start = -600
green_speed = 15
green_height = 78
red_width = 66
redx_start = random.randrange (0, display_width-red_width)
redy_start = -600
red_speed = 15
red_heigth = 78
#greenkid,redkid,bluekid-start,speed,h/w
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
x_change = -20
elif event.type == pygame.K_RIGHT:
x_change = 20
if event.type == pygame.KEYUP:
if event.type == pygame.K_LEFT or pygame.K_RIGHT:
x_change = 0
x += x_change
gameDisplay.blit(background(0,0))
player(x,y)
bluekid(bluex, bluey, bluew, blueh)
redkid(redx, redy, redw, redh)
greenkid(greenx, greeny, greenw, greenh)
#display
pygame.display.update()
clock.tick(30)
game_loop()
pygame.quit()
quit()
The rendering logic in the game loop just needs to be indented to it is a part of the while loop inside it, like this:
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
x_change = -20
elif event.type == pygame.K_RIGHT:
x_change = 20
if event.type == pygame.KEYUP:
if event.type == pygame.K_LEFT or pygame.K_RIGHT:
x_change = 0
x += x_change
gameDisplay.blit(background(0,0))
player(x,y)
bluekid(bluex, bluey, bluew, blueh)
redkid(redx, redy, redw, redh)
greenkid(greenx, greeny, greenw, greenh)
pygame.display.update()
clock.tick(30)
bg = "lv1.jpg"
ch = "char.png"
import pygame, sys
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((640, 400), 0, 32)
background = pygame.image.load(bg).convert()
char = pygame.image.load(ch).convert_alpha()
clock = pygame.time.Clock()
charspeed = 0
charx = 100
chary = 200
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
pygame.quit()
sys.exit()
if event.type== KEYDOWN:
if event.type == K_LEFT:
charspeed = -100
elif event.type == K_RIGHT:
charspeed = +100
if event.type== KEYUP:
if event.key==K_LEFT:
charspeed=0
elif event.key==K_RIGHT:
charspeed=0
screen.blit(background, (0,0))
milli = clock.tick()
seconds = milli/1000.
chardm = seconds*charspeed
charx += chardm
screen.blit(char, (charx, chary))
pygame.display.update()
For some reason the charspeed wont increment by 100 when i press down on the right key. I am trying to make a game with a clock but it doesn't seem to work. I am very new to pygame as you can see so Plz help!
The problem is here:
if event.type== KEYDOWN:
if event.type == K_LEFT:
charspeed = -100
elif event.type == K_RIGHT:
charspeed = +100
The event.type is KEYDOWN, so it can't also be K_RIGHT.
What you want is event.key == K_RIGHT.
See the pygame.event docs for details.