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

# /////
# 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()