-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsprites.py
176 lines (164 loc) · 6.99 KB
/
sprites.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
import pygame as pg
from settings import *
from combat import ask_a_question
class Player(pg.sprite.Sprite):
"""Player sprite class that takes the game class, x coord, y coord,
and picture as arguments."""
def __init__(self, game, x, y, image):
self.groups = game.all_sprites
pg.sprite.Sprite.__init__(self, self.groups)
self.game = game
self.image = pg.image.load(image)
self.rect = self.image.get_rect()
# defining x and y coordinate velocity, default 0
self.vx, self.vy = 0, 0
# sets the location of the sprite in pixels, but since we are using tiles we need to
# multiply by TILESIZE to get the appropriate coordinate in tiles
self.x = x * TILESIZE
self.y = y * TILESIZE
self.drawshift_x = 0
self.drawshift_y = 0
def get_keys(self):
# assumes velocity is 0 on both axis unless key is pressed
self.vx, self.vy = 0, 0
keys = pg.key.get_pressed()
# changes velocity based on the key, uses PLAYER_SPEED from settings.py
if keys[pg.K_LEFT] or keys[pg.K_a]:
self.vx = -PLAYER_SPEED
if keys[pg.K_RIGHT] or keys[pg.K_d]:
self.vx = PLAYER_SPEED
if keys[pg.K_UP] or keys[pg.K_w]:
self.vy = -PLAYER_SPEED
if keys[pg.K_DOWN] or keys[pg.K_s]:
self.vy = PLAYER_SPEED
# Fixes diagonals going double speed, 0.7071 is derived from pythragians theorem
if self.vx != 0 and self.vy != 0:
self.vx *= 0.7071
self.vy *= 0.7071
def collision_check(self, dir, sprite_group, kill_var):
"""Collision checking method. Takes axis (x or y) and sprite group as arguments."""
if dir == "x":
# spritecollide has 3 arguments: self, the sprite group you are checking, and
# True or False depending if you want the object to disappear when you collide
hits = pg.sprite.spritecollide(self, sprite_group, kill_var)
if hits:
if sprite_group == self.game.monsters:
pygame.mixer.Sound.play(monsterohsnap)
ask_a_question()
if sprite_group == self.game.bosses:
pygame.mixer.Sound.play(bosstentacles)
print("Boss collision!")
ask_a_question()
pygame.mixer.Sound.play(bossdead)
# aligns the side of player sprite with side of wall
if self.vx > 0:
# pygame.mixer.Sound.play(wall)
self.x = hits[0].rect.left - self.rect.width
if self.vx < 0:
self.x = hits[0].rect.right
# sets x velocity to 0 due to collision
self.vx = 0
self.rect.x = self.x
if dir == "y":
hits = pg.sprite.spritecollide(self, sprite_group, kill_var)
if hits:
if sprite_group == self.game.monsters:
pygame.mixer.Sound.play(ohnomonster)
ask_a_question()
if sprite_group == self.game.bosses:
pygame.mixer.Sound.play(bosstentacles)
print("Boss collision!")
ask_a_question()
pygame.mixer.Sound.play(bossdead)
# aligns the top / bottom of player sprite with bottom / top of wall
if self.vy > 0:
self.y = hits[0].rect.top - self.rect.height
if self.vy < 0:
self.y = hits[0].rect.bottom
# sets y velocity to 0 due to collision
self.vy = 0
self.rect.y = self.y
return False
def update(self):
if self.x > WIDTH - self.drawshift_x:
self.drawshift_x += -WIDTH
self.x = -self.drawshift_x
if self.x < -self.drawshift_x:
self.drawshift_x += WIDTH
self.x = WIDTH - self.drawshift_x
if self.y > HEIGHT - self.drawshift_y:
self.drawshift_y += -HEIGHT
self.y = -self.drawshift_y
if self.y < -self.drawshift_y:
self.drawshift_y += HEIGHT
self.y = HEIGHT - self.drawshift_y
# method for determining velocity
self.get_keys()
# updates current position based on velocity * time
self.x += self.vx * self.game.dt
self.y += self.vy * self.game.dt
# collision detection must be done separately for x and y to allow for
# sliding against a wall while also running into it
self.rect.x = self.x
self.collision_check('x', self.game.walls, False)
self.collision_check('x', self.game.monsters, True)
self.collision_check('x', self.game.bosses, True)
self.rect.y = self.y
self.collision_check('y', self.game.walls, False)
self.collision_check('y', self.game.monsters, True)
self.collision_check('y', self.game.bosses, True)
class Monster(pg.sprite.Sprite):
"""Monster sprite class that takes the game class, x coord, y coord,
and picture as arguments."""
def __init__(self, game, x, y, image):
self.groups = game.all_sprites, game.monsters
pg.sprite.Sprite.__init__(self, self.groups)
self.game = game
self.image = pg.image.load(image)
self.rect = self.image.get_rect()
self.x = x
self.y = y
def update(self):
self.rect.x = self.x * TILESIZE
self.rect.y = self.y * TILESIZE
class Boss(pg.sprite.Sprite):
"""Monster sprite class that takes the game class, x coord, y coord,
and picture as arguments."""
def __init__(self, game, x, y, image):
self.groups = game.all_sprites, game.bosses
pg.sprite.Sprite.__init__(self, self.groups)
self.game = game
self.image = pg.image.load(image)
self.rect = self.image.get_rect()
self.x = x
self.y = y
def update(self):
self.rect.x = self.x * TILESIZE
self.rect.y = self.y * TILESIZE
class Wall(pg.sprite.Sprite):
def __init__(self, game, x, y):
self.groups = game.all_sprites, game.walls
pg.sprite.Sprite.__init__(self, self.groups)
self.game = game
self.image = pg.Surface((TILESIZE, TILESIZE))
self.image.fill(BROWN)
self.rect = self.image.get_rect()
self.x = x
self.y = y
self.rect.x = x * TILESIZE
self.rect.y = y * TILESIZE
# self.image.set_colorkey(GREEN) # makes the green wall transparent, comment out to see them
class Minimap(pg.sprite.Sprite):
def __init__(self, game, x, y, dungeon):
self.groups = game.all_sprites
pg.sprite.Sprite.__init__(self, self.groups)
self.game = game
self.dungeon = dungeon
self.size = 6*TILESIZE
self.image = pg.Surface((self.size, self.size))
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.x = x
self.y = y
self.rect.x = self.x * TILESIZE
self.rect.y = self.y * TILESIZE