Boomerang implementing logic - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Game Development (https://python-forum.io/forum-11.html) +--- Thread: Boomerang implementing logic (/thread-22078.html) |
Boomerang implementing logic - Piethon - Oct-28-2019 Hello everybody. I am making a game with pygame and till know there are different weapons such as a shurikan and a blowpipe. But now I wanted to implement a boomerang, and I don't know what to do, that it comes back to the player, after a certain amount of time. So in a settings file, I am defining my weapons (I'm posting the code of the shurikan, because I haven't implemented a boomerang yet. I first want to know how to make it coming back to the player): WEAPONS['shurikan'] = {'speed': 575, 'lifetime': 800, 'rate': 400, 'kickback': 0, 'spread': 3, 'damage': 8, 'size': 'shurikan', 'count': 1} Then we have the shoot section: class Player(pg.sprite.Sprite): def __init__(self, game, x, y): # I've left out the things that are not important for this question self.weapon = 'shurikan' self.shurikan = True self.shoot_ammo = True # Then there is key press stuff and now the shoot section def shoot(self): if self.shoot_ammo == True: now = pg.time.get_ticks() if now - self.last_shot > WEAPONS[self.weapon]['rate']: self.last_shot = now dir = vec(1, 0).rotate(-self.rot) pos = self.pos + BARREL_OFFSET.rotate(-self.rot) self.vel = vec(-WEAPONS[self.weapon]['rate'], 0).rotate(-self.rot) for i in range(WEAPONS[self.weapon]['count']): spread = uniform(-WEAPONS[self.weapon]['spread'], WEAPONS[self.weapon]['spread']) Blowpipe(self.game, pos, dir.rotate(spread))Then there is also a weapon class. class Blowpipe(pg.sprite.Sprite): # I haven't renamed the class yet but it is for all kind of weapons def __init__(self, game, pos, dir): self.groups = game.all_sprites, game.blowpipes pg.sprite.Sprite.__init__(self, self.groups) self.game = game self.image = game.blowpipe_images[WEAPONS[game.player.weapon]['size']] self.rect = self.image.get_rect() self.pos = vec(pos) self.rect.center = pos self.vel = dir * WEAPONS[game.player.weapon]['speed'] self.spawn_time = pg.time.get_ticks() self.rot = 360 def update(self): self.pos += self.vel * self.game.dt self.rect.center = self.pos if pg.sprite.spritecollideany(self, self.game.walls): self.kill() if pg.time.get_ticks() - self.spawn_time > WEAPONS[self.game.player.weapon]['lifetime']: self.kill()So I just posted some code here, because I want to know, how to make the boomerang coming back to the player and how to implement that in my code. Hope it is not so complicated for you to understand. Thanks for helping me. Piethon RE: Boomerang implementing logic - metulburr - Oct-28-2019 do you mean in a circle or from of the player and back in just a line? RE: Boomerang implementing logic - SheeppOSU - Oct-28-2019 If the boomerang is going to go in a straight line, simply do the same thing you did with the shurikan, but get the tick that it was thrown at, and after a certain amount of ticks, you can calculate the angle that it needs to move at to go back to the player. It'd have to calculate the angle each time since the player will be moving. Or, more realistically, if you plan on implementing this kind of feature at some point, it can come back in a straight line and land on the ground, which would be just as simple as throwing it forward. If you plan on having it go in an arch in the direction the player is facing, that would be a little more complicated. Instead of having ticks to keep track, the boomerang will move at one angle, and each time it moves, change the angle it's moving at so that it will eventually form an arch. Once it finishes its arch, or the angle becomes the opposite of what it started as, then since the player most likely moved, you would have to do the same thing that I described with the line, or have it drop on the ground. If you don't know about how you can move at angles, Windspar provided a good example here - https://python-forum.io/Thread-pygame-Moving-an-object-at-angles I hope this helps you. RE: Boomerang implementing logic - Piethon - Oct-29-2019 (Oct-28-2019, 09:49 PM)metulburr Wrote: do you mean in a circle or from of the player and back in just a line? Just back in a line to the player. RE: Boomerang implementing logic - nilamo - Oct-29-2019 Quote:def update(self): self.pos += self.vel * self.game.dt I think maybe if you add a decay setting for the velocity (which would be 0 for almost all weapons), you could have a boomerang decay over time so it's velocity was negative, which would then have it's position reverse and head back where it came. That wouldn't send it back to the player if they player happened to move first, though. Do you have a full example that's runnable (maybe a github repo) so we can play around with it? RE: Boomerang implementing logic - Piethon - Oct-31-2019 (Oct-29-2019, 04:34 PM)nilamo Wrote:Quote:def update(self): self.pos += self.vel * self.game.dt I didn't add a decay setting but I tried this: class Blowpipe(pg.sprite.Sprite): def __init__(self, game, pos, dir): # Stuff from my last post self.vel = dir * WEAPONS[game.player.weapon]['speed'] self.spawn_time = pg.time.get_ticks() self.rot = 360 self.last = pg.time.get_ticks() self.cooldown = 300 def update(self): if self.game.player.weapon == 'boomerang': now = pg.time.get_ticks() self.pos += self.vel * self.game.dt self.rect.center = self.pos if now - self.last >= self.cooldown: self.pos -= self.vel * self.game.dt self.pos += self.vel * self.game.dt self.rect.center = self.pos if pg.sprite.spritecollideany(self, self.game.walls): self.kill() if pg.time.get_ticks() - self.spawn_time > WEAPONS[self.game.player.weapon]['lifetime']: self.kill()What it does, is that is slow for 0.3 seconds and then it gets faster. But why is it not going backwards? RE: Boomerang implementing logic - nilamo - Oct-31-2019 if self.game.player.weapon == 'boomerang': self.pos += self.vel * self.game.dt if now - self.last >= self.cooldown: self.pos -= self.vel * self.game.dt self.pos += self.vel * self.game.dtI snipped a few things out to try to make it clearer. Line 5, you increase the position for every item, including boomerangs. Line 4, you decrease the position for boomerangs. So for boomerangs, it doesn't actually go backward, because you immediately move it forward again. RE: Boomerang implementing logic - Piethon - Oct-31-2019 I did it like that now, and it doesn't work: .... def update(self): self.pos += self.vel * self.game.dt self.rect.center = self.pos if self.game.player.weapon == 'boomerang': now = pg.time.get_ticks() self.pos += self.vel * self.game.dt self.rect.center = self.pos if now - self.last >= self.cooldown: self.pos -= self.vel * self.game.dtStill the same. First moving slow, then faster. RE: Boomerang implementing logic - SheeppOSU - Oct-31-2019 if now - self.last >= self.cooldown is true then its code will just counteract the one aboveI think you meant to do this def update(self): self.pos += self.vel * self.game.dt self.rect.center = self.pos if self.game.player.weapon == 'boomerang': now = pg.time.get_ticks() if now - self.last >= self.cooldown: self.pos -= self.vel * self.game.dt else: self.pos += self.vel * self.game.dt self.rect.center = self.pos RE: Boomerang implementing logic - Piethon - Nov-01-2019 (Oct-31-2019, 09:46 PM)SheeppOSU Wrote: if I did this and now it is flying the time of the cool down and then it just stands there and waits till it gets removed. My update section is looking like this: def update(self): self.pos += self.vel * self.game.dt self.rect.center = self.pos if self.game.player.weapon == 'boomerang': now = pg.time.get_ticks() if now - self.last >= self.cooldown: self.pos -= self.vel * self.game.dt else: self.pos += self.vel * self.game.dt self.rect.center = self.pos if pg.sprite.spritecollideany(self, self.game.walls): self.kill() if pg.time.get_ticks() - self.spawn_time > WEAPONS[self.game.player.weapon]['lifetime']: self.kill()What am I doing wrong? |