game.py 4.28 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
#!/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

11
12
from PyQt5 import QtWidgets
from PyQt5.QtGui import QRegion
Antoine Lima's avatar
Antoine Lima committed
13
14
15
from PyQt5.QtCore import QTime, QTimer, QRect, Qt, QUrl
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
16
17
18
19
20

from module import Module
import modules
from ui.game_ui import Ui_Form as GameWidget

Antoine Lima's avatar
Antoine Lima committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
		
44
45
46
47
48
49
50
51
52
class GameModule(Module):
	def __init__(self, parent=None):
		super().__init__(parent, GameWidget())

		# Timer managment
		self.timerUpdateChrono = QTimer(self)
		self.timerUpdateChrono.timeout.connect(self.updateChrono)

		# Button connections
Antoine Lima's avatar
Antoine Lima committed
53
54
55
		self.ui.btnScore1.clicked.connect(lambda: self.goal(0))
		self.ui.btnScore2.clicked.connect(lambda: self.goal(1))
	
56
57
58
59
60
	def load(self):
		logging.debug('Loading GameModule')

		self.gameStartTime = QTime.currentTime()
		self.timerUpdateChrono.start(1000)
61
		self.ui.lcdChrono.display(QTime(0,0).toString("hh:mm:ss"))
Antoine Lima's avatar
Antoine Lima committed
62
63
		
		self.gameoverChecker = GameOverChecker('score', 10)
64

Antoine Lima's avatar
Antoine Lima committed
65
		self.scores = [0, 0]
66
		self.updateScores()
67
68
69
70
71
72
73
74

	def unload(self):
		logging.debug('Unloading GameModule')
		del self.gameStartTime
		self.timerUpdateChrono.stop()
	
	def other(self, **kwargs):
		logging.debug('Other GameModule')
75
76
77
	
	def resizeEvent(self, event):
		# 40% of the window width to have (5% margin)-(40% circle)-(10% middle)-(40% circle)-(5% margin)
Antoine Lima's avatar
Antoine Lima committed
78
		btnDiameter = self.mainwin.width()*0.4
79
80
81
82
83
84
85
86
87
88
89
90
		region = QRegion(QRect(0, 0, btnDiameter, btnDiameter), QRegion.Ellipse)
		self.ui.btnScore1.setMinimumSize(btnDiameter, btnDiameter)
		self.ui.btnScore2.setMinimumSize(btnDiameter, btnDiameter)
		self.ui.btnScore1.setMask(region)
		self.ui.btnScore2.setMask(region)
		
		QtWidgets.QWidget.resizeEvent(self, event)

	def keyPressEvent(self, e):
		if e.key() == Qt.Key_Escape:
			self.ui_handleClick_btnCancel()
		elif e.key() == Qt.Key_Left:
Antoine Lima's avatar
Antoine Lima committed
91
			self.goal(0)
92
		elif e.key() == Qt.Key_Right:
Antoine Lima's avatar
Antoine Lima committed
93
			self.goal(1)
94
95
96

	def updateChrono(self):
		# Updated each second
Antoine Lima's avatar
Antoine Lima committed
97
98
99
100
101
		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()
102

Antoine Lima's avatar
Antoine Lima committed
103
104
105
	def getGameTime(self):
		return self.gameStartTime.secsTo(QTime.currentTime())
	
106
	def updateScores(self):
Antoine Lima's avatar
Antoine Lima committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
		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()
			
136
137
138

	def ui_handleClick_btnCancel(self):
		self.switchModule(modules.MenuModule)
Antoine Lima's avatar
Antoine Lima committed
139
140
141
142
143
144
145
		
	def checkEndGame(self):
		win = self.gameoverChecker.check(self.getGameTime(), self.scores)
		
		if win>=0:
			self.send(modules.EndGameModule, winner=win)
			self.switchModule(modules.EndGameModule)