无法理解如何在PyGame中制作角色面部鼠标 [英] Can't understand how to make character face mouse in PyGame

查看:51
本文介绍了无法理解如何在PyGame中制作角色面部鼠标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我到目前为止的内容.此刻,玩家在移动,而我现在想要做的就是一直面对着鼠标光标(想想迈阿密热线或其他自上而下的游戏).我使用了一些在网上找到的涉及atan2的代码,但我几乎不了解它的作用(以某种方式找到播放器和鼠标之间的距离...),而我的角色在屏幕外疯狂旋转,直到出现内存不足"错误.任何帮助将不胜感激,我在互联网上四处浏览,找不到任何对我有帮助的东西.

Below is what I have so far. At the moment, the player moves, and all I want it to do now is face the mouse cursor at all times (think Hotline Miami or other top-down games). I've used some code involving atan2 that I found online, but I barely understand what it does (finds the distance between the player and mouse somehow...) and my character just spins wildly offscreen until I get an 'Out of memory' error. Any help would be much appreciated, I've looked all over the internet and can't find anything that helps me.

import pygame, sys, math
from pygame.locals import *

pygame.init()

#setup the window with a 720p resolution and a title
winX, winY = 1280, 720
display = pygame.display.set_mode((winX, winY))
winTitle = pygame.display.set_caption("Game name")

#Colours
cBlack = (0, 0, 0)

#setup the clock and FPS limit
FPS = 70
clock = pygame.time.Clock()

#sprite groups
allSprites = pygame.sprite.Group()

#background image
bg = pygame.image.load("bg.jpg")

class Player(pygame.sprite.Sprite):
    def __init__(self, speed):
        #import the __init__ from the Sprite class
        pygame.sprite.Sprite.__init__(self)
        #sets the objects speed to the speed argument
        self.speed = speed
        #set the soldiers image
        self.image = pygame.image.load("soldier_torso_DW.png")
        #get the rectangle of the image (used for movement later)
        self.rect = self.image.get_rect()
        #sets starting position
        self.rect.x, self.rect.y = winX/2, winY/2

    def checkPlayerMovement(self):
        """Check if user has pressed any movement buttons
            and sets the characters position accordingly."""
        pressed = pygame.key.get_pressed()
        if pressed[K_w]:
            self.rect.y -= self.speed
        if pressed[K_s]:
            self.rect.y += self.speed
        if pressed[K_a]:
            self.rect.x -= self.speed
        if pressed[K_d]:
            self.rect.x += self.speed

    def checkMouseMovement(self):
        """Check if user has moved the mouse and rotates the
            character accordingly."""
        mX, mY = pygame.mouse.get_pos()
        angleRad = math.atan2(mY, mX) - math.atan2(self.rect.y, self.rect.x)
        angleDeg = math.degrees(angleRad)
        print angleDeg
        self.image = pygame.transform.rotate(self.image, angleDeg)

    def update(self):
        """Performs all movement and drawing functions and shit
            for the object"""
        self.checkPlayerMovement()
        self.checkMouseMovement()
        #draw the image at the given coordinate
        display.blit(self.image, (self.rect.x, self.rect.y))

def updateAll():
    #fill the window with black
    display.blit(bg, (0, 0))
    #update all sprites
    allSprites.update()
    #keeps FPS at 60
    clock.tick(FPS)
    #updates the display
    pygame.display.flip()

#creates a player with a speed of 5
mainChar = Player(5)
#add the player character to main sprite group
allSprites.add(mainChar)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    updateAll()

推荐答案

(完全公开,我对pygame包不熟悉,但是我已经用其他语言进行过这种编程)

