Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在pygame中,计算X和Y速度以击中平面2d表面上的目标_Python_Pygame_Game Physics_Game Development - Fatal编程技术网

Python 在pygame中,计算X和Y速度以击中平面2d表面上的目标

Python 在pygame中,计算X和Y速度以击中平面2d表面上的目标,python,pygame,game-physics,game-development,Python,Pygame,Game Physics,Game Development,我正在使用Python和Pygame创建一个游戏 在将JS与p5.JS和Java与libwjgl一起使用之前,我已经使用过这个函数,但由于某些原因,它不能与Pygame一起使用 我正试图从一个移动的物体上击中一个静止的目标。 现在我错过了目标。你可以在gif中看到它。每一发炮弹都应该击中目标(现在一切都没有命中,但方向正确) 一旦玩家点击鼠标按钮,子弹就会发射 我就是这样做的: def shoot(self): posX, posY = 100, 100 # Static target co

我正在使用Python和Pygame创建一个游戏

在将JS与p5.JS和Java与libwjgl一起使用之前,我已经使用过这个函数,但由于某些原因,它不能与Pygame一起使用

我正试图从一个移动的物体上击中一个静止的目标。 现在我错过了目标。你可以在gif中看到它。每一发炮弹都应该击中目标(现在一切都没有命中,但方向正确)

一旦玩家点击鼠标按钮,子弹就会发射

我就是这样做的:

def shoot(self):
  posX, posY = 100, 100 # Static target coordinates

  diffX = self.player.x - posX               
  diffY = self.player.y - posY                 

  distance = math.sqrt((diffX * diffX) + (diffY * diffY)) # Calculate the distance

  velX = float((-1 / distance * diffX * 6)) # Calculate volocity required to hit the target
  velY = float((-1 / distance * diffY * 6)) # Calculate volocity required to hit the target 

  # Bullet(x, y, width, height, velocityX, velocityY)
  # Will be rendered on the screen
  self.bullets.append(Bullet(self.player.x, self.player.y, 10, 10,  velX, velY)) # The bullet is added to array, which later gets rendered on the screen
子弹级别:

import pygame

class Bullet(object):
  def __init__(self, x, y, width, height, velY, velX):
    self.width = width
    self.height = height
    self.x = x
    self.y = y
    self.velX = velX
    self.velY  = velY
    self.bullet = pygame.Rect(self.x, self.y, self.width, self.height)


  def render(self, screen):
    pygame.draw.rect(screen, (255, 255, 255), self.bullet)

  def update(self):
    self.bullet.x += self.velX
    self.bullet.y += self.velY
这在我提到的其他语言中工作得很好,但在Python中,已发射的射弹已关闭

这是它的样子。红场是目标:

谢谢大家的帮助。我真的很感激:)

编辑: 完整游戏代码

import pygame
from PodSixNet.Connection import connection, ConnectionListener
from objects.Button import Button
from time import sleep
from STATE import STATE
import sys, os
from objects.Text import Text
from resources.hubColours import ColoursClass
from pathlib import Path
from objects.Bullet import Bullet
import math

class DefenseGame(ConnectionListener):
def __init__(self, hub, width, height, soundController, fontController, fps=60):
    #Hub
    self.hub = hub

    #COLOURS
    self.color = ColoursClass("alt")

    #SOUNDS
    self.soundController = soundController

    #SCREEN
    self.width = width
    self.height = height
    self.background = pygame.Surface((self.width, self.height), pygame.HWSURFACE | pygame.DOUBLEBUF).convert()  
    self.background.fill(self.color.getColour(7)) # fill background white

    #INFO
    self.fps = fps
    self.playtime = 0.0

    #FONTS
    self.fontController = fontController

    #STATE
    # All player related stuff is stored in the HUB.
    # TODO:
    # Player class
    self.isRunning = True


    self.moveLeft = False
    self.moveRight = False
    self.moveUp = False
    self.moveDown = False

    self.bullets = []

    self.moveAmnt = 5

    self.timeLeft = "Waiting for players..."


    self.clock = pygame.time.Clock()

    #OBJECTS
    self.on_init()

#Initialize game objects
def on_init(self):
  self.char = pygame.transform.smoothscale(pygame.image.load(str(Path("character.png"))), (50, 50))

# Draws on screen
def render(self, screen):                               # Update all objects (through object handler)                                            # This will update the contents of the entire display
    screen.blit(self.background, (0, 0))
    self.drawInfoText("Color: " + self.hub.playerColorName, 10, 10, self.fontController.tiny, screen)
    self.drawInfoText("Player Count: " + str(self.hub.getInGamePlayerCount()), 10, 20, self.fontController.tiny, screen)
    self.drawInfoText("FPS: " + str(round(self.getFPS(), 2)), 10, 30, self.fontController.tiny, screen)
    self.drawInfoText("Network Status: " + self.hub.statusLabel, 10, 40, self.fontController.tiny, screen)
    self.player.render(screen)
    self.player2.render(screen)
    # screen.blit(self.char, (self.posX, self.posY))

    if len(self.bullets) > 0:
      for b in self.bullets:
        b.render(screen)

