this is how my code looks like. I suppose to draw frog on the window and make a movement. I suppose this should work, but , but the code doesn't even get to the mainRun event part. How should I fix it?
### Run Game
class MainRun(object):
# init function to initialize all the class
def __init__(self):
self.frog = Frog()
def run(self):
print("a")
while True:
print("b")
self.frog.draw(window)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
frog.move("left")
if event.key == pygame.K_RIGHT:
frog.move("right")
if event.key == pygame.K_UP:
frog.move("up")
if event.key == pygame.K_DOWN:
frog.move("down")
# add player updates here
self.frog.draw(window)
pygame.display.update()
windowClock.tick(60)
window.fill(white)
if __name__ == __main__:
MainRun()
You just instantiation your class.If you want to run the method run.Should add code after 'main':
if __name__ == '__main__':
m = MainRun()
m.run()
Related
I have this 2D platformer game in PyGame where a character moves left, right and up (jump). I recently implemented a function to pause the game, which works great.
However since the code stops the character on pygame.KEYUP then if the user lets off the side-moving keys (A for left, D for right) AFTER they have paused the game then after resuming the character will be stuck running since it never got the KEYUP event.
Any ideas that makes the character stop X-axis movement after pause? Thankful for any help!
Pause function:
def game_pause:
pause = True
while pause == True:
pygame.init()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
pause = False
Main
loop:
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
#---Key presses---
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
player.go_left()
elif event.key == pygame.K_d:
player.go_right()
elif event.key == pygame.K_SPACE:
player.jump()
elif event.key == pygame.K_RETURN:
game_pause()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_a and player.change_x < 0:
player.stop()
elif event.key == pygame.K_d and player.change_x > 0:
player.stop()
Functions that moves the player-class:
def go_left(self):
self.change_x = -5
def go_right(self):
self.change_x = 5
def stop(self):
self.change_x = 0
Maybe you could set
pause = False
in the main loop and in the go_left(), go_right(), stop() functions make an if statement like
def go_left(self):
if not pause :
self.change_x = -5
so when you pause the game the if statement becomes false
New to python and pygame. I was trying to make the ship move left or right continuously, which I did by creating a class "move_ship" and passing self.arguments as false. Then created a function inside which works when self.arguments are True and increase or decreases the x-position value of ship. Then called the class with variable "ship_moving". ...created a event which would set self.argument as true and at last called the function inside the class to move the ship:-
class move_ship():
def __init__(self):
self.moving_left=False
self.moving_right=False
def moving(self):
if self.moving_left:
ship_rect.centerx-=1
if self.moving_right:
ship_rect.centerx+=1
ship_moving=move_ship()
def run_game:
pygame.init()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type ==pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
ship_moving.moving_right=True
elif event.key == pygame.K_LEFT:
ship_moving.moving_left=True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
ship_moving.moving_right=False
elif event.key == pygame.K_LEFT:
ship_moving.moving_left=False
ship_moving.moving()
which worked perfectly fine but the I wanted to know why it didn't work when I tried the same thing but with function only.
moving_right=False
moving_left= False
def move_ship():
if moving_left:
ship_rect.centerx-=1
if moving_right:
ship_rect.centerx+=1
def run_game:
pygame.init()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type ==pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
moving_right=True
elif event.key == pygame.K_LEFT:
moving_left=True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
moving_right=False
elif event.key == pygame.K_LEFT:
moving_left=False
move_ship()
You must use the global statement if you want to set variables in global namespace within a function:
def run_game():
global moving_right, moving_left
pygame.init()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type ==pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
moving_right=True
elif event.key == pygame.K_LEFT:
moving_left=True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
moving_right=False
elif event.key == pygame.K_LEFT:
moving_left=False
If you do not specify moveing_right, moveing_left to be interpreted as global, only local variables with the same name are set in the scope of the run_game function, but the global variables are never changed.
Can someone tell me what's wrong with this Python code? I'm using Python 3.8.2.
This code is from the book Python Crash Course, 2nd Edition: A Hands-On, Project-Based Introduction to Programming. The original code uses pygame.display.flip() instead of pygame.display.update(), the original code will produce this error code: pygame.error: Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface
However, after I changed it to pygame.display.update(), it just freezes my PC with blank PyGame window.
import pygame
from settings import Settings
from ship import Ship
class AlienInvasion:
""" overall class to manage game assets and behavior."""
def __init__(self):
"""Initialize the game, and create game resources."""
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
self.settings.screen_width = self.screen.get_rect().width
self.settings.screen_height = self.screen.get_rect().height
pygame.display.set_caption("Alien Invasion")
self.ship = Ship(self)
def run_game(self):
"""Start the main loop for the game."""
while True:
self._check_events()
self.ship.update()
self._update_screen()
def _check_events(self):
"""respond to keyboard and mouse events."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
self._check_keydown_events(event)
elif event.type == pygame.KEYUP:
self._check_keyup_events(event)
elif event.type == pygame.K_q:
sys.exit()
def _check_keydown_events(self, event):
"""Respond to keypresses."""
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
if event.key == pygame.K_LEFT:
self.ship.moving_left = True
if event.key == pygame.K_UP:
self.ship.moving_up = True
if event.key == pygame.K_DOWN:
self.ship.moving_down = True
def _check_keyup_events(self, event):
"""Respond to key releases."""
if event.key == pygame.K_RIGHT:
self.ship.moving_right = False
if event.key == pygame.K_LEFT:
self.ship.moving_left = False
if event.key == pygame.K_UP:
self.ship.moving_up = False
if event.key == pygame.K_DOWN:
self.ship.moving_down = False
def _update_screen(self):
"""Update images on the screen, and flip to the new screen."""
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
pygame.display.update()
if __name__ == '__main__':
#make a game instance, and run the game.
ai = AlienInvasion()
ai.run_game()
You typed the program in incorrectly. I found the source code for the entire book at https://github.com/ehmatthes/pcc_2e and this particular example is https://github.com/ehmatthes/pcc_2e/blob/master/chapter_12/piloting_the_ship/alien_invasion.py
Your program runs the same way for me - I get a blank frozen screen too. As shown above, your program is ignoring the pygame.K_q keypress because you entered that line of code in the _check_events() function, instead of _check_keydown_events(). That's what's making it seem like your computer is frozen.
The author's source code on github (linked above) runs fine for me. I recommend you download or copy/paste that code instead of trying to type it in by hand.
I'm trying to implement a pause function in my tamagotchi clone (I'm practising for my controlled assessment next year) and I can't get the left and up keys to work simultaneously as a pause button. If possible I want to stay as true to the original game as possible so I would prefer not to use on-screen buttons. Thanks!
import pygame
import time
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
size =(200, 200)
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Tama v4.5')
screen.fill(WHITE)
pygame.init()
clock = pygame.time.Clock()
sprites = ['AdultSpriteAAA.png']
up_pressed = False
left_pressed = False
right_pressed = False
def main():
controls()
if up_pressed == True and left_pressed == True:
time.sleep(2)
pause()
player_position = pygame.mouse.get_pos()
x = player_position[0]
y = player_position[1]
screen.blit(background, [0,0])
screen.blit(sprite, [x, y])
pygame.display.flip()
clock.tick(60)
def controls():
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
print(animate())
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
global up_pressed
right_pressed = True
if event.key == pygame.K_LEFT:
global left_pressed
left_pressed = True
if event.key == pygame.K_RIGHT:
global right_pressed
right_pressed = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
global up_pressed
right_pressed = False
if event.key == pygame.K_LEFT:
global left_pressed
left_pressed = False
if event.key == pygame.K_RIGHT:
global right_pressed
right_pressed = False
def info():
return 0
def food():
return 1
def toilet():
return 2
def game():
return 3
def connect():
return 4
def talk():
return 5
def medic():
return 6
def post():
return 7
def history():
return 8
def animate():
return 9
def pause():
time.sleep(2)
while True:
controls()
if up_pressed == True and left_pressed == True:
time.sleep(2)
break
sprite = pygame.image.load(sprites[0]).convert()
background = pygame.image.load('Background 200x200.png').convert()
sprite.set_colorkey(BLACK)
while True:
main()
A way to make it pause when both left iey and up key are pressed is this:
import pygame
from pygame.locals import *
#game code
…
def pause():
keyspressed = pygame.keys.get_pressed()
if keyspressed[K_LEFT] and keyspressed[K_UP]:
#pause code
…
This code should be correct, but if you find any weird things, try to research the pygame key module. Keep in note that K_LEFT and K_UP are from pygame.locals, which is imported seperately from pygame
Here is a method that I have found really useful when writing games in PyGame:
if event.type == pygame.KEYDOWN
if event.key == (pygame.K_RIGHT and pygame.K_LEFT):
while True: # Infinite loop that will be broken when the user press the space bar again
event = pygame.event.wait()
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: # decid how to unpause?
break #Exit infinite loop
An interesting tid-bit I only recently discovered is that pygame.key.get_pressed() returns a tuple of 1s and 0s representing all of the keys on the keyboard, and these can be used as booleans or indexed to get the effective "value" of a key. Some great tuts at http://programarcadegames.com/
I know this question can be seen as a duplicate, but I spent some hours searching and figuring out what is wrong at my code.
My problem is that my object, called player, doesn't move constantly when left or right key is being held down:
for event in pygame.event.get():
if event.type == QUIT:
self.terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
self.terminate()
if event.key == K_LEFT or event.key == K_a:
self.moveRight = False
self.moveLeft = True
if event.key == K_RIGHT or event.key == K_d:
self.moveLeft = False
self.moveRight = True
if event.type == KEYUP:
if event.key == K_LEFT or event.key == K_a:
self.moveLeft = False
if event.key == K_RIGHT or event.key == K_d:
self.moveRight = False
# Move the player around
if self.moveLeft :
# Moves the player object to left with self.PLAYERMOVERATE pixels.
self.player.setLeftRight(-1 * self.PLAYERMOVERATE)
if self.moveRight :
self.player.setLeftRight(self.PLAYERMOVERATE)
I also tried this alternative:
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.player.setLeftRight(-1 * self.PLAYERMOVERATE)
if keys[pygame.K_RIGHT]:
self.player.setLeftRight(self.PLAYERMOVERATE)
I think that the problem is that you are not handling the input in the main game loop.
In your code you seem to be handling the input inside a method of the object Player. This is not how input should be handled. In your second code example there is a while True: loop which will mean the loop is never exited from and thus the method's execution is never finished. I suspect that there may be a similar issue in your first example.
Instead you should:
Create all objects and classes.
Write the main game loop.
The main game loop should handle input, then process the logic of the game and then render whatever should be rendered.
Here is a short code example.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # Exit from pygame window
quit() # End python thread
if event.type == KEYDOWN:
if event.key == K_LEFT or event.key == K_a:
player.moveRight = False
player.moveLeft = True
if event.key == K_RIGHT or event.key == K_d:
player.moveLeft = False
player.moveRight = True
if event.type == KEYUP:
if event.key == K_LEFT or event.key == K_a:
player.moveLeft = False
if event.key == K_RIGHT or event.key == K_d:
player.moveRight = False
# Move player using method
if player.moveLeft:
# Move player
# ...
# Render player
I hope that this helped you and if you have any further questions please feel free to post them in the comment section below!