I do not understand why the button does not draw on the background it worked before
this does not show an error.
here is the code------>
is this code wrong ? is my problem even reproducible? it could be in the code for the button i would appreciate the help
import pygame
pygame.init()
screen = pygame.display.set_mode((3840,2160))
running = True
mouse = pygame.mouse.get_pos()
pygame.display.set_caption("GermanBall")
bg = pygame.image.load(r"C:\Users\tomarj\OneDrive - Tata Advanced Systems Limited\Desktop\War Crime\Tan.jpg")
icon = pygame.image.load(r"C:\Users\tomarj\OneDrive - Tata Advanced Systems Limited\Desktop\War Crime\box.png")
button1 = pygame.image.load(r"C:\Users\tomarj\OneDrive - Tata Advanced Systems Limited\Desktop\War Crime\shirt.png").convert_alpha()
class Button():
def __init__(self,x,y,image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
self.rect = self.image.get_rect()
self.rect.topleft = (x,y)
posmoose = pygame.mouse.get_pos()
if self.rect.collidepoint(posmoose):
if pygame.mouse.get_pressed()[0] == 1:
print("click")
def draw(self):
screen.blit(self.image,(self.rect.x,self.rect.y))
stat = Button(1550,700,button1,0.5)
pygame.display.set_icon(icon)
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.blit(bg,(0,0))
stat.draw()
pygame.display.update()
The indentation is wrong in your class: methods draw, intro, ... should be at the same level as __init__. But basically your class is useless since you're not creating any object of the class. You should have something like my_button = Button(...) in your code (and outside the class itself).
Also it is good practice to move your class at the top level.
So perhaps you should start from something like that:
import pygame
pygame.init()
screen = pygame.display.set_mode((3840,2160))
running = True
mouse = pygame.mouse.get_pos()
pygame.display.set_caption("GermanBall")
bg = pygame.image.load(r"C:\Users\tomarj\OneDrive - Tata Advanced Systems Limited\Desktop\War Crime\Tan.jpg")
icon = pygame.image.load(r"C:\Users\tomarj\OneDrive - Tata Advanced Systems Limited\Desktop\War Crime\box.png")
button1 = pygame.image.load(r"C:\Users\tomarj\OneDrive - Tata Advanced Systems Limited\Desktop\War Crime\shirt.png").convert_alpha()
pygame.display.set_icon(icon)
class Button():
def __init__(self,x,y,image, scale):
...
def draw(self):
...
def intro(self):
...
def game(self):
...
def manager():
...
my_button = Button(100, 200, button1, 1.0) # <- create a button
while running == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.blit(bg,(0,0))
my_button.draw() # <- draw the button
pygame.display.update()
Your draw function doesn't know what screen is. You should add an argument screen to your draw function, and pass the function call in the main loop the screen.
Related
I was following a pygame tutorial, tested to see if the player blit was working and it wasnt, checked for problems but there were none that I could find, and then I tested a .blit() directly in the game loop and that didnt work so I've been stumped for a good bit now.
player class below, "Player_Down" should be irrelevant rn since its just an image
class Player():
def __init__(self, x, y):
direction = "down"
self.image = player_down
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def draw(self):
screen.blit(self.image, self.rect)
ply = Player(SCREEN_WIDTH // 2 , SCREEN_HEIGHT - 150)
Game loop with draw function called
running = True
while running:
screen.fill((83,90,83))
ply.draw()
#event handler
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("Game quit via X button")
running = False
pygame.display.update()
There is no problem with the code in the question. Your suspicion that blit does not work is wrong (alos see How to draw images and sprites in pygame?). The code works fine.
However, I suggest passing the screen Surface as an argument to draw method. See the minimal and working example:
import pygame
pygame.init()
SCREEN_WIDTH, SCREEN_HEIGHT = 400, 400
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
player_down = pygame.Surface((30, 30))
player_down.fill((255, 0, 0))
class Player():
def __init__(self, x, y):
direction = "down"
self.image = player_down
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def draw(self, surf):
surf.blit(self.image, self.rect)
ply = Player(SCREEN_WIDTH // 2 , SCREEN_HEIGHT - 150)
running = True
while running:
#event handler
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("Game quit via X button")
running = False
screen.fill((83,90,83))
ply.draw(screen)
pygame.display.update()
pygame.quit()
exit()
For some reason, my return isn't working. This is from a tutorial. When I download the file and edit it from there it works, but if I copy and paste it from the exact file it doesn't work. Sorry, I am a beginner - open to any suggestions
The is the tutorial I used:
https://www.youtube.com/watch?v=G8MYGDf_9ho
Code:
import pygame
import sys
pygame.init()
WinHeight = 600
WinWidth = 900
Window = pygame.display.set_mode((WinWidth,WinHeight))
#button class
class Button():
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
def draw(self, surface):
action = False
#get mouse position
pos = pygame.mouse.get_pos()
#check mouseover and clicked conditions
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
#draw button on screen
surface.blit(self.image, (self.rect.x, self.rect.y))
return action
Good_ball_img = pygame.image.load("GoodBall.png")
Bad_ball_img = pygame.image.load("BadBall.png")
#Button instances
Good_ball = Button(100,100,Good_ball_img,2)
Bad_ball = Button(200,200,Bad_ball_img,3)
def drawwin():
Window.fill((202,241,208))
Good_ball.draw(Window)
Bad_ball.draw(Window)
pygame.display.update()
def Main():
run = True
while run:
if Good_ball.draw(Window):
print("green clicked")
if Bad_ball.draw(Window)=="t":
print("red clicked")
for event in pygame.event.get():
#quit game
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
drawwin()
checkpress()
if __name__ == "__main__":
Main()
Code works for me if I change order - first process all events later check mouse position.
Problema can be because PyGame updates values in pygame.mouse and pygame.key only if you run pygame.event.get() - so it may need pygame.event.get() or at least pygame.event.pump() before other functions.
for event in pygame.event.get():
#quit game
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
if Good_ball.draw(Window):
print("green clicked")
if Bad_ball.draw(Window):
print("red clicked")
EDIT:
In documentation for pygame.event there is
To get the state of various input devices, you can forego the event queue and
access the input devices directly with their appropriate modules: `pygame.mouse`,
`pygame.key` and `pygame.joystick`. If you use this method, remember
that pygame requires some form of communication with the system window manager
and other parts of the platform. To keep pygame in sync with the system,
you will need to call `pygame.event.pump()` to keep everything current.
Minimal working code - with surfaces instead images so everyone can simply copy and run it
import pygame
import sys
# --- constants --- # PEP8: `UPPER_CASE_NAMES`
WINDOW_WIDTH = 900
WINDOW_HEIGHT = 600
# --- classes --- # PEP8: `CamelCaseNames`
class Button():
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
def check_click(self):
action = False
# get mouse
pos = pygame.mouse.get_pos()
left_button = pygame.mouse.get_pressed()[0]
# check mouseover and clicked conditions
if left_button:
if self.rect.collidepoint(pos) and not self.clicked:
self.clicked = True
action = True
else:
self.clicked = False
return action
def draw(self, surface):
# draw button on screen
surface.blit(self.image, self.rect)
# --- functions --- # PEP8: `lower_case_names`
def draw_window(window):
window.fill((202, 241, 208))
good_ball.draw(window)
bad_ball.draw(window)
pygame.display.update()
# --- main ---
pygame.init()
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
# button class
#good_ball_img = pygame.image.load("GoodBall.png")
good_ball_img = pygame.Surface((100, 50))
good_ball_img.fill((0, 255, 0))
#bad_ball_img = pygame.image.load("BadBall.png")
bad_ball_img = pygame.Surface((100, 50))
bad_ball_img.fill((255,0,0))
# Button instances
good_ball = Button(100, 100, good_ball_img, 2) #
bad_ball = Button(200, 200, bad_ball_img, 3)
run = True
while run:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
# - checks and updates -
if good_ball.check_click():
print("green clicked")
if bad_ball.check_click():
print("red clicked")
#checkpress()
# - draws -
draw_window(window)
PEP 8 -- Style Guide for Python Code
So there you go, I wanted to experiment a little pygame but I find myself stuck.
Context
I created a small sprite (with Piskelapp) that represents the player and looks like:
player.png
then add my background in jpg format. However when launching the game, my sprite is cut by the background as follows:
The ship is not placed in front of the background and more I go up it, more it disappears behind the background...
Here is my code:
import pygame
pygame.init()
# class user
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.pv = 100
self.__max_health = 100
self.attack = 2
self.velocity = 5
self.image = pygame.image.load('assets/player.png')
self.rect = self.image.get_rect()
self.rect.x = 400
self.rect.y = 500
# open game window
pygame.display.set_caption("Rocket 'n' Rock")
screen = pygame.display.set_mode((1080, 720))
# background import
bg = pygame.image.load('assets/bg.jpg')
# load player
player = Player()
running = True
# game mainloop
while running:
# bg apply
screen.blit(bg, (0,-400))
# screen update
pygame.display.flip()
# player image apply
screen.blit(player.image, player.rect)
# if player close the window
for event in pygame.event.get():
# *close event
if event.type == pygame.QUIT:
running = False
pygame.quit()
print("close game")
anyone have a tip? I'm wondering if it's not a file format problem?
thank you for your time
In you game mainloop, you should put:
screen.blit(player.image, player.rect)
before:
pygame.display.flip()
I am trying to play my sound only once when my mouse is over the the green button but it doesn't seem to work — plays repeatedly.
mouseisover = True
if greenbutton2.isOver(pos):
window.blit(bls2,(0,0))
if mouseisover:
mouseover.play()
mouseisover = False
my whole game _intro code at the main loop for my game intro first I set a mouseisover variable and made it True then after in my main loop I said if thats True then play the sound then under it I said mouseisover = False but still it plays my sound again and again none stop
# start screen
def game_intro():
carsound = pygame.mixer.Sound("carsound1.wav") #
mouseisover = True
mouseover = pygame.mixer.Sound("lols (2).wav") # MOUSEOVERSOUND
class button():
def __init__(self, color, x,y,width,height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self,window,outline=None):
#Call this method to draw the button on the screen
if outline:
pygame.draw.rect(window, outline, (self.x-2,self.y-2,self.width+4,self.height+4),0)
pygame.draw.rect(window, self.color, (self.x,self.y,self.width,self.height),0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 60)
text = font.render(self.text, 1, (0,0,0))
window.blit(text, (self.x + (self.width/2 - text.get_width()/2), self.y + (self.height/2 - text.get_height()/2)))
def isOver(self, pos):
#Pos is the mouse position or a tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
white = (250,250,250)
greenbutton = button((0,255,0),60,449,200,80, 'Click Me )')
greenbutton2 = button((0,255,0),50,518,200,80, 'Click Me )')
greenbutton3 = button((0,255,0),50,600,200,70, 'Click Me )')
bls2 = pygame.image.load("about2.png")
bls3 = pygame.image.load("credits25.png")
bls4 = pygame.image.load("playgame1.png")
def fade(width, height):
fade = pygame.Surface((width, height))
fade.fill((0,0,0))
for alpha in range(0, 100):
fade.set_alpha(alpha)
window.blit(fade, (0,0))
pygame.display.update()
pygame.time.delay(15)
def redraw():
bls = pygame.image.load("bgs.png")
window.blit(bls,(0,0))
# this makes it
snow_list=[]
no_of_circles=100;
clock = pygame.time.Clock()
FPS = 60
clock.tick(FPS)
for i in range(no_of_circles):
x = random.randrange(0, 800)
y = random.randrange(0, 700)
snow_list.append([x,y])
red = (200,0,0)
green = (255,250,250)
bright_red = (255,250,0)
bright_green = (0,255,0)
clock = pygame.time.Clock()
intro = True
while intro:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
intro = False
pygame.quit()
redraw()
pos = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONDOWN:
if greenbutton.isOver(pos):
fade(800,800)
main_loop()
pos = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONDOWN:
if greenbutton2.isOver(pos):
window.blit(bls2,(0,0))
fade(800,800)
menu()
if greenbutton2.isOver(pos):
window.blit(bls2,(0,0))
if mouseisover:
mouseover.play()
mouseisover = False
if greenbutton3.isOver(pos):
mouseover.play()
window.blit(bls3,(0,0))
if greenbutton.isOver(pos):
mouseover.play()
window.blit(bls4,(0,0))
pos = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONDOWN:
if greenbutton3.isOver(pos):
fade(800,800)
creditss()
# GAME INTRO IMAGE
for point in snow_list:
point[1]+=1
pygame.draw.circle(window, (255,255,255), point, 2)
if(point[1] >= 600):
point[0] = random.randrange(0, 600)
point[1] = random.randrange(-10, -5)
clock.tick(FPS)
partics()
pygame.display.update()
It is difficult to answer without any more context, but my best guess is that this code is located in a loop.
This would mean that every time the loop runs, the variable mouseisover is assigned the value True, discarding the previous value.
Assuming this is your case you want to initialize your variable outside of the loop.
what your code looks like right now
while (loop):
mouseisover = True
if greenbutton2.isOver(pos):
window.blit(bls2,(0,0))
if mouseisover:
mouseover.play()
mouseisover = False
what you should do
mouseisover = True
while (loop):
if greenbutton2.isOver(pos):
window.blit(bls2,(0,0))
if mouseisover:
mouseover.play()
mouseisover = False
This, however, means that the sound will play only once and never again.
Update :
You can add a method like this to your button class :
def playSoundIfMouseIsOver(self, pos, sound):
if self.isOver(pos):
if not self.over:
sound.play()
self.over = True
else:
self.over = False
and then to make them beep simply call playSoundIfMouseIsOver with the position of the mouse and the sound you want to play
greenbutton2.playSoundIfMouseIsOver(pos, mouseover)
greenbutton3.playSoundIfMouseIsOver(pos, mouseover)
greenbutton.playSoundIfMouseIsOver(pos, mouseover)
This simply remembers the last value of isOver, and if it changes from False to True, it plays a sound.
These changes will require you to change every if that handled playing a sound with the new method
If you have more buttons you could place all your buttons inside a list and then iterate on the list to do the same action for every button
Creating the list (place this after creating the different buttons):
myButtonList = [greenbutton, greenbutton2, greenbutton3]
Iterating on that list (replaces the three similar lines) :
for myButton in myButtonList:
myButton.playSoundIfMouseIsOver(pos, mouseover)
Also, I saw some weird stuff in your code, you have 4 button classes that are the exact same. You can define the button class a single time by simply placing it at the very beginning of the program, outside of any loop.
If you place your class definitions inside loops, they will only be accessible inside that loop!
I am trying to resize my game from a menu but I am stuck. I am trying to scale the size of the screen the menu has to be when I click on new game. Does anyone have an idea on how to fix this since I cant find anything else.
import pygame
import runpy
import webbrowser, os
from Game import *
pygame.init()
class Option:
hovered = False
def __init__(self, text, pos):
self.text = text
self.pos = pos
self.set_rect()
self.draw()
def draw(self):
self.set_rend()
screen.blit(self.rend, self.rect,)
def set_rend(self):
self.rend = menu_font.render(self.text, True, self.get_color())
def get_color(self):
if self.hovered:
return (255,255,255)
else:
return (100,100,100)
def set_rect(self):
self.set_rend()
self.rect = self.rend.get_rect()
self.rect.topleft = self.pos
def onSelect(self):
if self.text == "Quit":
pygame.quit()
quit()
if self.text == "Instructions":
webbrowser.open_new("file://" + os.path.realpath("Manual.pdf"))
**if self.text == "New game":
Main()**
class Background(pygame.sprite.Sprite):
def __init__(self, image_file,):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
pygame.init()
pygame.mixer.music.load('Really Slow Motion - Fjord Keeper (Epic Intense Uplifting).mp3')
pygame.mixer.music.play(-1)
BackGround = Background('bg.png')
screen = pygame.display.set_mode((480, 320))
menu_font = pygame.font.Font(None, 40)
options = [Option("New game", (2, 195)), Option("Instructions", (2, 245)),
Option("Quit", (2, 295))]
while True:
pygame.event.pump()
screen.fill((0, 0, 0))
screen.blit(BackGround.image, BackGround.rect)
ev = pygame.event.get()
for event in ev:
if event.type == pygame.QUIT:
pygame.quit()
for option in options:
if option.rect.collidepoint(pygame.mouse.get_pos()):
option.hovered = True
else:
option.hovered = False
if option.hovered:
for event in ev:
if event.type == pygame.MOUSEBUTTONDOWN:
option.onSelect()
option.draw()
pygame.display.update()
This is my menu so far, but I'm trying to scale it so it will be 1300x1000.
I'm on mobile and I don't know how to do the code thing so I'll just type it out, k? K....
screen = pygame.display.set_mode((1300, 1300))
Put this where you want it to change. So lets say you put it as the f key. Then when you press f it should change the screen res to the set_mode.
just reset the display:
screen=pg.display.set_mode((1300,1000))
If you put this wherever you want the screen size to change, it'll work :)