forked from chrisknepper/Fractionauts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Game.py
195 lines (169 loc) · 8.89 KB
/
Game.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
import pygame
import os
import json
#import pygtk
from Button import Button
from Container import *
from Question import Question
from AnswerButton import AnswerButton
from Background import Background
from TextItem import TextItem
class Game(object):
def __init__(self, main):
self.main = main
self.buttons = []
self.gameScreenUI = []
self.currentAnswers = []
self.level_loaded = False
self.last_mousepressed = []
self.levelWon = False
self.failed_rocket = os.path.join('assets', 'rocket_down.png')
self.launching_rocket = os.path.join('assets', 'rocket_launch.png')
self.background_image = os.path.join('assets','Background.png')
self.background = Background(self.background_image)
self.background_rocket = Background(self.launching_rocket, 800, 675 - (self.main.currentLevel * 100))
print 'currentLevel is ' + str(self.main.currentLevel)
# Game playing screen buttons
self.emptyBtn = Button(750, 725, 200, 75, 'Reset', (206, 148, 73), (109, 78, 38))
self.menuBtn = Button(950, 725, 250, 75, 'Back to Menu', (202, 198, 82), (85, 83, 34))
self.doneBtn = Button(915, 625, 250, 75, 'Check Answer', (7,208,226), (4,111,121))
self.buttons.append(self.menuBtn)
self.buttons.append(self.emptyBtn)
self.buttons.append(self.doneBtn)
# Game screen text elements
self.scoreDisplay = TextItem(700, 0, 200, 75, ['Score: '], showRect = False)
self.levelDisplay = TextItem(900, 0, 300, 75, ['Current Level: '], showRect = False)
self.goalDisplay = TextItem(950, 240, 177, 60, ['Fill to: '], textColor= (255,255,255), showRect = False)
self.feedback_width = 600
self.feedback_height = 200
self.feedback_x = (self.main.width / 2) - (self.feedback_width / 2)
self.feedback_y = (self.main.height / 2) - (self.feedback_height / 2)
self.gameScreenUI.append(self.goalDisplay)
self.gameScreenUI.append(self.scoreDisplay)
self.gameScreenUI.append(self.levelDisplay)
self.winScreen = TextItem(self.feedback_x, self.feedback_y, self.feedback_width, self.feedback_height, ['Nice Job!', 'Click here to go on!'], (84, 194, 92), (39, 90, 43), True, Background(self.launching_rocket, self.feedback_x, self.feedback_y, self.feedback_width / 2, 100))
self.winScreen.close()
self.loseScreen = TextItem(self.feedback_x, self.feedback_y, self.feedback_width, self.feedback_height, ['Oops, that\'s not quite right.', 'Click here and try again.'], (209, 72, 72), (96, 33, 33), True, Background(self.failed_rocket, self.feedback_x, self.feedback_y, self.feedback_width / 2, 100))
self.loseScreen.close()
# Game screen elements
self.goalContainer = Container(950, 300, 0, 1, 177, 259, False)
self.goalFill = 1.0 #temporary goal fill amount #the number you are aiming for
def listenForEvents(self):
if self.level_loaded and 1 in pygame.mouse.get_pressed()\
and not (1 in self.last_mousepressed):
for answer in self.currentAnswers:
if answer.is_under(pygame.mouse.get_pos()):
print 'You clicked the ' + answer.text + ' answer'
answer.selected = not answer.selected
if answer.selected:
self.goalContainer.fill(self.goalContainer.filled+answer.filled)
else:
self.goalContainer.fill(self.goalContainer.filled-answer.filled)
if self.winScreen.drawing == True and self.winScreen.is_under(pygame.mouse.get_pos()):
self.winScreen.close()
if(self.checkLevelExists(self.main.currentLevel + 1)):
self.main.currentLevel += 1
self.main.set_mode('play')
else:
self.main.currentLevel = 0
self.main.set_mode('menu')
if self.loseScreen.drawing == True and self.loseScreen.is_under(pygame.mouse.get_pos()):
# close lose screen.
self.loseScreen.close()
#Play state buttons
for button in self.buttons:
if button.is_under(pygame.mouse.get_pos()):
print 'You clicked the ' + button.text + ' button'
#Menu button
if button == self.menuBtn:
self.main.set_mode('menu')
#Empty button
elif button == self.emptyBtn:
for answer in self.currentAnswers:
answer.selected = False
self.goalContainer.fill(0.0)
#Done button
#Evaluate the answer. If correct, return to main menu
# if incorrect, do nothing for now
elif button == self.doneBtn:
if self.evaluateAnswer():
self.winScreen.open()
self.levelWon = True
self.main.score = str(int(self.main.score) + 5)
else:
self.loseScreen.open()
print 'WRONG ANSWER'
self.last_mousepressed = pygame.mouse.get_pressed()
def renderScreen(self):
self.main.screen.fill((206, 156, 60))
self.background.draw(self.main.screen)
self.background_rocket.draw(self.main.screen)
self.goalContainer.draw(self.main.screen)
for button in self.buttons:
button.draw(self.main.screen)
for answer in self.currentAnswers:
answer.draw(self.main.screen)
for item in self.gameScreenUI:
item.draw(self.main.screen)
if(self.winScreen.drawing == True):
self.winScreen.draw(self.main.screen)
if(self.loseScreen.drawing == True):
self.loseScreen.draw(self.main.screen)
if not self.level_loaded:
self.main.screen.fill((0, 0, 0))
#Load the level-th JSON file in the levels folder
def loadLevel(self, level):
print 'loading level'
load_file = str(level) + '.json'
path = os.path.join('assets/levels', load_file)
try:
with open(path) as level_file:
level_data = json.load(level_file)
self.currentAnswers = []
self.arrangeAnswers(level_data["options"], 3, 75, 125, 225, 375)
answer = level_data["answer"].split("/")
self.goalFill = float(answer[0])/float(answer[1])
self.goalDisplay.setText(["Fill to: "+answer[0]+"/"+answer[1]])
print self.goalFill
level_file.close()
self.level_loaded = True
self.background_rocket.y = 600 - (self.main.currentLevel * 50)
self.levelDisplay.setText(["Current Level: " + str(self.main.currentLevel + 1)])
self.scoreDisplay.setText((["Score: " + str(self.main.score)]))
except IOError:
new_game = open(path, 'w')
new_game.close()
def checkLevelExists(self, level):
return os.path.exists(os.path.join('assets/levels', str(level) + '.json'))
#Arrange passed-in answers array in a grid with sensible default options
def arrangeAnswers(self, answers, perRow = 3, base_x = 100, \
base_y = 50, h_spacing = 200, v_spacing = 350):
#Starting our counter variables at 1 to avoid an additional if block
#(because we can never divide by 0 this way)
counter = 1
currentRow = 1
posInCurrentRow = -1 #Initialize current row position to -1
#so first answer isn't offset incorrectly
for answer in answers:
answer = answer.split("/")#get numerator and denominator
if(counter > currentRow * perRow):
currentRow = currentRow + 1
posInCurrentRow = 0
else:
posInCurrentRow = posInCurrentRow + 1
answer_x = base_x + (h_spacing * posInCurrentRow)
answer_y = base_y + ((currentRow - 1) * v_spacing)
temp = Container(answer_x, answer_y, int(answer[0]), int(answer[1]))
self.currentAnswers.append(temp)
counter = counter + 1
#Compare the main container's current filled percentage with the goal filled percentage
def evaluateAnswer(self):
#later we should have a more solid way to deal with float errors
print str(round(self.goalContainer.filled, 5))+" == "+str(round(self.goalFill, 5))
print round(self.goalContainer.filled, 5) == round(self.goalFill, 5)
return round(self.goalContainer.filled, 5) == round(self.goalFill, 5)
def enter(self):
print("entered play state")
self.levelWon = False
self.loadLevel(self.main.currentLevel)
self.goalContainer.fill(0)