add action loop

This commit is contained in:
DasMoorhuhn 2024-12-12 03:34:02 +01:00
parent 7a80477890
commit f9c15707ef
11 changed files with 192 additions and 121 deletions

1
deb.sh Executable file
View File

@ -0,0 +1 @@
sudo apt-get install -y freeglut3-dev

View File

Before

Width:  |  Height:  |  Size: 712 B

After

Width:  |  Height:  |  Size: 712 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 606 B

After

Width:  |  Height:  |  Size: 606 B

View File

Before

Width:  |  Height:  |  Size: 604 B

After

Width:  |  Height:  |  Size: 604 B

View File

Before

Width:  |  Height:  |  Size: 604 B

After

Width:  |  Height:  |  Size: 604 B

View File

Before

Width:  |  Height:  |  Size: 578 B

After

Width:  |  Height:  |  Size: 578 B

4
requierements.txt Normal file
View File

@ -0,0 +1,4 @@
PyOpenGL
PyGObject-stubs
PyQt5
PyQt5-stubs

74
transparent_widget.py Normal file
View File

@ -0,0 +1,74 @@
from PyQt5.QtWidgets import QOpenGLWidget
from OpenGL.GL import *
from OpenGL.GLU import gluOrtho2D
class TransparentGLWidget(QOpenGLWidget):
def __init__(self, img):
super().__init__()
self.img = img
self.texture = None
self.image_width = 1
self.image_height = 1
def initializeGL(self):
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_DEPTH_TEST)
glClearColor(0.0, 0.0, 0.0, 0.0)
self.texture, self.image_width, self.image_height = self.load_texture()
def resizeGL(self, w, h):
glViewport(0, 0, w, h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, w, 0, h) # Orthografische Projektion für 2D
glMatrixMode(GL_MODELVIEW)
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glPushMatrix() # Matrix speichern
self.draw_textured_quad()
glPopMatrix() # Matrix wiederherstellen
def load_texture(self):
img_data = self.img.tobytes()
width, height = self.img.size
# Create OpenGL texture
texture_id = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture_id)
# Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
# Load texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)
return texture_id, width, height
def draw_textured_quad(self):
try:
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, self.texture)
width, height = self.width(), self.height()
glBegin(GL_QUADS)
glTexCoord2f(0.0, 0.0)
glVertex2f(0, 0) # Down left corner
glTexCoord2f(1.0, 0.0)
glVertex2f(width, 0) # Down right corner
glTexCoord2f(1.0, 1.0)
glVertex2f(width, height) # Up right corner
glTexCoord2f(0.0, 1.0)
glVertex2f(0, height) # Up left corner
glEnd()
glDisable(GL_TEXTURE_2D)
except:
pass

115
vpet.py
View File

@ -14,13 +14,14 @@ class Dialogs:
class Frames:
"""These strings do match to the PNGs of the VPet which are representation the frames of an animation"""
idle_1 = 'idle1'
idle_2 = 'idle2'
idle_3 = 'idle3'
move_1 = 'moving_1'
move_2 = 'moving_2'
hearts_1 = 'heart'
floating = 'floating'
def __init__(self):
self.idle_1 = Image.open('pets_sprites/demonite/idle1.png')
self.idle_2 = Image.open('pets_sprites/demonite/idle2.png')
self.idle_3 = Image.open('pets_sprites/demonite/idle3.png')
self.move_1 = Image.open('pets_sprites/demonite/moving_1.png')
self.move_2 = Image.open('pets_sprites/demonite/moving_2.png')
self.hearts_1 = Image.open('pets_sprites/demonite/heart.png')
self.floating = Image.open('pets_sprites/demonite/floating.png')
class Animations:
@ -53,27 +54,88 @@ class Animations:
pass
class Activity:
def __init__(self):
self.is_idle = True
self.is_sleeping = False
self.is_dreaming = False
self.is_moving = False
self.is_talking = False
self.is_thinking = False
self.is_interacting_with_user = False
def set_idle(self):
self.is_idle = True
self.is_sleeping = False
self.is_dreaming = False
self.is_moving = False
self.is_talking = False
self.is_thinking = False
self.is_interacting_with_user = False
def set_sleeping(self):
self.is_idle = False
self.is_sleeping = True
self.is_moving = False
self.is_talking = False
self.is_thinking = False
def set_dreaming(self):
self.is_idle = False
self.is_dreaming = True
self.is_moving = False
self.is_talking = False
self.is_thinking = False
def set_moving(self):
self.is_idle = False
self.is_moving = True
self.is_sleeping = False
self.is_dreaming = False
def set_talking(self):
self.is_idle = False
self.is_talking = True
self.is_thinking = False
self.is_sleeping = False
def set_thinking(self):
self.is_idle = False
self.is_talking = False
self.is_thinking = True
self.is_sleeping = False
def set_interacting_with_user(self):
self.is_idle = False
self.is_sleeping = False
self.is_dreaming = False
self.is_moving = False
self.is_talking = False
self.is_thinking = False
self.is_interacting_with_user = True
class VPet:
def __init__(self, x=0, y=0, screen=1):
def __init__(self, move, pos, draw, x=0, y=0, screen=1):
self.screen = screen
self.pos = pos
self.x_postion = x
self.y_postion = y
self.x_destination = 0
self.y_destination = 0
self.rotation = Rotate.up
self.is_idle = True
self.is_sleeping = False
self.is_dreaming = False
self.is_moving = False
self.is_talking = False
self.is_thinking = False
self.move = move
self.draw = draw
self.frames = Frames()
self.activity = Activity()
def reset_activity_to_idle(self):
self.is_idle = True
self.is_sleeping = False
self.is_dreaming = False
self.is_moving = False
self.is_talking = False
self.is_thinking = False
def action_loop(self):
print(f'Interacting with user: {self.activity.is_interacting_with_user}')
if self.activity.is_interacting_with_user: return
if self.activity.is_sleeping:
pass
def choose_walk_destination(self):
"""Decide, where the VPet should move to"""
@ -83,21 +145,20 @@ class VPet:
"""Decide, what kind of activity should be done"""
pass
def move(self, x: int, y: int):
def walk(self, x: int, y: int):
"""Move the VPet to xy"""
self.is_moving = True
self.activity.is_moving = True
def sleep(self):
"""Set the VPet asleep"""
self.reset_activity_to_idle()
self.is_sleeping = True
self.activity.set_sleeping()
Animations.sleep(rotation=self.rotation)
def wakeup(self):
"""Wake up the VPet from sleep"""
if not self.is_sleeping: return
if not self.activity.is_sleeping: return
Animations.wakeup(rotation=self.rotation)
self.reset_activity_to_idle()
self.activity.set_idle()
def blink_eyes(self):
"""Make the VPet blink"""

