[英]Pygame Moving a Ball with The Mouse
I have this assignment where when I click the mouse a ball will be launched and eventually destroy a box.我有这个任务,当我点击鼠标时,一个球将被发射并最终摧毁一个盒子。 I am having trouble moving the ball with the mouse click.我无法通过单击鼠标移动球。 The variables that are defined after the "print initial value line" are required to be those values.在“打印初始值行”之后定义的变量必须是这些值。 I'm not too familiar with pygame and don't know where I should be drawing and if I should remove the ball before I draw a new one.我对 pygame 不太熟悉,不知道我应该在哪里画画,也不知道我是否应该在画一个新球之前把球移开。
import pygame, sys
from Drawable import *
from Ball import *
from Block import *
from Text import *
from pygame.locals import *
pygame.init()
surface = pygame.display.set_mode((500,500))
surface.fill((255,255,255))
class Line(Drawable):
def __init__(self,x=0, y=0,color=(0,255,0)):
super().__init__(x, y, color)
self.position = x , y
self.visible = False
def draw(self):
if self.visible == True:
pygame.draw.line(surface,(0,0,0),(0,400),(500,400))
def get_rect(self):
pass
ground = Line()
ground.visible = True
ground.draw()
ball = Ball()
ball.visible = True
ball.draw(surface)
block = Block()
block.visible = True
block.draw(surface)
text = Text()
text.visible = True
text.draw(surface)
print("Initial Ball Location:", ball.position)
dt = 0.1
g = 6.67
R = 0.7
eta = 0.5
mouespos1 = 0
mousepos2 = 0
xv = 1
yv = 1
def mousedown():
global mousepos1
mousepos1 = pygame.mouse.get_pos()
def mouseup():
global xv
global yv
mousepos2 = pygame.mouse.get_pos()
xv = mousepos2[0] - mousepos1[0]
print("XV in mouseup:", xv)
yv = -1 * (mousepos2[1] - mousepos1[1])
print("YV in mouesup:", yv)
def updateballpos():
global xv, yv
print("Ran Update")
moveX = ball.x + (dt * xv)
ball.moveX(moveX)
moveY = ball.y - (dt * yv)
ball.moveY(moveY)
print("new x", ball.x)
print("new y", ball.y)
if ball.y > 400:
yv = -R * yv
xv = eta * xv
else:
yv = yv - g * dt
ball.draw(surface)
pygame.display.update()
while(True):
for event in pygame.event.get():
if (event.type == pygame.QUIT) or \
(event.type == pygame.KEYDOWN and event.__dict__['key'] == pygame.K_q):
pygame.quit()
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
mousedown()
if event.type == pygame.MOUSEBUTTONUP:
mouseup()
print("xv in while", xv)
print("yv in while", yv)
if yv > 0 and xv > 0:
updateballpos()
pygame.display.update()
And this is the Ball Class and Drawable Class这是 Ball 类和 Drawable 类
import pygame
import abc
import random
class Drawable(metaclass = abc.ABCMeta):
def __init__(self,x,y,color):
self.x = x
self.y = y
self.color = color
self.position = (self.x,self.y)
self.visible = False
def getLoc(self):
return (self.x, self.y)
def setLoc(self,p):
self.x = p[0]
self.y = p[1]
def getColor(self):
return self.__color
def getX(self):
return self.__x
def getY(self):
return self.__y
@abc.abstractmethod
def draw(self,surface):
pass
@abc.abstractmethod
def get_rect(self):
pass
from Drawable import *
import pygame, sys
from pygame.locals import *
class Ball(Drawable):
def __init__(self, x=20, y=400,color=(0, 0,0)):
super().__init__(x, y,color)
self.x = x
self.y = y
self.position = (self.x,self.y)
self.visible = False
def draw(self,s):
if self.visible == True:
pygame.draw.circle(s,(255,0,0),(int(self.x), int(self.y)),8)
def get_rect(self):
pass
def getLoc(self):
return (self.x, self.y)
def setLoc(self, x, y):
self.x = x
self.y = y
def moveX(self, inc):
self.x = self.x + inc
def moveY(self, inc):
self.y = self.y + inc
I recommend adding the updateballpos
as a method of the Ball
, because it only updates the ball attributes.我建议添加updateballpos
作为Ball
的方法,因为它只更新球的属性。 The xv
and yv
variables should also be attributes of the balls, then you can give every ball a different velocity. xv
和yv
变量也应该是球的属性,然后你可以给每个球一个不同的速度。
To spawn new balls, you can just create Ball
instances and append them to a list, and then use for
loops to update and draw the balls in this list.要生成新球,您只需创建Ball
实例并将它们附加到列表中,然后使用for
循环更新和绘制此列表中的球。 You can clear the screen with the fill
method (or blit a background surface) before you draw the balls.在绘制球之前,您可以使用fill
方法(或 blit 背景表面)清除屏幕。
For the slingshot effect you could store the rel
attribute (relative movement of the mouse in pixels) of the pygame.MOUSEMOTION
events, pass it to the balls when you instantiate them and just assign it to the xv
, yv
attributes.对于弹弓效果,您可以存储pygame.MOUSEMOTION
事件的rel
属性(鼠标的相对移动,以像素为单位),在实例化它们时将其传递给球,然后将其分配给xv
、 yv
属性。
Here's a minimal, complete example:这是一个最小的完整示例:
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((500,500))
class Ball:
# Pass the xv, yv as arguments as well.
def __init__(self, x=20, y=400, xv=0, yv=0, color=(0, 0,0)):
self.x = x
self.y = y
# Give the objects xv and yv attributes.
self.xv = xv
self.yv = yv
self.position = (self.x,self.y)
self.visible = False
def draw(self,s):
if self.visible == True:
pygame.draw.circle(s,(255,0,0),(int(self.x), int(self.y)),8)
def get_rect(self):
pass
def getLoc(self):
return (self.x, self.y)
def setLoc(self, x, y):
self.x = x
self.y = y
def moveX(self, dt):
self.x += dt * self.xv
def moveY(self, dt):
self.y += dt * self.yv
# Add a method to update the position and other attributes.
# Call it every frame.
def update(self, dt):
self.moveX(dt)
self.moveY(dt)
if self.y > 400:
self.yv = -R * self.yv
self.xv = eta * self.xv
else:
self.yv = self.yv - g * dt
dt = 0.1
g = 6.67
R = 0.7
eta = 0.5
balls = []
clock = pygame.time.Clock()
rel_x = 0
rel_y = 0
while True:
for event in pygame.event.get():
if (event.type == pygame.QUIT or
event.type == pygame.KEYDOWN and event.key == pygame.K_q):
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONUP:
# Create a new ball instance and append it to the list.
# Pass the rel (the relative mouse movement) as well.
ball = Ball(xv=rel_x*10, yv=rel_y*10) # * 10 to make the balls faster.
ball.visible = True
balls.append(ball)
if event.type == pygame.MOUSEMOTION:
# event.rel is the relative movement of the mouse.
rel_x = event.rel[0]
rel_y = event.rel[1]
# Call the update methods of all balls.
for ball in balls:
ball.update(dt)
# Clear the screen with fill (or blit a background surface).
screen.fill((255,255,255))
# Draw the balls.
for ball in balls:
ball.draw(screen)
pygame.display.update()
dt = clock.tick(30) / 1000
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.