game.py 4.39 KB
Newer Older
1
2
3
4
5
6
7
8
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 18 18:34:40 2018

@author: Antoine Lima, Leo Reynaert, Domitille Jehenne
"""

9
import os
10
11
import logging

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

18
from replay import Replay
19
20
21
22
from module import Module
import modules
from ui.game_ui import Ui_Form as GameWidget

Antoine Lima's avatar
Antoine Lima committed
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
		
46
47
48
49
50
51
52
53
54
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
55
56
		self.ui.btnScore1.clicked.connect(lambda: self.goal(0))
		self.ui.btnScore2.clicked.connect(lambda: self.goal(1))
57
58
		
		self.replayer = Replay()
Antoine Lima's avatar
Antoine Lima committed
59
	
60
61
62
63
64
	def load(self):
		logging.debug('Loading GameModule')

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

Antoine Lima's avatar
Antoine Lima committed
69
		self.scores = [0, 0]
70
		self.updateScores()
71
72
73
74
75
76
77
78

	def unload(self):
		logging.debug('Unloading GameModule')
		del self.gameStartTime
		self.timerUpdateChrono.stop()
	
	def other(self, **kwargs):
		logging.debug('Other GameModule')
79
80
81
	
	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
82
		btnDiameter = self.mainwin.width()*0.4
83
84
85
86
87
88
89
90
91
92
93
94
		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
95
			self.goal(0)
96
		elif e.key() == Qt.Key_Right:
Antoine Lima's avatar
Antoine Lima committed
97
			self.goal(1)
98
99
100

	def updateChrono(self):
		# Updated each second
Antoine Lima's avatar
Antoine Lima committed
101
102
103
104
105
		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()
106

Antoine Lima's avatar
Antoine Lima committed
107
108
109
	def getGameTime(self):
		return self.gameStartTime.secsTo(QTime.currentTime())
	
110
	def updateScores(self):
Antoine Lima's avatar
Antoine Lima committed
111
112
113
114
115
116
117
118
119
120
121
122
123
124
		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
			replayFile = self.mainwin.getContent("replay{}.mp4".format(side))
			
125
126
127
128
129
130
131
132
133
134
			if os.path.exists(replayFile):
				self.showingReplay = True
				
				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)
Antoine Lima's avatar
Antoine Lima committed
135
136
137
138
139
140
141
	
	def endOfReplay(self, status):
		if status!=QMediaPlayer.PlayingState:
			self.ui.videoWidget.setFullScreen(False);
			self.showingReplay = False
			self.updateScores()
			
142
143
144

	def ui_handleClick_btnCancel(self):
		self.switchModule(modules.MenuModule)
Antoine Lima's avatar
Antoine Lima committed
145
146
147
148
149
150
151
		
	def checkEndGame(self):
		win = self.gameoverChecker.check(self.getGameTime(), self.scores)
		
		if win>=0:
			self.send(modules.EndGameModule, winner=win)
			self.switchModule(modules.EndGameModule)