Pygame Arrow Control - python

I am wondering why is it that when I execute the file,
the arrow control and movement of the left rectangle will not continuously move up or down, even though I am holding down on the arrow keys for a long time.
import pygame
black = ( 0, 0, 0)
white = ( 255, 255, 255)
green = ( 0, 255, 0)
red = ( 255, 0, 0)
pygame.init()
size = [700,500]
screen = pygame.display.set_mode(size)
fonto = pygame.font.SysFont("algerian", 100)
font = pygame.font.SysFont("algerian", 12)
text = fonto.render("Game Over", True, (0, 128, 10))
pygame.display.set_caption("Vasanths First Legit Game")
done = False
pygame.mouse.set_visible(0)
clock = pygame.time.Clock()
score = 1
rect_x = 50
rect_y = 50
rect_xp = 10
rect_yp = 10
rect_change_x = 10
rect_change_y = 10
rect_change_xp = 10
rect_change_yp = 3
while done == False:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done=True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
rect_yp = rect_change_yp+rect_yp
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
rect_yp = 0+rect_yp
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
rect_yp=-3+rect_yp
if event.key == pygame.K_RIGHT:
rect_yp=3+rect_yp
if event.key == pygame.K_UP:
rect_yp=-3+rect_yp
if event.key == pygame.K_DOWN:
rect_yp=3+rect_yp
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
rect_yp=0+rect_yp
if event.key == pygame.K_RIGHT:
rect_yp=0+rect_yp
if event.key == pygame.K_UP:
rect_yp=0+rect_yp
if event.key == pygame.K_DOWN:
rect_yp=0+rect_yp
pos = pygame.mouse.get_pos()
x = pos[0]
y = pos[1]
screen.fill(black)
pygame.draw.rect(screen,white,[rect_x,rect_y,10,10])
pygame.draw.rect(screen,green,[x,490,50,10])
pygame.draw.rect(screen,green,[10,rect_yp,10,50])
# Move the rectangle starting point
rect_x += rect_change_x
rect_y += rect_change_y
if rect_y == 0:
rect_change_x=rect_change_x*1
rect_change_y=rect_change_y*-1
if rect_y == 490:
if rect_x < x + 50 :
scoref = font.render(score, True, (0, 128, 0))
screen.blit(scoref,
(20 - scoref.get_width() // 10, 20 - scoref.get_height() // 10))
rect_change_x=rect_change_x*1
rect_change_y=rect_change_y*-1
if rect_x < x:
rect_change_y = 0
rect_change_x = 0
#dont do this , it will go bizzonkes
score = str(score)
score = int(score)
if rect_y == 490:
if rect_x < x + 50 :
if rect_change_x !=0:
if rect_change_y !=0:
score=int(score)
score = score + 1
score=str(score)
if rect_change_x == 0:
if rect_change_y == 0:
screen.blit(text,
(320 - text.get_width() // 2, 240 - text.get_height() // 2))
if rect_x == 700:
rect_change_x = rect_change_x*-1
rect_change_y = rect_change_y*1
if rect_x == 0:
rect_change_x = rect_change_x*0
rect_change_y = rect_change_y*0
if rect_y == 500:
rect_change_y = 0
rect_change_x = 0
screen.blit(text,
(320 - text.get_width() // 2, 240 - text.get_height() // 2))
score=str(score)
print(score)
score = str(score)
scoref = font.render(score, True, (0, 128, 0))
screen.blit(scoref,
(20 - scoref.get_width() // 10, 20 - scoref.get_height() // 10))
clock.tick(30)
pygame.display.flip()
pygame.quit ()

In pygame the input is handled in a event loop. There is a event queue, the system sends input from the keyboard, and by calling pygame.event.get() you get the first event in the queue. There are many types of events, the most popular being KEYUP and KEYDOWN.
The mistake that most beginner people make, is that they believe that when a button is pressed, a KEYDOWN event is sent the whole time. That is not needed, since if you press a button, it is pressed until you release it. So you need to have certain flags to see if a button is pressed.
The most popular way of doing this is by using a d = v*t equation. Since the speed is constant, we need to introduce a direction. So our equation would look like this:
distance_changed = direction * speed * time_change
In your event loop, you then change the direction:
1 if KEYDOWN-RIGHT
-1 if KEYDOWN-LEFT
0 if KEYUP-LEFTorRIGHT.
Now the question might pop up, why use time_change? Since, we cannot predict on which machines the program will work, the amount of times the loop will repeat will not be known.
If you take an old machine, the game will work much slower. So we measure the time taken from the last movement, so that it will not changed on different machines.
I have see that you use pygame.tick(30), which waits so that the time it took for the loop to finish was constant. The problem arises, when you run this at an older machine. The loop cannot speed up.
As a suggestion, you should divide you game into functions. It's much more readable, and you can use you code in different places. Also, your event loop, has to many ifs. Use elif since there is no point to check if RIGTH key was pressed if LEFT was already pressed.

This is how I handle it in one of my own Pygame projects:
class Inputs:
def __init__(self):
self.bindings = {"up": pygame.K_UP,
"down": pygame.K_DOWN,
"left": pygame.K_LEFT,
"right": pygame.K_RIGHT,
"lp": pygame.K_a,
"mp": pygame.K_s,
"hp": pygame.K_d,
"lk": pygame.K_z,
"mk": pygame.K_x,
"hk": pygame.K_c,
"pause": pygame.K_RETURN}
self.inputState = {"up": False,
"down": False,
"right": False,
"left": False,
"lp": False,
"mp": False,
"hp": False,
"lk": False,
"mk": False,
"hk": False,
"pause": False}
self.buffer = InputBuffer()
def lookupBinding(self, keyEntered):
for binding, keyBound in self.bindings.items():
if keyEntered == keyBound:
return binding
return "not found"
def getInputState(self, events):
for event in events:
if event.type == pygame.KEYDOWN:
binding = self.lookupBinding(event.key)
if binding != "not found":
newInput = Input()
newInput.inputName = binding
newInput.timeSinceInput = 0
self.buffer.push(newInput)
self.inputState[binding] = True
if event.type == pygame.KEYUP:
binding = self.lookupBinding(event.key)
if binding != "not found":
self.inputState[binding] = False
return self.inputState
I keep two dictionaries, one of in-game "commands", such as directions, to the pygame key, then another of those commands to a boolean representing the command's on/off state. By watching for KEYDOWN and KEYUP events, I can determine which mapped inputs are on and which are off.
EDIT: A benefit of this way method that I should mention is that it makes it very easy to change the key mapping later on, or even allow custom key-mappings. Your game logic only needs to rely on the basic inputs, such as a jump or move input, and won't need to change if the key-mappings change.

I would use pygame.key.get_pressed(), but you are also forgetting pygame.key.set_repeat(). The first argument is the # of milliseconds it takes to start repeating, and the second is the interval at which the key repeats.
This is an example which uses both:
x = 400
y = 300
import pygame, sys
bkg = (255, 211, 0)
clr = (0, 0, 0)
squ = (8, 11, 134)
pygame.init()
size = (800, 600)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Bloxy")
pygame.key.set_repeat(1, 1)
font = pygame.font.SysFont("Stencil", 20)
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_LEFT]:
x -= 5
if keys_pressed[pygame.K_RIGHT]:
x += 5
if keys_pressed[pygame.K_UP]:
y -= 5
if keys_pressed[pygame.K_DOWN]:
y += 5
if x > 800:
x = 0
if x < 0:
x = 800
if y > 600:
y = 0
if y < 0:
y = 600
screen.fill(bkg)
text = font.render('(' + str(x) + ',' + str(y) + ')', True, clr)
screen.blit(text, [10, 10])
pygame.draw.rect(screen, squ, [x - 10, y - 10, 20, 20])
pygame.display.flip()
clock.tick(60)

Related

Restarting a snake game after game over screen appears in pygame

in the game that I have found on github there is a game over screen that shows your score, now I want to make the game restart if you press space so that you don't need to close the program and open it again to play it again. The problem isn't how to make the game restart when you press space but to actually make it restart. Here is the code:
import pygame
import random
import sys
import time
# Difficulty settings
# Easy -> 10
# Medium -> 25
# Hard -> 40
# Harder -> 60
# Impossible-> 120
difficulty = 25
# Window size
frame_size_x = 720
frame_size_y = 480
# Checks for errors encountered
check_errors = pygame.init()
# pygame.init() example output -> (6, 0)
# second number in tuple gives number of errors
if check_errors[1] > 0:
print(f'[!] Had {check_errors[1]} errors when initialising game, exiting...')
sys.exit(-1)
else:
print('[+] Game successfully initialised')
# Initialise game window
pygame.display.set_caption('Snake Eater')
game_window = pygame.display.set_mode((frame_size_x, frame_size_y))
# Colors (R, G, B)
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
green = pygame.Color(0, 255, 0)
blue = pygame.Color(0, 0, 255)
# FPS (frames per second) controller
fps_controller = pygame.time.Clock()
# Game variables
snake_pos = [100, 50]
snake_body = [[100, 50], [100 - 10, 50], [100 - (2 * 10), 50]]
food_pos = [random.randrange(1, (frame_size_x // 10)) * 10, random.randrange(1, (frame_size_y // 10)) * 10]
food_spawn = True
direction = 'RIGHT'
change_to = direction
score = 0
# Game Over
def game_over():
my_font = pygame.font.SysFont('times new roman', 90)
game_over_surface = my_font.render('YOU DIED', True, red)
game_over_rect = game_over_surface.get_rect()
game_over_rect.midtop = (frame_size_x / 2, frame_size_y / 4)
game_window.fill(black)
game_window.blit(game_over_surface, game_over_rect)
show_score(0, red, 'times', 20)
pygame.display.update()
time.sleep(3)
pygame.quit()
sys.exit()
# Score
def show_score(choice, color, font, size):
score_font = pygame.font.SysFont(font, size)
score_surface = score_font.render('Score : ' + str(score), True, color)
score_rect = score_surface.get_rect()
if choice == 1:
score_rect.midtop = (frame_size_x - 100, 15)
else:
score_rect.midtop = (frame_size_x / 2, frame_size_y / 1.25)
game_window.blit(score_surface, score_rect)
# pygame.display.flip()
# Main logic
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Whenever a key is pressed down
elif event.type == pygame.KEYDOWN:
# W -> Up; S -> Down; A -> Left; D -> Right
if event.key == pygame.K_UP or event.key == ord('w'):
change_to = 'UP'
if event.key == pygame.K_DOWN or event.key == ord('s'):
change_to = 'DOWN'
if event.key == pygame.K_LEFT or event.key == ord('a'):
change_to = 'LEFT'
if event.key == pygame.K_RIGHT or event.key == ord('d'):
change_to = 'RIGHT'
# Esc -> Create event to quit the game
if event.key == pygame.K_ESCAPE:
pygame.event.post(pygame.event.Event(pygame.QUIT))
# Making sure the snake cannot move in the opposite direction instantaneously
if change_to == 'UP' and direction != 'DOWN':
direction = 'UP'
if change_to == 'DOWN' and direction != 'UP':
direction = 'DOWN'
if change_to == 'LEFT' and direction != 'RIGHT':
direction = 'LEFT'
if change_to == 'RIGHT' and direction != 'LEFT':
direction = 'RIGHT'
# Moving the snake
if direction == 'UP':
snake_pos[1] -= 10
if direction == 'DOWN':
snake_pos[1] += 10
if direction == 'LEFT':
snake_pos[0] -= 10
if direction == 'RIGHT':
snake_pos[0] += 10
# Snake body growing mechanism
snake_body.insert(0, list(snake_pos))
if snake_pos[0] == food_pos[0] and snake_pos[1] == food_pos[1]:
score += 1
food_spawn = False
else:
snake_body.pop()
# Spawning food on the screen
if not food_spawn:
food_pos = [random.randrange(1, (frame_size_x // 10)) * 10, random.randrange(1, (frame_size_y // 10)) * 10]
food_spawn = True
# GFX
game_window.fill(black)
for pos in snake_body:
# Snake body
# .draw.rect(play_surface, color, xy-coordinate)
# xy-coordinate -> .Rect(x, y, size_x, size_y)
pygame.draw.rect(game_window, green, pygame.Rect(pos[0], pos[1], 10, 10))
# Snake food
pygame.draw.rect(game_window, white, pygame.Rect(food_pos[0], food_pos[1], 10, 10))
# Game Over conditions
# Getting out of bounds
if snake_pos[0] < 0 or snake_pos[0] > frame_size_x - 10:
game_over()
if snake_pos[1] < 0 or snake_pos[1] > frame_size_y - 10:
game_over()
# Touching the snake body
for block in snake_body[1:]:
if snake_pos[0] == block[0] and snake_pos[1] == block[1]:
game_over()
show_score(1, white, 'consolas', 20)
# Refresh game screen
pygame.display.update()
# Refresh rate
fps_controller.tick(difficulty)
Implement a function that initializes all the global game states:
def init_game():
global snake_pos, snake_body
global food_pos, food_spawn
global direction, change_to, score
# Game variables
snake_pos = [100, 50]
snake_body = [[100, 50], [100 - 10, 50], [100 - (2 * 10), 50]]
food_pos = [random.randrange(1, (frame_size_x // 10)) * 10, random.randrange(1, (frame_size_y // 10)) * 10]
food_spawn = True
direction = 'RIGHT'
change_to = direction
score = 0
Invoke the function when SPACE is pressed:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Whenever a key is pressed down
elif event.type == pygame.KEYDOWN:
# [...]
if event.key == pygame.K_SPACE:
init_game()

pygame strange behavior on key pressings

I am kind of new to pygame module.
I am keeping track of the key pressings from the terminal via PyCharm IDE.
To clearness, I am adding screenshot of the workspace of mine below.
Now, the problem is, I found out that, If I am pressing and holding DOWN and UP keys at the same time, the system can detect RIGHT key pressings, however ignorant to LEFT key pressings.
Same thing is valid for holding W and S keys together and sensing T key but not sensing E or Q keys.
RIGHT & LEFT being hold, senses DOWN does not sense UP
I am adding a fully ready to run code(except you need pygame module installed) for ones who might want to try on their computer.
import pygame
#import time
pygame.init()
display_width = 800
display_height = 600
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
#carImg = pygame.image.load('raceCar.png')
# def drawCar(x, y):
# gameDisplay.blit(carImg, (x, y))
x = display_width * 0.45
y = display_height * 0.6
dx = 0
dy = 0
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("MY GAME")
clock = pygame.time.Clock()
crashed = False
Quit = False
i = 0
while not crashed and not Quit:
for event in pygame.event.get():
# if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
# Quit = True
#
# elif event.type == pygame.KEYDOWN:
#
# if event.key == pygame.K_DOWN:
# dy += 5
# elif event.key == pygame.K_UP:
# dy += -5
# elif event.key == pygame.K_RIGHT:
# dx += 5
# elif event.key == pygame.K_LEFT:
# dx += -5
#
# elif event.type == pygame.KEYUP:
#
# if event.key == pygame.K_DOWN:
# dy += -5
# elif event.key == pygame.K_UP:
# dy += 5
# elif event.key == pygame.K_RIGHT:
# dx += -5
# elif event.key == pygame.K_LEFT:
# dx += 5
#
# elif event.type == pygame.QUIT:
# Quit = True
i += 1
print(i, event)
# x = (x + 1) % display_width
# y = (y - 1) % display_height
x += dx
y += dy
gameDisplay.fill(white)
x = x if x <= display_width else -163
x = x if x+163 >= 0 else display_width
y = y if y <= display_height else -244
y = y if y + 244 >= 0 else display_height
# drawCar(x, y)
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
Note that, I have commented out unnecessary parts in order to make it ready to run for anyone easily.
I suspect it's the way your code is handling key-presses. It's better to use the pygame.key.get_pressed(), which returns a dictionary of the current state of all keys pressed at that instant. But the presented code (the commented out section) does not seem to have any issues that would cause this.
Below is some example code that demonstrates handling multiple key-presses. You can also use it to ensure your keyboard handles multiple presses correctly. I would expect every keyboard can handle a minimum of 3 simultaneous key-presses, since otherwise Ctrl-Alt-Del would be impossible.
import pygame
# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 50
WINDOW_SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
DARK_BLUE = ( 3, 5, 54)
WHIPPED_CREAM = ( 251, 252, 214 )
### initialisation
pygame.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), WINDOW_SURFACE )
pygame.display.set_caption("Multi Keys Test")
# We need to write some stuff
default_font = pygame.font.SysFont(None, 40)
### Main Loop
clock = pygame.time.Clock()
done = False
while not done:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
# Make a string of which arrow-keys are pressed
# EDIT: Removing the loop, as it seems to be causing some minor confusion
currently_pressed = ""
keys = pygame.key.get_pressed()
if ( keys[ pygame.K_UP ] ):
currently_pressed += "up "
if ( keys[ pygame.K_DOWN ] ):
currently_pressed += "down "
if ( keys[ pygame.K_LEFT ] ):
currently_pressed += "left "
if ( keys[ pygame.K_RIGHT ] ):
currently_pressed += "right "
keys_text = default_font.render( currently_pressed, True, WHIPPED_CREAM )
# Update the window, but not more than 60fps
window.fill( DARK_BLUE )
window.blit( keys_text, ( 10, 10 ) )
pygame.display.flip()
# Clamp FPS
clock.tick_busy_loop(60)
pygame.quit()
For what it's worth, I can get it to show "left right up down" all together.
This is most likely the result of hardware limitations. It's called keyboard ghosting and happens to most cheap commercial keyboards

Pygame - How does one space out randomly generated platforms evenly?

So, in my previous question, I received an answer that helped orient the platforms the way I wanted. However, there's a new issue that I cannot get around. How do make the platforms appear with sufficient space between them?
(press 1 to start the game)
# For the program, it was necessary to import the following.
import pygame, sys, random
import pygame.locals as GAME_GLOBALS
import pygame.event as GAME_EVENTS
import pygame.time as GAME_TIME
pygame.init() # To initialise the program, we need this command. Else nothing will get started.
StartImage = pygame.image.load("Assets/Start-Screen.png")
GameOverImage = pygame.image.load("Assets/Game-Over-Screen.png")
# Window details are here
windowWidth = 1000
windowHeight = 400
surface = pygame.display.set_mode((windowWidth, windowHeight))
pygame.display.set_caption('GAME NAME HERE')
oneDown = False
gameStarted = False
gameEnded = False
gamePlatforms = []
platformSpeed = 2
platformDelay = 2000
lastPlatform = 0
gameBeganAt = 0
timer = 0
player = {
"x": 10,
"y": 200,
"height": 25,
"width": 10,
"vy": 5
}
def drawingPlayer():
pygame.draw.rect(surface, (248, 255, 6), (player["x"], player["y"], player["width"], player["height"]))
def movingPlayer():
pressedKey = pygame.key.get_pressed()
if pressedKey[pygame.K_UP]:
player["y"] -= 5
elif pressedKey[pygame.K_DOWN]:
player["y"] += 5
def creatingPlatform():
global lastPlatform, platformDelay
platformX = windowWidth
gapPosition = random.randint(0, windowWidth)
verticalPosition = random.randint(0, windowHeight)
gamePlatforms.append({"pos": [platformX, verticalPosition], "gap": gapPosition}) # creating platforms
lastPlatform = GAME_TIME.get_ticks()
if platformDelay > 800:
platformDelay -= 50
def movingPlatform():
for idx, platform in enumerate(gamePlatforms):
platform["pos"][0] -= platformSpeed
if platform["pos"][0] < -10:
gamePlatforms.pop(idx)
def drawingPlatform():
global platform
for platform in gamePlatforms:
pygame.draw.rect(surface, (214, 200, 253), (platform["pos"][0], platform["pos"][1], 20, 80))
def gameOver():
global gameStarted, gameEnded, platformSpeed
platformSpeed = 0
gameStarted = False
gameEnded = True
def quitGame():
pygame.quit()
sys.exit()
def gameStart():
global gameStarted
gameStarted = True
while True:
surface.fill((95, 199, 250))
pressedKey = pygame.key.get_pressed()
for event in GAME_EVENTS.get():
if event.type == pygame.KEYDOWN:
# Event key for space should initiate sound toggle
if event.key == pygame.K_1:
oneDown = True
gameStart()
if event.type == pygame.KEYUP:
if event.key == pygame.K_1:
oneDown = False
#KEYUP for the space bar
if event.type == GAME_GLOBALS.QUIT:
quitGame()
if gameStarted is True:
drawingPlayer()
movingPlayer()
creatingPlatform()
movingPlatform()
drawingPlatform()
elif gameEnded is True:
surface.blit(GameOverImage, (0, 0))
else:
surface.blit(StartImage, (0, 0))
pygame.display.update()
I have tried increasing the value of the platformDelay variable, with no avail. I have also tried tinkering around with creatingPlatform(). No matter what I do, they always appear in clumps! I would like it to be a game where the platforms come towards the player in regular intervals so it's actually playable, but then the speed of the platforms approaching will increase over time to increase the difficulty of the game. How would I go about doing this? Thank you! :)
I recommend to use pygame.time.get_ticks() to get the number of milliseconds the program is running. Note, since the time is given in milliseconds, a value of 1000 would be 1 second.
Initialize a variable newPlatformTimePoint by 0 and define an interval between an interval in which new platforms appear
newPlatformTimePoint = 0
newPlatformInterval = 200 # 0.2 seconds
When the game was startedGet the current time point in the main loop and set the time point for the first platform when the game was started:
timePoint = pygame.time.get_ticks()
if event.key == pygame.K_1:
oneDown = True
gameStart()
newPlatformTimePoint = timePoint + 1000 # 1 second after start
Add a new platform when the time point exceeded and increment set the next time point, by incrementing it by newPlatformInterval. Not the interval can be changed (speeded up) during the game.
if gameStarted is True:
drawingPlayer()
movingPlayer()
if timePoint > newPlatformTimePoint:
newPlatformTimePoint = timePoint + newPlatformInterval
creatingPlatform()
movingPlatform()
drawingPlatform()
Main loop code, with the applied suggestions:
newPlatformTimePoint = 0
newPlatformInterval = 200 # 0.2 seconds
while True:
timePoint = pygame.time.get_ticks()
surface.fill((95, 199, 250))
pressedKey = pygame.key.get_pressed()
for event in GAME_EVENTS.get():
if event.type == pygame.KEYDOWN:
# Event key for space should initiate sound toggle
if event.key == pygame.K_1:
oneDown = True
gameStart()
newPlatformTimePoint = timePoint + 1000 # 1 second after start
if event.type == pygame.KEYUP:
if event.key == pygame.K_1:
oneDown = False
#KEYUP for the space bar
if event.type == GAME_GLOBALS.QUIT:
quitGame()
if gameStarted is True:
drawingPlayer()
movingPlayer()
if timePoint > newPlatformTimePoint:
newPlatformTimePoint = timePoint + newPlatformInterval
creatingPlatform()
movingPlatform()
drawingPlatform()
elif gameEnded is True:
surface.blit(GameOverImage, (0, 0))
else:
surface.blit(StartImage, (0, 0))
pygame.display.update()

pygame - make a stickman jump using arrow keys but goes no higher than 10 units

the stickman I have is able to move and all, using the arrow keys, and but, when the up arrow key is pressed, I want him to only be able to go about 10 units every time the key is pressed, no matter how long it is pressed for. In other words I want him to jump, and have a limit to how high he can jump. I've tried a couple things but nothing has worked.
import pygame
def drawMan(screen,x,y):
#head
pygame.draw.ellipse(screen,BLACK,[0+x,0+y,10,10], 0)
#body
pygame.draw.line(screen,BLACK,[4+x,17+y],[4+x,7+y], 2)
#legs
pygame.draw.line(screen,BLACK,[4+x,17+y],[9+x,27+y], 2)
pygame.draw.line(screen,BLACK,[4+x,17+y],[-1+x,27+y], 2)
#arms
pygame.draw.line(screen,BLACK,[4+x,7+y],[8+x,17+y], 2)
pygame.draw.line(screen,BLACK,[4+x,7+y],[0+x,17+y], 2)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BORDER = (100,100,100)
pygame.init()
size = (800, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Jump")
done = False
clock = pygame.time.Clock()
pygame.mouse.set_visible(1)
xCoord = 11
yCoord = 463
xSpeed = 0
ySpeed = 0
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
xSpeed = -3
if event.key == pygame.K_RIGHT:
xSpeed = 3
if event.key == pygame.K_UP:
ySpeed = -3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
xSpeed = 0
if event.key == pygame.K_RIGHT:
xSpeed = 0
if event.key == pygame.K_UP:
ySpeed = 3
if xCoord >= 780:
xSpeed = 0
xCoord -= 1
elif xCoord <= 13:
xSpeed = 0
xCoord += 1
elif yCoord > 465:
ySpeed = 0
yCoord -= 1
elif yCoord <= 13:
ySpeed = 0
yCoord += 1
else:
xCoord += xSpeed
yCoord += ySpeed
screen.fill(WHITE)
pygame.draw.line(screen, BORDER, [0,0],[800,0], 20)
pygame.draw.line(screen, BORDER, [0,0],[0,500], 20)
pygame.draw.line(screen, BORDER, [0,500],[800,500], 20)
pygame.draw.line(screen, BORDER, [800,500],[800,0], 20)
drawMan(screen,xCoord,yCoord)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Set a variable that allows him to jump. If the variable isn't True, then the jump key does nothing.
When he jumps, switch the variable to False. Don't reset it until he hits the ground again.
Pseudocode:
IF INPUT = "jump" AND can_jump == True THEN
can_jump = False
player.jump()
END IF
IF player.y == 0 and can_jump == False THEN
can_jump = True
END IF
dudee i know it is so late but i found out the answer for this and it is a simple thing
import pygame as game
import keyboard
game.init()
dis=game.display.set_mode((1280,720))
state=0
simpclr=(24,24,24)
white=(255,255,255)
posx=5
posy=5
a=0
jcd=1
clock=game.time.Clock()
while not state:
for event in game.event.get():
if event.type==game.QUIT:
state=1
dis.fill(white)
pl=game.Rect(posx,posy,20,20)
game.draw.rect(dis,simpclr,pl)
game.display.flip()
posy+=2
if keyboard.is_pressed('d'):
posx+=5
if jcd<10:
if keyboard.is_pressed(" "):
posy-=10
jcd+=1
if jcd<50 and jcd>=10:
jcd+=1
if jcd==50:
jcd=1
if posx==1230:
posx-=5
if posy==100:
posy-=5
game.display.flip()
clock.tick(60)
game.quit()

How would I make a car move the direction it's pointing (After use of pygame.translation.rotate)

Okay so I'm making a test for making a racing game...
And I want the car to move in the direction it's pointing.
Here is my code.
import pygame, sys
from pygame.locals import *
pygame.init()
mainClock = pygame.time.Clock()
degree = 0
WHITE = 250,250,250
rect2 = pygame.rect = (100,100,50,50)
WINDOWWIDTH = 1200
WINDOWHEIGHT = 750
thing = pygame.image.load('car.png')
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Teh test')
left = False
right = False
while True:
rect2 = pygame.rect = (100,100,50,50)
if right == True:
degree -= 2
if left == True:
degree += 2
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == ord('a'):
left = True
if event.key == ord('d'):
right = True
if event.type == KEYUP:
if event.key == ord('a'):
left = False
if event.key == ord('d'):
right = False
pygame.draw.rect(screen,WHITE,rect2)
screen.fill((40, 40, 40))
thing2 = pygame.transform.rotate(thing,degree)
screen.blit(thing2,(100,100))
pygame.display.update()
mainClock.tick(60)
So like I said I want to know how to move the car in the direction it's pointing.
I tried to think of a way but I couldn't think of anything. So there isn't really anything to correct.
(If there are any questions I'll edit my question to answer it.) Please make sure you know pygame before answering.
You'll want to use trigonometry to calculate how much you want to move in the x and y directions, so that the car ends up moving in the correct direction. To calculate this, you can do this:
dx = math.cos(math.radians(degree))
dy = math.sin(math.radians(degree))
position = (position[0] + dx * SPEED, position[1] - dy * SPEED)
Note that you'll also need to initialize a position variable somewhere at the start of your code like this:
position = (100, 100)
Then, you have to change the blit line of code so you draw at the position variable, instead of at (100, 100) all of the time:
screen.blit(thing2, position)
Edit: Working example
import pygame, sys
from pygame.locals import *
import math
pygame.init()
mainClock = pygame.time.Clock()
degree = 0
WHITE = 250,250,250
rect2 = pygame.rect = (100,100,50,50)
WINDOWWIDTH = 1200
WINDOWHEIGHT = 750
thing = pygame.image.load('car.png')
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Teh test')
left = False
right = False
position = (100, 100)
while True:
rect2 = pygame.rect = (100,100,50,50)
if right == True:
degree -= 2
if left == True:
degree += 2
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == ord('a'):
left = True
if event.key == ord('d'):
right = True
if event.type == KEYUP:
if event.key == ord('a'):
left = False
if event.key == ord('d'):
right = False
pygame.draw.rect(screen,WHITE,rect2)
screen.fill((40, 40, 40))
thing2 = pygame.transform.rotate(thing,degree)
dx = math.cos(math.radians(degree))
dy = math.sin(math.radians(degree))
position = (position[0] + dx, position[1] - dy)
screen.blit(thing2, position)
pygame.display.update()
mainClock.tick(60)
Working example to kabb answer
import pygame, sys
from pygame.locals import *
import math # math library
pygame.init()
mainClock = pygame.time.Clock()
degree = 0
WHITE = 250,250,250
rect2 = pygame.rect = (100,100,50,50)
WINDOWWIDTH = 1200
WINDOWHEIGHT = 750
thing = pygame.image.load('car.png')
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Teh test')
left = False
right = False
forward = False
backward = False
thing2_x = 100
thing2_y = 100
speed = 20
while True:
rect2 = pygame.rect = (100,100,50,50)
if right: # don't need == True
degree -= 2
while degree < 0:
degree += 360
elif left: # don't need == True
degree += 2
while degree > 359:
degree -= 360
dx = math.cos(math.radians(degree))
dy = math.sin(math.radians(degree))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
elif event.key == K_a: # use constants K_a
left = True
elif event.key == K_d: # use constants K_d
right = True
elif event.key == K_w: # use constants K_w
forward = True
elif event.key == K_s: # use constants K_s
backward = True
if event.type == KEYUP:
if event.key == K_a: # use constants K_a
left = False
elif event.key == K_d: # use constants K_d
right = False
elif event.key == K_w: # use constants K_w
forward = False
elif event.key == K_s: # use constants K_s
backward = False
if forward:
thing2_y -= int(speed * dx)
thing2_x -= int(speed * dy)
elif backward:
thing2_y += int(speed * dx)
thing2_x += int(speed * dy)
pygame.draw.rect(screen,WHITE,rect2)
screen.fill((40, 40, 40))
thing2 = pygame.transform.rotate(thing,degree)
screen.blit(thing2,(thing2_x,thing2_y))
pygame.display.update()
mainClock.tick(60)

Categories

Resources