def onMove(self):
  connection.Send({"action": "playerMove", 'x': self.player.x , 'y': self.player.y, 'id': self.hub.playerId})


def shoot(self):
  posX, posY = pygame.mouse.get_pos()

  diffX = self.player.x - posX               
  diffY = self.player.y - posY                 

  distance = math.sqrt((diffX * diffX) + (diffY * diffY))
  print("DISTANCE: ", distance)

  velX = float((-1 / distance * diffX * 20))
  velY = float((-1 / distance * diffY * 20))  

  print(velX, velY)

  self.bullets.append(Bullet(self.player.x, self.player.y, 10, 10,  velX, velY))

# Looks for events
def handle_events(self, events):
    for event in events:
        if event.type == pygame.QUIT: 
            self.exitGame(event)
            self.hub.setState(STATE.Home)
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                self.exitGame(event)
                self.hub.setState(STATE.SelectGame)

            if event.key == pygame.K_w:
              self.moveUp = True
            if event.key == pygame.K_a:
              self.moveLeft = True
            if event.key == pygame.K_s:
              self.moveDown = True
            if event.key == pygame.K_d:
              self.moveRight = True

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_w:
              self.moveUp = False
            if event.key == pygame.K_a:
              self.moveLeft = False
            if event.key == pygame.K_s:
              self.moveDown = False
            if event.key == pygame.K_d:
              self.moveRight = False

        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:          # Mouse first button
                self.shoot()

# Update stuff (loop)
def update(self):
    self.Pump()                 # Connection
    connection.Pump()           # Connection

    timer = self.clock.tick(self.fps)
    if self.moveLeft:
      self.player.x -= timer
      self.onMove()
    if self.moveRight:
      self.player.x += timer
      self.onMove()
    if self.moveUp:
      self.player.y -= timer
      self.onMove()
    if self.moveDown:
      self.player.y += timer
      self.onMove()

    if len(self.bullets) > 0:
      for b in self.bullets:
        b.update()
    # sleep(0.001)


# returns FPS
def getFPS(self):
    self.clock.tick(self.fps)
    return  self.clock.get_fps()

# Helper for quickly drawing on screen
def drawInfoText(self, text, x, y, font, screen):
    surface = font.render(str(text), 1, self.color.getColour(8))
    screen.blit(surface, (x, y))

# Exits the game to home
def exitGame(self, e):
    self.soundController.stopSoundEffects()
    connection.Send({"action":"exitGame", "isInGame": False})
    self.hub.isInGame = False

self.bullet
是一个对象。项目符号的位置由矩形的位置跟踪(
self.bullet.x
self.bullet.y
)。由于矩形位置是整数,因此每次更新位置时都会导致不准确

使用浮点数据跟踪位置。使用c

将子弹的位置和速度存储到
pygame.math.Vector2
对象

类项目符号(对象):
定义初始值(self、x、y、宽度、高度、velX、velY):
self.width=宽度
自我高度=高度
self.x=x
self.y=y
self.bullet=pygame.Rect(self.x、self.y、self.width、self.height)
self.pos=pygame.math.Vector2(self.bullet.center)
self.vel=pygame.math.Vector2(velX,velY)
更新位置属性而不是矩形位置:

类项目符号(对象):
# [...]
def更新(自我):
self.pos=self.pos+self.vel
在绘制项目符号之前更新矩形的位置:

类项目符号(对象):
# [...]
def渲染(自身,屏幕):
self.bullet.center=(int(self.pos[0]),int(self.pos[1]))
pygame.draw.rect(屏幕,(255,255,255),self.bullet)
用于计算速度:

def喷射(自身):
posX,posY=100100#静态目标坐标
traget=pygame.math.Vector2(posX,posY)
start=pygame.math.Vector2(self.player.x,self.player.y)
delta=traget-启动
距离=增量长度()
方向=delta.normalize()
水平=方向*6
self.bullets.append(Bullet(self.player.x,self.player.y,10,10,vel[0],vel[1]))

可能
self.bullet.x
self.bullet.y
是完整的数据。I
bullet
一个对象?请您指定您预期会发生什么以及会发生什么?我不知道目标是什么,所以“射弹关闭…”的描述不清楚。我们有可能看到更多关于你想要发生什么的信息吗?@rabbi76我的更新方法来自Bullet类。是的,它是一个矩形。我要更新这篇文章,这样就有了完整的子弹等级。py@Pygasm我的目标是让射弹击中目标(看看gif)。每次射击都应该击中目标(在我的代码中是posX和posY)。我将用鼠标坐标替换它。谢谢你的回答!但是,一旦我做了更改,投射物就不会出现在屏幕上。它似乎指向不同的方向。我试图从更新方法中打印项目符号的位置:以下是输出:下面是代码的样子:@mantasmikaluskas
self.bullet.center=(int(self.vel[0]),int(self.vel[1])
必须是
self.bullet.center=(int(self.pos[0]),int(self pos[1])
。这是我最初的回答中的一个错误,我后来已经纠正了。