-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplatformer.py
More file actions
executable file
·259 lines (235 loc) · 11.1 KB
/
platformer.py
File metadata and controls
executable file
·259 lines (235 loc) · 11.1 KB
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
#!/usr/bin/python
import pygame, sys, argparse
from pygame.locals import *
from sprites import Player, Goomba
from world import Map
from globals import *
from inventory import *
VERSION = "v0.1-alpha"
# EDIT HERE TO FIT YOUR NEEDS #
screen_width = 1000
screen_height = 500
DEBUG = 1
# Load the graphics
# BLOCKS #
BLOCKGRAPHICS = { LAND : pygame.image.load(LAND),
SKY : pygame.image.load(SKY),
SHRINK : pygame.image.load(SHRINK),
GROW : pygame.image.load(GROW),
LEDGE: pygame.image.load(LEDGE) }
# SPRITES #
SPRITEGRAPHICS = { 'Goomba' : pygame.image.load(GOOMBA),
'Player' : pygame.image.load(PLAYER),
'Bullet' : pygame.image.load(BULLET) }
# OBJECTS #
OBJIMG = { '0' : pygame.image.load('img/empty.png'),
'100' : pygame.image.load(LAND),
'101' : pygame.image.load(SHRINK) }
# Inventory slot corrdinates #
SLOTCORD = []
invframe = pygame.Rect(200, 200, 330, 400)
invframe.center = screen_width/2, screen_height/2
innerframe = pygame.Rect(200, 200, 310, 160)
innerframe.bottomleft = invframe.left+10, invframe.bottom-10
left = innerframe.left+10
top = innerframe.top+10
objectframe = pygame.Rect(0, 0, 20, 20)
for raw in range(5):
for slot in range(10):
SLOTCORD.append([left, top])
left += 30
left = innerframe.left+10
top += 30
def argparser():
parser = argparse.ArgumentParser(description="Platformer - A simple RPG", epilog="Written by Data5tream and Octember", version="v0.1-beta")
parser.add_argument("-m", "--map", help="Use to select map file (Use map or map2) ", action="store")
args = parser.parse_args()
global selectedmap
if args.map == 'map':
selectedmap = 'map.db'
elif args.map == 'map2':
selectedmap = 'map2.db'
else: # Default map
selectedmap = 'map2.db'
def main():
# Initialize
pygame.init()
map = Map(selectedmap)
player = Player(map.start_position)
particles = pygame.sprite.Group([])
goombas = pygame.sprite.Group(map.enemies)
all_sprites = pygame.sprite.Group(map.enemies + [player])
screen_cols, screen_rows = screen_width / BLOCK_SIZE, screen_height / BLOCK_SIZE
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Platformer '+VERSION)
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 30)
invopen = 0 # True if the inventory is open, false if not.
dragging = 0 # True if dragging an item, false if not.
# Event loop
right_down, left_down = False, False
while 1:
for event in pygame.event.get():
if invopen == 0: # If inventory isn't opened do this:
if event.type == QUIT or event.type == KEYDOWN and event.key == K_ESCAPE: # Quit the game
return
elif event.type == KEYDOWN: # Handle pushed keys
if event.key in (K_LEFT, K_a):
left_down = True
player.move_left()
elif event.key in (K_RIGHT, K_d):
right_down = True
player.move_right()
elif event.key in (K_SPACE, K_w):
player.jump()
elif event.key == K_i:
invopen = 1
elif event.type == KEYUP: # Handle released keys
if event.key in (K_LEFT, K_a):
player.move_right() if right_down else player.stop_x()
left_down = False
elif event.key in (K_RIGHT, K_d):
player.move_left() if left_down else player.stop_x()
right_down = False
elif event.type == MOUSEBUTTONDOWN: # Handle mouse clicks
pos = pygame.mouse.get_pos()
bullet = player.shoot((pos[0] + screen_x, pos[1] + screen_y))
particles.add(bullet)
all_sprites.add(bullet)
elif invopen== 1: # If inventory is open do this:
if dragging == 0:
if event.type == QUIT:
return
elif event.type == KEYDOWN:
if event.key == K_ESCAPE or event.key == K_i:
invopen = 0
elif event.type == MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
if pos[0] in range(invframe.right-30, invframe.right) and pos[1] in range(invframe.top, invframe.top+30):
invopen = 0
for slot in range(50):
if pos[0] in range(SLOTCORD[slot][0], SLOTCORD[slot][0]+20) and pos[1] in range(SLOTCORD[slot][1], SLOTCORD[slot][1]+20):
#Drag the item if the selected slot is not empty
if inventory.content[slot][0] != 0:
dragItem = slot
dragging = 1
elif dragging:
if event.type == KEYDOWN:
if event.key == K_ESCAPE or event.key == K_i:
dragging = 0
# Drop the item in previous slot
elif event.type == MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
for slot in range(50):
# Test if there is a slot where the player clicked
if pos[0] in range(SLOTCORD[slot][0], SLOTCORD[slot][0]+20) and pos[1] in range(SLOTCORD[slot][1], SLOTCORD[slot][1]+20):
dragging = 0
inventory.content[slot], inventory.content[dragItem] = inventory.content[dragItem], inventory.content[slot]
else:
dragging = 0
# Return item to previous slot
'''
TODO: Add an inventory so we don't have to disable this entirely.
Add or remove land blocks from the selected square
pos = pygame.mouse.get_pos()
x, y = int(pos[0] + screen_x) / BLOCK_SIZE, int(pos[1] + screen_y) / BLOCK_SIZE
tile = map.grid[y][x]
if event.button == 1 and tile.color == LAND:
map.walls.remove(tile.rect)
tile.color = SKY
elif event.button == 3 and tile.color == SKY:
map.walls.append(tile)
tile.color = LAND
'''
elapsed_time = clock.tick()
# If player's healty drops beyond 0, end the game
if player.health <= 0:
# Player is death
pygame.quit()
print "[-] You have died!"
sys.exit()
# If all enemies were killed, quit game and display win message
if len(goombas) == 0:
# Player has won
pygame.quit()
print "[+] You have won!"
sys.exit()
# Update all creatures. O(v*N), N: number of sprites, v: size of sprite
for sprite in all_sprites:
sprite.update(elapsed_time, map)
# O(N^2)
collided_enemies = pygame.sprite.spritecollide(player, goombas, True)
for enemy in collided_enemies:
player.damage(10/Player.DEFENSE)
# Display damage and health message
if DEBUG:
print "[-] 10 Damage recieved from "+str(enemy)
print "[*] Player has now "+str(player.health)+" life points"
# O(N^2)
shot_enemies = pygame.sprite.groupcollide(goombas, particles, True, True) # KILL EM ALL
# Position screen
screen_x, screen_y = max(player.rect.x - 250, 0), max(player.rect.y - 250, 0)
screen_x = min(screen_x, map.width - screen_width)
screen_y = min(screen_y, map.height - screen_height)
# Draw the visible map
grid_x, grid_y = int(screen_x) / BLOCK_SIZE, int(screen_y) / BLOCK_SIZE
for row in map.grid[grid_y : grid_y + screen_rows + 1]:
for square in row[grid_x : grid_x + screen_cols + 1]:
# Select the correct block and blit it to the screen
screen.blit(BLOCKGRAPHICS[square.type], square.rect.move(-screen_x, -screen_y))
# Draw health bar
pygame.draw.rect(screen, (250, 0, 0), pygame.Rect(screen_width - 100, 5, player.health, 20), 0)
# Draw sprites (Creatures, bullets, etc)
for sprites in all_sprites:
screen.blit(SPRITEGRAPHICS[sprites.type], sprites.rect.move(-screen_x, -screen_y))
# Draw the inventory if necessary
if invopen:
invframe = pygame.Rect(200, 200, 330, 400)
invframe.center = screen_width/2, screen_height/2
innerframe = pygame.Rect(200, 200, 310, 160)
innerframe.bottomleft = invframe.left+10, invframe.bottom-10
left = innerframe.left+10
top = innerframe.top+10
objectframe = pygame.Rect(0, 0, 20, 20)
pygame.draw.rect(screen, (44, 44, 44), invframe)
pygame.draw.rect(screen, (88, 88, 88), innerframe)
objectframe = pygame.Rect(0, 0, 20, 20)
for raw in range(5):
for slot in range(10):
objectframe.topleft = left, top
pygame.draw.rect(screen, (100, 100, 100), objectframe)
# object[1] is the itemID, OBJIMG is a dictonary of loaded images
object = inventory.content[slot+(10*(raw-5))]
screen.blit(OBJIMG[str(object[0])], objectframe)
left += 30
left = innerframe.left+10
top += 30
statsrect = pygame.Rect(200, 200, 200, 200)
statsrect.top, statsrect.right = invframe.top+10, invframe.right-10
pygame.draw.rect(screen, (22, 22, 22), statsrect)
statsx, statsy = statsrect.left+10, statsrect.top+10
stats = font.render('Max. HP: '+str(Player.MAXHEALTH), True, (250, 250, 250), (22, 22, 22))
screen.blit(stats, (statsx, statsy))
statsy += 25
stats = font.render('Attack: '+str(Player.ATTACK), True, (250, 250, 250), (22, 22, 22))
screen.blit(stats, (statsx, statsy))
statsy += 25
stats = font.render('Defense: '+str(Player.DEFENSE), True, (250, 250, 250), (22, 22, 22))
screen.blit(stats, (statsx, statsy))
statsy += 25
stats = font.render('Speed: '+str(Player.SPEED), True, (250, 250, 250), (22, 22, 22))
screen.blit(stats, (statsx, statsy))
if dragging:
pos = pygame.mouse.get_pos()
objectframe.topleft = pos[0] , pos[1]
dobject = inventory.content[dragItem]
screen.blit(OBJIMG[str(dobject[0])], objectframe)
# Draw FPS if necessary
if DEBUG:
text = font.render('FPS: ' + str(1000 / elapsed_time), True, (0, 0, 0), (250, 250, 250))
screen.blit(text, text.get_rect())
# Update the screen
pygame.display.update()
if __name__ == '__main__':
argparser()
main()