当前位置:   article > 正文

Python实践项目讲解:如何用制作一个桌面宠物_python桌宠

python桌宠

制作一个桌面宠物(Desktop Pet)在Python中通常涉及多个步骤,包括创建宠物的图形界面、添加动画效果、处理用户交互等。下面是一个简化的步骤指南,帮助你开始使用Python制作桌面宠物:

  1. 选择图形库
    • Tkinter(Python自带的图形库,简单但功能有限)。
    • Pygame(适用于游戏和多媒体应用,功能强大)。
    • PyQt 或 PySide(跨平台的图形用户界面工具包,用于创建复杂的桌面应用)。
    • 第三方库如Kivy(多平台Python库,用于开发多触摸应用)或wxPython(另一个跨平台的GUI工具包)。
  2. 设计宠物形象
    • 你可以使用图像编辑软件(如Adobe Photoshop、GIMP等)来创建宠物的图片或动画。
    • 宠物可以有不同的状态,比如睡觉、跑动、吃东西等,每种状态对应不同的图片或动画。
  3. 编写代码
    • 初始化图形窗口,并加载宠物的初始状态图片。
    • 编写代码来处理宠物的动画,比如定期更换图片来模拟宠物的动作。
    • 添加用户交互功能,比如用户可以点击或拖动宠物来移动它,或者与宠物进行简单的互动。
  4. 添加逻辑
    • 根据用户的操作或时间的变化,更新宠物的状态和行为。
    • 可以添加一些随机性,使宠物的行为看起来更自然。
  5. 测试与调试
    • 在不同的操作系统和配置上测试你的桌面宠物,确保它能在各种环境下正常工作。
    • 调试并修复任何发现的问题。
  6. 打包与发布
    • 使用如PyInstallercx_Freeze等工具将你的应用打包成一个可执行文件。
    • 发布你的桌面宠物,可以分享到网上供其他人下载和使用。

运行结果:

Python代码示例:(代码不完整,完整代码请看文末图片)

我基本上快发完了,你们先自己试一下能不能写完它

