Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Help me find a way to make the lasers fire in a certain direction.
-
-
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. -
I tried placing it self.update, but then it wouldn’t work.
-
Can we please get the code full listing? Please use the
</>
icon above the post edit box to paste your code so it is formatted for this forum.
```
Insert Code Here
``` -
from scene import * import math import random import sound import ui A = Action() width, height = ui.get_screen_size() #Setting up meteorites #Setting up background colour for the entire scene class Game(Scene): def setup(self): self.bg = SpriteNode('spc:BackgroundBlack') self.lasers = [] self.items = [] self.LaserTime = 0 self.frame_counter = 0 self.meteor = [] #Creating the player self.Player = SpriteNode('iow:arrow_up_b_32') self.Player.color = (1.0, 1.0, 1.0) self.Player.anchor_point = (0.5, 0.5) self.Player.x_scale = 2/1.0 self.Player.y_scale = 3/1.0 self.Player.position = (512, 400) self.Player.rotation = 0.0 self.add_child(self.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.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) #The score label self.score_label = LabelNode(text='Score: 0') self.score_label.anchor_point = (0, 0) self.score_label.position = (10, 790) self.score_label.font = ('Joystix', 30) self.add_child(self.score_label) #Movement code. def update(self): self.handle_button_presses() self.move_lasers() self.update_lasers() self.spawn_meteor() width, height = ui.get_screen_size() self.LaserTime = self.LaserTime + 1 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 self.Player.position.x %= width self.Player.position.y %= height def move_lasers(self): for touch in self.touches.values(): if touch.location in self.laserButton.bbox and self.LaserTime >= 15: #reset the time self.LaserTime = 0 new_laser = SpriteNode('shp:Circle') new_laser.x_scale = 0.3/1.0 new_laser.y_scale = 0.3/1.0 new_laser.position = self.Player.position new_laser.rotation = self.Player.rotation self.add_child(new_laser) self.lasers.append(new_laser) sound.play_effect('arcade:Laser_6') def update_lasers(self): for l in self.lasers: l.direction = Vector2(-math.sin(l.rotation), math.cos(l.rotation))*10 l.position += l.direction if l.position.x < 0: l.remove_from_parent() self.lasers.remove(l) if l.position.x > 1112: l.remove_from_parent() self.lasers.remove(l) if l.position.y < 0: l.remove_from_parent() self.lasers.remove(l) if l.position.y > 834: l.remove_from_parent() self.lasers.remove(l) def spawn_meteor(self): self.frame_counter = self.frame_counter + 1 if self.frame_counter >= 60: self.frame_counter = 0 new_meteor = SpriteNode('spc:MeteorGraySmall1') new_meteor.position = (random.randint(0, 1024), 834) self.add_child(new_meteor) self.meteor.append(new_meteor) for meteor in self.meteor: meteor.position = (meteor.position.x, meteor.position.y - 5) if meteor.position.y < - 100: meteor.remove_from_parent() self.meteor.remove(meteor) if __name__ == '__main__': run(Game(), LANDSCAPE, show_fps=True)
-
So, (as is often the case...) I was wrong about how to do the wrap around when the player gets to the edge of the screen.
self.Player.position.x %= width self.Player.position.y %= height # must be changed to... self.Player.position = (self.Player.position.x % self.size.w, self.Player.position.y % self.size.h)
This is because position is a
scene.Point
which is scene.Vector2 which behaves more like a tuple than a list.Also, you can safely delete all lines containing
self.Player.location
. -
-
update_lasers()
can be simplified...def update_lasers(self): for laser in self.lasers: laser.direction = Vector2(-math.sin(laser.rotation), math.cos(laser.rotation))*10 laser.position += laser.direction if laser.position not in self.bounds: # laser has gone off the screen laser.remove_from_parent() self.lasers.remove(laser)
-
Also, it seems to me that you don't need both an Action that sets rotation and the actual assignment to rotation.. If you want to simulate acceleration, then you need to keep track of a velocity, and pressing the arrow button changes the velocity, and then the rotation is set by adding velocity.