I'm attempting to make a store in my game, but am having issues with pygame.mouse.get_pressed(). When the user clicks on a button, the program thinks that they clicked on it more than once, therefore using more credits than the user intended. I would like to add a delay so that the game doesn't do this. I would like 1 click to represent them buying one object. I have tried reducing the framerate for that window, but the result is the same. Here is the code I currently have.
This is where all the mouse action occurs.
def button(x, y, w, h, ic, ac, action = None):
global paused
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac, (x, y, w, h))
if click[0] == 1 and action == Game:
Game()
if click[0] == 1 and action == quitgame:
sys.exit()
if click[0] == 1 and action == None:
paused = False
if click[0] == 1 and action == StartScreen:
save()
StartScreen()
if click[0] == 1 and action == LootScreen:
LootScreen()
if click[0] == 1 and action == open_common_drop:
open_common_drop()
if click[0] == 1 and action == open_rare_drop:
open_rare_drop()
else:
pygame.draw.rect(gameDisplay, ic, (x, y, w, h))
This is where the loot store is currently at.
def LootScreen():
global current_drops
loot = True
while loot:
for event in pygame.event.get():
if event.type == pygame.QUIT:
save()
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_t:
open_common_drop()
elif event.key == pygame.K_y:
open_rare_drop()
if event.key == pygame.K_ESCAPE:
StartScreen()
gameDisplay.fill(gray)
title('Loot Chests!')
button(400, 150, 260, 50, blue, bright_blue, open_common_drop)
button(695, 150, 260, 50, red, bright_red, open_rare_drop)
button(display_width * 0.42, display_height / 1.15, 255, 50, red, bright_red, StartScreen)
game_display_text('Open Common Chest (T)', 407, 165)
game_display_text('Open Rare Chest (Y)', 725, 165)
game_display_text('You Got: %s' % current_drops, 50, display_height / 2)
game_display_text('Credits: %.2f' % player_loot_data['credit_count'], 15, 15)
game_display_text('Main Menu', display_width * 0.47, display_height / 1.13)
game_display_text('Janus\': %s' % player_loot_data['loot_data_one'] , 950, 500)
game_display_text('Peace of Minds: %s' % player_loot_data['loot_data_two'], 950, 535)
pygame.display.update()
clock.tick(30)
You will need to use a bool switch in your button function. Here I re-worked the function in a way that should work.
def button(x, y, w, h, ic, ac, action = None, held):
global paused
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac, (x, y, w, h))
if click[0] == 1:
if held == False:
if action == Game:
Game()
elif action == quitgame:
sys.exit()
elif action == None:
paused = False
elif action == StartScreen:
save()
StartScreen()
elif action == LootScreen:
LootScreen()
elif action == open_common_drop:
open_common_drop()
elif action == open_rare_drop:
open_rare_drop()
held = True
else:
held = False
else:
pygame.draw.rect(gameDisplay, ic, (x, y, w, h))
return held
As you see, there is a new variable held added to the function to process whether the button is held or not. Held is taken and returned here, so it won't reset every time the function is called.
With that down, let me show you why I wrote it that way, and just how this logic works at its core.
import pygame
#
display = pygame.display.set_mode((800,600))
clock = pygame.time.Clock()
#
held = False # Variable to handle if mouse button is held
#
RUNNING = True
while RUNNING:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
RUNNING = False
#
button = pygame.mouse.get_pressed() # Get mouse state
if button[0]: # Check if left mouse button is pressed
if held == False: # Check if button is held down
print(True) # If button is not held down, print true
held = True # Set held eqaual to true for next iteration
else: # If left mouse button is not pressed
held = False # held is set to false, alowing event to happen again
#
display.fill((0,0,0))
#
pygame.display.flip()
#
pygame.quit()
The above is a very simple stand alone program that also implements the held variable to monitor if the mouse button is held. In this program, the variable held is first declared as False as the mouse is not being pressed. Then, within the main loop, pygame.mouse.get_pressed() is called to get the mouse input, and is immediately followed by a check for the left mouse button. If the left mouse button is pressed, a check for held will happen. If it is false, the program will print True. held is then set to True for the next iteration. The else: statement will fire if the left mouse button is not held down and reset held to its default False state.
I would suggest a timed bool switch. Here's an example that should help out.
import time
boolswitch = False
timer = 0.0
clock = time.time()
x = time
while True:
if timer > 0.25:
boolswitch = True
timer = 0.0
else:
x = time.time()
timer += (x-clock)
clock = x
if boolswitch:
click = pygame.mouse.get_pressed()
if click[0] == 1:
boolswitch = False
clock = time.time()
Related
I am making a game in pygame 1.9.2.
It's a faily simple game in which a ship moves between five columns of bad guys who attack by moving slowly downward. I am attempting to make it so that the ship moves left and right with the left and right arrow keys. Here is my code:
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
location-=1
if location==-1:
location=0
if keys[K_RIGHT]:
location+=1
if location==5:
location=4
It works too well. The ship moves too fast. It is near impossible to have it move only one location, left or right. How can i make it so the ship only moves once every time the key is pressed?
You can get the events from pygame and then watch out for the KEYDOWN event, instead of looking at the keys returned by get_pressed()(which gives you keys that are currently pressed down, whereas the KEYDOWN event shows you which keys were pressed down on that frame).
What's happening with your code right now is that if your game is rendering at 30fps, and you hold down the left arrow key for half a second, you're updating the location 15 times.
events = pygame.event.get()
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
location -= 1
if event.key == pygame.K_RIGHT:
location += 1
To support continuous movement while a key is being held down, you would have to establish some sort of limitation, either based on a forced maximum frame rate of the game loop or by a counter which only allows you to move every so many ticks of the loop.
move_ticker = 0
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
if move_ticker == 0:
move_ticker = 10
location -= 1
if location == -1:
location = 0
if keys[K_RIGHT]:
if move_ticker == 0:
move_ticker = 10
location+=1
if location == 5:
location = 4
Then somewhere during the game loop you would do something like this:
if move_ticker > 0:
move_ticker -= 1
This would only let you move once every 10 frames (so if you move, the ticker gets set to 10, and after 10 frames it will allow you to move again)
pygame.key.get_pressed() returns a list with the state of each key. If a key is held down, the state for the key is 1, otherwise 0. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement:
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= speed
if keys[pygame.K_RIGHT]:
x += speed
if keys[pygame.K_UP]:
y -= speed
if keys[pygame.K_DOWN]:
y += speed
This code can be simplified by subtracting "left" from "right" and "up" from "down":
while True:
keys = pygame.key.get_pressed()
x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed
y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * speed
The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action or movement:
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x -= speed
if event.key == pygame.K_RIGHT:
x += speed
if event.key == pygame.K_UP:
y -= speed
if event.key == pygame.K_DOWN:
y += speed
See also Key and Keyboard event
Minimal example of continuous movement: replit.com/#Rabbid76/PyGame-ContinuousMovement
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
rect = pygame.Rect(0, 0, 20, 20)
rect.center = window.get_rect().center
vel = 5
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
print(pygame.key.name(event.key))
keys = pygame.key.get_pressed()
rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel
rect.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel
rect.centerx = rect.centerx % window.get_width()
rect.centery = rect.centery % window.get_height()
window.fill(0)
pygame.draw.rect(window, (255, 0, 0), rect)
pygame.display.flip()
pygame.quit()
exit()
Minimal example for a single action: replit.com/#Rabbid76/PyGame-ShootBullet
import pygame
pygame.init()
window = pygame.display.set_mode((500, 200))
clock = pygame.time.Clock()
tank_surf = pygame.Surface((60, 40), pygame.SRCALPHA)
pygame.draw.rect(tank_surf, (0, 96, 0), (0, 00, 50, 40))
pygame.draw.rect(tank_surf, (0, 128, 0), (10, 10, 30, 20))
pygame.draw.rect(tank_surf, (32, 32, 96), (20, 16, 40, 8))
tank_rect = tank_surf.get_rect(midleft = (20, window.get_height() // 2))
bullet_surf = pygame.Surface((10, 10), pygame.SRCALPHA)
pygame.draw.circle(bullet_surf, (64, 64, 62), bullet_surf.get_rect().center, bullet_surf.get_width() // 2)
bullet_list = []
run = True
while run:
clock.tick(60)
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
bullet_list.insert(0, tank_rect.midright)
for i, bullet_pos in enumerate(bullet_list):
bullet_list[i] = bullet_pos[0] + 5, bullet_pos[1]
if bullet_surf.get_rect(center = bullet_pos).left > window.get_width():
del bullet_list[i:]
break
window.fill((224, 192, 160))
window.blit(tank_surf, tank_rect)
for bullet_pos in bullet_list:
window.blit(bullet_surf, bullet_surf.get_rect(center = bullet_pos))
pygame.display.flip()
pygame.quit()
exit()
import pygame
pygame.init()
pygame.display.set_mode()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(); #sys.exit() if sys is imported
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_0:
print("Hey, you pressed the key, '0'!")
if event.key == pygame.K_1:
print("Doing whatever")
In note that K_0 and K_1 aren't the only keys, to see all of them, see pygame documentation, otherwise, hit tab after typing in
pygame.
(note the . after pygame) into an idle program. Note that the K must be capital. Also note that if you don't give pygame a display size (pass no args), then it will auto-use the size of the computer screen/monitor. Happy coding!
I think you can use:
pygame.time.delay(delayTime)
in which delayTime is in milliseconds.
Put it before events.
Try this:
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
if count == 10:
location-=1
count=0
else:
count +=1
if location==-1:
location=0
if keys[K_RIGHT]:
if count == 10:
location+=1
count=0
else:
count +=1
if location==5:
location=4
This will mean you only move 1/10 of the time. If it still moves to fast you could try increasing the value you set "count" too.
The reason behind this is that the pygame window operates at 60 fps (frames per second) and when you press the key for just like 1 sec it updates 60 frames as per the loop of the event block.
clock = pygame.time.Clock()
flag = true
while flag :
clock.tick(60)
Note that if you have animation in your project then the number of images will define the number of values in tick(). Let's say you have a character and it requires 20 sets images for walking and jumping then you have to make tick(20) to move the character the right way.
Just fyi, if you're trying to ensure the ship doesn't go off of the screen with
location-=1
if location==-1:
location=0
you can probably better use
location -= 1
location = max(0, location)
This way if it skips -1 your program doesn't break
make something like this, but based on time delay. i call my function first time immediately and then lunch timer, and while button is pressed i call it every button_press_delta seconds
from time import time
before main loop:
button_press_delta = 0.2
right_button_pressed = 0
while not done:
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
if not right_button_pressed:
call_my_function()
right_button_pressed = 1
right_button_pressed_time_start = time()
if right_button_pressed:
right_button_pressed_time = (
time() - right_button_pressed_time_start)
if right_button_pressed_time > button_press_delta:
call_my_function()
right_button_pressed_time_start = time()
else:
right_button_pressed = 0
You should use clock.tick(10) as stated in the docs.
all of the answers above are too complexicated i would just change the variables by 0.1 instead of 1
this makes the ship 10 times slower
if that is still too fast change the variables by 0.01
this makes the ship 100 times slower
try this
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
location -= 0.1 #or 0.01
if location==-1:
location=0
if keys[K_RIGHT]:
location += 0.1 #or 0.01
if location==5:
location=4
To slow down your game, use pygame.clock.tick(10)
I am making a game in pygame 1.9.2.
It's a faily simple game in which a ship moves between five columns of bad guys who attack by moving slowly downward. I am attempting to make it so that the ship moves left and right with the left and right arrow keys. Here is my code:
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
location-=1
if location==-1:
location=0
if keys[K_RIGHT]:
location+=1
if location==5:
location=4
It works too well. The ship moves too fast. It is near impossible to have it move only one location, left or right. How can i make it so the ship only moves once every time the key is pressed?
You can get the events from pygame and then watch out for the KEYDOWN event, instead of looking at the keys returned by get_pressed()(which gives you keys that are currently pressed down, whereas the KEYDOWN event shows you which keys were pressed down on that frame).
What's happening with your code right now is that if your game is rendering at 30fps, and you hold down the left arrow key for half a second, you're updating the location 15 times.
events = pygame.event.get()
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
location -= 1
if event.key == pygame.K_RIGHT:
location += 1
To support continuous movement while a key is being held down, you would have to establish some sort of limitation, either based on a forced maximum frame rate of the game loop or by a counter which only allows you to move every so many ticks of the loop.
move_ticker = 0
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
if move_ticker == 0:
move_ticker = 10
location -= 1
if location == -1:
location = 0
if keys[K_RIGHT]:
if move_ticker == 0:
move_ticker = 10
location+=1
if location == 5:
location = 4
Then somewhere during the game loop you would do something like this:
if move_ticker > 0:
move_ticker -= 1
This would only let you move once every 10 frames (so if you move, the ticker gets set to 10, and after 10 frames it will allow you to move again)
pygame.key.get_pressed() returns a list with the state of each key. If a key is held down, the state for the key is 1, otherwise 0. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement:
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= speed
if keys[pygame.K_RIGHT]:
x += speed
if keys[pygame.K_UP]:
y -= speed
if keys[pygame.K_DOWN]:
y += speed
This code can be simplified by subtracting "left" from "right" and "up" from "down":
while True:
keys = pygame.key.get_pressed()
x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed
y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * speed
The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action or movement:
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x -= speed
if event.key == pygame.K_RIGHT:
x += speed
if event.key == pygame.K_UP:
y -= speed
if event.key == pygame.K_DOWN:
y += speed
See also Key and Keyboard event
Minimal example of continuous movement: replit.com/#Rabbid76/PyGame-ContinuousMovement
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
rect = pygame.Rect(0, 0, 20, 20)
rect.center = window.get_rect().center
vel = 5
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
print(pygame.key.name(event.key))
keys = pygame.key.get_pressed()
rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel
rect.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel
rect.centerx = rect.centerx % window.get_width()
rect.centery = rect.centery % window.get_height()
window.fill(0)
pygame.draw.rect(window, (255, 0, 0), rect)
pygame.display.flip()
pygame.quit()
exit()
Minimal example for a single action: replit.com/#Rabbid76/PyGame-ShootBullet
import pygame
pygame.init()
window = pygame.display.set_mode((500, 200))
clock = pygame.time.Clock()
tank_surf = pygame.Surface((60, 40), pygame.SRCALPHA)
pygame.draw.rect(tank_surf, (0, 96, 0), (0, 00, 50, 40))
pygame.draw.rect(tank_surf, (0, 128, 0), (10, 10, 30, 20))
pygame.draw.rect(tank_surf, (32, 32, 96), (20, 16, 40, 8))
tank_rect = tank_surf.get_rect(midleft = (20, window.get_height() // 2))
bullet_surf = pygame.Surface((10, 10), pygame.SRCALPHA)
pygame.draw.circle(bullet_surf, (64, 64, 62), bullet_surf.get_rect().center, bullet_surf.get_width() // 2)
bullet_list = []
run = True
while run:
clock.tick(60)
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
bullet_list.insert(0, tank_rect.midright)
for i, bullet_pos in enumerate(bullet_list):
bullet_list[i] = bullet_pos[0] + 5, bullet_pos[1]
if bullet_surf.get_rect(center = bullet_pos).left > window.get_width():
del bullet_list[i:]
break
window.fill((224, 192, 160))
window.blit(tank_surf, tank_rect)
for bullet_pos in bullet_list:
window.blit(bullet_surf, bullet_surf.get_rect(center = bullet_pos))
pygame.display.flip()
pygame.quit()
exit()
import pygame
pygame.init()
pygame.display.set_mode()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(); #sys.exit() if sys is imported
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_0:
print("Hey, you pressed the key, '0'!")
if event.key == pygame.K_1:
print("Doing whatever")
In note that K_0 and K_1 aren't the only keys, to see all of them, see pygame documentation, otherwise, hit tab after typing in
pygame.
(note the . after pygame) into an idle program. Note that the K must be capital. Also note that if you don't give pygame a display size (pass no args), then it will auto-use the size of the computer screen/monitor. Happy coding!
I think you can use:
pygame.time.delay(delayTime)
in which delayTime is in milliseconds.
Put it before events.
Try this:
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
if count == 10:
location-=1
count=0
else:
count +=1
if location==-1:
location=0
if keys[K_RIGHT]:
if count == 10:
location+=1
count=0
else:
count +=1
if location==5:
location=4
This will mean you only move 1/10 of the time. If it still moves to fast you could try increasing the value you set "count" too.
The reason behind this is that the pygame window operates at 60 fps (frames per second) and when you press the key for just like 1 sec it updates 60 frames as per the loop of the event block.
clock = pygame.time.Clock()
flag = true
while flag :
clock.tick(60)
Note that if you have animation in your project then the number of images will define the number of values in tick(). Let's say you have a character and it requires 20 sets images for walking and jumping then you have to make tick(20) to move the character the right way.
Just fyi, if you're trying to ensure the ship doesn't go off of the screen with
location-=1
if location==-1:
location=0
you can probably better use
location -= 1
location = max(0, location)
This way if it skips -1 your program doesn't break
make something like this, but based on time delay. i call my function first time immediately and then lunch timer, and while button is pressed i call it every button_press_delta seconds
from time import time
before main loop:
button_press_delta = 0.2
right_button_pressed = 0
while not done:
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
if not right_button_pressed:
call_my_function()
right_button_pressed = 1
right_button_pressed_time_start = time()
if right_button_pressed:
right_button_pressed_time = (
time() - right_button_pressed_time_start)
if right_button_pressed_time > button_press_delta:
call_my_function()
right_button_pressed_time_start = time()
else:
right_button_pressed = 0
You should use clock.tick(10) as stated in the docs.
all of the answers above are too complexicated i would just change the variables by 0.1 instead of 1
this makes the ship 10 times slower
if that is still too fast change the variables by 0.01
this makes the ship 100 times slower
try this
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
location -= 0.1 #or 0.01
if location==-1:
location=0
if keys[K_RIGHT]:
location += 0.1 #or 0.01
if location==5:
location=4
To slow down your game, use pygame.clock.tick(10)
I have created this game which gives you a time limit to kill as many as the targets as you can. Below is the part of the code which pauses and unpauses the game. The problem I am having is that when I pause the game the timer which sets the time limit is still counting. How do I get this to stop?
paused = False
def button(msg, msg_two, x, y, w, h, i, a, fontsize, action=None):
global paused
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if (x < mouse[0] < (x+450)) and (y < mouse[1]<(y+100)):
pygame.draw.rect(gameDisplay, a, [x, y, w, h])
largeText = pygame.font.Font('freesansbold.ttf',fontsize)
TextSurf, TextRect = text_objects(msg, largeText, green)
TextRect.center = ((x+(w/2)),(y+(h/2)))
gameDisplay.blit(TextSurf, TextRect)
if click[0] == 1 and action != None:
if action == "play":
gameloop()
elif action == "quit":
game_quit()
elif action == "pause":
paused = True
pause()
elif action == "unpause":
unpause()
else:
pygame.draw.rect(gameDisplay, i, [x, y, w, h])
largeText = pygame.font.Font('freesansbold.ttf',fontsize)
TextSurf, TextRect = text_objects(msg_two, largeText, green)
TextRect.center = ((x+(w/2)),(y+(h/2)))
gameDisplay.blit(TextSurf, TextRect)
def game_quit():
pygame.quit()
quit()
def unpause():
global paused
paused = False
def pause():
pygame.mouse.set_visible(1)
button_x = (display_width/4)-150
button_y = display_height/1.5
button_width = 450
button_height = 100
while paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white)
largeText = pygame.font.Font('freesansbold.ttf',72)
TextSurf, TextRect = text_objects('paused', largeText, red)
TextRect.center = ((display_width/2),(display_height/3))
gameDisplay.blit(TextSurf, TextRect)
mouse = pygame.mouse.get_pos()
button("let's go", "carry on", button_x, button_y, button_width, button_height, blue, light_blue, 70, "unpause")
button("Bye then :(", "Leaving?", button_x+600, button_y, button_width, button_height, red, light_red, 70, "quit")
pygame.display.update()
clock.tick(15)
def gameloop():
gameExit = False
start = time.time()
elapsed = 0
while not gameExit and elapsed < 30:
button("Stop", "Stop", 1550, 0, 50, 50, red, light_red, 15, "pause")
elapsed = time.time() - start - (enemy_kills/2)
gameloop()
def game_intro():
pygame.mouse.set_visible(1)
button_x = (display_width/4)-150
button_y = display_height/1.5
button_width = 450
button_height = 100
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white)
largeText = pygame.font.Font('freesansbold.ttf',72)
TextSurf, TextRect = text_objects('Shoot Hitler and not trump', largeText, red)
TextRect.center = ((display_width/2),(display_height/3))
gameDisplay.blit(TextSurf, TextRect)
mouse = pygame.mouse.get_pos()
button("let's go", "wanna play?", button_x, button_y, button_width, button_height, blue, light_blue, 70, "play")
button("Bye then :(", "wanna quit?", button_x+600, button_y, button_width, button_height, red, light_red, 70, "quit")
pygame.display.update()
clock.tick(15)
game_intro()
I apologize if I have missed out important parts of the code. Inform me if I have
There are other strange things in this program that makes it hard to understand it enough to give you a proper answer.
For example, the fact that you call back gameloop() at the end of the gameloop function - it creates a recursive call that should no t be recursive at all.
Anyway, what happens is that you should move most of these functions inside a class - so that some of the state variables like paused can be an attribute of that class. Instances of the class are meant to be game plays.
In that case, your "start" variable would be made an attribute as well, so that it could be modified from within the unpause method.
You then could count the amount of paused time, and add that amount to the "start" tick count .
Or you can just make start a global variable and go on with your current pattern. Since I am not re-organizng all of your code just to answer the question, keeping the things more or less as they are would require you to do:
def gameloop():
global start
...
def pause():
global pause_start
pause_start = time.time()
...
def unpause():
global start, pause_start
pause_duration = time.time() - pause_start
start += pause_duration
...
I can't work out to make the button function run once when clicked. Whenever the mouse button is down it runs through the function loop until released. I only want to run through the loop once per click. Here is the code:
def Button(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(window, ac, (x, y, w, h))
#if event.type == pygame.MOUSEBUTTONDOWN:
if click[0] == 1 and action != None:
pygame.draw.rect(window, lightgrey, (x, y, w, h))
if action == "undo":
print("hey")
if action == "reset":
for row in range(6):
for column in range(7):
board[row][column] = 0
elif action == "quit":
pygame.quit()
quit()
else:
pygame.draw.rect(window, ic, (x, y, w, h))
print("hey") prints roughly 3 times if you click as fast as you can as it is running through the loop repetitively.
pygame.mouse.get_pressed() will return True for as long as the mouse is held down. Assuming this checks every frame, it's going to return 1 or True for multiple frames, thus causing your print statement to occur multiple times.
if event.type == pygame.MOUSEBUTTONDOWN:
This line you commented out is the one you should be using. It only activates when the mouse is actually clicked, but not while it is being held down. Note that for this to work, you must have a loop like for event in pygame.event.get() before this line.
So what you basically need to do is remove click = pygame.mouse.get_pressed() and replace if click[0] == 1 with the line you commented out. Hopefully this works :)
For some reason I cannot exit this loop when I change to intro = false, can anyone help as to how I'd exit this if statement. It is my menu screen, and once I click 'new game' I want it to exit the game_intro function.
This is where I define game_intro:
def game_intro():
intro = True
if intro == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
window.fill(superlightgrey)
fontvertical = pygame.font.SysFont("comicsansms", 100)
text = fontvertical.render("Connect 4", True, skyblue)
word = (10, 1)
window.blit(text,word)
ButtonIntro("New Game", 340, 140, 200, 50, superlightgrey, superlightgrey, "Play")
This is where I created the button function:
def ButtonIntro(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(window, ac, (x, y, w, h))
if click[0] == 1 and action != None:
pygame.draw.rect(window, lightgrey, (x, y, w, h))
if action == "Play":
intro = False
##WHAT DO I NEED HERE TO EXIT LOOP
and this is where I call on the function:
while intro == True:
game_intro()
print("loopexited")
The intro variable is inside a function, when you create a variable inside a function it's not connected to anything outside the function.
intro = True
def myfunction():
intro = False
myfunction()
print(intro)
This code prints:
True
The intro variable inside the myfunction is created as an entirely separate variable from the one outside.
It looks like you might have another separate intro variable inside the game_intro function too.
You can get around this using the global keyword, but you might be better off trying to find a different way to structure your code (global is considered a bad practice.)