You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
413 lines
16 KiB
Python
413 lines
16 KiB
Python
2 years ago
|
# /////
|
||
|
# Remake of 1869 in python
|
||
|
# ////
|
||
|
|
||
|
import pyglet
|
||
|
import Assets
|
||
|
import Labels
|
||
|
import Utils
|
||
|
import logging # TODO to be implemented
|
||
|
|
||
|
from pyglet.window import key
|
||
|
from pyglet.window import mouse
|
||
|
from pyglet.gl import *
|
||
|
from scenes import IntroScreen
|
||
|
from scenes import ConfigScreen
|
||
|
|
||
|
glEnable(GL_BLEND)
|
||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||
|
|
||
|
pyglet.gl.glClearColor(0.1, 0.1, 0.1, 1)
|
||
|
|
||
|
"""
|
||
|
naming conventions:
|
||
|
d_varname = dict
|
||
|
s_varname = set
|
||
|
l_varname = list
|
||
|
t_varname = tuple
|
||
|
b_varname = batch
|
||
|
og_varname = orderedGroup for z relation of graphics
|
||
|
"""
|
||
|
|
||
|
class main(pyglet.window.Window):
|
||
|
def __init__(self, width=640, height=480, fps=False, *args, **kwargs):
|
||
|
super(main, self).__init__(width, height,
|
||
|
caption='1869 Remake', *args, **kwargs)
|
||
|
self.x = 0
|
||
|
self.y = 0
|
||
|
self.WindowMinWidth = width
|
||
|
self.WindowMinHeight = height
|
||
|
self.currentWindowWidth = width
|
||
|
self.currentWindowHeight = height
|
||
|
# self.push_handlers(pyglet.window.event.WindowEventLogger())
|
||
|
# -> gibt aus welche events an das window geschickt wurden -> gut zum finden von events die manipuliert werden sollen
|
||
|
|
||
|
self.og_background = pyglet.graphics.OrderedGroup(0)
|
||
|
self.og_semi_background = pyglet.graphics.OrderedGroup(1)
|
||
|
self.og_semi_foreground = pyglet.graphics.OrderedGroup(2)
|
||
|
self.og_foreground = pyglet.graphics.OrderedGroup(3)
|
||
|
|
||
|
self.b_sprites = pyglet.graphics.Batch()
|
||
|
self.b_labels = pyglet.graphics.Batch()
|
||
|
self.b_widgets = pyglet.graphics.Batch()
|
||
|
|
||
|
self.mouse_x = 0
|
||
|
self.mouse_y = 0
|
||
|
self.alive = 1
|
||
|
|
||
|
self.activeScene = None
|
||
|
self.activeSceneName = None
|
||
|
self.sceneTransferPhase = 1
|
||
|
self.d_stopWatch = dict()
|
||
|
|
||
|
self.d_active_SpriteAnimations = dict()
|
||
|
self.d_active_LabelAnimations = dict()
|
||
|
self.d_active_WidgetAnimations = dict()
|
||
|
self.targetScene = 'INTRO'
|
||
|
self.d_active_sprites = dict()
|
||
|
self.d_active_labels = dict()
|
||
|
self.d_active_widgets = dict()
|
||
|
|
||
|
# TODO check if this widget system for text input can be used to imitate text lieferant from c# code
|
||
|
self.text_cursor = self.get_system_mouse_cursor('text')
|
||
|
self.focus = None
|
||
|
|
||
|
#####
|
||
|
# system funcs
|
||
|
#####
|
||
|
def on_resize(self, width, height):
|
||
|
width = max(width,self.WindowMinWidth)
|
||
|
height = max(height, self.WindowMinHeight)
|
||
|
super(main, self).on_resize(width, height)
|
||
|
|
||
|
currentScaleFactor_x = width/self.currentWindowWidth
|
||
|
currentScaleFactor_y = height/self.currentWindowHeight
|
||
|
|
||
|
self.currentWindowWidth = width
|
||
|
self.currentWindowHeight = height
|
||
|
if self.d_active_sprites is not None:
|
||
|
for keys, sprite in self.d_active_sprites.items():
|
||
|
sprite.scale_x = max(width, sprite.image.width)/min(width, sprite.width)
|
||
|
sprite.scale_y = max(sprite.image.height, height)/min(sprite.image.height, height)
|
||
|
if self.d_active_labels is not None:
|
||
|
for keys, label in self.d_active_labels.items():
|
||
|
label.content_width = label.content_width*(max(label.content_width, width)/ min(label.content_width, width))
|
||
|
label.content_height = label.content_height*(max(label.content_height, height)/ min(label.content_height, height))
|
||
|
label.x = label.x* currentScaleFactor_x
|
||
|
label.y = label.y* currentScaleFactor_y
|
||
|
label.font_size = label.font_size*currentScaleFactor_x
|
||
|
if self.d_active_widgets is not None:
|
||
|
for keys, widget in self.d_active_widgets.items():
|
||
|
#widget.width = width - 110
|
||
|
pass
|
||
|
|
||
|
def on_draw(self):
|
||
|
self.render()
|
||
|
|
||
|
def render(self):
|
||
|
self.clear()
|
||
|
|
||
|
self.b_sprites.draw()
|
||
|
self.b_labels.draw()
|
||
|
self.b_widgets.draw()
|
||
|
|
||
|
self.flip()
|
||
|
|
||
|
def on_close(self):
|
||
|
self.alive = 0
|
||
|
|
||
|
#####
|
||
|
# input Handler Funcs
|
||
|
#####
|
||
|
|
||
|
def on_mouse_motion(self, x, y, dx, dy):
|
||
|
# forward mouse information to active scene
|
||
|
self.activeScene.on_mouse_motion(self, x, y, dx, dy)
|
||
|
self.mouse_x = x
|
||
|
self.mouse_y = y
|
||
|
|
||
|
if self.d_active_widgets is not None:
|
||
|
for key,widget in self.d_active_widgets.items():
|
||
|
if widget.hit_test(x, y):
|
||
|
self.set_mouse_cursor(self.text_cursor)
|
||
|
break
|
||
|
else:
|
||
|
self.set_mouse_cursor(None)
|
||
|
|
||
|
def on_mouse_press(self, x, y, button, modifiers):
|
||
|
# forward mouse information to active scene
|
||
|
self.activeScene.on_mouse_press(self, x, y, button, modifiers)
|
||
|
if button == 1: # Left click
|
||
|
pass
|
||
|
for key,widget in self.d_active_widgets.items():
|
||
|
if widget.hit_test(x, y):
|
||
|
self.set_focus(widget)
|
||
|
break
|
||
|
else:
|
||
|
self.set_focus(None)
|
||
|
|
||
|
if self.focus:
|
||
|
self.focus.caret.on_mouse_press(x, y, button, modifiers)
|
||
|
|
||
|
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||
|
if self.focus:
|
||
|
self.focus.caret.on_mouse_drag(x, y, dx, dy, buttons, modifiers)
|
||
|
|
||
|
def on_key_press(self, symbol, modifiers):
|
||
|
# forward keypress information to active scene
|
||
|
self.activeScene.on_key_press(self, symbol, modifiers)
|
||
|
if symbol == key.ESCAPE:
|
||
|
self.alive = 0
|
||
|
if symbol == key.TAB:
|
||
|
if modifiers & key.MOD_SHIFT:
|
||
|
dir = -1
|
||
|
else:
|
||
|
dir = 1
|
||
|
|
||
|
if self.focus in self.d_active_widgets:
|
||
|
i = self.d_active_widgets.index(self.focus)
|
||
|
else:
|
||
|
i = 0
|
||
|
dir = 0
|
||
|
|
||
|
self.set_focus(self.d_active_widgets[(i + dir) % len(self.d_active_widgets)])
|
||
|
|
||
|
def on_text(self, text):
|
||
|
if self.focus:
|
||
|
self.focus.caret.on_text(text)
|
||
|
|
||
|
def on_text_motion(self, motion):
|
||
|
if self.focus:
|
||
|
self.focus.caret.on_text_motion(motion)
|
||
|
|
||
|
def on_text_motion_select(self, motion):
|
||
|
if self.focus:
|
||
|
self.focus.caret.on_text_motion_select(motion)
|
||
|
|
||
|
def set_focus(self, focus):
|
||
|
if self.focus:
|
||
|
self.focus.caret.visible = False
|
||
|
self.focus.caret.mark = self.focus.caret.position = 0
|
||
|
print('defocused')
|
||
|
self.focus = focus
|
||
|
if self.focus:
|
||
|
print('focused')
|
||
|
self.focus.caret.visible = True
|
||
|
self.focus.caret.mark = 0
|
||
|
self.focus.caret.position = len(self.focus.document.text)
|
||
|
#####
|
||
|
# stopwatch functions
|
||
|
####
|
||
|
|
||
|
def checkStopwatch(self, obj, targetSeconds):
|
||
|
"""
|
||
|
tracks time based operations for given objects
|
||
|
-> targetSeconds: returns true if current Timer is below /reached targetSeconds
|
||
|
"""
|
||
|
if obj in self.d_stopWatch:
|
||
|
if self.d_stopWatch[obj] <= targetSeconds:
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
else:
|
||
|
return False
|
||
|
|
||
|
def setStopwatch(self, obj, seconds):
|
||
|
if obj not in self.d_stopWatch:
|
||
|
self.d_stopWatch[obj] = seconds
|
||
|
return True
|
||
|
else:
|
||
|
# not allowed to set a timer on an object twice
|
||
|
return False
|
||
|
|
||
|
def stopwatch_tick(self):
|
||
|
for obj in self.d_stopWatch:
|
||
|
self.d_stopWatch[obj] -= 1
|
||
|
|
||
|
def clearStopwatchTask(self, obj):
|
||
|
if obj in self.d_stopWatch:
|
||
|
self.d_stopWatch.pop(obj)
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
|
||
|
def clearStopwatch(self):
|
||
|
self.d_stopWatch.clear()
|
||
|
|
||
|
#####
|
||
|
# resource loaders
|
||
|
#####
|
||
|
def load_sprites(self):
|
||
|
"""
|
||
|
load all sprites used in the specific scene
|
||
|
"""
|
||
|
if isinstance(self.activeScene, IntroScreen.IntroScene):
|
||
|
return {
|
||
|
'max_design_intro_sprite': pyglet.sprite.Sprite(Assets.max_design_intro_image, batch=self.b_sprites, group=self.og_background),
|
||
|
'artwork_intro_sprite': pyglet.sprite.Sprite(Assets.artwork_intro_image, batch=self.b_sprites, group=self.og_background),
|
||
|
'programmers_intro_sprite': pyglet.sprite.Sprite(Assets.programmers_intro_image, batch=self.b_sprites, group=self.og_background),
|
||
|
'music_intro_sprite': pyglet.sprite.Sprite(Assets.music_intro_image, batch=self.b_sprites, group=self.og_background),
|
||
|
'title_intro_sprite': pyglet.sprite.Sprite(Assets.title_intro_image, batch=self.b_sprites, group=self.og_background),
|
||
|
'blackscreen': pyglet.sprite.Sprite(Assets.blackScreen, batch=self.b_sprites, group=self.og_foreground),
|
||
|
}
|
||
|
if isinstance(self.activeScene, ConfigScreen.ConfigScene):
|
||
|
return {
|
||
|
'configSprite': pyglet.sprite.Sprite(Assets.configScreen, batch=self.b_sprites, group=self.og_background),
|
||
|
'blackscreen': pyglet.sprite.Sprite(Assets.blackScreen, batch=self.b_sprites, group=self.og_foreground),
|
||
|
}
|
||
|
|
||
|
def load_labels(self):
|
||
|
"""
|
||
|
load all labels used in the specific scene
|
||
|
"""
|
||
|
if isinstance(self.activeScene, IntroScreen.IntroScene):
|
||
|
return {
|
||
|
'press_enter': pyglet.text.Label(text="Press Enter", font_name=None, font_size=10, color=(255, 255, 255, 0), x=(self.width*7/10), y=(self.height*2/7), anchor_x='center', batch=self.b_labels, group=self.og_semi_foreground),
|
||
|
}
|
||
|
if isinstance(self.activeScene, ConfigScreen.ConfigScene):
|
||
|
return {}#CONFIG has no preset Labels -> they are created by the scene on demand
|
||
|
|
||
|
def load_widgets(self):
|
||
|
"""
|
||
|
load all widgets used in the specific scene
|
||
|
"""
|
||
|
if isinstance(self.activeScene, ConfigScreen.ConfigScene):
|
||
|
return {
|
||
|
'mainInput': Utils.TextWidget("-TEST TEXT-", x=(self.width/2 )-50, y=self.height/2, width=100 ,batch=self.b_widgets),
|
||
|
'textController':Utils.ControledTextBox(x=(self.width/2 )-50, y=(self.height/2) - 50, width=100 , height = 150, batch=self.b_widgets),
|
||
|
}
|
||
|
|
||
|
def load_sounds(self):
|
||
|
"""
|
||
|
load all sound resources -> probably optimize for scenes
|
||
|
"""
|
||
|
return {
|
||
|
}
|
||
|
|
||
|
#####
|
||
|
# maintanence funcs
|
||
|
#####
|
||
|
def clear_externalLabel(self, target=None):
|
||
|
pass
|
||
|
|
||
|
def register_externalLabel(self, keyName, text, x, y, width, batch):
|
||
|
if keyName in self.d_active_labels:
|
||
|
return False
|
||
|
else:
|
||
|
self.d_active_labels[keyName]
|
||
|
|
||
|
|
||
|
def clear_animationLists(self, target=None):
|
||
|
if target in [None, 'sprites']:
|
||
|
self.d_active_SpriteAnimations.clear()
|
||
|
if target in [None, 'labels']:
|
||
|
self.d_active_LabelAnimations.clear()
|
||
|
if target in [None, 'widgets']:
|
||
|
self.d_active_WidgetAnimations.clear()
|
||
|
|
||
|
def register_animation(self, anim, wantedAnimation):
|
||
|
"""
|
||
|
registers anims to be animated by custom animations
|
||
|
"""
|
||
|
if isinstance(anim, pyglet.sprite.Sprite):
|
||
|
if anim in self.d_active_SpriteAnimations:
|
||
|
return False
|
||
|
else:
|
||
|
self.d_active_SpriteAnimations[anim] = wantedAnimation
|
||
|
elif isinstance(anim, pyglet.text.Label):
|
||
|
if anim in self.d_active_LabelAnimations:
|
||
|
return False
|
||
|
else:
|
||
|
self.d_active_LabelAnimations[anim] = wantedAnimation
|
||
|
else:
|
||
|
if anim in self.d_active_WidgetAnimations:
|
||
|
return False
|
||
|
else:
|
||
|
self.d_active_WidgetAnimations[anim] = wantedAnimation
|
||
|
|
||
|
def run_AnimationManager(self):
|
||
|
"""
|
||
|
animates all registered animations that are currently active
|
||
|
"""
|
||
|
l_deactivateAnims = list()
|
||
|
for sprite, animationType in self.d_active_SpriteAnimations.items():
|
||
|
# forward sprite animation infos to active scene
|
||
|
self.activeScene.maintain_SpriteAnimations(l_deactivateAnims, sprite, animationType)
|
||
|
for label, animationType in self.d_active_LabelAnimations.items():
|
||
|
# forward label animation infos to active scene
|
||
|
self.activeScene.maintain_LabelAnimations(l_deactivateAnims, label, animationType)
|
||
|
for widget, animationType in self.d_active_WidgetAnimations.items():
|
||
|
# forward label animation infos to active scene
|
||
|
self.activeScene.maintain_WidgetAnimations(l_deactivateAnims, widget, animationType)
|
||
|
# when all anims are played out active anims must be cleared for finished ones
|
||
|
for anim in l_deactivateAnims:
|
||
|
if isinstance(anim, pyglet.sprite.Sprite):
|
||
|
self.d_active_SpriteAnimations.pop(anim, None)
|
||
|
if isinstance(anim, pyglet.text.Label):
|
||
|
self.d_active_LabelAnimations.pop(anim, None)
|
||
|
if isinstance(anim, Utils.TextWidget):
|
||
|
self.d_active_WidgetAnimations.pop(anim, None)
|
||
|
|
||
|
def activate_scene(self, scene):
|
||
|
self.activeScene = scene
|
||
|
self.activeSceneName = self.activeScene.sceneName
|
||
|
|
||
|
def transferToScene(self, originScene, targetScene):
|
||
|
"""
|
||
|
transfers from a scene to a scene
|
||
|
phase false = no transition
|
||
|
phase 1 = origin is deactivated
|
||
|
phase 2 = target is loaded
|
||
|
"""
|
||
|
if self.sceneTransferPhase is False:
|
||
|
self.sceneTransferPhase = 1
|
||
|
if self.sceneTransferPhase is 1:
|
||
|
if self.activeScene is None :
|
||
|
self.sceneTransferPhase = 2
|
||
|
elif self.activeScene.isAlive is False:
|
||
|
self.activeScene.killSprites(self,self.d_active_sprites)
|
||
|
self.activeScene.killLabels(self,self.d_active_labels)
|
||
|
self.activeScene.killWidgets(self,self.d_active_widgets)
|
||
|
self.sceneTransferPhase = 2
|
||
|
if self.sceneTransferPhase is 2:
|
||
|
if self.targetScene is "INTRO":
|
||
|
self.activate_scene(IntroScreen.IntroScene())
|
||
|
if self.targetScene is "CONFIG":
|
||
|
self.activate_scene(ConfigScreen.ConfigScene())
|
||
|
self.d_active_sprites = self.load_sprites()
|
||
|
self.d_active_labels = self.load_labels()
|
||
|
self.d_active_widgets = self.load_widgets()
|
||
|
self.activeScene.prepareSprites(self, self.d_active_sprites)
|
||
|
self.activeScene.prepareLabels(self, self.d_active_labels)
|
||
|
self.activeScene.prepareWidgets(self,self.d_active_widgets)
|
||
|
self.targetScene = False
|
||
|
self.sceneTransferPhase = False
|
||
|
|
||
|
def checkSceneTransfers(self):
|
||
|
"""
|
||
|
check if any scene transferes have to be made
|
||
|
"""
|
||
|
#scenetransfer is broken -> repair + more control (e.g. introscene)
|
||
|
if self.activeScene is None:
|
||
|
self.transferToScene(self.activeScene,self.targetScene)
|
||
|
elif self.activeScene.isInTransfer is True or self.sceneTransferPhase is 1:
|
||
|
self.transferToScene(self.activeScene,self.targetScene)
|
||
|
|
||
|
#####
|
||
|
# main loop
|
||
|
#####
|
||
|
def run(self):
|
||
|
while self.alive == 1:
|
||
|
self.run_AnimationManager()
|
||
|
self.checkSceneTransfers()
|
||
|
if self.activeScene is not None:
|
||
|
self.targetScene = self.activeScene.run(self)
|
||
|
self.render()
|
||
|
event = self.dispatch_events()
|
||
|
|
||
|
|
||
|
# Programm starting point
|
||
|
if __name__ == '__main__':
|
||
|
game = main(resizable=True)
|
||
|
game.run()
|