It should call events() function and restart the whole process by displaying the block on the screen again, why isn't it working?
I tried breaking out of gameover(), tried calling pygame.display.update() but nothing seems to work [This is my 1st python game ever, so I may have been a little messy in typing my code]. Can anyone help me solve the problem?
import pygame
import time
pygame.init()
global display_height
global display_width
display_height = 800
display_width = 800
class slither(object):
def __init__(self,top):
self.top=top
self.x = display_height/2
self.y = display_width/2
self.x_change = 0
self.y_change = 0
self.gameOver = False
self.gameLoop = False
self.FPS=30
self.brick_size=10
self.black = (0,0,0)
self.white = (255,255,255)
self.red = (255,0,0)
self.font = pygame.font.SysFont(None, 30)
self.clock = pygame.time.Clock()
self.events()
self.message('',(0,0,0))
self.gameover()
def create_move(self, a, b):
pygame.draw.rect(screen, self.black , [a,b,self.brick_size,self.brick_size])
def message(self, msg, color):
screen_text=self.font.render(msg, True, color)
screen.blit(screen_text, [display_height/2, display_width/2])
pygame.display.update()
def events(self):
while self.gameLoop == False:
screen.fill(self.white)
self.create_move(self.x,self.y)
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.const=True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.x_change = -self.brick_size
self.y_change = 0
elif event.key == pygame.K_RIGHT:
self.x_change = self.brick_size
self.y_change = 0
elif event.key == pygame.K_UP:
self.y_change = -self.brick_size
self.x_change = 0
elif event.key == pygame.K_DOWN:
self.y_change = self.brick_size
self.x_change = 0
if self.x_change == -self.brick_size:
self.x -= self.brick_size
y=self.y
self.create_move(self.x, y)
elif self.x_change == self.brick_size:
self.x += self.brick_size
y=self.y
self.create_move(self.x, y)
if self.y_change == -self.brick_size:
self.y -= self.brick_size
x=self.x
self.create_move(x, self.y)
elif self.y_change == self.brick_size:
self.y += self.brick_size
x=self.x
self.create_move(x, self.y)
if self.x == display_height or self.x < 0 or self.y == display_width or self.y < 0 :
self.gameover()
pygame.display.update()
self.clock.tick(30)
def gameover(self):
while self.gameOver == False:
screen.fill((255, 255, 255))
self.message('Game over, Press any to continue or W to quit ', self.black)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
screen.fill(self.white)
self.message('Game Over, You lose', self.black)
time.sleep(2)
pygame.quit()
quit()
else:
self.events() #continue
screen=pygame.display.set_mode((display_height,display_width))
pygame.display.set_caption('Snake')
slither(0).events()
pygame.quit()
quit()
EDIT: I SOLVED IT, THANKS.
This is all I had to change.
Basically, because the block was still out of the screen, hence the gameover() used to get executed again, so when I brought the block back onto the screen, it worked.
else: #continue
self.x=display_height/2
self.y=display_width/2
self.events()
Related
I was programming player movement for my game and I'm not getting errors but the code isn't working correctly. The game is just presenting a black screen, if your able to help, please do that would be greatly appreciated! I've tried resetting my browser and such, but nothings working anyone able to help? (I'm using repl.it)
import pygame, sys
WIDTH, HEIGHT = 400, 400
TITLE = "DarkRoom"
pygame.init()
win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
clock = pygame.time.Clock()
class Player:
def __init__(self, x, y):
self.rect = pygame.Rect(x, y, 32, 32)
self.x = int(x)
self.y = int(y)
self.color = (255, 255, 255)
self.velX = 0
self.velY = 0
self.left_pressed = False
self.right_pressed = False
self.up_pressed = False
self.down_pressed = False
self.speed = 4
def draw(self, win):
pygame.draw.rect(win, self.color, self.rect)
def update(self):
self.velX = 0
self.velY = 0
if self.left_pressed and not self.right_pressed:
self.velX = -self.speed
if self.right_pressed and not self.left_pressed:
self.velX = self.speed
if self.up_pressed and not self.down_pressed:
self.velY = -self.speed
if self.down_pressed and not self.up_pressed:
self.velY = self.speed
self.x += self.velX
self.y += self.velY
self.rect = pygame.Rect(self.x, self.y, 32, 32)
player = Player(WIDTH/2, HEIGHT/2)
while True:
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_LEFT:
player.left_pressed = True
if event.key == pygame.K_RIGHT:
player.right_pressed = True
if event.key == pygame.K_UP:
player.up_pressed = True
if event.key == pygame.K_DOWN:
player.down_pressed = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.left_pressed = False
if event.key == pygame.K_RIGHT:
player.right_pressed = False
if event.key == pygame.K_UP:
player.up_pressed = False
if event.key == pygame.K_DOWN:
player.down_pressed = False
win.fill((12, 24, 36))
player.draw(win)
player.update()
pygame.display.flip()
clock.tick(120)
It is just a matter of Indentation. You have to draw the player and update the display in the application loop, but not after the application loop:
while True:
for event in pygame.event.get():
# [...]
# INDENTATION
#->|
player.update()
pygame.display.flip()
clock.tick(120)
This question already has an answer here:
Python pygame need help disabling multiple keypresses at once [duplicate]
(1 answer)
Closed 2 years ago.
I am working on a pygame version of the game snake. The problem I am having so far is that I don't want to allow diagonal movement but currently there is. Any help would be much appreciated. Thanks in advance 🙂
import pygame
class Snake:
def __init__(self):
self.x = 250
self.y = 250
self.x_change = 0
self.y_change = 0
self.width = 25
self.height = 25
self.win = pygame.display.set_mode((500,500))
self.clock = pygame.time.Clock()
self.run = True
pygame.init()
pygame.display.set_caption('Snake')
def gameLoop(self):
while self.run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.x_change = -10
elif event.key == pygame.K_RIGHT:
self.x_change = 10
elif event.key == pygame.K_UP:
self.y_change = -10
elif event.key == pygame.K_DOWN:
self.y_change = 10
self.x += self.x_change
self.y += self.y_change
self.win.fill((76, 66, 53))
pygame.draw.rect(self.win, (145, 255, 51), (self.x, self.y, self.width, self.height))
pygame.display.update()
self.clock.tick(3)
pygame.quit()
p1 = Snake()
p1.gameLoop()
You can reset the change for the other axis back to 0. This way only one direction is changed per key press
def gameLoop(self):
while self.run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.x_change = -10
self.y_change = 0
elif event.key == pygame.K_RIGHT:
self.x_change = 10
self.y_change = 0
elif event.key == pygame.K_UP:
self.y_change = -10
self.x_change = 0
elif event.key == pygame.K_DOWN:
self.y_change = 10
self.x_change = 0
self.x += self.x_change
self.y += self.y_change
self.win.fill((76, 66, 53))
pygame.draw.rect(self.win, (145, 255, 51), (self.x, self.y, self.width, self.height))
pygame.display.update()
self.clock.tick(3)
pygame.quit()
I've been at it for a while, and I cannot seem to figure out why my sprite is not moving up or down when the program is run.
Player Sprite Class
def __init__(self,name,x,y):
pygame.sprite.Sprite.__init__(self)
self.name = str(name)
self.speed = 5
self.image = pygame.image.load(name+'.png').convert_alpha()
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def move_up(self):
self.rect.y -= self.speed
def move_down(self):
self.rect.y += self.speed
def move_left(self):
self.rect.x -= self.speed
def move_right(self):
self.rect.x += self.speed
def update(self):
self.screen.blit(self.image,(self.rect))
Main File / Loop
class Console:
def __init__(self,width,height):
pygame.init()
self.w = width
self.h = height
self.clock = pygame.time.Clock()
self.screen = pygame.display.set_mode((self.w,self.h))
self.screenName = pygame.display.set_caption("Star's Labyrinth")
class Background(pygame.sprite.Sprite):
def __init__(self,image_file,x,y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def main():
gameExit = False
game_display = Console(1024,576)
game_display.screen
starboy = Player("starboy",200,200)
background = Background("background.png",0,0)
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
starboy.move_left()
elif event.key == pygame.K_d:
starboy.move_right()
elif event.type == pygame.K_w:
starboy.move_up()
elif event.type == pygame.K_s:
starboy.move_down()
print(pygame.event.get())
game_display.screen.blit(background.image,background.rect)
starboy.update
game_display.screen.blit(starboy.image,(starboy.rect.x,starboy.rect.y))
pygame.display.update()
game_display.clock.tick(30)
I have tried different types of commands trying to figure out whether it's a variable or function problem. Also is there a way I can make it move without having to tap the key.
In the event loop you're checking if the event.type is pygame.K_w or pygame.K_s, but you have to check if the event.key is equal to these constants. Change
elif event.type == pygame.K_w:
starboy.move_up()
elif event.type == pygame.K_s:
starboy.move_down()
to:
elif event.key == pygame.K_w:
starboy.move_up()
elif event.key == pygame.K_s:
starboy.move_down()
You also forgot the parentheses behind starboy.update.
I'm trying to move a single image around the screen in Pygame using methods controlled by the keyboard, but it appears to be creating duplicates in those positions instead of moving the original image. Why is this happening, given that the image is created before entering the main loop?
Here is my code:
import pygame, sys
from pygame.locals import *
pygame.init()
FPS = 30
fpsClock = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((600, 500), 0, 32)
pygame.display.set_caption('Animation')
posx = 10
posy = 10
class Hero():
def __init__(self):
self.x = posx
self.y = posy
def appearance(self):
return pygame.image.load('C:\\Users\\admin\\Desktop\\right.png')
def move_right(self):
self.x += 25
return self.x
def move_left(self):
self.x -= 25
return self.x
def move_up(self):
self.y -= 25
return self.y
def move_down(self):
self.y += 25
return self.y
new_hero = Hero() #create a Hero
item = new_hero.appearance() #create one reference
while True:
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:
posx = new_hero.move_left()
elif event.key == pygame.K_RIGHT:
posx = new_hero.move_right()
elif event.key == pygame.K_UP:
posy = new_hero.move_up()
elif event.key == pygame.K_DOWN:
posy = new_hero.move_down()
DISPLAYSURF.blit(item, (posx, posy))
pygame.display.update()
fpsClock.tick(FPS)
You forgot to put in code to delete all the past images.
This is the basic layout of a pygame project. You should ALWAYS (if you do not have a background image) fill the screen with white after updating.
white = 255, 255, 255
while True:
DISPLAYSURF.fill(white)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
pygame.display.update()
import pygame
pygame.init()
window = pygame.display.set_mode((800,600))
pygame.display.set_caption("TEST2")
black=(0,0,0)
white=(255,255,255)
moveX,moveY=0,0
clock = pygame.time.Clock()
class Sprite:
def __init__(self,x,y):
self.x=x
self.y=y
self.width=100
self.height=110
self.i100 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite0.PNG")
self.i1 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite1.PNG")
self.i2 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite2.PNG")
self.i3 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite3.PNG")
self.i4 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite4.PNG")
self.i5 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite5.PNG")
self.i6 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite6.PNG")
self.i7 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite7.PNG")
self.i8 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite8.PNG")
self.i9 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite9.PNG")
self.i10 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite10.PNG")
self.i11 = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite11.PNG")
self.timeTarget=10
self.timeNum=0
self.currentImage=0
def update(self):
self.timeNum+=1
if(self.timeNum==self.timeTarget):
if (self.currentImage==0):
self.currentImage+=1
else:
self.currentImage=0
self.timeNum=0
self.render()
def render(self):
if (self.currentImage==0):
window.blit(self.i100, (self.x,self.y))
else:
window.blit(self.i1, (self.x,self.y))
window.blit(self.i2, (self.x,self.y))
window.blit(self.i3, (self.x,self.y))
player=Sprite(110,100)
gameLoop = True
while gameLoop:
for event in pygame.event.get():
if event.type==pygame.QUIT:
gameLoop = False
if (event.type==pygame.KEYDOWN):
if (event.key==pygame.K_LEFT):
moveX = -3
if (event.key==pygame.K_RIGHT):
moveX = 3
if (event.key==pygame.K_UP):
moveY = -3
if (event.key==pygame.K_DOWN):
moveY = 3
if (event.type==pygame.KEYUP):
if (event.key==pygame.K_LEFT):
moveX=0
if (event.key==pygame.K_RIGHT):
moveX=0
if (event.key==pygame.K_UP):
moveY=0
if (event.key==pygame.K_DOWN):
moveY=0
window.fill(black)
player.x+=moveX
player.x+=moveY
player.update()
clock.tick(50)
pygame.display.flip()
pygame.quit()
What im doing is trying to animate 11 photos into an animation with pygame. this code works but when I run it the pictures seem to almost overlap. I did window.blit for the first few images and put them under else? I feel like I rendered them wrong. also I must add im really bad at picking up what people are trying to say and best learn from examples. Thanks!
BTW: your code could look like this:
I use my images in example but there are still lines with your images.
I use timer to change images.
You can press space to pause and escape to exit.
etc.
import pygame
#----------------------------------------------------------------------
class Sprite:
def __init__(self, x, y, curren_time):
self.rect = pygame.Rect(x, y, 100, 110)
self.images = []
#for x in range(12):
for x in range(1,4):
img = pygame.image.load("ball" + str(x) +".png")
#img = pygame.image.load("C:/Users/Trevor/SkyDrive/Documents/TEST2.0/Sprite" + str(x) +".PNG")
self.images.append( img )
self.current_image = 0
self.time_num = 100 # miliseconds
self.time_target = curren_time + self.time_num
def update(self, curren_time):
if curren_time >= self.time_target:
self.time_target = curren_time + self.time_num
self.current_image += 1
if self.current_image == len(self.images):
self.current_image = 0
def render(self, window):
window.blit(self.images[self.current_image], self.rect)
#----------------------------------------------------------------------
# CONSTANS - uppercase
BLACK = (0 ,0 ,0 )
WHITE = (255,255,255)
#----------------------------------------------------------------------
# MAIN
def main():
pygame.init()
window = pygame.display.set_mode((800,600))
pygame.display.set_caption("TEST2")
move_x, move_y = 0, 0
clock = pygame.time.Clock()
curren_time = pygame.time.get_ticks()
player = Sprite(110,100, curren_time)
font = pygame.font.SysFont(None, 150)
pause_text = font.render("PAUSE", 1, WHITE)
pause_rect = pause_text.get_rect( center = window.get_rect().center ) # center text on screen
# mainloop
state_game = True
state_pause = False
while state_game:
curren_time = pygame.time.get_ticks()
# events
for event in pygame.event.get():
if event.type == pygame.QUIT:
state_game = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
state_game = False
elif event.key == pygame.K_SPACE:
state_pause = not state_pause
if event.key == pygame.K_LEFT:
move_x = -3
elif event.key == pygame.K_RIGHT:
move_x = 3
elif event.key == pygame.K_UP:
move_y = -3
elif event.key == pygame.K_DOWN:
move_y = 3
elif event.type == pygame.KEYUP:
if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
move_x = 0
elif event.key in (pygame.K_UP, pygame.K_DOWN):
move_y = 0
# moves
if not state_pause:
player.rect.x += move_x
player.rect.y += move_y
player.update(curren_time)
# draws
window.fill(BLACK)
player.render(window)
if state_pause:
window.blit(pause_text, pause_rect)
pygame.display.flip()
# FPS
clock.tick(50)
# the end
pygame.quit()
#----------------------------------------------------------------------
if __name__ == '__main__':
main()
ball1.png
ball2.png
ball3.png
By putting all those window.blit(...) calls one after another, you are drawing those three frames on top of each other. Even if your computer lagged for a second between each call, you still wouldn't see them individually because they all can't appear until pygame.display.flip() is called.
You should store the images in a list, and keep a counter like currentFrame that loops from 0 to number_of_frames-1 (or len(frames)-1). Then each frame of the game you do something like this:
class Player:
...
def draw(window):
window.blit(self.frames[self.currentFrame])