I am new level coder, and I making a game that has different kinds of attacks, and I want to be able to combo into attacks seemlessly, but I cannot figure out how to make a delay between different attacks. So far I have tried to use to the same value that is the attack delay so that if the delay is reset, you can use a different attack, but it is not letting me do that because it doesn't know what the variable "now" is because I need "now" needs to be specifically in that function. Here is the code:
class Player(pg.sprite.Sprite):
def __init__(self, game):
self.game = game
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((30, 35))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
self.pos = vec(WIDTH / 2, HEIGHT / 2)
self.vel = vec(0, 0)
self.acc = vec(0, 0)
self.attack_counter = 0
self.dt = 0.2
# this is all the attack delay stuff
self.last_attack = 100
self.last_attack_n_light_right = 700
self.last_attack_s_light_right = 425
self.last_attack_d_light_right = 700
self.last_attack_s_air_right = 425
self.last_attack_n_light_left = 700
self.last_attack_s_light_left = 425
self.last_attack_d_light_left = 700
self.last_attack_n_air = 425
self.last_attack_s_air_left = 425
self.last_attack_d_air = 425
self.attack_delay = pg.time.get_ticks()
self.attack_delay_n_light_right = pg.time.get_ticks()
self.attack_delay_s_light_right = pg.time.get_ticks()
self.attack_delay_d_light_right = pg.time.get_ticks()
self.attack_delay_s_air_right = pg.time.get_ticks()
self.attack_delay_n_light_left = pg.time.get_ticks()
self.attack_delay_s_light_left = pg.time.get_ticks()
self.attack_delay_d_light_left = pg.time.get_ticks()
self.attack_delay_n_air = pg.time.get_ticks()
self.attack_delay_s_air_left = pg.time.get_ticks()
self.attack_delay_d_air = pg.time.get_ticks()
self.move_delay = pg.time.get_ticks()
def jump(self):
# jump if jump key is pressed, and triple jumps are recharged when touching platforms
global player_jump_count
self.rect.x += 1
self.rect.x -= 1
player_jump_count -= 1
self.vel.y = -PLAYER_JUMP
hits = pg.sprite.spritecollide(self, self.game.platforms, False)
if hits:
player_jump_count = 3
if player_jump_count < 1:
self.vel.y = PLAYER_GRAV
def s_light_right(self):
keys = pg.key.get_pressed()
now = pg.time.get_ticks()
# print(now, " ", self.attack_delay_s_light_right)
if self.s_light_left.now - self.attack_delay_s_light_left > self.last_attack_s_light_left:
if keys[pg.K_d]:
if now - self.attack_delay_s_light_right > self.last_attack_s_light_right: # this is where the problem is
self.attack_delay_s_light_right = now
bullet = Bullet(self.rect.centerx + 20, self.rect.centery - 10, self.vel.x + 10, 0, 20, 20, self.dt)
self.game.all_sprites.add(bullet)
self.game.bullets.add(bullet)
def s_light_left(self):
keys = pg.key.get_pressed()
now = pg.time.get_ticks()
if keys[pg.K_a]:
if now - self.attack_delay_s_light_left > self.last_attack_s_light_left:
self.attack_delay_s_light_left = now
bullet = Bullet(self.rect.centerx - 20, self.rect.centery - 10, self.vel.x - 10, 0, 20, 20, self.dt)
self.game.all_sprites.add(bullet)
self.game.bullets.add(bullet)
def n_light_right(self):
keys = pg.key.get_pressed()
now = pg.time.get_ticks()
if not keys[pg.K_a] and not keys[pg.K_d] and not keys[pg.K_s]:
if now - self.attack_delay_n_light_right > self.last_attack_n_light_right:
self.attack_delay_n_light_right = now
bullet = Bullet(self.rect.centerx + 40, self.rect.centery - 40, 0, 0, 20, 20, self.dt)
self.game.all_sprites.add(bullet)
self.game.bullets.add(bullet)
def n_light_left(self):
keys = pg.key.get_pressed()
now = pg.time.get_ticks()
if not keys[pg.K_a] and not keys[pg.K_d] and not keys[pg.K_s]:
if now - self.attack_delay_n_light_left > self.last_attack_n_light_left:
self.attack_delay_n_light_left = now
bullet = Bullet(self.rect.centerx - 60, self.rect.centery - 40, 0, 0, 20, 20, self.dt)
self.game.all_sprites.add(bullet)
self.game.bullets.add(bullet)
def d_light_right(self):
keys = pg.key.get_pressed()
now = pg.time.get_ticks()
if keys[pg.K_s]:
if not keys[pg.K_a] and not keys[pg.K_d]:
if now - self.attack_delay_d_light_right > self.last_attack_d_light_right:
self.attack_delay_d_light_right = now
bullet = Bullet(self.rect.centerx + 40, self.rect.centery + 3.5, 0, 0, 30, 15, self.dt)
self.game.all_sprites.add(bullet)
self.game.bullets.add(bullet)
def d_light_left(self):
keys = pg.key.get_pressed()
now = pg.time.get_ticks()
if keys[pg.K_s]:
if not keys[pg.K_a] and not keys[pg.K_d]:
if now - self.attack_delay_d_light_left > self.last_attack_d_light_left:
self.attack_delay_d_light_left = now
bullet = Bullet(self.rect.centerx - 60, self.rect.centery + 3.5, 0, 0, 30, 15, self.dt)
self.game.all_sprites.add(bullet)
self.game.bullets.add(bullet)
def s_air_right(self):
keys = pg.key.get_pressed()
now = pg.time.get_ticks()
if keys[pg.K_d]:
if now - self.attack_delay_s_air_right > self.last_attack_s_air_right:
self.attack_delay_s_air_right = now
bullet = Bullet(self.rect.centerx + 20, self.rect.centery - 10, self.vel.x + 10, 0, 20, 20, self.dt)
self.game.all_sprites.add(bullet)
self.game.bullets.add(bullet)
def s_air_left(self):
keys = pg.key.get_pressed()
now = pg.time.get_ticks()
if keys[pg.K_a]:
if now - self.attack_delay_s_air_left > self.last_attack_s_air_left:
self.attack_delay_s_air_left = now
bullet = Bullet(self.rect.centerx - 20, self.rect.centery - 10, self.vel.x - 10, 0, 20, 20, self.dt)
self.game.all_sprites.add(bullet)
self.game.bullets.add(bullet)
def n_air(self):
keys = pg.key.get_pressed()
now = pg.time.get_ticks()
if not keys[pg.K_a] and not keys[pg.K_d] and not keys[pg.K_s]:
if now - self.attack_delay_n_air > self.last_attack_n_air:
self.attack_delay_n_air = now
bullet = Bullet(self.rect.centerx + 5, self.rect.centery - 60, 0, 0, 20, 20, self.dt)
bullet2 = Bullet(self.rect.centerx - 25, self.rect.centery - 60, 0, 0, 20, 20, self.dt)
self.game.all_sprites.add(bullet)
self.game.bullets.add(bullet)
self.game.all_sprites.add(bullet2)
self.game.bullets.add(bullet2)
def d_air(self):
keys = pg.key.get_pressed()
now = pg.time.get_ticks()
if keys[pg.K_s]:
if not keys[pg.K_a] and not keys[pg.K_d]:
if now - self.attack_delay_d_air > self.last_attack_d_air:
self.attack_delay_d_air = now
bullet = Bullet(self.rect.centerx + 5, self.rect.centery + 60, 0, 12, 20, 20, self.dt)
bullet2 = Bullet(self.rect.centerx - 25, self.rect.centery + 60, 0, 12, 20, 20, self.dt)
self.game.all_sprites.add(bullet)
self.game.bullets.add(bullet)
self.game.all_sprites.add(bullet2)
self.game.bullets.add(bullet2)
def update(self):
self.acc = vec(0, PLAYER_GRAV)
keys = pg.key.get_pressed()
if keys[pg.K_a]:
self.acc.x = -PLAYER_ACC
if keys[pg.K_d]:
self.acc.x = PLAYER_ACC
# apply friction
self.acc.x += self.vel.x * PLAYER_FRICTION
# equations of motion
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
self.rect.midbottom = self.pos
It sounds like what you want is a object level variable: one that is common to and instance of the class and shared by all the member methods of that instance. That can be declared and used like this:
class foo:
def __init__(self, val):
self.now = val
def double_it(self):
return self.now * 2
>>> f = foo(10)
>>> f.double_it()
20
Edit to add:
It's not really clear from the question why you'd need this, but you do specify that the variable should not be included in __init__()
. If that is the case, it is possible to create instance attributes "on the fly" although it is usually not very good practice and leads to some rather unreadable code:
class bar:
def double_it(self, val):
self.now = val * 2
>>> b = bar()
>>> b.now <----- we expect this to fail; nothing has set `b.val` yet.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'bar' object has no attribute 'now'
>>> b.double_it(10)
>>> b.now
20
There is really no good reason for doing that though, and most linters will flag it (for example, pylint):
:attribute-defined-outside-init (W0201): *Attribute %r defined outside __init__*
Used when an instance attribute is defined outside the __init__ method. This
message belongs to the classes checker.
It would be better to set the value to None
in the constructor and then change it later.