制作一个桌面宠物(Desktop Pet)在Python中通常涉及多个步骤,包括创建宠物的图形界面、添加动画效果、处理用户交互等。下面是一个简化的步骤指南,帮助你开始使用Python制作桌面宠物:
- 选择图形库:
Tkinter
(Python自带的图形库,简单但功能有限)。Pygame
(适用于游戏和多媒体应用,功能强大)。PyQt
或PySide
(跨平台的图形用户界面工具包,用于创建复杂的桌面应用)。- 第三方库如
Kivy
(多平台Python库,用于开发多触摸应用)或wxPython
(另一个跨平台的GUI工具包)。
- 设计宠物形象:
- 你可以使用图像编辑软件(如Adobe Photoshop、GIMP等)来创建宠物的图片或动画。
- 宠物可以有不同的状态,比如睡觉、跑动、吃东西等,每种状态对应不同的图片或动画。
- 编写代码:
- 初始化图形窗口,并加载宠物的初始状态图片。
- 编写代码来处理宠物的动画,比如定期更换图片来模拟宠物的动作。
- 添加用户交互功能,比如用户可以点击或拖动宠物来移动它,或者与宠物进行简单的互动。
- 添加逻辑:
- 根据用户的操作或时间的变化,更新宠物的状态和行为。
- 可以添加一些随机性,使宠物的行为看起来更自然。
- 测试与调试:
- 在不同的操作系统和配置上测试你的桌面宠物,确保它能在各种环境下正常工作。
- 调试并修复任何发现的问题。
- 打包与发布:
- 使用如
PyInstaller
、cx_Freeze
等工具将你的应用打包成一个可执行文件。 - 发布你的桌面宠物,可以分享到网上供其他人下载和使用。
- 使用如
运行结果:
Python代码示例:(代码不完整,完整代码请看文末图片)
我基本上快发完了,你们先自己试一下能不能写完它
ps:图片自己可以找,不一定要我的
import sys
import os
import random
from PyQt5 import QtWidgets, QtGui, QtCoreclass DeskPet(QtWidgets.QLabel):def __init__(self):super().__init__()self.initUI()self.childPets = []self.isDragging = Falseself.isMoving = Falseself.change = Falsedef initUI(self):self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)self.setAttribute(QtCore.Qt.WA_TranslucentBackground)self.setGeometry(500, 500, 130, 130)self.currentAction = self.startIdleself.timer = QtCore.QTimer(self)self.timer.timeout.connect(self.updateAnimation)self.changeDirectionTimer = QtCore.QTimer(self) # 添加定时器self.changeDirectionTimer.timeout.connect(self.changeDirection) # 定时器触发时调用changeDirection方法self.startIdle()self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)self.customContextMenuRequested.connect(self.showMenu)self.setMouseTracking(True)self.dragging = Falsedef loadImages(self, path):return [QtGui.QPixmap(os.path.join(path, f)) for f in os.listdir(path) if f.endswith('.png')]def startIdle(self):self.setFixedSize(130, 130)self.currentAction = self.startIdleself.images = self.loadImages("Deskpet/resource/xianzhi")self.currentImage = 0self.timer.start(100)self.moveSpeed = 0self.movingDirection = 0if self.changeDirectionTimer.isActive():self.changeDirectionTimer.stop() # 停止方向改变的定时器def startWalk(self):self.setFixedSize(130, 130)if not self.isDragging:self.currentAction = self.startWalkdirection = random.choice(["zuo", "you"])self.images = self.loadImages(f"Deskpet/resource/sanbu/{direction}")self.currentImage = 0self.movingDirection = -1 if direction == "zuo" else 1self.moveSpeed = 10self.timer.start(100)self.changeDirectionTimer.start(3000) # 启动定时器def movePet(self):screen = QtWidgets.QDesktopWidget().screenGeometry()new_x = self.x() + self.movingDirection * self.moveSpeedif new_x < 10:new_x = 10if self.currentAction == self.startWalk:self.movingDirection *= -1# 停止加载原先的图片self.timer.stop()self.images = [] # 清空当前图片列表if self.movingDirection == -1: # 向左移动self.images = self.loadImages("Deskpet/resource/sanbu/zuo")else: # 向右移动self.images = self.loadImages("Deskpet/resource/sanbu/you")self.currentImage = 0self.timer.start(100)elif new_x > screen.width() - self.width() - 10:new_x = screen.width() - self.width() - 10if self.currentAction == self.startWalk:self.movingDirection *= -1# 停止加载原先的图片self.timer.stop()self.images = [] # 清空当前图片列表# 根据移动方向加载对应的图片if self.movingDirection == -1: # 向左移动self.images = self.loadImages("Deskpet/resource/sanbu/zuo")else: # 向右移动self.images = self.loadImages("Deskpet/resource/sanbu/you")self.currentImage = 0self.timer.start(100)self.deskpet_rect = self.geometry()for child in self.childPets:if isinstance(child, XiaobaiWindow):self.xiaobai_rect = child.geometry()if self.deskpet_rect.intersects(self.xiaobai_rect):child.close()self.startMeet()self.move(new_x, self.y())def startMeet(self):self.setFixedSize(150, 150)self.currentAction = self.startMeetself.images = self.loadImages("Deskpet/resource/meet")self.currentImage = 0self.moveSpeed = 0self.movingDirection = 0self.timer.start(30)def startLift(self):self.setFixedSize(160, 160)self.currentAction = self.startLiftself.images = self.loadImages("Deskpet/resource/linqi")self.currentImage = 0self.moveSpeed = 0self.movingDirection = 0self.timer.start(100)def startFall(self):self.setFixedSize(150, 150)self.currentAction = self.startFallself.images = self.loadImages("Deskpet/resource/xialuo")self.currentImage = 0self.movingDirection = 0self.moveSpeed = 5self.stopOtherActions()self.timer.start(30)def stopOtherActions(self):self.timer.stop()if self.currentAction == self.startWalk:self.changeDirectionTimer.stop() # 停止方向判定定时器self.startIdle()elif self.currentAction == self.startLift:self.startIdle()elif self.currentAction == self.startFall:passelse:self.startIdle()def updateAnimation(self):self.setPixmap(self.images[self.currentImage])self.currentImage = (self.currentImage + 1) % len(self.images)if hasattr(self, 'movingDirection'):if self.currentAction == self.startFall:self.fallPet()else:self.movePet()def fallPet(self):self.setFixedSize(130, 130)screen = QtWidgets.QDesktopWidget().screenGeometry()new_y = self.y() + self.moveSpeedif new_y > screen.height() - self.height() - 10:new_y = screen.height() - self.height() - 10self.timer.stop()self.startIdle()self.move(self.x(), new_y)def showMenu(self, position):menu = QtWidgets.QMenu()if self.currentAction == self.sleep:menu.addAction("偷吃宵夜", self.Snack)menu.addAction("唤醒", self.WakeUp)menu.addSeparator()menu.addAction("隐藏", self.minimizeWindow)menu.addAction("退出", self.close)else:menu.addAction("散步", self.startWalk)menu.addAction("下落", self.startFall)menu.addAction("运动", self.exercise)menu.addAction("吃饭", self.eating)menu.addAction("睡觉", self.sleep)menu.addAction("屁屁舞", self.pipi)menu.addAction("分身术", self.clonePet)menu.addAction("动感光波!", self.transform)menu.addAction("呼唤小白", self.summonXiaobai)menu.addAction("测试", self.startMeet)child_menu = menu.addMenu("小彩蛋")child_menu.addAction("开发者的Q/A", self.starttalk)child_menu.addAction("小游戏", self.transform)menu.addSeparator()menu.addAction("停止", self.startIdle)menu.addAction("隐藏", self.minimizeWindow)menu.addAction("退出", self.close)menu.exec_(self.mapToGlobal(position))def Snack(self):self.setFixedSize(160, 130)self.currentAction = self.sleepself.images = self.loadImages("Deskpet/resource/snack")self.currentImage = 0self.timer.start(100)self.moveSpeed = 0self.movingDirection = 0QtCore.QTimer.singleShot(len(self.images) * 100, self.sleep)def transform(self):self.setFixedSize(160, 130)self.currentAction = self.transformself.images = self.loadImages("Deskpet/resource/xiandanchaoren")self.currentImage = 0self.timer.start(100)self.moveSpeed = 0self.movingDirection = 0def pipi(self):self.setFixedSize(300, 130)self.currentAction = self.pipiself.images = self.loadImages("Deskpet/resource/pipi")self.currentImage = 0self.timer.start(25)self.moveSpeed = 0self.movingDirection = 0def exercise(self):self.setFixedSize(150,180 )self.currentAction = self.exerciseself.images = self.loadImages("Deskpet/resource/yundong")self.currentImage = 0self.timer.start(125)self.moveSpeed = 0self.movingDirection = 0def eating(self):self.setFixedSize(160, 90)self.currentAction = self.eatingself.images = self.loadImages("Deskpet/resource/eat")self.currentImage = 0self.timer.start(25)self.moveSpeed = 0self.movingDirection = 0QtCore.QTimer.singleShot(len(self.images) * 30, self.startIdle)def sleep(self):self.setFixedSize(315, 500)self.currentAction = self.sleepself.images = self.loadImages("Deskpet/resource/sleep")self.currentImage = 0self.timer.start(155)self.moveSpeed = 0self.movingDirection = 0def showWakeUpMenu(self):self.setFixedSize(130, 130)self.sleeping = Truemenu = QtWidgets.QMenu()menu.addAction("唤醒", self.wakeUp)menu.exec_(self.mapToGlobal(self.pos()))def WakeUp(self):self.setFixedSize(180, 180)self.sleeping = Falseself.currentAction = self.WakeUpself.images = self.loadImages("Deskpet/resource/waken")self.currentImage = 0self.timer.start(30)# 延时,等待所有图片加载完成QtCore.QTimer.singleShot(len(self.images) * 30, self.finishWakeUp)def Ninjia(self):self.setFixedSize(160, 150)self.sleeping = Falseself.currentAction = self.Ninjiaself.images = self.loadImages("Deskpet/resource/Ninjia")self.currentImage = 0self.timer.start(30)# 延时,等待所有图片加载完成QtCore.QTimer.singleShot(len(self.images) * 30, self.startIdle)def Ninjia2(self):new_pet = DeskPet()self.childPets.append(new_pet)self.setFixedSize(160, 150)self.sleeping = Falseself.currentAction = self.Ninjia2self.images = self.loadImages("Deskpet/resource/Ninjia2")self.currentImage = 0self.timer.start(30)# 延时,等待所有图片加载完成QtCore.QTimer.singleShot(len(self.images) * 30, self.startIdle)def finishWakeUp(self):self.movingDirection = 0self.wakeUpImagesLoaded = Trueself.setFixedSize(180, 180)self.timer.stop()self.currentAction = self.startIdleself.images = self.loadImages("Deskpet/resource/xianzhi")self.currentImage = 0self.timer.start(100)def clonePet(self):new_pet = DeskPet()self.childPets.append(new_pet)self.Ninjia()new_pet.show()new_pet.Ninjia2()def starttalk(self):starttalk = ChatApp()starttalk.show()self.childPets.append(starttalk)def summonXiaobai(self):xiaobai = XiaobaiWindow()xiaobai.show()self.childPets.append(xiaobai)def closeEvent(self, event):for child in self.childPets:child.close() # 关闭所有子窗口super().closeEvent(event)def minimizeWindow(self):self.showMinimized()def mousePressEvent(self, event):if event.button() == QtCore.Qt.LeftButton:self.dragging = Trueself.isDragging = Trueself.drag_position = event.globalPos() - self.pos()self.prevAction = self.currentActionself.startLift()event.accept()def mouseMoveEvent(self, event):if QtCore.Qt.LeftButton and self.dragging:self.move(event.globalPos() - self.drag_position)event.accept()def mouseReleaseEvent(self, event):if event.button() == QtCore.Qt.LeftButton:self.dragging = Falseself.isDragging = False# 根据需要重新启动changeDirectionTimerif self.currentAction == self.startWalk:self.changeDirectionTimer.start()self.prevAction() # 或者 self.startIdle(), 根据之前的动作恢复状态event.accept()def changeDirection(self):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:return # 如果正在执行下落动作,不改变方向if random.random() < 0.5: # 随机选择是否改变方向self.movingDirection *= -1self.change = Trueif self.change == True:# 停止加载原先的图片self.timer.stop()self.images = [] # 清空当前图片列表self.startWalk()self.change = Falseclass XiaobaiWindow(QtWidgets.QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)self.setAttribute(QtCore.Qt.WA_TranslucentBackground)self.setGeometry(500, 500, 125, 100)self.timer = QtCore.QTimer(self)self.timer.timeout.connect(self.updateAnimation)self.images = self.loadImages("Deskpet/resource/xiaobai")self.currentImage = 0self.timer.start(20)self.dragPosition = QtCore.QPoint()self.label = QtWidgets.QLabel(self)self.label.setGeometry(0, 0, 140, 100)def mousePressEvent(self, event):if event.button() == QtCore.Qt.LeftButton:self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()event.accept()def mouseMoveEvent(self, event):if event.buttons() == QtCore.Qt.LeftButton:self.move(event.globalPos() - self.dragPosition)event.accept()def showMenu(self, position):menu = QtWidgets.QMenu()menu.addAction("隐藏", self.minimizeWindow)menu.addAction("回去", self.close)menu.exec_(self.mapToGlobal(position))def loadImages(self, path):return [QtGui.QPixmap(os.path.join(path, f)) for f in os.listdir(path) if f.endswith('.png')]def updateAnimation(self):self.label.setPixmap(self.images[self.currentImage])self.currentImage = (self.currentImage + 1) % len(self.images)def minimizeWindow(self):self.showMinimized()def closeEvent(self, event):self.timer.stop()super().closeEvent(event)def eventFilter(self, obj, event):if event.type() == QtCore.QEvent.ContextMenu:self.showMenu(event.pos())return Truereturn super().eventFilter(obj, event)def showEvent(self, event):self.installEventFilter(self)class ChatApp(QtWidgets.QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setWindowTitle('聊天窗口')layout = QtWidgets.QVBoxLayout()label = QtWidgets.QLabel("你好,我是开发者”乐子猪“\n请问你想问什么?\n(该聊天的内容不完善且功能有缺陷)")layout.addWidget(label)button1 = QtWidgets.QPushButton("开发者你是哪里人呀?")button1.clicked.connect(self.on_button1_clicked)layout.addWidget(button1)button2 = QtWidgets.QPushButton("开发者你是一个什么样的人呀?")button2.clicked.connect(self.on_button2_clicked)layout.addWidget(button2)button3 = QtWidgets.QPushButton("我想给开发者生猴子(〃ノωノ)")layout.addWidget(button3)self.new_window = None # 新窗口实例作为成员变量self.setLayout(layout)def on_button1_clicked(self):self.new_window = QtWidgets.QWidget()self.new_window.setWindowTitle('新窗口')layout = QtWidgets.QVBoxLayout()label = QtWidgets.QLabel("我是广东人。(不过不是土生土长的)\n#请问你还想聊什么?")layout.addWidget(label)button4 = QtWidgets.QPushButton("开发者你喜欢吃什么")button4.clicked.connect(self.on_button4_clicked)layout.addWidget(button4)button3 = QtWidgets.QPushButton("我想给开发者生猴子(〃ノωノ)")layout.addWidget(button3)self.new_window.setLayout(layout)self.new_window.show()def on_button2_clicked(self):self.new_window = QtWidgets.QWidget()self.new_window.setWindowTitle('新窗口')layout = QtWidgets.QVBoxLayout()label = QtWidgets.QLabel("一个帅气逼人,温柔可爱,风流倜傥的美男子!\n#请问你还想聊什么?")layout.addWidget(label)