-
Notifications
You must be signed in to change notification settings - Fork 1
/
game.py
297 lines (255 loc) · 9.87 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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
#2007-04-1 RJ Marsan
#Pylaga
#Original: 2007-02-20 Derek Mcdonald
#Subclass of pylaga.py
#################################################################################################################
#
#
# arguably the most important class, this is the game object
# it *is* the game. in an object.
#
#import pygame os and sys libraries
try:
import pygame, os, sys, math, random
from pygame.locals import*
import globalvars
from bullet import Bullet, EnemyBullet
from background import BackgroundManager, bgstars
from enemy import Enemy, EnemyManager
from player import Player
from stage import Stage
from display import *
from menu import Menu
from menulists import MenuLists,menulists
import ecollision
except:
print "A File Was Missing. CHECK!"
#sys.exit(0)
if not pygame.font: print 'Warning, fonts disabled'
#################################################################################################################
#now for the actual game class (I like classes. lets make classes of everything. rainbows are fun.)
class Gamelolz:
#This is the __init__
#its important.
def __init__(self,parent):
self.parent=parent
globalvars.asdf = 0
self.lagcount=0
self.leftkeydown=0
self.rightkeydown=0
self.enemylist=[]
self.list_enemys=EnemyManager()
self.stage=Stage(self.list_enemys,globalvars.player_list)
self.list_allie_shots=pygame.sprite.RenderUpdates()
self.enemy_shots=pygame.sprite.RenderUpdates()
#clears all the variables
def clear_vars(self):
self.leftkeydown=0
self.rightkeydown=0
health.set_health(globalvars.max_health)
points.set_points(0)
globalvars.x=400
globalvars.y=globalvars.WIN_RESY-60
self.stage.set_stage(-1) #hax
globalvars.enemy_bullet_odds=100
self.list_enemys.empty()
self.list_allie_shots.empty()
globalvars.player_list.empty()
self.enemy_shots.empty()
print "Game Restarted"
#define function to draw player ship on X, Y plane
def pship(self, x,y):
globalvars.player_list.clear(globalvars.surface,globalvars.screen)
self.enemylist+=globalvars.player_list.draw(globalvars.surface)
#Define function to move the enemy ship
def emove(self):
self.list_enemys.clear(globalvars.surface, globalvars.screen)
self.enemylist+=self.list_enemys.draw(globalvars.surface)
#draws all the enemys you ask it
def draw_enemys(self):
#k so now some recursive loops:
for enemycol in range(self.stage.get_stage()[0]):
#now for the rows
for enemyrow in range(self.stage.get_stage()[1]):
#make a new enemy object:
tempenemy=Enemy(self.list_enemys)
#this ones a long one, but it works:
tempenemy.set_pos(globalvars.xmin+enemycol*(globalvars.enemy_width+globalvars.enemy_spacing_x),globalvars.ymin+enemyrow*(globalvars.enemy_height+globalvars.enemy_spacing_y)-150)
#this one is even worse, but works even better:
tempenemy.set_range(globalvars.xmin+enemycol*(globalvars.enemy_width+globalvars.enemy_spacing_x),globalvars.xmax-(self.stage.get_stage()[0]-enemycol)*(globalvars.enemy_height+globalvars.enemy_spacing_x))
#now add the temp enemy to the array and we're good to go
self.list_enemys.add(tempenemy)
#So i'm trying out having the program check for collisions, instead of the enemy objects
#i think i might switch to the objects, but still keep this function just hand the computing to the object
#seems most efficient
def test_collision(self):
todie=pygame.sprite.groupcollide(self.list_enemys, self.list_allie_shots,0,0)
#print todie
for enemy,bullet in todie.iteritems():
self.list_allie_shots.remove(bullet)
enemy.set_state(0)
points.add_points(1)
if pygame.sprite.spritecollideany(self.player, self.enemy_shots):
#print "ZOMFG SHOTZORZ"
self.player.set_hit()
health.hit()
#if there are no enemys left, go to the next stage
def check_done(self):
if not self.list_enemys:
self.stage.next_stage()
self.draw_enemys()
#checks to see if we can expand the ranges of the bots so its nice and.... umm... nice.
def check_rows(self):
if globalvars.asdf % 20==0:
#simple sorting algorithm to find the highest values
highest=globalvars.xmin
lowest=globalvars.xmax
for enemy in self.list_enemys:
if enemy.get_range()[1] > highest:
highest=enemy.get_range()[1]
if enemy.get_range()[0] < lowest:
lowest=enemy.get_range()[0]
highest=globalvars.xmax-highest
lowest=lowest-globalvars.xmin
if highest != 0 or lowest != 0: #makes things |--| this much more efficient
for enemy in self.list_enemys:
erange=enemy.get_range()
enemy.set_range(erange[0]-lowest,erange[1]+highest)
#major hack just to get this thing playable..... sorry
def again(self):
if health.get_health() <= 0:
return False
return True
#this is called if the player shoots
def pshoot(self, sx, sy):
self.player.shoot(self.list_allie_shots,sx,sy)
#draws the bullet.... duh. come on dude.
def drawbullets(self):
#for x in self.list_allie_shots:
#x.draw()
self.list_allie_shots.clear(globalvars.surface,globalvars.screen)
self.enemy_shots.clear(globalvars.surface,globalvars.screen)
self.enemylist+=self.list_allie_shots.draw(globalvars.surface)
self.enemylist+=self.enemy_shots.draw(globalvars.surface)
#...
def drawsidepanel(self):
if globalvars.asdf%5==0:
globalvars.side_panel.update()
globalvars.side_panel.clear(globalvars.surface,globalvars.screen)
self.enemylist+=globalvars.side_panel.draw(globalvars.surface)
#goes through all the arrays and makes each of them move 1 space, simple and easy yet it deserves a comment...
def tick(self):
self.list_allie_shots.update()
self.list_enemys.update()
self.enemy_shots.update()
######################
#heres a bunch of metafunctions
#i break it up so its really easy to add new features
#like if we ant a counter? add something to check() and draw()
#all of these are called once per frame
def check(self):
self.check_done()
self.test_collision()
self.check_rows()
bgstars.update()
self.list_enemys.shoot(self.enemy_shots)
self.player.update()
def draw(self):
self.enemylist+=bgstars.draw()
self.enemylist+=bgstars.clear()
self.drawbullets()
self.pship(globalvars.x,globalvars.y)
self.emove()
self.drawsidepanel()
#does just what it sounds like.....
def clear_screen(self):
globalvars.surface.fill(globalvars.bgcolor)
pygame.display.flip()
#for debugging info mostly
def dispvars(self):
print "The Enemy Array size is:",len(self.list_enemys.sprites())
print "The Player Shot Array size is:",len(self.list_allie_shots.sprites())
print "The Enemy Shot Array size is:",len(self.enemy_shots.sprites())
#does lots and lots of stuff, it really needs to be cleaned up
def input(self, events):
global x
global y
pygame.event.pump() #somewhere in their docs it said this line was a good idea
for event in events:
if event.type == QUIT:
sys.exit(0)
if event.type == pygame.MOUSEMOTION:
pygame.event.get()
tempx=pygame.mouse.get_pos()[0]-self.player.rect.width/2
## Just to make sure we don't get the ship way out there:
if tempx > globalvars.xmax: #if its outside the globalvars.window, just stick it as far as possible
self.player.move(globalvars.xmax,globalvars.y)
elif tempx < globalvars.xmin:
self.player.move(globalvars.xmin,globalvars.y)
elif abs(tempx-globalvars.x) > globalvars.smooth_scroll_var1: #smooth scrolling if the mouse gets far from the ship
self.player.move(self.player.get_pos().left+(tempx-self.player.get_pos().left)/globalvars.smooth_scroll_var2,globalvars.y)
else: #if it gets down to this point,
#we've passed all sanity checks so just move it
self.player.move(tempx,globalvars.y)
## if the mouse is clicked, shoot!
if event.type == pygame.MOUSEBUTTONDOWN:
self.pshoot(self.player.rect.centerx-globalvars.BULLET_WIDTH/2,globalvars.y)
## if 'q' is pressed, quit
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
sys.exit(0)
if event.key == pygame.K_p:
menulists.pause_menu()
if event.key == pygame.K_ESCAPE:
sys.exit(0)
#keyboard controls
if event.key == pygame.K_LEFT:
self.leftkeydown=1
if event.key == pygame.K_RIGHT:
self.rightkeydown=1
if event.key == pygame.K_SPACE:
self.pshoot(self.player.rect.centerx-globalvars.BULLET_WIDTH/2,globalvars.y)
#keyboard controls
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
self.leftkeydown=0
if event.key == pygame.K_RIGHT:
self.rightkeydown=0
if self.leftkeydown: self.player.move_one(0)
if self.rightkeydown: self.player.move_one(1)
pygame.event.clear()
##################################################################################################################
#pretty simple
def start(self):
self.clear_vars()
self.player=Player()
globalvars.player_list.add(self.player)
self.player.set_pos(globalvars.x,globalvars.y)
self.loop()
#Yeah see this one does all of the work
def loop(self):
#start loop
while self.again():
#refresh globalvars.screen...needs to be done once in a while
if globalvars.asdf>=globalvars.REFRESH_TIME:
#self.clear_screen()
globalvars.asdf=0
globalvars.asdf+=1
#check everythign and see if changes need to be made
self.check()
#draw bullets
self.draw()
#move everything 1
self.tick()
#initiate input function
self.input(pygame.event.get())
#applies the smart screen updating
pygame.display.update(self.enemylist)
self.enemylist=[]
#pauses and waits
timeittook=globalvars.clock.tick(globalvars.FPS)
#if timeittook > 1000/globalvars.FPS:
# print "LAG:"+str(self.lagcount)+" at "+str(timeittook)+"ms"
#self.dispvars()
# self.lagcount+=1
#print globalvars.clock.get_fps()