0

I am trying to find a way to get the rotation of the ship and apply it to the beam so that it will travel in the direction it was shot in.. I really have no idea how I would do this but here is my code: Please excuse the messiness of it, I put comments in so you know whats what.

import sys, pygame, math, time;
from pygame.locals import *;
spaceship = ('spaceship.png')
mouse_c = ('crosshair.png')
backg = ('background.jpg')
fire_beam = ('beams.png')
pygame.init()
screen = pygame.display.set_mode((800, 600))
bk = pygame.image.load(backg).convert_alpha()
mousec = pygame.image.load(mouse_c).convert_alpha()
space_ship = pygame.image.load(spaceship).convert_alpha()
f_beam = pygame.image.load(fire_beam).convert_alpha()
f_beam = pygame.transform.scale(f_beam, (50, 50))
f_beam_rect = f_beam.get_rect()
clock = pygame.time.Clock()
pygame.mouse.set_visible(False)
space_ship_rect = space_ship.get_rect()
space_ship_rect.centerx = 375
space_ship_rect.centery = 300
speed = 3.5
pressed_down = 0
while True:
    clock.tick(60)
    screen.blit(bk, (0, 0))
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == MOUSEBUTTONDOWN and event.button == 3:
            pressed_down = 1
        elif event.type == MOUSEBUTTONUP:
            pressed_down = 0
        if pressed_down == 1:
            x, y = pygame.mouse.get_pos()
            x1, y1 = x - space_ship_rect.x, y - space_ship_rect.y
            angle = math.atan2(y1, x1)
            dx = speed*math.cos(angle)
            dy = speed*math.sin(angle)
            movex = space_ship_rect.centerx = space_ship_rect.centerx + dx#ship x
            movey = space_ship_rect.centery = space_ship_rect.centery + dy#ship y
        if event.type == MOUSEMOTION:
            x1, y1 = pygame.mouse.get_pos()
            x2, y2 = space_ship_rect.x, space_ship_rect.y
            dx, dy = x2 - x1, y2 - y1
            rads = math.atan2(dx, dy)
            degs = math.degrees(rads)
            display_s = pygame.transform.rotate(space_ship, (degs))#rotation of ship
        if event.type == MOUSEBUTTONDOWN and event.button == 1:
            #Is it possible for me to get the degree rotation of the space_ship and apply it to here so the beam will travel in the direction it was shot in?
    screen.blit(display_s, (space_ship_rect.centerx, space_ship_rect.centery))
    pos = pygame.mouse.get_pos()
    screen.blit(mousec, (pos))
    pygame.display.update()
6
  • Please double check the indentation before posting a code(Python spc.) I have formatted the code but I want you to ensure it. Commented Nov 24, 2013 at 15:24
  • You mean a laser beam is fired from a space ship and you want to fire the beam in the direction the spaceship is oriented? Commented Nov 24, 2013 at 15:26
  • @adil Yes, the indentation is now correct sorry about that, and yes that is what i'm looking for adil :) Commented Nov 24, 2013 at 15:35
  • 1
    You have spaceship angle (and dx, dy) so use it for laser beam. Commented Nov 24, 2013 at 15:42
  • Then why don't you just calculate the slope between your cross-hair and spaceship and also i will recommend if you attach a gun to your spaceship (a point) and use it to calculate the slope Commented Nov 24, 2013 at 15:43

2 Answers 2

2

I see you have problem with ship rotation.

If you create rotated spaceship display_s you get image with different size than space_ship size so you have to get display_s rectangle and assign spaceship center to display_s center.

 display_s_rect = display_s.get_rect( center=spaceship_rect.center)

Now you have to use display_s_rect to display display_s

 screen.blit(display_s, display_s_rect)

By the way:

blit() expect position where to put left top corner of blited image on screen.

With

screen.blit(display_s, (space_ship_rect.centerx, space_ship_rect.centery))

left top corner of display_s will be put in (space_ship_rect.centerx, space_ship_rect.centery) but I think you want to put display_s center in (space_ship_rect.centerx, space_ship_rect.centery)

Assign center values (as before) to (space_ship_rect.centerx, space_ship_rect.centery) but use (space_ship_rect.x, space_ship_rect.y) in blit().

You can use space_ship_rect in place of (space_ship_rect.x, space_ship_rect.y) in blit() with the same result.


I think you have the same problem with mousec position in blit().

Get mousec rectangle, assign mouse position to rectangle center and than use rectangle x,y to blit.

 mousec_rect = mousec.get_rect( center = pygame.mouse.get_pos() )
 screen.blit(mousec, mousec_rect)

EDIT:

your mainloop after my modification - now ship is rotate as it should

display_s = space_ship # default value at start when ship wasn't rotate

while True:
    clock.tick(60)
    screen.blit(bk, (0, 0))
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == MOUSEBUTTONDOWN and event.button == 3:
            pressed_down = 1
        elif event.type == MOUSEBUTTONUP:
            pressed_down = 0
        if pressed_down == 1:
            x, y = pygame.mouse.get_pos()
            x1, y1 = x - space_ship_rect.x, y - space_ship_rect.y
            angle = math.atan2(y1, x1)
            dx = speed*math.cos(angle)
            dy = speed*math.sin(angle)
            movex = space_ship_rect.centerx = space_ship_rect.centerx + dx#ship x
            movey = space_ship_rect.centery = space_ship_rect.centery + dy#ship y
        if event.type == MOUSEMOTION:
            x1, y1 = pygame.mouse.get_pos()
            x2, y2 = space_ship_rect.centerx, space_ship_rect.centery
            dx, dy = x2 - x1, y2 - y1
            rads = math.atan2(dx, dy)
            degs = math.degrees(rads)

            display_s = pygame.transform.rotate(space_ship, (degs))#rotation of ship
            display_s_rect = display_s.get_rect(center = space_ship_rect.center)            

        if event.type == MOUSEBUTTONDOWN and event.button == 1:
            #Is it possible for me to get the degree rotation of the space_ship and apply it to here so the beam will travel in the direction it was shot in?
            pass

    screen.blit(display_s, display_s_rect)
    #screen.blit(display_s, space_ship_rect)

    pos = pygame.mouse.get_pos()
    mousec_rect = mousec.get_rect(centerx=pos[0], centery=pos[1])

    screen.blit(mousec, mousec_rect )

    pygame.display.update()
Sign up to request clarification or add additional context in comments.

Comments

0

Before the While Loop:
beam_speed=<somevalue>
f_beam_rect=space_ship_rect #initialise beam position
fired=False #check if beam is fired or not

Inside While Loop

##If beam is fired(right click) blit images through-out the path
if fired:
    b_angle = math.atan2(by1, bx1)
    bdx = beam_speed*math.cos(b_angle)
    bdy = beam_speed*math.sin(b_angle)
    f_beam_rect.centerx = f_beam_rect.centerx + bdx
    f_beam_rect.centery = f_beam_rect.centery + bdy
    screen.blit(f_beam,f_beam_rect)

for event in pygame.event.get():

    if event.type == QUIT:
        pygame.quit()
        sys.exit()

###If mouse is clicked then find the direction (mouse position and spaceship)

    elif event.type == MOUSEBUTTONDOWN and event.button == 1:
        bx, by = pygame.mouse.get_pos()
        bx1, by1 = bx - space_ship_rect.x, by - space_ship_rect.y
        fired=True

Now you can make a function which checks that beam collides with enemy objects and if True then stop blitting both the beam and that object.
Also reset the variable fired=False and reset beam position to start from spaceship again f_beam_rect=space_ship_rect

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.