(Full disclosure, I'm not familiar with the pygame package, but I have done this sort of programming in other languages)

当您要让玩家确定面对对象旋转时应旋转多少时,玩家应将自己视为世界中心.但是,其坐标不一定总是(0,0).首先,我们需要从希望面对的物体中减去玩家的pos,将坐标转换为以自我为中心的坐标.

When you want a player to determine how much it should rotate to face an object, the player should consider itself to be the world center. However, its coordinates are not always going to be (0,0). We first need to transform our coordinates into egocentric ones by subtracting the players' pos from the object it wishes to face.

接下来,您似乎只是在使用玩家的位置来计算旋转角度.除非玩家始终面对与矢量从其当前位置到原点的方向相同的方向,否则这不是正确的计算.您必须包括其他信息来跟踪玩家的旋转,通常这是通过具有(x,y)分量的单位方向向量完成的.

Next, it looks like you're only using the player's position to compute the rotation. Unless the player always faces a direction equivalent to the direction of a vector from its current position to the origin, this is not a correct calculation. You must include additional information to track the player's rotation, and this is often done through a unit direction vector with (x, y) components.

  1. 计算从对象位置到玩家位置的相对矢量
    • 将此向量称为V rel
  • 现在的结果是玩家需要相对于自身旋转的数量

atan2()函数

atan2函数将使您从X轴正方向进行 signed 旋转.

因此,给定笛卡尔XY平面和位置(x,y),如果从(0,0)到(x,y)绘制矢量,则atan2(y,x)会给您向量(1,0)和(x,y).例如,如果您的(x,y)为(0,1)(沿y轴),则atan2(1,0)将给您π/2或90°,并且如果您的(x,y)沿负y轴(0,-1),那么atan2(0,-1)会给您-π/2或-90°.

So, given the Cartesian X-Y plane and a position (x, y), if you drew a vector from (0, 0) to (x, y), then atan2(y, x) will give you the angle between the vector (1, 0) and (x, y). For example, if your (x, y) was (0, 1) (along the y axis), then atan2(1, 0) will give you π/2, or 90°, and if your (x, y) went along the negative y axis (0, -1), then atan2(0, -1) will give you -π/2, or -90°.

从atan2输出的正角始终是逆时针旋转,而负角是顺时针旋转.大多数计算器的确要求格式atan2(y,x),但不是全部,所以要小心.在Python的数学库中,它是atan2(y,x)

A positive angle output from atan2 is always a counter-clockwise rotation, and a negative angle is a clockwise rotation. Most calculators do require the form atan2(y, x), but not all, so be careful. In Python's math library, it is atan2(y, x)

请原谅不按比例缩放,不良的色彩选择,幼儿园质量的图片,并尝试着眼于概念.

Forgive the not-to-scale, bad color choice, kindergarten quality pictures and try to focus on the concepts.

对象位于位置(5,5)玩家位置(-3,-1).玩家面对的方向(-0.8,0.6)

Object at position (5, 5) Player at position (-3, -1). Player facing direction (-0.8, 0.6)

  1. 相对矢量为(Object x -Player x ,Object y -Player y )=(5,5)-(-3,-1)=(5--3,5--1)=(5 + 3,5 + 1)= (8,6)
  1. Relative vector is (Objectx - Playerx, Objecty - Playery) = (5, 5) - (-3, -1) = (5 - -3, 5 - -1) = (5+3, 5+1) = (8, 6)

  1. atan2(V rel )= atan2(6,8)= 0.9272952180016122 rad

  1. atan2(Vrel) = atan2(6, 8) = 0.9272952180016122 rad

  • atan2(playerDir y ,playerDir x )= atan2(-0.8,0.6)= 2.498091544796509 rad
  • atan2(playerDiry, playerDirx) = atan2(-0.8, 0.6) = 2.498091544796509 rad





  • atan2(V rel )-atan2(player)= 0.9272952180016122-2.498091544796509 = -1.5707963267948966 rad
  • atan2(Vrel) - atan2(player) = 0.9272952180016122 - 2.498091544796509 = -1.5707963267948966 rad

因此,玩家必须围绕自己的中心(顺时针近90度)旋转-1.57 rad以面向对象.

So the player must rotate -1.57 rad about its own center (nearly 90 degrees clockwise) to face the object.

这篇关于无法理解如何在PyGame中制作角色面部鼠标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