Can any one see what I did wrong, please? I want the block to jump but it doesnt work properly. This is my first python project so please try to explain what I did wrong so I dont do it again, thanks.
import pygame
pygame.init()
bg = pygame.image.load('bg.jpg')
class Player():
def __init__(self, x, y, height, width):
self.x = x
self.y = y
self.height = height
self.width = width
self.Jumpcount = 10
self.Isjump = False
def draw(self, window):
pygame.draw.rect(window, (255, 0, 0), (self.x, self.y, self.width, self.height))
pygame.draw.rect(window, (0, 255, 0), (self.x, self.y, self.width / 2, self.height / 2))
pygame.draw.rect(window, (0, 255, 0), (self.x + self.width / 2, self.y + self.height / 2, self.width / 2, self.height / 2))
pygame.draw.rect(window, (139, 26, 26), (0, 400 + self.height, 500, 500 - self.height))
def Jump(self, Jumping):
if Jumping:
self.Isjump = True
if self.Isjump:
if self.Jumpcount >= -10:
neg = 1
if self.Jumpcount < 0:
neg = -1
self. y = self.Jumpcount**2 * 0.25 * neg
self.Jumpcount -= 1
else:
self.Isjump = False
self.Jumpcount = 10
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption('Test')
Jumping = False
run = True
man = Player(70, 400, 40, 40)
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
print('123')
Jumping = True
man.Jump(Jumping)
win.blit(bg, (0, 0))
man.draw(win)
pygame.display.update()
pygame.quit()
There is no error message but when I press space it doesnt do anything.
Remove the second pygame.event.get() loop. The first loop is consuming all the events, but checks only the QUIT event and does nothing for other events. The second loop is likely empty. Do all the event checks in the first loop.
You want to have only one event loop each iteration of the main loop.
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
print('123')
Jumping = True
man.Jump(Jumping)
I think your problem lies in having two for loops event in pygame.event.get()
To fix this you just want to have the two if statements under one for loop like so:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
print('123')
Jumping = True
man.Jump(Jumping)
that should fix your problem.
Related
I want to be able to drag the blue object along the x-axis (black line) using mouse so that it does not move in y-direction. When I try to drag it, nothing happens. Where is the problem?
import pygame
def initialize():
pygame.init()
global height, width
height = 600
width = 900
screen = pygame.display.set_mode((width, height))
screen.fill((255, 255, 255))
pygame.draw.line(screen, (0, 0 ,0), (0, height / 2), (width, height / 2), 3)
return screen
def object():
dragging = False
object_1 = pygame.rect.Rect(width / 4, height / 2 - 75, 50, 150)
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if object_1.collidepoint(event.pos):
dragging = True
mouse_x, mouse_y = event.pos
offset_x = object_1.x - mouse_x
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
dragging = False
elif event.type == pygame.MOUSEMOTION:
if dragging:
mouse_x, mouse_y = event.pos
object_1.x = mouse_x + offset_x
return object_1
if __name__ == "__main__":
running = True
screen = initialize()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
object_1 = object()
pygame.draw.rect(screen, (0, 0, 250), object_1)
pygame.display.update()
You have to create the object once before the main application loop and you have to handle the events in the application loop.
Furthermore you have to redraw the entire scene in the application loop. The main application loop has to:
handle the events by either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by either pygame.display.update() or pygame.display.flip()
Add a function which creates an object:
def create_object():
object_1 = pygame.rect.Rect(width / 4, height / 2 - 75, 50, 150)
return object_1
Create an object before the application loop:
if __name__ == "__main__":
# [...]
object_1 = create_object()
while running:
# [...]
Add a function which can drag an object:
dragging = False
def drag_object(events, object_1):
global dragging, offset_x
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if object_1.collidepoint(event.pos):
dragging = True
mouse_x, mouse_y = event.pos
offset_x = object_1.x - mouse_x
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
dragging = False
elif event.type == pygame.MOUSEMOTION:
if dragging:
mouse_x, mouse_y = event.pos
object_1.x = mouse_x + offset_x
Get the list of events once in the application loop and pass the events to the function drag_object:
while running:
# [...]
drag_object(events, object_1)
Clear the display, draw the scene and update the display in the application loop:
while running:
# [...]
screen.fill((255, 255, 255))
pygame.draw.line(screen, (0, 0 ,0), (0, height / 2), (width, height / 2), 3)
pygame.draw.rect(screen, (0, 0, 250), object_1)
pygame.display.update()
See the example:
import pygame
def initialize():
pygame.init()
global height, width
height = 600
width = 900
screen = pygame.display.set_mode((width, height))
return screen
def create_object():
object_1 = pygame.rect.Rect(width / 4, height / 2 - 75, 50, 150)
return object_1
dragging = False
def drag_object(events, object_1):
global dragging, offset_x
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if object_1.collidepoint(event.pos):
dragging = True
mouse_x, mouse_y = event.pos
offset_x = object_1.x - mouse_x
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
dragging = False
elif event.type == pygame.MOUSEMOTION:
if dragging:
mouse_x, mouse_y = event.pos
object_1.x = mouse_x + offset_x
if __name__ == "__main__":
running = True
screen = initialize()
object_1 = create_object()
while running:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
running = False
drag_object(events, object_1)
screen.fill((255, 255, 255))
pygame.draw.line(screen, (0, 0 ,0), (0, height / 2), (width, height / 2), 3)
pygame.draw.rect(screen, (0, 0, 250), object_1)
pygame.display.update()
Alternatively you can create a class for the object:
import pygame
def initialize():
pygame.init()
global height, width
height = 600
width = 900
screen = pygame.display.set_mode((width, height))
return screen
class MyObject:
def __init__(self):
self.rect = pygame.rect.Rect(width / 4, height / 2 - 75, 50, 150)
self.dragging = False
self.offset_x = 0
def drag(self, events):
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if self.rect.collidepoint(event.pos):
self.dragging = True
self.offset_x = self.rect.x - event.pos[0]
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
self.dragging = False
elif event.type == pygame.MOUSEMOTION:
if self.dragging:
self.rect.x = event.pos[0] + self.offset_x
def draw(self, surf):
pygame.draw.rect(surf, (0, 0, 250), object_1)
if __name__ == "__main__":
running = True
screen = initialize()
object_1 = MyObject()
while running:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
running = False
object_1.drag(events)
screen.fill((255, 255, 255))
pygame.draw.line(screen, (0, 0 ,0), (0, height / 2), (width, height / 2), 3)
object_1.draw(screen)
pygame.display.update()
i have a program in which a square is supposed to jump, then fall down. For some reason, the square is jumping but it doesn't fall down. I'm not sure what's the issue is, i hope you could help me fix it. jumping gif
Here i'm displaying the window while the game is being played
#DISPLAY WINDOW
def draw_window(square):
#SCREEEN
WIN.fill(black)
#OBJECTS
#LINE
pygame.draw.line(WIN, white, (0, 400), (900, 400), 10)
#SQUARE
square.draw()
pygame.display.update()
Here i'm defining a square class and it's methods including jumping
#SQUARE
class Square():
def __init__(self):
self.y = 295
self.vel = 10
def draw(self):
pygame.draw.rect(WIN, red, [50, self.y, 100, 100])
def jump(self, jumpCount):
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
self.y -= (jumpCount ** 2) * 0.05 * neg
jumpCount -= 1
else:
jump = False
jumpCount = 10
Here is the main game loop with all functions
def main():
jump = False
jumpCount = 10
square = Square()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#JUMPING
if event.type == pygame.KEYDOWN:
if not jump and event.key == pygame.K_SPACE:
jump = True
if jump:
square.jump(jumpCount)
draw_window(square)
pygame.quit()
Here are some modifications to your code:
In the class Square, draw method should pass in a pygame.Rect as a parameter of pygame.draw.rect.
The jump method of Square created local variable jump and jump_count, changes to these variables will not affect the variable in main(). So you have to return these values and update them in main()
Full Code:
import pygame
clock = pygame.time.Clock()
WIN = pygame.display.set_mode((800, 600))
red = (255, 0, 0)
white = (255, 255, 255)
black = (0, 0, 0)
FPS = 60
class Square():
def __init__(self):
self.y = 295
self.vel = 10
def draw(self):
pygame.draw.rect(WIN, red, pygame.Rect(50, self.y, 100, 100))
def jump(self, jumpCount):
jump = True
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
self.y -= (jumpCount ** 2) * 0.05 * neg
jumpCount -= 1
else:
jump = False
jumpCount = 10
return jump, jumpCount
#DISPLAY WINDOW
def draw_window(square):
#SCREEEN
WIN.fill(black)
#OBJECTS
#LINE
pygame.draw.line(WIN, white, (0, 400), (900, 400), 10)
#SQUARE
square.draw()
pygame.display.update()
def main():
jump = False
jumpCount = 10
square = Square()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#JUMPING
if event.type == pygame.KEYDOWN:
if not jump and event.key == pygame.K_SPACE:
jump = True
if jump:
jump, jumpCount = square.jump(jumpCount)
draw_window(square)
pygame.quit()
main()
Output:
I'm creating a class for pygame which will allow users to create textboxes for their game. My code doesn't reach the mousebuttondown part for some reason though. I'm attaching my whole code along with parts that I'm facing issues with.
it doesn't print done
def main(self, events, mousepos, id):
for event in events:
if event.type == pygame.QUIT:
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if self.rect(id, mousepos):
print("done")
keeps printing no
def rect(self, text_id, mousepos):
x, y, width, height = self.dict_all[text_id]
if ((x + width) > mousepos[0] > x) and ((y + height) > mousepos[1] > y):
print("yes")
return True
else:
print("no")
return False
whole code below, update was a method I was trying to make but didn't work for some reason.
import pygame
pygame.font.init()
class textBox:
def __init__(self, surface, id, color, width, height, x, y, antialias, maxtextlen):
self.surface = surface
self.id = id
self.color = color
self.width = width
self.height = height
self.x = x
self.y = y
self.antialias = antialias
self.maxtextlen = maxtextlen
self.text_list = []
self.text_list_keys = []
self.currentId = 0
self.click_check = False
self.font = pygame.font.SysFont('comicsans', 20)
self.dict_all = {}
pygame.draw.rect(self.surface, (self.color), (self.x, self.y, self.width, self.height))
# for i in self.text_list_keys:
# if self.id not in i:
# self.text_list_keys.append(self.id)
# self.text_list.append(tuple(self.id))
# else:
# self.nothing()
self.dict_all[self.id] = tuple((self.x, self.y, self.width, self.height))
def update(self, events, mousepos):
for event in events:
if event.type == pygame.QUIT:
exit()
if event.type == pygame.MOUSEBUTTONDOWN and ((self.x + self.width) > mousepos[0] > self.x) \
and ((self.y + self.height) > mousepos[1] > self.y):
print("reached: " + mousepos)
self.click_check = True
else:
self.click_check = False
if self.click_check:
print("1")
if event.type == pygame.KEYDOWN:
print("#")
if event.key == pygame.K_a:
print("reached")
new_t = ""
for j in range(len(self.text_list)):
t = (self.text_list[j][0]).index(self.getId(self.currentId))
new_t = t
self.text_list[new_t].append("a")
self.surface.blit(self.font.render(f'{self.text_list[new_t]}', self.antialias, (0, 0, 0)),
(self.x, self.y))
else:
print("this")
else:
pass
def rect(self, text_id, mousepos):
x, y, width, height = self.dict_all[text_id]
if ((x + width) > mousepos[0] > x) and ((y + height) > mousepos[1] > y):
print("yes")
return True
else:
print("no")
return False
def getId(self, text_id):
self.currentId = text_id
def nothing(self):
return False
def main(self, events, mousepos, id):
for event in events:
if event.type == pygame.QUIT:
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if self.rect(id, mousepos):
print("done")
test.py
import pygame
from pygame_textbox import textBox
pygame.init()
win_width = 500
win_height = 500
screen = pygame.display.set_mode((win_width, win_height))
pygame.display.set_caption("test")
run = True
while run:
mouse = pygame.mouse.get_pressed()
screen.fill((0, 0, 0))
events = pygame.event.get()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
exit()
a = textBox(screen, 1, (255, 255, 255), 100, 30, 100, 100, True, 20)
# a.getId(1)
a.rect(1, mouse)
a.main(events, mouse, 1)
pygame.display.update()
The 2nd argument to the method main has to be the mouse position rather than the mouse buttons:
run = True
while run:
# [...]
mouse_pos = pygame.mouse.get_pos()
a.main(events, mouse_pos, 1)
# [...]
While pygame.mouse.get_pressed() a sequence of booleans representing the state of all the mouse buttons, pygame.mouse.get_pos() returns the X and Y position of the mouse cursor.
Uhh sorry for the super vague title, I have no idea whats wrong with my code either.
if event.type == pygame.K_SPACE:
run= True
There appears to be a problem when running this line, like the code is shaded a different colour on my screen, and it doesn't change run to True
This problem seems to be fixed if i delete:
def mainmenu()
and just use a while loop, however, I think it gets pretty messy and am quite hesitant to delete that.
Furthermore, when I run the mainmenu() function, it takes quite a long time to load up, a problem which I haven't had thus far and I am unsure why or how to fix it.
import pygame
import time
import random
pygame.init()
window = pygame.display.set_mode((1000,700))
White=(255,255,255)
font = pygame.font.SysFont("comicsansms", 25)
#for easier counting of lives, score here starts from 1, just simply subtract 1 from whats displayed later
score = 1
clicks = 1
lives = 3
run=False
intro=True
def mainmenu():
while intro:
window.fill((0, 0, 0))
text = font.render("Press space to start!" , True, White)
window.blit(text, (500, 350))
for event in pygame.event.get():
if event.type == pygame.QUIT:
intro = False
pygame.quit()
quit()
if event.type == pygame.K_SPACE:
run= True
class Circle():
def __init__(self, color, x, y, radius, width):
self.color = color
self.x = x
self.y = y
self.radius = radius
self.width = width
def draw(self, win, outline=None):
pygame.draw.circle(win, self.color, (self.x, self.y), self.radius, self.width)
def isOver(self, mouse):
dx, dy = mouse[0] - self.x, mouse[1] - self.y
return (dx * dx + dy * dy) <= self.radius * self.radius
circles = []
def redrawWindow():
window.fill((0, 0, 0))
for c in circles:
c.draw(window)
text = font.render("Score:" + str(score-1), True, White)
window.blit(text, (0,0))
text = font.render("Lives:" + str(lives), True, White)
window.blit(text, (900, 0))
clock = pygame.time.Clock()
FPS = 60
x = str(pygame.time.get_ticks())
current_time = 0
next_circle_time = 0
while run:
delta_ms = clock.tick()
current_time += delta_ms
if current_time > next_circle_time:
next_circle_time = current_time + 1000 # 1000 milliseconds (1 second)
r = 20
new_circle = Circle((255, 255, 255), random.randint(r, 800-r), random.randint(r, 600-r), r, r)
circles.append(new_circle)
print()
redrawWindow()
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run=False
pygame.quit()
quit()
if event.type == pygame.MOUSEBUTTONDOWN:
clicks += 1
mouse = pygame.mouse.get_pos()
for circle in circles:
if circle.isOver(mouse):
score += 1
circles.pop(circles.index(circle))
lives= 3-(clicks-score)
pygame.display.update()
run is a variable in global namespace. If you want to write a variable in global namespace within a function, then you have to use the global statement, which means that the listed identifiers are to be interpreted as globals:
run=False
intro=True
def mainmenu():
global run, intro
while intro:
window.fill((0, 0, 0))
text = font.render("Press space to start!" , True, White)
window.blit(text, (500, 350))
for event in pygame.event.get():
if event.type == pygame.QUIT:
intro = False
pygame.quit()
quit()
if event.type == pygame.K_SPACE:
run = True
import pygame
from pygame.locals import *
class PlayerPaddle(object):
def __init__(self, screensize):
self.screensize = screensize
self.position_x = int(screensize[0]*0.5)
self.position_y = int(screensize[1]*0.8)
self.width = 10
self.height = 4
self.rect = pygame.Rect(self.position_x - (self.width*0.5),
self.position_y - (self.height*0.5),
self.width, self.height)
self.color = (100, 200, 200)
self.speed = 5
self.direction = 0
def update(self):
self.position_x += self.direction * self.speed
def render(self, screen):
pygame.draw.rect(screen, self.color, self.rect, 0)
pygame.draw.rect(screen, (0,0,0), self.rect, 1)
def main():
pygame.init()
screensize = (600, 700)
screen = pygame.display.set_mode(screensize)
clock = pygame.time.Clock()
player_paddle = PlayerPaddle(screensize)
running = True
while running:
clock.tick(64)
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_paddle.direction = 1
elif event.key == pygame.K_RIGHT:
player_paddle.direction = -1
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player_paddle.direction = 0
elif event.key == pygame.K_RIGHT:
player_paddle.direction = 0
player_paddle.update()
screen.fill((100, 100, 100))
player_paddle.render(screen)
pygame.display.flip()
pygame.quit()
main()
Sorry for long code.. But I'm getting so frustrated. Why am i getting "'PlayerPaddle' object has no attribute 'update'"
Error !?
For what i have been able to understand its my def update(self) function that is returning null or smth.. But how is that? Is it in my eventhandler that the error is? Is it updating the position wrong?
It looks like your indentation is off. Your methods update and render are indented inside the __init__ method. Move them out one indentation level.