I want the sprite to face the mouse, I think i have fixed most things but still some more problems

StackOverflow https://stackoverflow.com/questions/19514353

  •  01-07-2022
  •  | 
  •  

سؤال

I wanted the players image to face the crosshair which follows the mouse, I used a function to rotate the image and after solving many problems (incorrect angles, not using the function properly etc. etc.) I got it to rotate imagers but when I use it on the players image it doesn't work, firstly the players image does not even blit to the screen, secondly the game lags incredible, thirdly after moving the curse around for a while it returns this an error,

so this is my script:

#set up
import pygame, sys, random, time, math
from pygame.locals import *
from math import atan2, degrees, pi
pygame.init()

#variables end----------------------------------------------------------------

#imagers
grass = "grass_shit.png" #grass image
player_img = "shithead.png" #player name
ali_img = "shit_head2.png" #alien image
dead_screen = "dead_shit.png"
cross_hair = "crosshair.png"

#screen
screen = pygame.display.set_mode((850, 640),0,32) #set screen                       
background = pygame.image.load(grass).convert() #load image to screen

#character variables
char = pygame.image.load(player_img).convert_alpha() #covert player image
player_x, player_y = 0, 0 #character position
move_player_x, move_player_y = 0, 0 #how far the character will move, #x is left and right, y is up and down

#alien variables
ali = pygame.image.load(ali_img).convert_alpha() #covert alien image
ali_x, ali_y = random.randint(10, 480), random.randint(10, 500)
move_ali_x, move_ali_y = 0, 0

#mouse things
crosshair = pygame.image.load(cross_hair).convert_alpha()

#other
blit_everything = True
dead = False

#variables end----------------------------------------------------------------

while True:    
    for event in pygame.event.get():
        if event.type==QUIT:
            pygame.quit()
            sys.exit()
        if event.type==KEYDOWN:    
            if event.key==K_a:
                move_player_x=-3
            elif event.key==K_d:
                move_player_x=+3
            elif event.key==K_w:
                move_player_y=-3
            elif event.key==K_s:
                move_player_y=+3
        if event.type==KEYUP:
            if event.key==K_a:
                move_player_x=0
            elif event.key==K_d:
                move_player_x=0
            elif event.key==K_w:
                move_player_y=0
            elif event.key==K_s:
                move_player_y=0
        if event.type==KEYDOWN:
            if event.key== K_LEFT:
                move_player_x=-3
            elif event.key== K_RIGHT:
                move_player_x=+3
            elif event.key==K_UP:
                move_player_y=-3
            elif event.key== K_DOWN:
                move_player_y=+3
        if event.type==KEYUP:
            if event.key==K_LEFT:
                move_player_x=0
            elif event.key==K_RIGHT:
                move_player_x=0
            elif event.key==K_UP:
                move_player_y=0
            elif event.key==K_DOWN:
                move_player_y=0

        if ali_x < player_x:
            move_ali_x =+ 0.5
        elif ali_x > player_x:
            move_ali_x =- 0.5
        if ali_y < player_y:
            move_ali_y =+ 0.5
        elif ali_y > player_y:
            move_ali_y =- 0.5

        ali_y += move_ali_y
        ali_x += move_ali_x
        ali_rect = pygame.Rect(ali_x, ali_y, 35, 35)

        player_x += move_player_x
        player_y += move_player_y
        char_rect = pygame.Rect(player_x, player_y, 35, 35)

        if char_rect.colliderect(ali_rect):
            background = pygame.image.load(dead_screen).convert()
            blit_everything = False
            dead = True

        mouse_x, mouse_y = pygame.mouse.get_pos()
        mouse_x -= crosshair.get_width() / 2
        mouse_y -= crosshair.get_height() / 2

        dx = player_x - mouse_x
        dy = player_y - mouse_y
        player_atan = atan2(-dy, dx)
        player_atan %= 2 * pi
        player_angle = degrees(player_atan)
        char = pygame.transform.rotate(char, player_angle)
        print player_angle

        screen.blit(background,(0,0))   

        #blit everything
        if blit_everything == True:
            screen.blit(char,(player_x,player_y))
            screen.blit(ali,(ali_x, ali_y))
            screen.blit(crosshair,(mouse_x, mouse_y))

        pygame.display.update()

here is the error:

Traceback (most recent call last):
  File "/home/claude/Dropbox/BigKahunaBurger/BigKahunaBurger LOOP.py", line 160, in <module>
    char = pygame.transform.rotate(char, player_angle)
error: Width or height is too large
>>>

and on line 161 I made the program print the angles to make sure they were angles and this is what I get:

162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
162.829790545
159.757500243
149.225963899
126.609372987
152.009531506
114.018423659

as you can see all the numbers are angles, I tried rounding the angles off but that had no effect.

any help would be greatly appreciated

thank you

هل كانت مفيدة؟

المحلول

When you are rotating:

char = pygame.transform.rotate(char, player_angle)

If you rotate an image, then the next rotated image will be slightly larger again. If you keep doing this, eventually the image will become too large for Pygame to handle, and your program will crash with the error message, pygame.error: Width or height is too large.

The only exception to this is if you rotate an image by a multiple of 90 degrees, such as 0, 90, 180, 270, or 360 degrees. In that case, the pixels can be rotated without any distortion.

Source

نصائح أخرى

why dont you use different camera for HUD things ???

  • for example in OpenGL
  • i use unit matrices for hp,energy/shield indicators cursors and other stuff
  • and for the in-game objects i use the real camera settings.
  • this is much faster and even more precise then horrible transforms to achieve the same...
  • of course unless you want to project your cursor onto objects like laser dots from Predator :-)

btw try to trace your error. - we do not see the line numbering in here so would be fine to distinct that area for us somehow. - my guess is that one or more of your variables get bigger and bigger after each frame - until is too big to convert to integer value (for example pixel position) - add counter to your code and increase it after each frame or key hit - add breakpoint if that counter is bigger then some treshold - and watch for obviously wrong values of your variables after some frames/keyhits/mouse moves ...

PS. error could be also something outside the box - memory leak or not initialized variable or something

PPS. your angles can be allright, but they create a transformation matrix with some more parameters and the problem could be there

To avoid distortion you can use rotate the original each time instead of rotating the image you already distorted by rotating. This works like continuously making a copy of a copy of a copy in a copy machine: in the end your copy is too distorted. By using this you don't have to make the angles multiples of 90.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top