Commit 19dd30b9 authored by Antoine Lima's avatar Antoine Lima

End screen and video replay

parent b2caf55c
Pipeline #28317 failed with stages
......@@ -3,6 +3,7 @@
pyuic5 --import-from=ui ui/main.ui -o ui/main_ui.py
pyuic5 --import-from=ui ui/menu.ui -o ui/menu_ui.py
pyuic5 --import-from=ui ui/game.ui -o ui/game_ui.py
pyuic5 --import-from=ui ui/endgame.ui -o ui/endgame_ui.py
pyuic5 --import-from=ui ui/options.ui -o ui/options_ui.py
pyuic5 --import-from=ui ui/auth2p.ui -o ui/auth2p_ui.py
pyuic5 --import-from=ui ui/leaderboard.ui -o ui/leaderboard_ui.py
......
......@@ -8,6 +8,7 @@ Created on Wed Apr 18 18:34:40 2018
import sys
import logging
from os.path import dirname, abspath, join
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QGraphicsBlurEffect
......@@ -16,8 +17,6 @@ from PyQt5.QtCore import QTime, Qt
from ui.main_ui import Ui_MainWindow
from modules import *
#acceptedKeys = [Qt.Key_Escape, Qt.Key_Enter, Qt.Key_Return, Qt.UpArrow, Qt.DownArrow, Qt.LeftArrow, Qt.RightArrow]
class MainWin(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
......@@ -30,11 +29,22 @@ class MainWin(QtWidgets.QMainWindow):
#bgBlur.setBlurRadius(5)
#self.ui.panels.setGraphicsEffect(bgBlur)
# Set the content folder's path
self._contentFolder = join(dirname(dirname(abspath(__file__))), 'content')
print(self._contentFolder)
# Module loading
self.modules = [MenuModule, GameModule, OptionsModule, AuthModule, LeaderboardModule]
self.modules = [
MenuModule(self),
AuthModule(self),
GameModule(self),
EndGameModule(self),
LeaderboardModule(self),
OptionsModule(self)
]
for mod in self.modules:
self.ui.panels.addWidget(mod(self))
self.ui.panels.addWidget(mod)
self.ui.panels.setCurrentIndex(0)
self.ui.panels.currentWidget().setFocus()
......@@ -51,6 +61,9 @@ class MainWin(QtWidgets.QMainWindow):
def displaySystemTime(self):
self.ui.lcdTime.display(QTime.currentTime().toString("hh:mm:ss"))
def getContent(self, path):
return join(self._contentFolder, path)
if __name__=='__main__':
app = QtWidgets.QApplication(sys.argv)
......
......@@ -18,29 +18,46 @@ class Module(QtWidgets.QWidget):
def __init__(self, parent=None, widget=None):
# UI Setup
QtWidgets.QWidget.__init__(self, parent)
self.parent_win = parent
self.mainwin = parent
self.ui = widget
self.ui.setupUi(self)
def find(self, type):
mod_idx = [i for i, x in enumerate(self.mainwin.modules) if isinstance(x, type)]
return -1 if len(mod_idx)==0 else mod_idx[0]
def switchModule(self, new_type):
panel_idx = self.parent_win.modules.index(new_type)
curmod_idx = self.find(type(self))
newmod_idx = self.find(new_type)
if panel_idx<0:
logging.error('Error: unknown panel {}'.format(new_type))
if curmod_idx<0:
logging.error('Unknown panel {}'.format(type(self)))
elif newmod_idx<0:
logging.error('Unknown panel {}'.format(new_type))
else:
self.parent_win.ui.panels.currentWidget().releaseKeyboard()
# Unfocus the current module
self.mainwin.ui.panels.currentWidget().releaseKeyboard()
if QApplication.focusWidget() != None:
QApplication.focusWidget().clearFocus()
self.parent_win.ui.panels.currentWidget().unload()
self.parent_win.ui.panels.setCurrentIndex(panel_idx)
# Swap modules by unloading, changing the ui then loading
self.mainwin.modules[curmod_idx].unload()
self.mainwin.ui.panels.setCurrentIndex(newmod_idx)
self.mainwin.modules[newmod_idx].load()
self.parent_win.ui.panels.currentWidget().load()
# Select first element of the Module
self.parent_win.ui.panels.currentWidget().focusNextChild()
self.parent_win.ui.panels.currentWidget().focusPreviousChild()
self.parent_win.ui.panels.currentWidget().grabKeyboard()
self.mainwin.modules[newmod_idx].focusNextChild()
self.mainwin.modules[newmod_idx].focusPreviousChild()
self.mainwin.modules[newmod_idx].grabKeyboard()
def send(self, to, **kwargs):
mod_idx = self.find(to)
if mod_idx<0:
logging.error('Unknown panel {}'.format(to))
else:
self.mainwin.modules[mod_idx].other(**kwargs)
def load(self):
logging.warning('Unimplemented method "load" for {}'.format(self.__class__))
......
from modules.auth import AuthModule
from modules.game import GameModule
from modules.endgame import EndGameModule
from modules.menu import MenuModule
from modules.options import OptionsModule
from modules.leaderboard import LeaderboardModule
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 18 18:34:40 2018
@author: Antoine Lima, Leo Reynaert, Domitille Jehenne
"""
import logging
from PyQt5 import QtWidgets
from PyQt5.QtGui import QRegion
from PyQt5.QtCore import QTime, QTimer, QRect, Qt
from module import Module
import modules
from ui.endgame_ui import Ui_Form as GameWidget
class EndGameModule(Module):
def __init__(self, parent=None):
super().__init__(parent, GameWidget())
self.screenTimeout = QTimer()
self.screenTimeout.timeout.connect(self.ui_handleClick_btnQuit)
self.screenTimeout.setSingleShot(True)
def load(self):
logging.debug('Loading EndGameModule')
self.ui.lblP2_2.setText('Player {}'.format(self.winner+1))
# Quit the screen after 5 seconds if the user doesn't do it before
self.screenTimeout.start(5000)
def unload(self):
logging.debug('Unloading EndGameModule')
self.screenTimeout.stop()
self.winner = -1
def other(self, **kwargs):
logging.debug('Other EndGameModule')
if 'winner' in kwargs:
self.winner = kwargs['winner']
def keyPressEvent(self, e):
if e.key() == Qt.Key_Escape or e.key() == Qt.Key_Return:
self.ui_handleClick_btnQuit()
def ui_handleClick_btnQuit(self):
self.switchModule(modules.MenuModule)
......@@ -10,40 +10,59 @@ import logging
from PyQt5 import QtWidgets
from PyQt5.QtGui import QRegion
from PyQt5.QtCore import QTime, QTimer, QRect, Qt
from PyQt5.QtCore import QTime, QTimer, QRect, Qt, QUrl
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from module import Module
import modules
from ui.game_ui import Ui_Form as GameWidget
class GameOverChecker():
def __init__(self, conditionType, limit):
self.conditionType = conditionType
self.limit = limit
def check(self, time, scores):
'''
Checks if a game is over and return the winner if that's the case
Either returns -1 if the game is not finished or the highest score's index (0 or 1)
Takes the game time is seconds and a list containing the two scores
'''
# Gets the index of the highest scoring player (either 0 or 1)
bestPlayer = scores.index(max(scores))
if self.conditionType=='score' and scores[bestPlayer]>=self.limit:
return bestPlayer
elif self.conditionType=='time' and time>self.limit:
return bestPlayer
else:
return -1
class GameModule(Module):
def __init__(self, parent=None):
super().__init__(parent, GameWidget())
# Button setup
#print(str(self.ui.btnScore1.rect()))
#print(str(self.ui.btnScore2.rect()))
#region = QRegion(self.ui.btnScore1.rect(), QRegion.Ellipse);
#self.ui.btnScore1.setMask(region);
#self.ui.btnScore2.setMask(region);
# Timer managment
self.timerUpdateChrono = QTimer(self)
self.timerUpdateChrono.timeout.connect(self.updateChrono)
# Button connections
self.ui.btnScore1.clicked.connect(self.ui_handleClick_btnScore1)
self.ui.btnScore2.clicked.connect(self.ui_handleClick_btnScore2)
self.ui.btnScore1.clicked.connect(lambda: self.goal(0))
self.ui.btnScore2.clicked.connect(lambda: self.goal(1))
def load(self):
logging.debug('Loading GameModule')
self.gameStartTime = QTime.currentTime()
self.timerUpdateChrono.start(1000)
self.ui.lcdChrono.display(QTime(0,0).toString("hh:mm:ss"))
self.gameoverChecker = GameOverChecker('score', 10)
self.score1 = 0
self.score2 = 0
self.scores = [0, 0]
self.updateScores()
def unload(self):
......@@ -56,7 +75,7 @@ class GameModule(Module):
def resizeEvent(self, event):
# 40% of the window width to have (5% margin)-(40% circle)-(10% middle)-(40% circle)-(5% margin)
btnDiameter = self.parent_win.width()*0.4
btnDiameter = self.mainwin.width()*0.4
region = QRegion(QRect(0, 0, btnDiameter, btnDiameter), QRegion.Ellipse)
self.ui.btnScore1.setMinimumSize(btnDiameter, btnDiameter)
self.ui.btnScore2.setMinimumSize(btnDiameter, btnDiameter)
......@@ -69,26 +88,58 @@ class GameModule(Module):
if e.key() == Qt.Key_Escape:
self.ui_handleClick_btnCancel()
elif e.key() == Qt.Key_Left:
self.ui_handleClick_btnScore1()
self.goal(0)
elif e.key() == Qt.Key_Right:
self.ui_handleClick_btnScore2()
self.goal(1)
def updateChrono(self):
# Updated each second
elapsedSec = self.gameStartTime.secsTo(QTime.currentTime())
self.ui.lcdChrono.display(QTime(0,0).addSecs(elapsedSec).toString("hh:mm:ss"))
self.ui.lcdChrono.display(QTime(0,0).addSecs(self.getGameTime()).toString("hh:mm:ss"))
# Don't check scores while showing a replay to avoid closing the engame screen too soon
if not self.showingReplay:
self.checkEndGame()
def getGameTime(self):
return self.gameStartTime.secsTo(QTime.currentTime())
def updateScores(self):
self.ui.btnScore1.setText(str(self.score1))
self.ui.btnScore2.setText(str(self.score2))
def ui_handleClick_btnScore1(self):
self.score1 += 1
self.updateScores()
def ui_handleClick_btnScore2(self):
self.score2 += 1
self.updateScores()
self.ui.btnScore1.setText(str(self.scores[0]))
self.ui.btnScore2.setText(str(self.scores[1]))
self.checkEndGame()
def goal(self, side):
if side!=0 and side!=1:
logging.error('Wrong goal side: {}'.format(side))
else:
self.scores[side] += 1
# Show replay
# May require `sudo apt-get install qtmultimedia5-examples` in order to install the right libraries
self.showingReplay = True
replayFile = self.mainwin.getContent("replay{}.mp4".format(side))
self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
self.player.stateChanged.connect(self.endOfReplay)
self.player.setMuted(True)
self.player.setVideoOutput(self.ui.videoWidget)
self.player.setMedia(QMediaContent(QUrl.fromLocalFile(replayFile)))
self.player.play()
self.ui.videoWidget.setFullScreen(True)
def endOfReplay(self, status):
if status!=QMediaPlayer.PlayingState:
self.ui.videoWidget.setFullScreen(False);
self.showingReplay = False
self.updateScores()
def ui_handleClick_btnCancel(self):
self.switchModule(modules.MenuModule)
def checkEndGame(self):
win = self.gameoverChecker.check(self.getGameTime(), self.scores)
if win>=0:
self.send(modules.EndGameModule, winner=win)
self.switchModule(modules.EndGameModule)
......@@ -45,8 +45,11 @@ class MenuModule(Module):
elif e.key() == Qt.Key_Down:
self.parent().focusNextChild()
elif e.key() == Qt.Key_Return:
QApplication.focusWidget().animateClick()
if QApplication.focusWidget()==None:
logging.error('No focused widget to activate')
else:
QApplication.focusWidget().animateClick()
def ui_handleClick_btnExit(self):
logging.info('Closing..')
self.parent_win.close()
self.mainwin.close()
......@@ -48,12 +48,11 @@ class OptionsModule(Module):
def ui_handleClick_btnSave(self):
if self.ui.options.cellWidget(0, 1).currentText().lower() == 'true':
self.parent_win.showFullScreen()
#QWSServer::setCursorVisible(False);
self.mainwin.showFullScreen()
QApplication.setOverrideCursor(Qt.BlankCursor);
else:
self.parent_win.showNormal()
#QWSServer.setCursorVisible(True);
self.mainwin.showNormal()
QApplication.setOverrideCursor(Qt.ArrowCursor);
self.switchModule(modules.MenuModule)
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1280</width>
<height>720</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_5">
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="font">
<font>
<pointsize>40</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>The Winner is..</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignHCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>21</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_10">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="imgP1_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>400</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>300</width>
<height>300</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="assets.qrc">:/ui/img/placeholder_head.jpg</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>100</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lblP2_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="font">
<font>
<pointsize>25</pointsize>
</font>
</property>
<property name="text">
<string>Player 2</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_13">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>37</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources>
<include location="assets.qrc"/>
<include location="../../../../assets.qrc"/>
</resources>
<connections/>
</ui>
......@@ -64,6 +64,9 @@
<pointsize>70</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>0</string>
</property>
......@@ -114,6 +117,9 @@
<pointsize>70</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>0</string>
</property>
......@@ -188,8 +194,26 @@
</property>
</spacer>
</item>
<item>
<widget class="QVideoWidget" name="videoWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QVideoWidget</class>
<extends>QWidget</extends>
<header>PyQt5.QtMultimediaWidgets</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>360</height>
<width>1280</width>
<height>720</height>
</rect>
</property>
<property name="sizePolicy">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment