add action loop
|
Before Width: | Height: | Size: 712 B After Width: | Height: | Size: 712 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 606 B After Width: | Height: | Size: 606 B |
|
Before Width: | Height: | Size: 604 B After Width: | Height: | Size: 604 B |
|
Before Width: | Height: | Size: 604 B After Width: | Height: | Size: 604 B |
|
Before Width: | Height: | Size: 578 B After Width: | Height: | Size: 578 B |
4
requierements.txt
Normal file
@ -0,0 +1,4 @@
|
||||
PyOpenGL
|
||||
PyGObject-stubs
|
||||
PyQt5
|
||||
PyQt5-stubs
|
||||
74
transparent_widget.py
Normal 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
@ -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"""
|
||||
|
||||
119
window_qt.py
@ -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_()
|
||||
|
||||