ps:图片自己可以找,不一定要我的

  1. import sys
  2. import os
  3. import random
  4. from PyQt5 import QtWidgets, QtGui, QtCore
  5. class DeskPet(QtWidgets.QLabel):
  6. def __init__(self):
  7. super().__init__()
  8. self.initUI()
  9. self.childPets = []
  10. self.isDragging = False
  11. self.isMoving = False
  12. self.change = False
  13. def initUI(self):
  14. self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
  15. self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
  16. self.setGeometry(500, 500, 130, 130)
  17. self.currentAction = self.startIdle
  18. self.timer = QtCore.QTimer(self)
  19. self.timer.timeout.connect(self.updateAnimation)
  20. self.changeDirectionTimer = QtCore.QTimer(self) # 添加定时器
  21. self.changeDirectionTimer.timeout.connect(self.changeDirection) # 定时器触发时调用changeDirection方法
  22. self.startIdle()
  23. self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
  24. self.customContextMenuRequested.connect(self.showMenu)
  25. self.setMouseTracking(True)
  26. self.dragging = False
  27. def loadImages(self, path):
  28. return [QtGui.QPixmap(os.path.join(path, f)) for f in os.listdir(path) if f.endswith('.png')]
  29. def startIdle(self):
  30. self.setFixedSize(130, 130)
  31. self.currentAction = self.startIdle
  32. self.images = self.loadImages("Deskpet/resource/xianzhi")
  33. self.currentImage = 0
  34. self.timer.start(100)
  35. self.moveSpeed = 0
  36. self.movingDirection = 0
  37. if self.changeDirectionTimer.isActive():
  38. self.changeDirectionTimer.stop() # 停止方向改变的定时器
  39. def startWalk(self):
  40. self.setFixedSize(130, 130)
  41. if not self.isDragging:
  42. self.currentAction = self.startWalk
  43. direction = random.choice(["zuo", "you"])
  44. self.images = self.loadImages(f"Deskpet/resource/sanbu/{direction}")
  45. self.currentImage = 0
  46. self.movingDirection = -1 if direction == "zuo" else 1
  47. self.moveSpeed = 10
  48. self.timer.start(100)
  49. self.changeDirectionTimer.start(3000) # 启动定时器
  50. def movePet(self):
  51. screen = QtWidgets.QDesktopWidget().screenGeometry()
  52. new_x = self.x() + self.movingDirection * self.moveSpeed
  53. if new_x < 10:
  54. new_x = 10
  55. if self.currentAction == self.startWalk:
  56. self.movingDirection *= -1
  57. # 停止加载原先的图片
  58. self.timer.stop()
  59. self.images = [] # 清空当前图片列表
  60. if self.movingDirection == -1: # 向左移动
  61. self.images = self.loadImages("Deskpet/resource/sanbu/zuo")
  62. else: # 向右移动
  63. self.images = self.loadImages("Deskpet/resource/sanbu/you")
  64. self.currentImage = 0
  65. self.timer.start(100)
  66. elif new_x > screen.width() - self.width() - 10:
  67. new_x = screen.width() - self.width() - 10
  68. if self.currentAction == self.startWalk:
  69. self.movingDirection *= -1
  70. # 停止加载原先的图片
  71. self.timer.stop()
  72. self.images = [] # 清空当前图片列表
  73. # 根据移动方向加载对应的图片
  74. if self.movingDirection == -1: # 向左移动
  75. self.images = self.loadImages("Deskpet/resource/sanbu/zuo")
  76. else: # 向右移动
  77. self.images = self.loadImages("Deskpet/resource/sanbu/you")
  78. self.currentImage = 0
  79. self.timer.start(100)
  80. self.deskpet_rect = self.geometry()
  81. for child in self.childPets:
  82. if isinstance(child, XiaobaiWindow):
  83. self.xiaobai_rect = child.geometry()
  84. if self.deskpet_rect.intersects(self.xiaobai_rect):
  85. child.close()
  86. self.startMeet()
  87. self.move(new_x, self.y())
  88. def startMeet(self):
  89. self.setFixedSize(150, 150)
  90. self.currentAction = self.startMeet
  91. self.images = self.loadImages("Deskpet/resource/meet")
  92. self.currentImage = 0
  93. self.moveSpeed = 0
  94. self.movingDirection = 0
  95. self.timer.start(30)
  96. def startLift(self):
  97. self.setFixedSize(160, 160)
  98. self.currentAction = self.startLift
  99. self.images = self.loadImages("Deskpet/resource/linqi")
  100. self.currentImage = 0
  101. self.moveSpeed = 0
  102. self.movingDirection = 0
  103. self.timer.start(100)
  104. def startFall(self):
  105. self.setFixedSize(150, 150)
  106. self.currentAction = self.startFall
  107. self.images = self.loadImages("Deskpet/resource/xialuo")
  108. self.currentImage = 0
  109. self.movingDirection = 0
  110. self.moveSpeed = 5
  111. self.stopOtherActions()
  112. self.timer.start(30)
  113. def stopOtherActions(self):
  114. self.timer.stop()
  115. if self.currentAction == self.startWalk:
  116. self.changeDirectionTimer.stop() # 停止方向判定定时器
  117. self.startIdle()
  118. elif self.currentAction == self.startLift:
  119. self.startIdle()
  120. elif self.currentAction == self.startFall:
  121. pass
  122. else:
  123. self.startIdle()
  124. def updateAnimation(self):
  125. self.setPixmap(self.images[self.currentImage])
  126. self.currentImage = (self.currentImage + 1) % len(self.images)
  127. if hasattr(self, 'movingDirection'):
  128. if self.currentAction == self.startFall:
  129. self.fallPet()
  130. else:
  131. self.movePet()
  132. def fallPet(self):
  133. self.setFixedSize(130, 130)
  134. screen = QtWidgets.QDesktopWidget().screenGeometry()
  135. new_y = self.y() + self.moveSpeed
  136. if new_y > screen.height() - self.height() - 10:
  137. new_y = screen.height() - self.height() - 10
  138. self.timer.stop()
  139. self.startIdle()
  140. self.move(self.x(), new_y)
  141. def showMenu(self, position):
  142. menu = QtWidgets.QMenu()
  143. if self.currentAction == self.sleep:
  144. menu.addAction("偷吃宵夜", self.Snack)
  145. menu.addAction("唤醒", self.WakeUp)
  146. menu.addSeparator()
  147. menu.addAction("隐藏", self.minimizeWindow)
  148. menu.addAction("退出", self.close)
  149. else:
  150. menu.addAction("散步", self.startWalk)
  151. menu.addAction("下落", self.startFall)
  152. menu.addAction("运动", self.exercise)
  153. menu.addAction("吃饭", self.eating)
  154. menu.addAction("睡觉", self.sleep)
  155. menu.addAction("屁屁舞", self.pipi)
  156. menu.addAction("分身术", self.clonePet)
  157. menu.addAction("动感光波!", self.transform)
  158. menu.addAction("呼唤小白", self.summonXiaobai)
  159. menu.addAction("测试", self.startMeet)
  160. child_menu = menu.addMenu("小彩蛋")
  161. child_menu.addAction("开发者的Q/A", self.starttalk)
  162. child_menu.addAction("小游戏", self.transform)
  163. menu.addSeparator()
  164. menu.addAction("停止", self.startIdle)
  165. menu.addAction("隐藏", self.minimizeWindow)
  166. menu.addAction("退出", self.close)
  167. menu.exec_(self.mapToGlobal(position))
  168. def Snack(self):
  169. self.setFixedSize(160, 130)
  170. self.currentAction = self.sleep
  171. self.images = self.loadImages("Deskpet/resource/snack")
  172. self.currentImage = 0
  173. self.timer.start(100)
  174. self.moveSpeed = 0
  175. self.movingDirection = 0
  176. QtCore.QTimer.singleShot(len(self.images) * 100, self.sleep)
  177. def transform(self):
  178. self.setFixedSize(160, 130)
  179. self.currentAction = self.transform
  180. self.images = self.loadImages("Deskpet/resource/xiandanchaoren")
  181. self.currentImage = 0
  182. self.timer.start(100)
  183. self.moveSpeed = 0
  184. self.movingDirection = 0
  185. def pipi(self):
  186. self.setFixedSize(300, 130)
  187. self.currentAction = self.pipi
  188. self.images = self.loadImages("Deskpet/resource/pipi")
  189. self.currentImage = 0
  190. self.timer.start(25)
  191. self.moveSpeed = 0
  192. self.movingDirection = 0
  193. def exercise(self):
  194. self.setFixedSize(150,180 )
  195. self.currentAction = self.exercise
  196. self.images = self.loadImages("Deskpet/resource/yundong")
  197. self.currentImage = 0
  198. self.timer.start(125)
  199. self.moveSpeed = 0
  200. self.movingDirection = 0
  201. def eating(self):
  202. self.setFixedSize(160, 90)
  203. self.currentAction = self.eating
  204. self.images = self.loadImages("Deskpet/resource/eat")
  205. self.currentImage = 0
  206. self.timer.start(25)
  207. self.moveSpeed = 0
  208. self.movingDirection = 0
  209. QtCore.QTimer.singleShot(len(self.images) * 30, self.startIdle)
  210. def sleep(self):
  211. self.setFixedSize(315, 500)
  212. self.currentAction = self.sleep
  213. self.images = self.loadImages("Deskpet/resource/sleep")
  214. self.currentImage = 0
  215. self.timer.start(155)
  216. self.moveSpeed = 0
  217. self.movingDirection = 0
  218. def showWakeUpMenu(self):
  219. self.setFixedSize(130, 130)
  220. self.sleeping = True
  221. menu = QtWidgets.QMenu()
  222. menu.addAction("唤醒", self.wakeUp)
  223. menu.exec_(self.mapToGlobal(self.pos()))
  224. def WakeUp(self):
  225. self.setFixedSize(180, 180)
  226. self.sleeping = False
  227. self.currentAction = self.WakeUp
  228. self.images = self.loadImages("Deskpet/resource/waken")
  229. self.currentImage = 0
  230. self.timer.start(30)
  231. # 延时,等待所有图片加载完成
  232. QtCore.QTimer.singleShot(len(self.images) * 30, self.finishWakeUp)
  233. def Ninjia(self):
  234. self.setFixedSize(160, 150)
  235. self.sleeping = False
  236. self.currentAction = self.Ninjia
  237. self.images = self.loadImages("Deskpet/resource/Ninjia")
  238. self.currentImage = 0
  239. self.timer.start(30)
  240. # 延时,等待所有图片加载完成
  241. QtCore.QTimer.singleShot(len(self.images) * 30, self.startIdle)
  242. def Ninjia2(self):
  243. new_pet = DeskPet()
  244. self.childPets.append(new_pet)
  245. self.setFixedSize(160, 150)
  246. self.sleeping = False
  247. self.currentAction = self.Ninjia2
  248. self.images = self.loadImages("Deskpet/resource/Ninjia2")
  249. self.currentImage = 0
  250. self.timer.start(30)
  251. # 延时,等待所有图片加载完成
  252. QtCore.QTimer.singleShot(len(self.images) * 30, self.startIdle)
  253. def finishWakeUp(self):
  254. self.movingDirection = 0
  255. self.wakeUpImagesLoaded = True
  256. self.setFixedSize(180, 180)
  257. self.timer.stop()
  258. self.currentAction = self.startIdle
  259. self.images = self.loadImages("Deskpet/resource/xianzhi")
  260. self.currentImage = 0
  261. self.timer.start(100)
  262. def clonePet(self):
  263. new_pet = DeskPet()
  264. self.childPets.append(new_pet)
  265. self.Ninjia()
  266. new_pet.show()
  267. new_pet.Ninjia2()
  268. def starttalk(self):
  269. starttalk = ChatApp()
  270. starttalk.show()
  271. self.childPets.append(starttalk)
  272. def summonXiaobai(self):
  273. xiaobai = XiaobaiWindow()
  274. xiaobai.show()
  275. self.childPets.append(xiaobai)
  276. def closeEvent(self, event):
  277. for child in self.childPets:
  278. child.close() # 关闭所有子窗口
  279. super().closeEvent(event)
  280. def minimizeWindow(self):
  281. self.showMinimized()
  282. def mousePressEvent(self, event):
  283. if event.button() == QtCore.Qt.LeftButton:
  284. self.dragging = True
  285. self.isDragging = True
  286. self.drag_position = event.globalPos() - self.pos()
  287. self.prevAction = self.currentAction
  288. self.startLift()
  289. event.accept()
  290. def mouseMoveEvent(self, event):
  291. if QtCore.Qt.LeftButton and self.dragging:
  292. self.move(event.globalPos() - self.drag_position)
  293. event.accept()
  294. def mouseReleaseEvent(self, event):
  295. if event.button() == QtCore.Qt.LeftButton:
  296. self.dragging = False
  297. self.isDragging = False
  298. # 根据需要重新启动changeDirectionTimer
  299. if self.currentAction == self.startWalk:
  300. self.changeDirectionTimer.start()
  301. self.prevAction() # 或者 self.startIdle(), 根据之前的动作恢复状态
  302. event.accept()
  303. def changeDirection(self):
  304. if self.currentAction == self.startFall or self.currentAction == self.eating or self.currentAction == self.transform or self.currentAction == self.sleep or self.currentAction == self.pipi or self.currentAction == self.exercise or self.currentAction == self.WakeUp or self.currentAction == self.startIdle or self.startMeet:
  305. return # 如果正在执行下落动作,不改变方向
  306. if random.random() < 0.5: # 随机选择是否改变方向
  307. self.movingDirection *= -1
  308. self.change = True
  309. if self.change == True:
  310. # 停止加载原先的图片
  311. self.timer.stop()
  312. self.images = [] # 清空当前图片列表
  313. self.startWalk()
  314. self.change = False
  315. class XiaobaiWindow(QtWidgets.QWidget):
  316. def __init__(self):
  317. super().__init__()
  318. self.initUI()
  319. def initUI(self):
  320. self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
  321. self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
  322. self.setGeometry(500, 500, 125, 100)
  323. self.timer = QtCore.QTimer(self)
  324. self.timer.timeout.connect(self.updateAnimation)
  325. self.images = self.loadImages("Deskpet/resource/xiaobai")
  326. self.currentImage = 0
  327. self.timer.start(20)
  328. self.dragPosition = QtCore.QPoint()
  329. self.label = QtWidgets.QLabel(self)
  330. self.label.setGeometry(0, 0, 140, 100)
  331. def mousePressEvent(self, event):
  332. if event.button() == QtCore.Qt.LeftButton:
  333. self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()
  334. event.accept()
  335. def mouseMoveEvent(self, event):
  336. if event.buttons() == QtCore.Qt.LeftButton:
  337. self.move(event.globalPos() - self.dragPosition)
  338. event.accept()
  339. def showMenu(self, position):
  340. menu = QtWidgets.QMenu()
  341. menu.addAction("隐藏", self.minimizeWindow)
  342. menu.addAction("回去", self.close)
  343. menu.exec_(self.mapToGlobal(position))
  344. def loadImages(self, path):
  345. return [QtGui.QPixmap(os.path.join(path, f)) for f in os.listdir(path) if f.endswith('.png')]
  346. def updateAnimation(self):
  347. self.label.setPixmap(self.images[self.currentImage])
  348. self.currentImage = (self.currentImage + 1) % len(self.images)
  349. def minimizeWindow(self):
  350. self.showMinimized()
  351. def closeEvent(self, event):
  352. self.timer.stop()
  353. super().closeEvent(event)
  354. def eventFilter(self, obj, event):
  355. if event.type() == QtCore.QEvent.ContextMenu:
  356. self.showMenu(event.pos())
  357. return True
  358. return super().eventFilter(obj, event)
  359. def showEvent(self, event):
  360. self.installEventFilter(self)
  361. class ChatApp(QtWidgets.QWidget):
  362. def __init__(self):
  363. super().__init__()
  364. self.initUI()
  365. def initUI(self):
  366. self.setWindowTitle('聊天窗口')
  367. layout = QtWidgets.QVBoxLayout()
  368. label = QtWidgets.QLabel("你好,我是开发者”乐子猪“\n请问你想问什么?\n(该聊天的内容不完善且功能有缺陷)")
  369. layout.addWidget(label)
  370. button1 = QtWidgets.QPushButton("开发者你是哪里人呀?")
  371. button1.clicked.connect(self.on_button1_clicked)
  372. layout.addWidget(button1)
  373. button2 = QtWidgets.QPushButton("开发者你是一个什么样的人呀?")
  374. button2.clicked.connect(self.on_button2_clicked)
  375. layout.addWidget(button2)
  376. button3 = QtWidgets.QPushButton("我想给开发者生猴子(〃ノωノ)")
  377. layout.addWidget(button3)
  378. self.new_window = None # 新窗口实例作为成员变量
  379. self.setLayout(layout)
  380. def on_button1_clicked(self):
  381. self.new_window = QtWidgets.QWidget()
  382. self.new_window.setWindowTitle('新窗口')
  383. layout = QtWidgets.QVBoxLayout()
  384. label = QtWidgets.QLabel("我是广东人。(不过不是土生土长的)\n#请问你还想聊什么?")
  385. layout.addWidget(label)
  386. button4 = QtWidgets.QPushButton("开发者你喜欢吃什么")
  387. button4.clicked.connect(self.on_button4_clicked)
  388. layout.addWidget(button4)
  389. button3 = QtWidgets.QPushButton("我想给开发者生猴子(〃ノωノ)")
  390. layout.addWidget(button3)
  391. self.new_window.setLayout(layout)
  392. self.new_window.show()
  393. def on_button2_clicked(self):
  394. self.new_window = QtWidgets.QWidget()
  395. self.new_window.setWindowTitle('新窗口')
  396. layout = QtWidgets.QVBoxLayout()
  397. label = QtWidgets.QLabel("一个帅气逼人,温柔可爱,风流倜傥的美男子!\n#请问你还想聊什么?")
  398. layout.addWidget(label)

完整代码在这里
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/919836

推荐阅读
相关标签