i have this code:
un = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONUP:
x1, y1 = pygame.mouse.get_pos()
Player(PlayerX, PlayerY)
pygame.display.update()
i want to use the mouse x and the mouse y coordinates in both cases to see which one is bigger but i cant really use the coordinates since one of them always turns out undefined, how do i go about achieving this?
You can set a default position for the mouse, that corresponds to the slingshot being aimed foward. Make it like:
defx = 30 #Default x coordinate example
defy = 30 #Default y coordinate example
Then whenever you are comparing, you just get the difference just like you said.
But if you need to have the last mouse position, you can also make it like this:
lx, ly, x, y = 0, 0, 0, 0 #It's probably better to use two arrays here
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
lx, ly = x, y #This makes so that lx and ly are the last frame values of x and y
x, y = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONUP:
x1, y1 = pygame.mouse.get_pos()
This way you can use lx and ly as the last x and y values.
I didn't really understand what you wanted to do on the mouse up part, but you can do the same using lx1 and ly1.
What you are doing will not work because you cannot simultaneously have mouse up and mouse down. What you can do is store the mouse position once when it is pressed down. Lets call this heldDownMomentPosition. Then on a mousebuttonup event anytime after that, you can calculate the difference between heldDownMomentPosition and current mouse position. This will give you the direction in which the slingshot bullet needs to go. I used this mechanism in a game I made a while ago, here it is with some modifications to make it minimal. It has a simple drag to make it stop too.
import pygame
window = pygame.display.set_mode((600, 600))
slingShotBullet = pygame.Surface((40, 40)).convert()
slingShotBullet.fill((255, 255, 255))
pos = [300, 300]
vel = [0, 0]
clock = pygame.time.Clock()
heldDownMomentPosition = None
while True:
dt = clock.tick(60) * 0.001 #delta time in s
mousePressed = pygame.mouse.get_pressed()
mousePos = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
if heldDownMomentPosition is None:
if pygame.Rect(*pos, 40, 40).collidepoint(mousePos):
heldDownMomentPosition = pos[0] + 20, pos[1] + 20
if event.type == pygame.MOUSEBUTTONUP:
if heldDownMomentPosition is not None:
vel = [heldDownMomentPosition[0] - mousePos[0], heldDownMomentPosition[1] - mousePos[1]]
heldDownMomentPosition = None
vel[0] *= 0.99
vel[1] *= 0.99
pos[0] += vel[0] * dt
pos[1] += vel[1] * dt
window.fill(0)
window.blit(slingShotBullet, pos)
if heldDownMomentPosition is not None:
pygame.draw.line(window, (255, 0, 0), mousePos, heldDownMomentPosition, 2)
pygame.display.flip()
Related
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
r_colour = (200, 100,100)
bg_colour = (0,175,200)
(width, height) = (600, 600)
screen = pygame.display.set_mode((width, height))
screen.fill(bg_colour)
pygame.draw.rect(screen, r_colour, (30, 30, 100, 100), 0)
pygame.display.flip()
running = True
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
screen.fill(bg_colour)
pygame.draw.rect(screen, r_colour, (20, 30, 100, 100), 0)
pygame.display.update()
if running == True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
screen.fill(bg_colour)
pygame.draw.rect(screen, r_colour, (20, 30, 100, 100), 0)
pygame.display.update()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
running = False
pygame.quit()
I am trying to get the red square to move when pressing the 's' key, not sure as to why it only moves once and then stops. Very new to programming, so I am sorry, if it's long or hard to read.
A typical application has 1 single application loop. The application loop does:
handle the events and changes states dependent on the events
clears the display
draw the scene
update the display
The KEYDOWY event occurs once when a key is pressed, but it does not occur continuously when a key is hold down.
For a continuously movement you can get the state of the keys by pygame.key.get_pressed():
keys = pygame.key.get_pressed()
e.g. If the state of s is pressed can be evaluated by keys[pygame.K_s].
Add coordinates (x, y) for the position of the rectangle. Continuously manipulate the position in the main application loop, when a key is pressed.
e.g.
Increment x if d is pressed and decrement x if a is pressed.
Increment y if s is pressed and decrement y if w is pressed:
import pygame
r_colour = (200, 100,100)
bg_colour = (0,175,200)
(width, height) = (600, 600)
x, y = 20, 30
screen = pygame.display.set_mode((width, height))
running = True
while running:
# handle the events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# change coordinates
keys = pygame.key.get_pressed()
if keys[pygame.K_d]:
x += 1
if keys[pygame.K_a]:
x -= 1
if keys[pygame.K_s]:
y += 1
if keys[pygame.K_w]:
y -= 1
# clear the display
screen.fill(bg_colour)
# draw the scene
pygame.draw.rect(screen, r_colour, (x, y, 100, 100), 0)
# update the display
pygame.display.update()
pygame.quit()
I want to click these 2 circle balls and drag them to mouse current mouse position but it is not working.
I just want to click and drag the balls with mouse.
some codes was not added(import pygame,draw a display, colors etc.)
import pygame
window = pygame.display.set_mode((800,400))
clock = pygame.time.Clock()
##bg = pygame.image.load("bgpool.png")
##window.blit(bg,(0,0))
black = (0,0,0)
yellow = (255,255,0)
class Circle:
def __init__(self,x,y,color,radius):
self.x = x
self.y = y
self.color = color
self.radius = radius
pygame.draw.circle(window, color,(x,y),radius)
def quitgame():
pygame.quit()
quit()
def loop():
cikis = False
while not cikis:
for event in pygame.event.get():
if event.type == pygame.QUIT:
cikis = True
pygame.quit()
quit()
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
bas = pygame.MOUSEBUTTONDOWN
window.fill((255,255,255))
main_circle = Circle(75,175,black,10)
aim_circle = Circle(375,175,yellow,10)
if click[0] == 1:
if mouse[0] >= main_circle.x and mouse[0] <= main_circle.x + main_circle.radius:
if mouse[1] >= main_circle.y and mouse[1] <= main_circle.y + main_circle.radius:
if click[0] == 1:
main_circle.x == mouse[0]
main_circle.y == mouse[1]
clock.tick(120)
pygame.display.update()
loop()
pygame.quit()
quit()
While click = pygame.mouse.get_pressed() works, it's very much recommended to use Pygame's events, like you have done for pygame.QUIT.
Because you didn't provide much code, I added the bare minimum to make the code runnable, and I commented every modification:
import pygame
pygame.init()
window = pygame.display.set_mode((700, 500))
class Circle:
def __init__(self, x, y, color, radius):
# Changed pos to contain both coordinates
self.pos = (x, y)
# Where the radius ends
self.x_boundary = (x - radius, x + radius)
self.y_boundary = (y - radius, y + radius)
self.color = color
self.radius = radius
def recalc_boundary(self):
# Recalculate the boundaries of the circle,
# this is needed whenever the circle is moved
self.x_boundary = (
self.pos[0] - self.radius, self.pos[0] + self.radius
)
self.y_boundary = (
self.pos[1] - self.radius, self.pos[1] + self.radius
)
# Single instantiation of our circle
# didn't add aim_circle because it is irrelevant
# in my answer
main_circle = Circle(75, 175, (255, 0, 0), 10)
# Small lambda function that'll take care of
# checking whether or not a point x is
# within two boundaries.
# This replaces your
# `if mouse[0] >= main_circle.x and mouse[0]
# <= main_circle.x + main_circle.radius:`
# lines
within = lambda x, low, high: low <= x <= high
# Boolean that attests to whether or not the
# user is clicking on our circle
selected = False
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
# Test for MOUSEBUTTONDOWN events
elif event.type == pygame.MOUSEBUTTONDOWN:
# Left mouse button
if event.button == 1:
pos = pygame.mouse.get_pos()
# Check if the mouse is within
# our circle's limits, to see if the
# user is trying to click on it
if (
within(pos[0], *main_circle.x_boundary)
and within(pos[1], *main_circle.y_boundary)
):
selected = True
elif event.type == pygame.MOUSEBUTTONUP:
# User released mouse buttons
selected = False
if selected:
# Move to mouse position when selected,
# the circle 'follows' the mouse
main_circle.pos = pygame.mouse.get_pos()
main_circle.recalc_boundary()
window.fill((0, 0, 0))
# Moved this draw call to outside
# your class definition
pygame.draw.circle(
window, main_circle.color,
main_circle.pos,
main_circle.radius
)
pygame.display.update()
Note: it's a bad idea to instantiate a new Circle object each game loop iteration, this'll consume lots of CPU for nothing. I believe you've done that because you placed your circle draw calls inside it, but you should really just move it out into the loop.
I want to create a pygame window that doesn't have a frame and that moves when the user clicks on it and moves the mouse.
I tried this script but when I click on the windows, '0' is printed but not '1'
Something is wrong in my script.
# coding : utf-8
import pygame
from pygame.locals import *
from random import randint
from os import environ
from math import sqrt
pygame.init()
max_fps = 250
clock = pygame.time.Clock()
window_size_x, window_size_x = 720, 360
infos = pygame.display.Info()
environ['SDL_VIDEO_WINDOW_POS'] = str(int(infos.current_w / 2)) + ',' + str(int(infos.current_h / 2)) # center the window
screen = pygame.display.set_mode((window_size_x, window_size_x), pygame.NOFRAME)
def move_window(): # move the windows when custom bar is hold
window_x, window_y = eval(environ['SDL_VIDEO_WINDOW_POS'])
mouse_x, mouse_y = pygame.mouse.get_pos()
dist_x , dist_y = mouse_x - window_x, mouse_y - window_y # calculate the distance between mouse and window origin
for event in pygame.event.get():
if event.type != MOUSEBUTTONUP: # while bar is hold
print('1')
mouse_x, mouse_y = pygame.mouse.get_pos()
environ['SDL_VIDEO_WINDOW_POS'] = str(mouse_x - dist_x) + ',' + str(mouse_x - dist_x)
screen = pygame.display.set_mode((window_size_x, window_size_x), pygame.NOFRAME) # rebuild window
def main():
run = True
while run :
screen.fill((255, 255, 255))
pygame.display.update()
clock.tick(60) # build frame with 60 frame per second limitation
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN:
print('0')
move_window()
if __name__ == '__main__':
main()
Write a function, which moves the window from dependent on a previous mouse position (start_x, start_y) and a mouse position (new_x, new_y)
def move_window(start_x, start_y, new_x, new_y):
global window_size_x, window_size_y
window_x, window_y = eval(environ['SDL_VIDEO_WINDOW_POS'])
dist_x, dist_y = new_x - start_x, new_y - start_y
environ['SDL_VIDEO_WINDOW_POS'] = str(window_x + dist_x) + ',' + str(window_y + dist_y)
# Windows HACK
window_size_x += 1 if window_size_x % 2 == 0 else -1
screen = pygame.display.set_mode((window_size_x, window_size_y), pygame.NOFRAME)
In this function is a very important line:
window_size_x += 1 if window_size_x % 2 == 0 else -1
this line changes the width of the window from alternately by +1 and -1. On Windows systems there seems to be a bug, which ignores the new position parameter, if the size of the window didn't change.
This "hack" is a workaround, which slightly change the size of the window whenever the position is changed.
A different approach, with no flickering, may look as follows. Note, though, that this version is significantly slower:
def move_window(start_x, start_y, new_x, new_y):
global window_size_x, window_size_y
buffer_screen = pygame.Surface((window_size_x, window_size_y))
buffer_screen.blit(pygame.display.get_surface(), pygame.display.get_surface().get_rect())
window_x, window_y = eval(environ['SDL_VIDEO_WINDOW_POS'])
dist_x, dist_y = new_x - start_x, new_y - start_y
environ['SDL_VIDEO_WINDOW_POS'] = str(window_x + dist_x) + ',' + str(window_y + dist_y)
window_size_x += 1 if window_size_x % 2 == 0 else -1
screen = pygame.display.set_mode((window_size_x, window_size_y), pygame.NOFRAME)
screen.blit(buffer_screen, buffer_screen.get_rect())
pygame.display.flip()
Change the position on MOUSEMOTION and MOUSEBUTTONUP:
def main():
run = True
pressed = False
start_pos = (0,0)
while run :
# [...]
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN:
pressed = True
start_pos = pygame.mouse.get_pos()
elif event.type == MOUSEMOTION:
if pressed:
new_pos = pygame.mouse.get_pos()
move_window(*start_pos, *new_pos)
pygame.event.clear(pygame.MOUSEBUTTONUP)
elif event.type == MOUSEBUTTONUP:
pressed = False
new_pos = pygame.mouse.get_pos()
move_window(*start_pos, *new_pos)
Full example program:
# coding : utf-8
import pygame
from pygame.locals import *
from os import environ
pygame.init()
clock = pygame.time.Clock()
window_size_x, window_size_y = 720, 360
infos = pygame.display.Info()
environ['SDL_VIDEO_WINDOW_POS'] = str(int(infos.current_w/2)) + ',' + str(int(infos.current_h/2))
screen = pygame.display.set_mode((window_size_x, window_size_x), pygame.NOFRAME)
def move_window(start_x, start_y, new_x, new_y):
global window_size_x, window_size_y
window_x, window_y = eval(environ['SDL_VIDEO_WINDOW_POS'])
dist_x, dist_y = new_x - start_x, new_y - start_y
environ['SDL_VIDEO_WINDOW_POS'] = str(window_x + dist_x) + ',' + str(window_y + dist_y)
window_size_x += 1 if window_size_x % 2 == 0 else -1
screen = pygame.display.set_mode((window_size_x, window_size_y), pygame.NOFRAME)
def main():
run = True
pressed = False
start_pos = (0,0)
while run :
screen.fill((255, 255, 255))
pygame.display.update()
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.type == MOUSEBUTTONDOWN:
pressed = True
start_pos = pygame.mouse.get_pos()
elif event.type == MOUSEMOTION:
if pressed:
new_pos = pygame.mouse.get_pos()
move_window(*start_pos, *new_pos)
pygame.event.clear(pygame.MOUSEBUTTONUP)
elif event.type == MOUSEBUTTONUP:
pressed = False
new_pos = pygame.mouse.get_pos()
move_window(*start_pos, *new_pos)
if __name__ == '__main__':
main()
This solution no longer works under Windows systems and with Pygame 2.0. The position of a window can, however, be changed with the WINAPI function MoveWindow:
import pygame
from ctypes import windll
pygame.init()
screen = pygame.display.set_mode((400, 400), pygame.NOFRAME)
clock = pygame.time.Clock()
def moveWin(new_x, new_y):
hwnd = pygame.display.get_wm_info()['window']
w, h = pygame.display.get_surface().get_size()
windll.user32.MoveWindow(hwnd, new_x, new_y, w, h, False)
window_pos = [100, 100]
moveWin(*window_pos)
run = True
while run :
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
elif event.type == pygame.MOUSEMOTION:
if pygame.mouse.get_pressed()[0]:
window_pos[0] += event.rel[0]
window_pos[1] += event.rel[1]
moveWin(*window_pos)
screen.fill((255, 255, 255))
pygame.display.update()
clock.tick(60)
This code use only one for event loop with MOUSEBUTTONDOWN to set moving = True, MOUSEBUTTONUP to set moving = False and MOUSEMOTION which changes window's position when moving is True.
After move I use pygame.event.clear(pygame.MOUSEBUTTONUP) to remove this type of events because new window was getting this even and it was stoping window.
import pygame
from os import environ
# --- constants --- (UPPER_CASE_NAMES)
WINDOW_WIDTH = 720
WINDOW_HEIGHT = 360
# --- main ---
def main():
pygame.init()
infos = pygame.display.Info()
environ['SDL_VIDEO_WINDOW_POS'] = '{},{}'.format(infos.current_w//2, infos.current_h//2) # center the window
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.NOFRAME)
moving = False
clock = pygame.time.Clock()
run = True
while run:
screen.fill((255, 255, 255))
pygame.display.update()
clock.tick(60) # build frame with 60 frame per second limitation
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if not moving:
print('MOUSEBUTTONDOWN')
moving = True
# remeber start distance
#window_x, window_y = eval(environ['SDL_VIDEO_WINDOW_POS'])
window_x, window_y = map(int, environ['SDL_VIDEO_WINDOW_POS'].split(','))
dist_x = event.pos[0] # mouse x
dist_y = event.pos[1] # mouse y
elif event.type == pygame.MOUSEBUTTONUP:
if moving:
print('MOUSEBUTTONUP')
moving = False
elif event.type == pygame.MOUSEMOTION:
if moving:
print('moving')
mouse_x, mouse_y = pygame.mouse.get_pos()
diff_x = dist_x - mouse_x
diff_y = dist_y - mouse_y
window_x -= diff_x
window_y -= diff_y
environ['SDL_VIDEO_WINDOW_POS'] = "{},{}".format(window_x, window_y)
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.NOFRAME) # rebuild window
pygame.event.clear(pygame.MOUSEBUTTONUP) # to remove MOUSEBUTTONUP event which stops moving window
if __name__ == '__main__':
main()
The code's not ready, but I was getting there.
I had to abandon it, but it might help someone save some time.
Press f for full-screen mode. The part that is not done,
supposed to be the window-mode resize part. You must have an in-depth
look at toogle_resize() function for that.
The resize it's taking full desktop resolution and compare it
to the space between clik (MOUSEBUTTONDOWN) and (MOUSEBUTTONUP).
Or at least that's how I wanted it to work. Good luck!
Also the code needs to be optimized, it is raw.
import pyautogui
import pygame
import sys
from pygame.locals import *
from pyinput.mouse import Controller
Mouse controller gets the position on desktop, but I had to run it once more inside the while loop to get the updated values.
mouse = Controller()
standard = current_mouse_position = mouse.position
pygame.init()
Silkscreen = False
blueGray = (73, 111, 135)
width, height = pyautogui.size()
w = width / 4
h = height / 4
ww = width - w
hh = height - h
wi = ww - 4
hi = hh - 4
Set the background and the flags
room = pygame.image.load('img.png')
full_flags = pygame.FULLSCREEN | pygame.SCALED |
pygame.NOFRAME
normal_flags = pygame.NOFRAME | pygame.RESIZABLE |
pygame.SCALED
def toggle_fullscreen(f):
if f:
return pygame.display.set_mode((ww, hh), full_flags)
# pygame.display.set_mode(size, normal_flags) # uncomment
this to see issue being fixed as a workaround
return pygame.display.set_mode((ww, hh), normal_flags)
def toggle_resize(click):
if click:
return pygame.display.set_mode((ww + movement, hh),
normal_flags) # Expands by resize_y
# Set up the drawing window
screen = pygame.display.set_mode((ww, hh), normal_flags)
def bg():
screen.blit(room, (0, 0))
def border():
pygame.draw.rect(screen, blueGray, (0, 0, ww, hh), 2) #
width = 3
clock = pygame.time.Clock()
# Run until the user asks to quit
running = True
while running:
current_mouse_position = mouse.position
# print(current_mouse_position[0])
bg()
mw, mh = pygame.mouse.get_pos() # 0 - 1439(window size)
In the next line, I checked if the mouse is on the window border. Apply only to the left, right border. You must create code for the top, bottom border. Left, right borders, 3 pixels range each side.
if mw <= 3 or (mw > wi and mw < ww):
active = True
moveOne = 0
# print("data", moveOne)
# print(type(moveOne))
moveTwo = 0
# event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
running = False
sys.exit()
# print(mw, mh)
If the user clicks, the standard variable at the beginning of the code it gets the mouse current position. You must run the active bool and check if it is True if you want to start resizing from the border of the window.
The code is very complicated and needs some optimization, but I bet you gonna get it right. Good luck!;)
if event.type == pygame.MOUSEBUTTONDOWN:
standard = current_mouse_position[0]
print(standard)
if event.type == pygame.MOUSEBUTTONUP:
moveTwo = current_mouse_position[0]
movement = standard - moveTwo
print("This is:", moveTwo)
toggle_resize(click=MOUSEBUTTONUP)
active = False
Full-screen handler from here down. Press f for full screen and back to window mode.
if event.type == pygame.KEYDOWN:
Silkscreen = not Silkscreen
if event.key == K_f:
screen = toggle_fullscreen(Silkscreen)
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
border()
# Flip the display
pygame.display.flip()
clock.tick(144) # framerate
# Done! Time to quit.
pygame.quit()'
Here is a version of #Rabbid76's answer for Pygame 2. Note that this example may break as the module _sdl2.video, used to set the window position, is experimental.
move_window.py
import pygame
from pygame._sdl2.video import Window
start_pos = pygame.Vector2(0, 0) #Initial mouse position
pressed = False #Flag that denotes when the mouse is being continuously pressed down
def move_window(window : Window, start_mouse_pos : pygame.Vector2, new_mouse_pos : pygame.Vector2) -> None:
"""Moves the window by the offset between start_mouse_pos and new_mouse_pos"""
screen = pygame.display.get_surface()
buffer_screen = pygame.Surface((window.size[0], window.size[1]))
buffer_screen.blit(screen, screen.get_rect())
window_pos_Vec2 = pygame.Vector2(window.position)
window.position = window_pos_Vec2 + new_mouse_pos - start_mouse_pos
screen.blit(buffer_screen, buffer_screen.get_rect())
pygame.display.flip()
def check_event(window : Window, event : pygame.event, move_area : pygame.Rect = pygame.Rect(-1, -1, 1, 1)) -> None:
"""Takes a window and event and updates the window position accordingly. \n
move_area can be used to set what area of the screen can be clicked in order to move the window. \n
move_area defaults to a dummy rect which is then internally changed to the full window."""
global start_pos, pressed
if move_area == pygame.Rect(-1, -1, 1, 1):
move_area = pygame.Rect((0, 0), window.size)
mouse_pos = pygame.Vector2(pygame.mouse.get_pos())
if move_area.collidepoint(mouse_pos):
if event.type == pygame.MOUSEBUTTONDOWN:
pressed = True
start_pos = mouse_pos
elif event.type == pygame.MOUSEMOTION and pressed:
move_window(window, start_pos, mouse_pos)
elif event.type == pygame.MOUSEBUTTONUP:
pressed = False
move_window(window, start_pos, mouse_pos)
else:
pressed = False
And in your main file:
import pygame
from pygame._sdl2.video import Window
screen = pygame.display.set_mode(...)
window = Window.from_display_module()
#...
while True:
for event in pygame.event.get():
#...
move_window.check_event(window, event)
I am new to pygame and I am trying to make pong in order to learn it. I am trying to make smooth controls so that holding down an arrow will work, but it is not working right now.
import sys, pygame
pygame.init()
size = (500, 350)
screen = pygame.display.set_mode(size)
x = 1
xwid = 75
yhei = 5
pygame.key.set_repeat(0, 500)
while True:
vector = 0
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
vector = 4
elif event.key == pygame.K_LEFT:
vector = -4
pygame.draw.rect(screen,(255,255,255),(x,size[1] - yhei,xwid,yhei),0)
pygame.display.update()
screen.fill((0,0,0))
x += vector
if x <= 0:
x = 0
elif x >= size[0] - xwid:
x = size[0] - xwid
why does this not work for holding down the left or right arrows?
pygame.key.set_repeat(0, 500)
If you set the delay parameter to 0, key repeat will be disabled. The documentation isn't quite clear about that:
pygame.key.set_repeat()
control how held keys are repeated
set_repeat() -> None
set_repeat(delay, interval) -> None
When the keyboard repeat is enabled, keys that are held down will generate
multiple pygame.KEYDOWN events. The delay is the number of
milliseconds before the first repeated pygame.KEYDOWN will be sent.
After that another pygame.KEYDOWN will be sent every interval
milliseconds. If no arguments are passed the key repeat is disabled.
When pygame is initialized the key repeat is disabled.
Emphasis mine.
You could set the delay to 1, and it would work as expected:
pygame.key.set_repeat(1, 10) # use 10 as interval to speed things up.
But note that you should not use set_repeat and the pygame.KEYDOWN event to implement movement. If you do, you won't be able to observe real single key strokes, since if the player presses a key, a whole bunch of pygame.KEYDOWN events would be created.
Better use pygame.key.get_pressed(). Have a look at his minimal example:
import pygame
pygame.init()
screen = pygame.display.set_mode((680, 460))
clock = pygame.time.Clock()
# use a rect since it will greatly
# simplify movement and drawing
paddle = pygame.Rect((0, 0, 20, 80))
while True:
if pygame.event.get(pygame.QUIT): break
pygame.event.pump()
# move up/down by checking for pressed keys
# and moving the paddle rect in-place
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]: paddle.move_ip(0, -7)
if keys[pygame.K_DOWN]: paddle.move_ip(0, 7)
# ensure the paddle rect does not go out of screen
paddle.clamp_ip(screen.get_rect())
screen.fill((0,0,0))
pygame.draw.rect(screen, (255,255,255), paddle)
pygame.display.flip()
clock.tick(60)
try it !
pygame.key.set_repeat(1,500)
I know what do you mean. Try this:
import sys, pygame
from pygame.locals import *
pygame.init()
size = (500, 350)
screen = pygame.display.set_mode(size)
x = 1
xwid = 75
yhei = 5
clock = pygame.time.Clock()
while True:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
key_pressed = pygame.key.get_pressed()
if key_pressed[K_LEFT]:
x -= 4
if x <= 0:
x = 0
if key_pressed[K_RIGHT]:
x += 4
if x >= size[0] - xwid:
x = size[0] - xwid
pygame.draw.rect(screen,(255,255,255),(x,size[1] - yhei,xwid,yhei),0)
pygame.display.update()
screen.fill((0,0,0))