Добавление физики шару в 2д игре
вот я решил сделать программку, в которой шар катается по экрану, его можно кидать по экрану, а он будет отталкиваться от стенок и так далее. Естественно у меня появились проблемы, т.к. чтобы это сделать знаний не хватает...
вот код:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class BallApp(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.Tool)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.setGeometry(0, 0, QtWidgets.QDesktopWidget().screenGeometry().width(),
QtWidgets.QDesktopWidget().screenGeometry().height())
self.ball_radius = 30 # радиус шара
self.ball_color = QtGui.QColor(0, 0, 0) # черный цвет
self.outer_color = QtGui.QColor(255, 255, 255) # белая обводка
self.ball_pos = QtCore.QPoint(self.width() // 2, 0) # начальная позиция шара
self.velocity = QtCore.QPoint(0, 0)
self.is_dragging = False
self.offset = QtCore.QPoint(0, 0)
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.update_ball_position)
self.timer.start(16)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
# Рисуем шар
painter.setBrush(self.ball_color)
painter.setPen(QtGui.QPen(self.outer_color, 1))
painter.drawEllipse(self.ball_pos.x() - self.ball_radius, self.ball_pos.y() - self.ball_radius,
self.ball_radius * 2, self.ball_radius * 2)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
if self.is_ball_at(event.pos()):
self.is_dragging = True
self.offset = event.pos() - self.ball_pos
self.velocity = QtCore.QPoint(0, 0) # Остановить шар
# Закрытие программы
if event.button() == QtCore.Qt.RightButton:
QtCore.QCoreApplication.quit() # Завершение работы приложения
def mouseMoveEvent(self, event):
if self.is_dragging:
self.ball_pos = event.pos() - self.offset
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.LeftButton and self.is_dragging:
self.is_dragging = False
self.velocity = event.pos() - self.ball_pos
self.ball_pos += self.velocity
def is_ball_at(self, pos):
return (self.ball_pos.x() - self.ball_radius <= pos.x() <= self.ball_pos.x() + self.ball_radius and
self.ball_pos.y() - self.ball_radius <= pos.y() <= self.ball_pos.y() + self.ball_radius)
def update_ball_position(self):
# Упругость
if not self.is_dragging:
if self.ball_pos.y() + self.ball_radius < self.height():
self.velocity.setY(self.velocity.y() + 1) # гравитация
else:
self.velocity.setY(int(-self.velocity.y() * 0.7)) # отскок с потерей энергии
self.ball_pos.setY(self.height() - self.ball_radius)
self.ball_pos += self.velocity
# Отталкивание от краев
if self.ball_pos.x() < 0:
self.ball_pos.setX(0)
self.velocity.setX(-self.velocity.x()) # Отскок в другую сторону
elif self.ball_pos.x() > self.width() - self.ball_radius * 2:
self.ball_pos.setX(self.width() - self.ball_radius * 2)
self.velocity.setX(-self.velocity.x()) # Отскок в другую сторону
self.ball_pos.setY(max(0, min(self.ball_pos.y(), self.height() - self.ball_radius)))
self.update()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = BallApp()
window.showFullScreen()
sys.exit(app.exec_())
как мне сделать так, чтобы я курсором мог кидать этот шар? Чтобы шар после отпускания левой кнопки мыши летел в ту сторону, в которую двигался курсор, чтобы летел с той скоростью, с которой двигался курсор или например курсор остановился, я отпустил кнопку и шар просто полетел вертикально вниз.
Также как мне добавить физику шару? Чтобы шар при полете вверх немного замедлялся, при полете вниз ускорялся, чтобы он летел не слишком прямо, а немного дугообразно, ну как в реальности?
Также я не смог сделать так, чтобы шар при полной его остановке остановился окончательно, вместо этого он продолжает кататься по нижней части экрана бесконечно долго.
Я буду вам признателен, если вы мне объясните что к чему и как.