View File

@ -1,110 +1,35 @@
#!/bin/python3
import datetime
import time
import asyncio
from PyQt5.QtWidgets import QOpenGLWidget
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import Qt
from OpenGL.GL import *
from OpenGL.GLU import gluOrtho2D
from PIL import Image
from PyQt5.QtCore import Qt, QTimer
from transparent_widget import TransparentGLWidget
from vpet import Rotate
class TransparentGLWidget(QOpenGLWidget):
def __init__(self, image_path):
super().__init__()
self.image_path = image_path
self.texture = None
self.image_width = 1
self.image_height = 1
def initializeGL(self):
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_DEPTH_TEST)
glClearColor(0.0, 0.0, 0.0, 0.0)
# Textur init
self.texture, self.image_width, self.image_height = self.load_texture(self.image_path)
def resizeGL(self, w, h):
glViewport(0, 0, w, h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, w, 0, h) # Orthografische Projektion für 2D
glMatrixMode(GL_MODELVIEW)
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glPushMatrix() # Matrix speichern
self.draw_textured_quad()
glPopMatrix() # Matrix wiederherstellen
def load_texture(self, image_path):
img = Image.open(image_path).convert("RGBA")
img = img.rotate(angle=Rotate.up)
img_data = img.tobytes()
width, height = img.size
# Create OpenGL texture
texture_id = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture_id)
# Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
# Load texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)
return texture_id, width, height
def draw_textured_quad(self):
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, self.texture)
width, height = self.width(), self.height()
glBegin(GL_QUADS)
glTexCoord2f(0.0, 0.0)
glVertex2f(0, 0) # Down left corner
glTexCoord2f(1.0, 0.0)
glVertex2f(width, 0) # Down right corner
glTexCoord2f(1.0, 1.0)
glVertex2f(width, height) # Up right corner
glTexCoord2f(0.0, 1.0)
glVertex2f(0, height) # Up left corner
glEnd()
glDisable(GL_TEXTURE_2D)
from vpet import VPet
class MainWindow(QMainWindow):
def __init__(self, image_path):
def __init__(self):
super().__init__()
self.FPS = 60
# self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setWindowFlags(Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setCentralWidget(TransparentGLWidget(image_path))
self.click_event_time = 0
img = Image.open(image_path)
self.resize(img.width, img.height)
self.v_pet = VPet(self.move, self.pos, self.draw)
async def loop(self):
self.move(0, 0)
self.show()
print('Loop')
self.loop_timer = QTimer(self)
self.loop_timer.setSingleShot(False)
self.loop_timer.setInterval(self.FPS)
self.loop_timer.timeout.connect(self.loop)
self.loop_timer.start()
def mousePressEvent(self, event):
self.click_event_time = time.time()
self.v_pet.activity.set_interacting_with_user()
if event.button() == Qt.LeftButton:
self.drag_position = event.globalPos()
@ -115,7 +40,9 @@ class MainWindow(QMainWindow):
print('Click left')
if event.button() == Qt.RightButton:
print('Click right')
self.click_event_time = 0
self.v_pet.activity.is_interacting_with_user = False
def mouseMoveEvent(self, event):
self.click_event_time = 0
@ -124,12 +51,16 @@ class MainWindow(QMainWindow):
self.move(self.pos() + delta)
self.drag_position = event.globalPos()
def draw(self, img):
img = img.rotate(Rotate.up)
self.resize(img.width, img.height)
self.setCentralWidget(TransparentGLWidget(img))
async def start():
app = QApplication([])
image_path = 'pets_sprites/demonite/demonite_idle1.png' # Ersetze dies mit deinem Bildpfad
window = MainWindow(image_path)
await window.loop()
app.exec_()
def loop(self):
self.v_pet.action_loop()
self.show()
asyncio.run(start())
app = QApplication([])
window = MainWindow()
app.exec_()