/
Player.py
203 lines (173 loc) · 7.11 KB
/
Player.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
import SimpleGUICS2Pygame.simpleguics2pygame as simplegui
from KeyBoard import KeyBoard
from Sprite import Sprite
from Vector import Vector
from Bullet import Bullet
import os
import pygame
SCREENWIDTH = 1280
SCREENHEIGHT = 720
class Player(Sprite):
def __init__(self, image,image_alternate, columns, rows):
super().__init__(image,image_alternate, columns, rows)
pygame.mixer.pre_init(44100, -16, 1, 512) # Prevents Pygame sound delay: https://www.reddit.com/r/pygame/comments/8gsoue/delayed_audio_in_pygame/
self.lives = 2
self.moving = False
self.dead = False
self.shooting = False
self.jumping = False
#self.rolling = False
self.invincible = False
self.bullets = []
self.velocity = Vector(0, 0)
self.pos = Vector(SCREENWIDTH/2, SCREENHEIGHT - 20)
self.gravity = Vector(0, 0)
self.frameCounter = 0
self.deadCounter = 0
self.inAir = False
# Sound effects for the player
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
soundeffect = os.path.join(__location__, 'Sounds/classic_hurt.ogg')
self.oof = simplegui._load_local_sound(soundeffect)
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
soundeffect = os.path.join(__location__, 'Sounds/gunSound.ogg')
self.pew = simplegui._load_local_sound(soundeffect)
self.pew.set_volume(.25)
def update(self):
if self.frameCounter % 10 == 0:
self.updateFrame()
self.updateVel()
self.updateAcceleration()
self.pos += self.velocity
# Checks to stop player going off the screen
if self.pos.getP()[1] > SCREENHEIGHT - 100:
self.pos = Vector(self.pos.getP()[0], 620)
elif self.pos.getP()[1] < 0:
self.pos = Vector(self.pos.getP()[0], 1)
self.jumping = False
if self.pos.getP()[0] > SCREENWIDTH - 25:
self.pos = Vector(1255, self.pos.getP()[1])
elif self.pos.getP()[0] < 25:
self.pos = Vector(25, self.pos.getP()[1])
self.frameCounter += 1
# Custom draw method for the player sprite as the sprite sheet is more complex and had some issues
def draw(self, canvas):
if self.right:
centreDest = (self.pos.getP()[0], self.pos.getP()[1])
centerSource = [self.frameSize[i] * self.currentFrame[i] + self.frameCentre[i] for i in [0, 1]]
canvas.draw_image(self.image, centerSource, self.frameSize, centreDest, self.sizeDest)
else:
centreDest = (self.pos.getP()[0], self.pos.getP()[1])
centerSource = [(self.width - (self.frameSize[0] * self.currentFrame[0] + self.frameCentre[0])), (self.frameSize[1] * self.currentFrame[1] + self.frameCentre[1])]
canvas.draw_image(self.alternateimage, centerSource, self.frameSize, centreDest, self.sizeDest)
# Updating the frame depending on the animation
def updateFrame(self):
self.currentFrame[0] += 1
# Death animation
if self.lives <= 0:
self.deadCounter += 1
self.currentFrame[1] = 8
if self.currentFrame[0] > 5:
self.dead = True
# Rolling Animation (Not used in final game)
#elif self.rolling:
# self.currentFrame[1] = 7
# # Run rolling animation
# if self.currentFrame[0] >= 4:
# self.currentFrame[0] = 0
# self.rolling = False
# Jumping while not shooting
elif self.jumping and not self.shooting:
self.currentFrame[1] = 5
if self.currentFrame[0] >= 6:
self.currentFrame[0] = 4
# Shooting while still
elif self.shooting and not self.moving:
self.currentFrame[1] = 2
if self.currentFrame[0] >= 8:
self.currentFrame[0] = 0
# Shooting while moving
elif self.moving and self.shooting:
self.currentFrame[1] = 4
if self.currentFrame[0] >= 8:
self.currentFrame[0] = 0
# Moving while not shooting
elif self.moving and not self.shooting:
self.currentFrame[1] = 3
if self.currentFrame[0] >= 8:
self.currentFrame[0] = 0
# Doing nothing
else:
self.currentFrame[1] = 1
if self.currentFrame[0] >= 8:
self.currentFrame[0] = 0
# Updating the velocity
def updateVel(self):
if self.moving:
# Change horizontal velocity
if self.right:
self.velocity = Vector(5, self.velocity.getP()[1])
else:
self.velocity = Vector(-5, self.velocity.getP()[1])
self.velocity = Vector(self.velocity.getP()[0] * 0.94, self.velocity.getP()[1])
self.velocity += self.gravity
if self.jumping:
self.velocity = Vector(self.velocity.getP()[0], -10)
# Updating the acceleration
def updateAcceleration(self):
if self.inAir and not self.jumping:
self.gravity = Vector(0, 3)
else:
self.gravity = Vector(0, 0)
# Spawns a non hostile bullet
def shoot(self):
self.pew.play()
xStart, yStart = self.pos.getP()
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
imagenormal = os.path.join(__location__, 'images/sprites/boomerangbullet.png')
imagealternate = os.path.join(__location__, 'images/sprites/boomerangbulletleft.png')
# Sets velocity of bullet repective to direction the player is facing
if self.right:
vel = Vector(6, 0)
right = True
xStart += 60
else:
vel = Vector(-6, 0)
right = False
xStart -= 60
startPos = Vector(xStart, yStart + 30)
return Bullet(startPos, vel, False, "bullet", right, imagenormal, imagealternate, 8, 1)
# Following methods to be called in interaction class after user inputs to switch boolean variables
def startMoving(self):
if self.lives > 0:
self.moving = True
def startShooting(self):
if self.lives > 0:
self.shooting = True
self.bullets.append(self.shoot())
self.currentFrame[0] = 2
#def startRoll(self):
# if self.lives > 0:
# self.rolling = True
def startJump(self):
if self.lives > 0:
self.jumping = True
self.inAir = True
# Called from interaction class when user input ends
def stopJump(self):
if self.lives > 0:
self.jumping = False
def stopMoving(self):
if self.lives > 0:
self.moving = False
def stopShooting(self):
if self.lives > 0:
self.shooting = False
# Called from interaction class following collision
def removeLife(self):
if not self.invincible and self.lives > 0:
self.lives -= 1
self.oof.set_volume(1)
self.oof.play()
if self.lives == 0:
self.currentFrame[0] = 0