标题是什么,我有一个我可以用W,S,A,D控制的图像。但我想让可移动的播放器图像旋转到面向鼠标的位置。这是相关代码:
import pygame
import random
import time
import math
import sys
pygame.init()
#The size of the game window
display_width = 1280
display_height = 800
#Colors available
black = (0, 0, 0) #colours defined by RGB,
white = (255, 255, 255)
red = (200, 0, 0)
green = (0, 150, 0)
bright_red = (255, 0, 0)
bright_green =(0, 255, 0)
#This code opens up the Game window
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("Blockslayer")
clock = pygame.time.Clock()
pygame.mouse.set_visible(True)
#player character info
slayerImg = pygame.image.load('squareslayer.png').convert_alpha()
slayerWidth = 84
slayerHeight = 84
#mouse info
mouse_c = pygame.image.load("crosshair.png ").convert_alpha()
def crosshair(mousex,mousey):
mousex, mousey = pygame.mouse.get_pos()
small_ch = pygame.transform.scale(mouse_c, (20, 20))
gameDisplay.blit(small_ch, (mousex, mousey,))
print(mousex,mousey)
#player character
def slayer(x,y,):
#small_slayer = pygame.transform.scale(slayerImg, (120, 80,))
pos = pygame.mouse.get_pos()
angle = 360 - math.atan2(pos[1] - 84, pos[0] - 84) * 180 / math.pi
rotimage = pygame.transform.rotate((slayerImg), angle,)
rect = rotimage.get_rect(center=(x, y))
gameDisplay.blit(rotimage, rect,)
pygame.display.update()
#Game Logic
def block_game_loop():
x = (display_width * 0.45)
y = (display_height * 0.8)
pos = pygame.mouse.get_pos()
angle = 360 - math.atan2(pos[1] + x - 84, pos[0] + y - 84) * 180 / math.pi
rotimage = pygame.transform.rotate((slayerImg), angle,)
mousex, mousey = pygame.mouse.get_pos()
#def blockguy(blockguyX, blockguyY, blockguyW, blockguyH, ):
#blockguyX = random.randrange(0, 785)
#blockguyY = random.randrange (0, 600)
#blockguyW = 166
#blockguyH = 110
#blockguy_speed = 5
#Event handler
exit_game = False
while not exit_game:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
pressed = pygame.key.get_pressed()
if pressed[pygame.K_s]: y += 7
if pressed[pygame.K_w]: y -= 7
if pressed[pygame.K_a]: x -= 7
if pressed[pygame.K_d]: x += 7
gameDisplay.fill(white)
slayer(x, y,)
#Boundaries
if x > display_width:
x = 1275
if x < 0:
x = 5
if y > display_height:
y = 795
if y < 0:
y = 5
crosshair(mousex,mousey)
#blockguy(blockguyX, blockguyY, blockguyW, blockguyH, )
pygame.display.update()
clock.tick(60)
block_game_loop()
pygame.quit()
quit()
代码非常混杂在一起,因为我真的不知道wtf我在做什么,但到目前为止这是怎么回事 Youtube视频:https://www.youtube.com/watch?v=zShWAm4pSx8&feature=youtu.be
答案 0 :(得分:1)
看看这个rotate
函数(阅读评论)。
import math
import pygame
pygame.init()
gray = (30, 30, 30)
display_width, display_height = (1280, 800)
gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()
slayerImg = pygame.Surface((104, 84), pygame.SRCALPHA)
pygame.draw.polygon(slayerImg, (0, 120, 250), [(1, 1), (103, 42), (1, 83)])
def rotate(x, y, mouse_pos, image):
# Calculate x and y distances to the mouse pos.
run, rise = (mouse_pos[0]-x, mouse_pos[1]-y)
# Pass the rise and run to atan2 (in this order)
# and convert the angle to degrees.
angle = math.degrees(math.atan2(rise, run))
# Rotate the image (use the negative angle).
rotimage = pygame.transform.rotate(image, -angle)
rect = rotimage.get_rect(center=(x, y))
return rotimage, rect
def block_game_loop():
x = display_width * 0.45
y = display_height * 0.8
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
pressed = pygame.key.get_pressed()
if pressed[pygame.K_s]: y += 7
if pressed[pygame.K_w]: y -= 7
if pressed[pygame.K_a]: x -= 7
if pressed[pygame.K_d]: x += 7
mousex, mousey = pygame.mouse.get_pos()
# Boundaries
if x > display_width:
x = 1275
if x < 0:
x = 5
if y > display_height:
y = 795
if y < 0:
y = 5
gameDisplay.fill(gray)
rotimage, rect = rotate(x, y, (mousex, mousey), slayerImg)
gameDisplay.blit(rotimage, rect)
pygame.display.update()
clock.tick(60)
block_game_loop()
pygame.quit()
附录:这是一个示例,向您展示如何拍摄旋转的子弹。您需要一些基本的三角知识,因为您需要使用math.cos
和math.sin
来计算x和y速度。这将为您提供一个单位向量(长度为1),您需要缩放到所需的速度。现在,您需要将velocity
列表与rect,一个额外的位置列表和旋转的图像放在一个表示子弹对象的列表中。要更新rect位置,首先必须将速度添加到pos,然后将pos分配给rect中心(你必须这样做,因为rects只能将int作为x和y位置)。
我建议使用pygame.math.Vector2
和pygame sprite和sprite group而不是列表,正如您在链接的答案中看到的那样,因为这样可以更好地阅读。您仍然需要添加代码来删除项目符号,这也可以通过精灵和精灵组实现更简单。
import math
import pygame as pg
from pygame.math import Vector2
pg.init()
screen = pg.display.set_mode((640, 480))
FONT = pg.font.Font(None, 24)
BLACK = pg.Color('black')
BULLET_IMAGE = pg.Surface((20, 11), pg.SRCALPHA)
pg.draw.polygon(BULLET_IMAGE, pg.Color('grey11'), [(0, 0), (20, 5), (0, 11)])
def update_bullets(bullets):
"""Add the velocity to the pos then assign pos to the rect center."""
for bullet_rect, pos, velocity, _ in bullets:
pos[0] += velocity[0]
pos[1] += velocity[1]
bullet_rect.center = pos
def draw_bullets(bullets, screen):
for bullet_rect, pos, _, image in bullets:
screen.blit(image, bullet_rect)
pg.draw.rect(screen, (200, 140, 0), bullet_rect, 1)
def main():
clock = pg.time.Clock()
# The cannon image and rect.
cannon_img = pg.Surface((60, 22), pg.SRCALPHA)
pg.draw.rect(cannon_img, pg.Color('grey19'), [0, 0, 35, 22])
pg.draw.rect(cannon_img, pg.Color('grey19'), [35, 6, 35, 10])
orig_cannon_img = cannon_img # Store orig image to preserve quality.
cannon = cannon_img.get_rect(center=(320, 240))
angle = 0 # Angle of the cannon.
# Add bullets to this list. Bullets will also be lists
# consisting of a pygame.Rect, the velocity and the image.
bullets = []
bullet_speed = 5
playing = True
while playing:
for event in pg.event.get():
if event.type == pg.QUIT:
playing = False
elif event.type == pg.MOUSEBUTTONDOWN:
# Left button fires a bullet from cannon center with
# current angle. Add the bullet to the bullets list.
if event.button == 1:
# Use cosine and sine to calculate the x and y
# velocity. Scale them by the desired speed.
velocity = (math.cos(math.radians(angle)) * bullet_speed,
math.sin(math.radians(angle)) * bullet_speed)
img = pg.transform.rotate(BULLET_IMAGE, -angle)
bullet_rect = img.get_rect(center=cannon.center)
# The extra pos list is needed because the pygame.Rect
# can only have ints as the x and y value. We still
# need the rect for collision detection.
pos = list(bullet_rect.center)
bullet = [bullet_rect, pos, velocity, img]
bullets.append(bullet)
update_bullets(bullets)
# Find angle to target (mouse pos).
x, y = Vector2(pg.mouse.get_pos()) - cannon.center
angle = math.degrees(math.atan2(y, x))
# Rotate the cannon image.
cannon_img = pg.transform.rotate(orig_cannon_img, -angle)
cannon = cannon_img.get_rect(center=cannon.center)
# Draw
screen.fill(pg.Color('darkseagreen4'))
draw_bullets(bullets, screen)
screen.blit(cannon_img, cannon)
txt = FONT.render('angle {:.1f}'.format(angle), True, BLACK)
screen.blit(txt, (10, 10))
pg.draw.line(
screen, pg.Color(150, 60, 20),
cannon.center, pg.mouse.get_pos(), 2)
pg.display.update()
clock.tick(30)
if __name__ == '__main__':
main()
pg.quit()
答案 1 :(得分:0)
这是大鱼,这是我针对该问题的代码:
import math
sprite = sprite_new("spr_plasma_blast")
targetx = 0
targety = 0
m = 0
time = 0
speed = 8
if time == 0:
m = (targety - y)/(targetx - x)
xSpeed = math.sqrt((speed*speed)/((m*m) + 1))
if targetx < x:
xSpeed = -xSpeed
x = x + xSpeed
y = y + xSpeed*m
time = time + 1