当我移动鼠标时,所有子弹都在移动,而不仅仅是被射击

克里斯森特:

我正在尝试使用Pygame制作一个基本的自上而下的射击游戏。我只是想出了如何使子弹在鼠标所在的位置射击,但是现在的问题是,即使我在射击后移动鼠标,它们也会改变方向。此外,当项目符号与屏幕的左边缘碰撞时,它们不会像其他边缘一样消失。

main.py:

import pygame
import time
import math
import os
import sys
import random
from classes import *

pygame.init()

width, height = (1440, 900)
win = pygame.display.set_mode((width, height), pygame.FULLSCREEN)
pygame.display.set_caption("Dungeon")
win.fill((255, 255, 255))

# Variables to do with player shooting
shotTimer = 0
bullets = []
bulletVel = 9

# Initialize classes
player = Player(50, 800, 50, 50, PLAYERSPRITE)

def main():
    run = True
    FPS = 60
    clock = pygame.time.Clock()



    while run:
        clock.tick(FPS)

        now = pygame.time.get_ticks()

        mousex, mousey = pygame.mouse.get_pos()

        # Creates the player's bullets
        def shoot():
            global shotTimer

            if now - shotTimer >= player.cooldown:
                bullets.append(Projectile(round(player.x + player.width // 2), round(player.y + player.height // 2), 6))
                shotTimer = now

        def playerBulletUpdates():
            for bullet in bullets:
                if bullet.x >= 0 and bullet.x <= width:
                    if bullet.y >= 0 and bullet.y <= height:
                        global bulletVel

                        xDiff = mousex - player.x
                        yDiff = mousey - player.y

                        angle = math.atan2(yDiff, xDiff)

                        changeX = math.cos(angle) * bulletVel
                        changeY = math.sin(angle) * bulletVel

                        bullet.x += changeX
                        bullet.y += changeY
                    else:
                        bullets.pop(bullets.index(bullet))

        def bulletAngle():
            global bulletVel

            xDiff = mousex - player.x
            yDiff = mousey - player.y

            angle = math.atan2(yDiff, xDiff)

            changeX = int(math.cos(angle) * bulletVel)
            changeY = int(math.sin(angle) * bulletVel)

            bullet.x += changeX
            bullet.y += changeY

        def updateScreen():
            win.fill((255, 255, 255))
            player.draw(win)

            for bullet in bullets:
                bullet.draw(win)

            playerBulletUpdates()

            pygame.display.update()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

        keys = pygame.key.get_pressed()

        if keys[pygame.K_w] and player.y  >= 0: # UP
            player.y += -player.walkSpeed

        if keys[pygame.K_s] and player.y + player.walkSpeed + player.height <= height: # DOWN
            player.y += player.walkSpeed

        if keys[pygame.K_a] and player.x >= 0: #LEFT
            player.x += -player.walkSpeed

        if keys[pygame.K_d] and player.x + player.walkSpeed + player.width <= width: # RIGHT
            player.x += player.walkSpeed

        if pygame.mouse.get_pressed()[0]:
            shoot()

        updateScreen()

main()

classes.py:

import pygame
import math
import os

pygame.init()

width, height = (1440, 900)
win = pygame.display.set_mode((width, height), pygame.FULLSCREEN)

# Import Sprites
PLAYERSPRITE = pygame.image.load(os.path.join("assets", "gunner_class.png"))
BULLETSPRITE = pygame.image.load(os.path.join("assets", "bullet.png"))

class Player:
    def __init__(self, x, y, width, height, img):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.img = img
        self.walkSpeed = 5
        self.cooldown = 100

    def draw(self, window):
        window.blit(PLAYERSPRITE, (self.x, self.y))

class Projectile:
    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius

    def draw(self, window):
            # pygame.draw.circle(window, self.color, (self.x, self.y), self.radius)
            window.blit(BULLETSPRITE, (self.x, self.y))
金斯利:

项目符号在通过时不会被删除,这x=0仅仅是因为您没有将它们选在“ bad-x”上,因为“ else pop”子句仅在“ bad-y”上被调用。很容易解决:

    def playerBulletUpdates():
        for bullet in bullets:
            if bullet.x >= 0 and bullet.x <= width and \
               bullet.y >= 0 and bullet.y <= height:
                    ...
            else:
                # Bullet has gone off-screen
                bullets.pop(bullets.index(bullet))  

鼠标移动现有项目符号的原因是,在同一循环中,您需要重新计算每个项目符号的方向矢量,而不仅仅是重新计算

您的Projectile班级需要在初始化期间存储其方向向量-每个子弹一个,因为每个子弹可能不同。因此,我将在此处重新构造构造函数,然后添加一个update()函数来处理继续的运动。

class Projectile:
    def __init__(self, x, y, dx, dy, radius):
        self.x      = x
        self.y      = y
        self.radius = radius
        self.dx     = dx
        self.dy     = dy

    def draw(self, window):
        # pygame.draw.circle(window, self.color, (self.x, self.y), self.radius)
        window.blit(BULLETSPRITE, (self.x, self.y))

    def update( self ):
        """ Move the projectile along its path """
        self.x += self.dx
        self.y += self.dy

shoot() 现在计算方向vecotor〜

def shoot( mousex, mousey, player ):
    """ Creates a player's bullets """
    global shotTimer

    if now - shotTimer >= player.cooldown:
        global bulletVel

        xDiff = mousex - player.x
        yDiff = mousey - player.y
        angle = math.atan2(yDiff, xDiff)

        # Direction of travel
        changeX = math.cos(angle) * bulletVel
        changeY = math.sin(angle) * bulletVel

        # Start position
        new_bullet_x = round(player.x + player.width / 2)
        new_bulley_y = round(player.y + player.height / 2)

        bullets.append( Projectile( new_bullet_x, new_bulley_y, changeX, changeY, 6))
        shotTimer = now

使子弹更新功能也更加简单:

def playerBulletUpdates():
    for bullet in bullets:
        if bullet.x >= 0 and bullet.x <= width and bullet.y >= 0 and bullet.y <= height:
            # Move the bullet
            bullet.update()
        else:
            # Bullet has gone off-screen
            bullets.pop(bullets.index(bullet))

当您更改这些内容时。使用PyGame Rect对象的位置而不是离散的x研究PyGame对象可能是值得的y,因为这将提供出色的碰撞功能。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在X11上的所有Windows(不仅仅是一个窗口)中监视鼠标移动事件

我得到的是我所有的输出,而不仅仅是一个

如何移动不仅仅是一个分区

在 Boostrap 5 中,轮播移动整页而不仅仅是他的图像

检查所有成员的自定义状态,而不仅仅是我的自定义状态

pf阻止所有输入/输出流量,而不仅仅是我要阻止的一个端口

如何为我的所有 gradle 项目(不仅仅是子项目)共享构建代码脚本

VBA-ContentControlOnEnter正在影响我的所有控件,而不仅仅是指定的控件

悬停效果发生在所有文章上,而不仅仅是我正在悬停的文章

默认情况下,让jQuery DataTables提交所有行,而不仅仅是在搜索时显示的行

删除按钮删除所有子项,而不仅仅是带有键的子项

使IntelliJ标记所有参数,而不仅仅是String参数

预览所有上传的照片,而不仅仅是一张

搜索所有iBeacon,而不仅仅是使用特定的UUID

cp -u复制所有文件,而不仅仅是新文件

为什么这个 SUM 是所有分数,而不仅仅是最好的 5 分?

egrep 输出所有内容,而不仅仅是与列表中的模式匹配的行

开始,如何获得所有触摸,而不仅仅是首先还是最后?

Xpath下标返回所有节点,而不仅仅是请求的节点

获取所有重复的记录,而不仅仅是它们的列表

遍历所有属性,而不仅仅是可枚举的属性

导入运行模块中的所有代码,而不仅仅是导入的功能

以编程方式获取TFS变更集的所有文件(而不仅仅是增量)

查找所有匹配的子字符串,而不仅仅是“最扩展的”

jQuery .children返回所有内容,而不仅仅是请求的内容

如何为所有页面提供静态文件,而不仅仅是少数

SQLAlchemy删除所有项目,而不仅仅是第一个

显示所有Elasticsearch聚合结果/存储桶,而不仅仅是10

'onClick' 事件影响所有组件的状态,而不仅仅是一个