Help me find a way to make the lasers fire in a certain direction.
-
I need the type of code so that depending on which direction button was pressed last, the lasers fires in that direction. My code so far only shoots in a positive x axis. I need it to shoot in negative x axis, and positive and negative y axis as well.
Here is my code so far:from scene import * import turtle import ui import math import random A = Action() #Setting up background colour for the entire scene class Game(Scene): def setup(self): self.bg = SpriteNode('spc:BackgroundBlack') self.lasers = [] #Creating the player self.Player = SpriteNode('shp:RoundRect') self.Player.color = ("cyan") self.Player.anchor_point = (0.5, 0) self.Player.position = (512, 400) self.add_child(self.Player) #Controlling the player self.UpCrtl = SpriteNode('iow:arrow_up_b_32') self.UpCrtl.x_scale = 3.5/1.0 self.UpCrtl.y_scale = 3.5/1.0 self.UpCrtl.alpha = 0.5 self.UpCrtl.position = (175, 295) self.add_child(self.UpCrtl) self.DownCrtl = SpriteNode('iow:arrow_down_b_32') self.DownCrtl.x_scale = 3.5/1.0 self.DownCrtl.y_scale = 3.5/1.0 self.DownCrtl.alpha = 0.5 self.DownCrtl.position = (175, 130) self.add_child(self.DownCrtl) self.RightCrtl = SpriteNode('iow:arrow_right_b_32') self.RightCrtl.x_scale = 3.5/1.0 self.RightCrtl.y_scale = 3.5/1.0 self.RightCrtl.alpha = 0.5 self.RightCrtl.position = (250, 212.5) self.add_child(self.RightCrtl) self.LeftCrtl = SpriteNode('iow:arrow_left_b_32') self.LeftCrtl.x_scale = 3.5/1.0 self.LeftCrtl.y_scale = 3.5/1.0 self.LeftCrtl.alpha = 0.5 self.LeftCrtl.position = (100, 212.5) self.add_child(self.LeftCrtl) #The button for shooting self.laserButton = SpriteNode('shp:Circle') self.laserButton.color = ('gray') self.laserButton.x_scale = 3/1 self.laserButton.y_scale = 3/1 self.add_child(self.laserButton) self.laserButton.position = (1000, 212.5) def update(self): for touch in self.touches.values(): if touch.location in self.LeftCrtl.bbox: #left button pressed new_x = self.Player.position.x - 5 if new_x >= 0 and new_x <= 1100: self.Player.position = (new_x, self.Player.position.y) if touch.location in self.RightCrtl.bbox: #right button pressed new_x = self.Player.position.x + 5 if new_x >= 0 and new_x <= 1100: self.Player.position = (new_x, self.Player.position.y) if touch.location in self.UpCrtl.bbox: new_y = self.Player.position.y + 5 if new_y >= 0 and new_y <= 800: self.Player.position = (self.Player.position.x, new_y) if touch.location in self.DownCrtl.bbox: new_y = self.Player.position.y - 5 if new_y >= 0 and new_y <= 800: self.Player.position = (self.Player.position.x, new_y) if touch.location in self.laserButton.bbox: new_laser = SpriteNode('spc:LaserBlue6') new_laser.position = (self.Player.position.x, self.Player.position.y + 60) self.add_child(new_laser) self.lasers.append(new_laser) for l in self.lasers: l.position = (l.position.x, l.position.y + 7.5) if l.position.y > 800: l.remove_from_parent() self.lasers.remove(l) if __name__ == '__main__': run(Game(), LANDSCAPE, show_fps=True)
-
I’m still working on it, but I added this:
def update_lasers(self): for l in self.lasers: l.direction = Vector2(0,1) l.rotation = self.Player.rotation l.position = l.position + l.direction
I just want to check if I’m getting side tracked or not.
-
When a laser is moving, it should move based on IT's rotation,not the player rotation. You might move after the laser gets fired, but you want the laser to go straight.
So delete the line updating the rotation. The rotation was set when you spawn the laser.
This code should work, but of course the laser always goes in one direction. So next, you can redefine
direction
using the l.rotation, similar to the way you calculated it when you spawn the laser
-
I think I’ve finally done it! It works, as it shoots in the way I want it, and keeps on travelling even when I haven’t touched it, thanks.
All I have to do is add a action so I can’t spam or hold down on the button. What is the best way to add this?
-
Also, I would also like to know how to code screen wrapping.
-
player.location.x %= screen.width player.location.y %= screen.height
-
Oh, thanks.
-
Wait, how do find the screen width and height? And what about location?
-
last edited by
-
Re spamming, one approach is, in your button handling code, to keep track of self.t, and self.lastfire_time. When current time minus last fire time is > some value, reset the last fire time to current time, and fire a laser. Otherwise, pass
BTW, in your laser loop, you will need to check if the laser is off screen (not in self.bounds), then delete the object from the scene. Otherwise your scene will eventually bog down or crash because it is moving millions of laser objects.
This could also be done in your check_collisions method where you see if your lasers hit your enemies.
-
@cvp And what about location?
-
position
, not location.If you want to wrap, you need to fundamentally change your button logic, since you check limits
-
I have added this:
width, height = ui.get_screen_size()
And then added this later:
if self.Player.position.x <= 0 or self.Player.position.x >= 1112:
self.Player.position.x %= width
if self.Player.position.y <= 0 or self.Player.position.y >= 834:
self.Player.position.y %= height
This didn’t work. I checked if I had gotten the width and height variables in a seperate script, and I did. I am now stumped.
-
What do you think your if statement does?
-
Whenever the Players position.x is equal to or smaller than 0 or whenever the position.x is equal to or greater than 1112, you do the remainder of the division of the screen height.
-
Post your button handling code again... You used to have checks that the new position was in the screen.
You actually don't need the if statements --
You could say player.position.x%=self.width, which will always cause it to wrap around.
-
Here you go:
def handle_button_presses(self): rotationAdd = math.pi/180 self.Player.location = self.Player.position for touch in self.touches.values(): if touch.location in self.LeftCrtl.bbox: actions = [A.rotate_by(math.pi/180)] self.Player.rotation = self.Player.rotation + rotationAdd self.Player.run_action(A.sequence(actions)) if touch.location in self.RightCrtl.bbox: actions = [A.rotate_by(math.pi/-180)] self.Player.rotation = self.Player.rotation - rotationAdd self.Player.run_action(A.sequence(actions)) if touch.location in self.UpCrtl.bbox: direction = Vector2(-math.sin(self.Player.rotation), math.cos(self.Player.rotation)) self.Player.position += direction*3 if self.Player.position.x <= 0 or self.Player.position.x >= 1112: self.Player.position.x %= width if self.Player.position.y <= 0 or self.Player.position.y >= 834: self.Player.position.y %= height
I did change the movement code a little.
-
@BurntRice said:
if self.Player.position.x <= 0 or self.Player.position.x >= 1112: self.Player.position.x %= width if self.Player.position.y <= 0 or self.Player.position.y >= 834: self.Player.position.y %= height
@JonB said:
You actually don't need the if statements
self.Player.position.x %= width self.Player.position.y %= height
-
Is width an height actually defined someplace?
What isn't working in your code? Is your player rotating and moving as expected? Is only the wrapping broken?
-
Only the wrapping.
-
width, height = ui.get_screen_size()
I think this is right. I did a seperate script where I print it out inside the console, and it worked.