I want to view my blit() however once i add the line self.screen_dim.fill([255, 255, 255])
pygame.display.update() it overlaps
def __init__(self):
self.width = 500
self.height = 500
self.screen_dim = pygame.display.set_mode((self.width, self.height))
self.mole = pygame.image.load("mole.png")
self.mole_hit = pygame.image.load("mole-hit.png")
I am confused on how to get my pygame screen the images within that function is working however it overlaps if i added a new background color
def start(self):
stat = True
num_display = 1
x_array = []
y_array = []
for i in self.mole_pos:
x_array.append(i[0])
y_array.append(i[1])
while stat:
Rand_Pos = random.randint(0, 8)
if num_display == 1:
self.screen_dim.blit(self.mole, (x_array[Rand_Pos], y_array[Rand_Pos]))
for Event in pygame.event.get():
if Event.type == pygame.QUIT:
stat = False
if self.mouse_clicked(mouse.get_pos(), self.mole_pos[Rand_Pos]):
num_display = 0
self.screen_dim.blit(self.mole_hit, (x_array[Rand_Pos], y_array[Rand_Pos]))
continue
pygame.display.flip()
This ahs nothing to to with class. It is just a matter of Indentation. You have to draw self.mole_hit in the application loop rather than the event loop:
def start(self):
# [...]
while stat:
# [...]
for Event in pygame.event.get():
if Event.type == pygame.QUIT:
stat = False
#<--| INDENTATION
if self.mouse_clicked(mouse.get_pos(), self.mole_pos[Rand_Pos]):
num_display = 0
self.screen_dim.blit(self.mole_hit, (x_array[Rand_Pos], y_array[Rand_Pos]))
pygame.display.flip()
Related
I've been trying to make a Chrome Dino Game, however, I'm struggling with this problem:
On every frame, it should draw a new one at the new position and delete the previous one to make it look as if it's moving. HOWEVER, it remains at its previous position and a new image appears on its next position. I did write the pygame.display.update() code at the end of my maintop.
In the last time I ran into a similar problem, I managed to make it work by drawing a background image, but this time, it doesn't work.
following are my codes:
import pygame
import os
from random import randint
import schedule
pygame.init()
assets = os.path.join(os.path.dirname(__file__), "Assets")
screen_size = (screen_width, screen_height) = (1280, 720)
screen = pygame.display.set_mode(screen_size)
clock = pygame.time.Clock()
fps = 120
bg = pygame.image.load(os.path.join(assets, "IMG_15.png"))
ground = 700
running = True
spacebaridx = 0
gamestart = False
tick_on_start = 0
obs1 = pygame.image.load(os.path.join(assets, "colourmat/light_green.png"))
pygame.transform.scale(obs1, (100, 200))
obs2 = pygame.image.load(os.path.join(assets, "colourmat/light_green.png"))
pygame.transform.scale(obs2, (120, 200))
obs3 = pygame.image.load(os.path.join(assets, "colourmat/light_green.png"))
pygame.transform.scale(obs3, (150, 200))
ls_obs = []
def create_obs():
k = randint(1, 3)
if k == 1:
info = {"type":1, "img":obs1, "x":screen_width, "y":ground - 200, "tox":2}
ls_obs.append(info)
if k == 2:
info = {"type":2, "img":obs2, "x":screen_width, "y":ground - 200, "tox":2}
ls_obs.append(info)
else:
info = {"type":3, "img":obs3, "x":screen_width, "y":ground - 200, "tox":2}
ls_obs.append(info)
schedule.every(3).seconds.do(create_obs)
while running:
dt = clock.tick(fps)
if gamestart == True:
game_ticks = pygame.time.get_ticks() - tick_on_start
schedule.run_pending()
else:
game_ticks = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT: running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
if spacebaridx == 0: # Press space to start / to tell whether it's the first press
spacebaridx += 1
gamestart = True
tick_on_start = pygame.time.get_ticks()
else:
pass # Jump
for o in ls_obs:
o["x"] += o["tox"] * -1
screen.blit(bg, (0, 0))
for o in ls_obs:
screen.blit(o["img"], (o["x"], o["y"]))
pygame.display.update()
pygame.quit()
This issue is occurring because you aren't clearing the display within each frame. In pygame, in order to clear the display, we need to use the fill method. So in your code, at the top of your game loop before the event loop, add screen.fill((0, 0, 0)). This will fill your screen in the color black. Don't worry, the black won't be shown if you draw the background on top of it. Now, when you add a new image, the previous images won’t be displayed.
Modified Game Loop
while running:
screen.fill((0, 0, 0))
dt = clock.tick(fps)
if gamestart == True:
game_ticks = pygame.time.get_ticks() - tick_on_start
schedule.run_pending()
else:
game_ticks = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT: running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
if spacebaridx == 0: # Press space to start / to tell whether it's the first press
spacebaridx += 1
gamestart = True
tick_on_start = pygame.time.get_ticks()
else:
pass # Jump
for o in ls_obs:
o["x"] += o["tox"] * -1
screen.blit(bg, (0, 0))
for o in ls_obs:
screen.blit(o["img"], (o["x"], o["y"]))
pygame.display.update()
pygame.quit()
So apparently pygame.time.set_timer() doesn't work when used inside a class and I just can make it behave as a timer. Inside a class it will be called every frame
import pygame
pygame.init()
screen = pygame.display.set_mode((100, 100))
FPS = 60
clock = pygame.time.Clock()
class Bird():
def __init__(self):
self.count = 1
self.count_timer = pygame.USEREVENT + 1
pygame.time.set_timer(self.count_timer, 1000)
def go(self):
if event.type == self.count_timer:
print(self.count)
self.count += 1
b = Bird()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
b.go()
pygame.display.update()
clock.tick(FPS)
pygame.quit()
If the timer is outside of a class it works as expected and will be called once per second
import pygame
pygame.init()
screen = pygame.display.set_mode((100, 100))
FPS = 60
clock = pygame.time.Clock()
count = 1
count_timer = pygame.USEREVENT + 1
pygame.time.set_timer(count_timer, 1000)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == count_timer:
print(count)
count += 1
pygame.display.update()
clock.tick(FPS)
pygame.quit()
Can anyone explain what needs to be done to make it work inside of a class? Thank you
This has nothing to do with set_timer. However, you have to call the go method in the event loop for each event:
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
b.go() # <--- INSTERT
# b.go() <--- DELETE
I recommend passing the event object as an argument to the method:
class Bird():
# [...]
def go(self, e):
if e.type == self.count_timer:
print(self.count)
self.count += 1
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
b.go(event)
# [...]
Or pass the full list of events to the method:
import pygame
pygame.init()
screen = pygame.display.set_mode((100, 100))
FPS = 60
clock = pygame.time.Clock()
class Bird():
def __init__(self):
self.count = 1
self.count_timer = pygame.USEREVENT + 1
pygame.time.set_timer(self.count_timer, 1000)
def go(self, event_list):
if self.count_timer in [e.type for e in event_list]:
print(self.count)
self.count += 1
b = Bird()
running = True
while running:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
running = False#
b.go(event_list)
pygame.display.update()
clock.tick(FPS)
pygame.quit()
I am making a match-3 style game. I am a beginner with pygame and have managed to randomly generate a board so that each playthrough is different. My only issue at the moment is my tiles seem to be continuously cycling through the list I created for each image. I tried adding a for loop to delete each element as it is being generated but nothing I seem to change is working. Could anybody help? You can find the images I used in a google drive! I appreciate anything!
GoogleDrive
import pygame
from pygame.locals import *
import math
import time
import sys
import random
pygame.init()
# game variables
display_h = 900
display_w = 750
game_row = 12
game_column = 10
background_img = pygame.image.load('pink_background_resized.png')
clock = pygame.time.Clock()
running = True
# build screen and window name
screen = pygame.display.set_mode((display_w, display_h))
pygame.display.set_caption("Jelliez")
screen.fill((255,255,255))
class Tile():
# initialize tiles
def __init__(self, x, y, image, clicked):
self.image = image
self.rect = self.image.get_rect()
self.rect.topleft = (x,y)
self.clicked = clicked
def draw(self):
action = False
# get mouse position
pos = pygame.mouse.get_pos()
# check mouse over and clicked psotion
if self.rect.collidepoint(pos):
if (pygame.mouse.get_pressed()[0] == 1) and (self.clicked == False):
self.clicked = True
action = True
if pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
screen.blit(self.image, (self.rect.x, self.rect.y))
return action
def generateBoard():
screen.blit(background_img, (0,0))
return [[image_list[random.randrange(0, len(image_list))] for i in range (game_column)] for x in range(game_row)]
def showBoard(board):
screen.blit(background_img, (0,0))
rowNum = 0
for row in board:
columnNum = 0
for shape in row:
screen.blit(shape, (70 * columnNum, 64 * rowNum ))
columnNum += 1
rowNum += 1
# add game images
blue_jelly_img = pygame.image.load('blue_jelly.png').convert_alpha()
gray_jelly_img = pygame.image.load('gray_jelly.png').convert_alpha()
green_jelly_img = pygame.image.load('green_jelly.png').convert_alpha()
pink_jelly_img = pygame.image.load('pink_jelly.png').convert_alpha()
red_jelly_img = pygame.image.load('red_jelly.png').convert_alpha()
yellow_jelly_img = pygame.image.load('yellow_jelly.png').convert_alpha()
# create tile istances
blue_jelly = Tile(100, 231, blue_jelly_img, False)
gray_jelly = Tile(100, 231, gray_jelly_img, False)
green_jelly = Tile(100, 231, green_jelly_img, False)
pink_jelly = Tile(100, 231, pink_jelly_img, False)
red_jelly = Tile(100, 231, red_jelly_img, False)
yellow_jelly = Tile(100, 231, yellow_jelly_img, False)
image_list = [blue_jelly_img, gray_jelly_img, green_jelly_img, pink_jelly_img, red_jelly_img, yellow_jelly_img]
for x in range(len(image_list) - 6):
del(image_list[0])
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
gameBoard = generateBoard()
showBoard(gameBoard)
pygame.display.update()
pygame.quit()
The problem is that the board is recreated every frame.
Generate the board once before the application loop. Clear the display and show the board in the application loop:
gameBoard = generateBoard()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.blit(background_img, (0,0))
showBoard(gameBoard)
pygame.display.update()
pygame.quit()
I was following this tutorial on how to make a typing speed calculator using pygame and whenever I run the code everything renders out as it should but when I try clicking on the text field to input some text it just freezes and nothing happens. I tried to search online or watch tutorials but everything came up empty.
import sys
import time
import random
import pygame
from pygame.locals import *
"""Python Script for a typing speed test game"""
class Game(object):
def __init__(self):
self.h = 720
self.w = 1280
self.reset = True
self.active = False
self.word = ""
self.input_text = ""
self.time_start = 0
self.total_time = 0
self.accuracy = "0%"
self.wpm = 0
self.results = "Speed(WPM):0 Accuracy:0% Time:0"
self.end = False
self.head_col = (255,213,102)
self.text_col = (255,255,255)
self.result_color = (53,209,29)
pygame.init()
self.open_image = pygame.image.load("splash.jpg")
self.open_image = pygame.transform.scale(self.open_image, (self.w,self.h))
self.background = pygame.image.load("background.jpg")
self.background = pygame.transform.scale(self.background, (self.w, self.h))
self.screen = pygame.display.set_mode((self.w,self.h))
pygame.display.set_caption = "Type Speed Test"
def draw_text(self, screen, msg, y, fsize, color):
font = pygame.font.SysFont("consolas", fsize)
text = font.render(msg, 1, color)
text_rect = text.get_rect(center=(self.w/2, y))
screen.blit(text, text_rect)
pygame.display.update()
def get_sentences(self):
f = open("sentences.txt").read()
sentence = f.split("\n")
sentences = random.choice(sentence)
return sentences
def show_results(self, screen):
if(not self.end):
#Calculate Time
self.total_time = time.Time() - self.time_start
#Calcualte Accuracy
count = 0
for i,c in enumarate(self.word):
try:
if self.input_text[i] == c:
count += 1
except:
pass
self.accuracy = count/len(self.word)*100
#Calculate wpm
self.wpm = len(self.input_text)*60/(5*self.total_time)
self.end = True
print(self.total_time)
self.results = "Time:" + str(round(self.total_time))
+ " secs Accuracy: " + str(round(self.accuracy)) + "%"
+ " WPM: " + str(round(self.wpm))
#restart icon
self.time_img = pygame.image.load("icon.png")
self.time_img = pygame.transform.scale(self.time_img, (80,320))
#screen.blit(self.time_img, (80,320))
screen.blit(self.time_img, (self.w/2-75, self.h-140))
self.draw_text(screen, "Reset", self/h - 70, 26, (100,100,100))
print(self.results)
pygame.display.update()
def run(self):
self.reset_game()
self.running=True
while(self.running):
clock = pygame.time.Clock()
self.screen.fill((0,0,0), (50,250,650,50))
pygame.draw.rect(self.screen,self.head_col, (50,250,650,50), 2)
# update the text of user input
self.draw_text(self.screen, self.input_text, 274, 26,(250,250,250))
pygame.display.update()
for event in pygame.event.get():
if event.type == QUIT:
self.running = False
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP:
x,y = pygame.mouse.get_pos()
# position of input box
if(x>=50 and x<=650 and y>=250 and y<=300):
self.active = True
self.input_text = ''
self.time_start = time.time()
# position of reset box
if(x>=310 and x<=510 and y>=390 and self.end):
self.reset_game()
x,y = pygame.mouse.get_pos()
elif event.type == pygame.KEYDOWN:
if self.active and not self.end:
if event.key == pygame.K_RETURN:
print(self.input_text)
self.show_results(self.screen)
print(self.results)
self.draw_text(self.screen, self.results,350, 28, self.RESULT_C)
self.end = True
elif event.key == pygame.K_BACKSPACE:
self.input_text = self.input_text[:-1]
else:
try:
self.input_text += event.unicode
except:
pass
pygame.display.update()
clock.tick(60)
def reset_game(self):
self.screen.blit(self.open_image, (0,0))
pygame.display.update()
time.sleep(1)
self.reset=False
self.end = False
self.input_text=''
self.word = ''
self.time_start = 0
self.total_time = 0
self.wpm = 0
# Get random sentence
self.word = self.get_sentences()
if (not self.word): self.reset_game()
#drawing heading
self.screen.fill((0,0,0))
self.screen.blit(self.background,(0,0))
msg = "Typing Speed Test"
self.draw_text(self.screen, msg,80, 80,self.head_col)
# draw the rectangle for input box
pygame.draw.rect(self.screen,(255,192,25), (50,250,650,50), 2)
# draw the sentence string
self.draw_text(self.screen, self.word,200, 28,self.text_col)
pygame.display.update()
Game().run()
How can this be fixed?
Your never handeling KEYDOWN Events. because the else if statement is indented to far.
You should change the following.
class Game(object):
...
def run(self):
...
while(self.running):
...
for event in pygame.event.get():
if event.type == QUIT:
...
elif event.type == pygame.MOUSEBUTTONUP:
...
elif event.type == pygame.KEYDOWN:
...
in to this:
class Game(object):
...
def run(self):
...
while(self.running):
...
for event in pygame.event.get():
if event.type == QUIT:
...
elif event.type == pygame.MOUSEBUTTONUP:
...
elif event.type == pygame.KEYDOWN:
...
In Game.reset_game you recusively call Game.reset_game() with no exit.
Remove the call to self.reset_game so the game can be reset.
You also sleep for 1 second in reset_game without listening to events. This will make the pygame window seem inresponsive.
And it lets the process take 1000 seconds or ~ 17 minutes before the RecursionError is triggerd from recursively calling reset_game. Rather then seconds.
I am trying to animate a wizard walking to the left when holding down the left arrow key and walking to the right when holding down the right arrow key. The problem: I don't know how to assign a variable to the whole class.
Here is the error:
Traceback (most recent call last):
File "C:\Python27\Wizard Game\wizard game", line 18, in <module>
class player_standing_right(object):
File "C:\Python27\Wizard Game\wizard game", line 61, in player_standing_right
screen.blit(player_spr, player_rect)
NameError: name 'player_spr' is not defined
Here is my code:
import sys, pygame
pygame.init()
size = (640, 480)
screen = pygame.display.set_mode(size)
gamerunning = True
def load_image(name):
image = pygame.image.load(name)
return image
clock = pygame.time.Clock()
while gamerunning == True:
white = (255, 255, 255)
clock.tick(30)
screen.fill(white)
class player_standing_right(object):
def __init__(self):
self.player_spr = player_spr
player_spr = load_image("wizard right 0.bmp")
x = 0
player_right = [load_image("wizard right 0.bmp"), load_image("wizard right 1.bmp"), load_image("wizard right 0.bmp")]
player_left = [load_image("wizard left 0.bmp"), load_image("wizard left 1.bmp"), load_image("wizard left 0.bmp")]
def key_press(keypressed):
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == keypressed:
return True
def key_release(keyreleased):
for event in pygame.event.get():
if event.type == pygame.KEYUP:
if event.key == keyreleased:
return True
if key_press(pygame.K_LEFT):
player_spr = player_left[x]
while key_press(pygame.K_LEFT):
player_rect = player_rect.move(-1, 0)
x += 1
if x == len(player_left):
x = 0
player_spr = player_left[x]
if key_press(pygame.K_RIGHT):
player_spr = player_right[x]
while key_press(pygame.K_RIGHT):
player_rect = player_rect.move(1, 0)
x += 1
if x == len(player_right):
x = 0
player_spr = player_right[x]
screen.blit(player_spr, player_rect)
pygame.display.flip()
You assigned player_spr when key is left and right, but you didn't assign it on "idle" state. When you're starting game you're not pressing any key, thus sprite is not assigned. You did it before class definition. You can try to put it inside. Also I'm not an expert but I would define class outside the actual main loop.
#TRY USING THIS METHOD
class AnimationClass():
def __init__(self):
self.x = 0
self.y = 0
self.frame_count = 0
self.image_list = []
def update(self):
self.frame_count += 1
for num in range(1,5): # SET THE NUM OF FRAMES
image = pygame.image.load(f"YOURE IMAGE FILE{num}.png") # loading youre image file
self.image_list.append(image) # appending youre image file
window.blit(self.image_list[int(self.frame_count)],(self.x , self.y)) # rendering youre image
animation = AnimationClass()
Loop = True
while Loop == True:
for event in pygame.event.get():
if event.type == pg.QUIT:
Loop = False
animation.update() # CALLING THE UPDATE IN LOOP
pygame.display.update()