射击射弹的物体

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了射击射弹的物体相关的知识,希望对你有一定的参考价值。

我正试图让我的坦克射击,我做了我认为应该做的所有代码,但我不知道为什么坦克没有射击任何东西。

import pygame, assetloader
from pygame.locals import *
import random, time, math
import pygame


GRAD = math.pi/180
blue = (0, 0, 255)

wallRects = []

bullets = []

maze = [[] for i in range(25)] 





assetloader.set_asset_path("assets/")

我在这里定义了Bullet类:

def calculate_dir_with_angle(angle):
        direction = [0, 0]
        if (angle > 0 and angle < 180) or (angle > -360 and angle < -180):
            direction[0] = -1
        elif (angle > -180 and angle < 0) or (angle > 180 and angle < 360):
            direction[0] = 1
        elif (angle > -90 and angle < 90) or (angle > 270 and anlge < 360):
            direction[1] = -1
        elif (angle > 90 and angle < 270) or (angle > -270 and angle < -90):
            direction[1] = 1
        return direction


class Bullet:
    def __init__(self, pos, r, angle):
        self.x = pos[0]
        self.y = pos[1]
        self.r = r
        self.counter = 50
        direction = calculate_dir_with_angle(angle)
        self.vel = [direction[0] * 2, direction[1] * 2]

    def draw(self, screen):
        self.x = int(self.x)
        self.y = int(self.y)
        pygame.draw.circle(screen, (25, 25, 25), (self.x, self.y), (self.r))


    def move(self):
        self.x += self.vel[0]
        self.y += self.vel[1]



        self.rect = pygame.Rect(self.x-self.r, self.y - self.r, 2 * self.r, 2 * self.r)
        for wr in wallRects:
            if self.rect.centery >= wr.top and self.rect.centery <= wr.bottom:
                if self.rect.left <= wr.right and self.rect.left > wr.left:
                    self.vel[0] = -self.vel[0]
                    self.x = wr.right + self.r + 1
                    self.rect.x = wr.right + 1
                elif self.rect.right >= wr.left and self.rect.right < wr.right:
                    self.vel[0] = -self.vel[0]
                    self.x = wr.left + self.r - 1
                    self.rect.x = wr.left - 2 * self.r - 1 
            if self.rect.centerx >= wr.left and self.rect.centerx <= wr.right:
                if self.rect.top <= wr.bottom and self.rect.top > wr.top:
                    self.vel[1] = -self.vel[1]
                    self.y = wr.bottom + self.r + 1
                    self.rect.y = wr.bottom + 1
                elif self.rect.bottom >= wr.top and self.rect.bottom < wr.bottom:
                    self.vel[1] = -self.vel[1]
                    self.y = wr.top - self.r - 1
                    self.rect.y = wr.top - 2 * self.r - 1

        if self.counter > 0:
            self.counter -= 1




    def generateRandomPosition():
        row = random.randint(1, 23)
        col = random.randint(1, 23)
        while maze[row][col-1] != 0 or maze[row][col] != 0 or maze[row][col+1] != 0:
            row = random.randint(1, 23)
            col = random.randint(1, 23)

        return row, col

玩家1:

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y, pos):
        pygame.sprite.Sprite.__init__(self)

        self.image, self.rect = assetloader.load_image("Tank.png", -1)
        self.rect.x = x
        self.rect.y = y
        self.rect.clamp_ip(screen.get_rect())

        self.rows = pos[0]
        self.cols = pos[1]
        self.x = self.cols * gsize
        self.y = self.rows * gsize
        self.orig_image, self.orig_rect = assetloader.load_image("Tank.png", -1) 
        self.orig_rect.x = self.x
        self.orig_rect.y = self.y
        self.orig_gun_pos = self.orig_rect.midtop
        self.ammo = 5


    def checkCollisions(self):

            for b in bullets:
                if b.counter <= 0:
                    if b.rect.colliderect(self.orig_rect):
                        self.dead = True


    def calculate_gun_pos(self):
        self.orig_gun_pos = self.orig_rect.midtop
        new_y = self.orig_gun_pos[1] - self.orig_rect.centery
        new_x = self.orig_gun_pos[0] - self.orig_rect.centerx
        rads = self.dir * GRAD
        gun_x = (new_y * math.sin(rads)) + (new_x * math.cos(rads)) + (self.orig_rect.centerx)
        gun_y = (new_y * math.cos(rads)) - (new_x * math.sin(rads)) + (self.orig_rect.centery)
        self.gun_pos = (gun_x, gun_y)

    def shoot(self):
        if self.ammo > 0:
            self.calculate_gun_pos()
            b = Bullet(self.gun_pos, 3, self.dir)
            bullets.append(b)
            self.ammo -= 1



    def draw(self, screen):
        image = pygame.transform.rotate(self.image, self.dir)
        screen.blit(image, self.rect)





    def update(self):
        oldCenter = self.rect.center

        self.rect = self.image.get_rect()
        self.rect.center = oldCenter
        screen_rect = screen.get_rect()
        keys = pygame.key.get_pressed()





        if keys[K_m]:
            p.shoot()




        if not screen_rect.contains(self.rect):
            self.rect.clamp_ip(screen_rect)

调用函数:

size = width, height = 500, 400
gsize = 25
start_x, start_y = 0, 0
bgColor = 255, 255, 255


pygame.init()
screen = pygame.display.set_mode(size)#, pygame.FULLSCREEN)
pygame.display.set_caption("Sample Sprite")
clock = pygame.time.Clock()


p = Player(width/2, height/4, (3,4))



coll_font = pygame.font.Font(None, 30)



going = True
while going:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == QUIT:
            going = False
        elif event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                going = False


        elif event.type == KEYDOWN:
            if event.key == K_m:
                p.shoot()

        for b in bullets:
               b.move()





    p.update()






    screen.fill(bgColor)

    p.draw(screen)







    pygame.display.flip()



pygame.quit()

我如何调用子弹实际出现并触发,因为我有一个Bullet类,它在def shoot(self)的Player类中被调用,所以有人知道为什么没有出现子弹吗?

答案

我通常以这种方式添加子弹:我将包含所有精灵和子弹组的组传递给玩家实例,并在玩家的handle_event方法中向这些组添加新的子弹。

import pygame as pg
from pygame.math import Vector2


pg.init()
screen = pg.display.set_mode((640, 480))
screen_rect = screen.get_rect()
FONT = pg.font.Font(None, 24)
BG_COLOR = pg.Color('gray12')

BULLET_IMAGE = pg.Surface((20, 11), pg.SRCALPHA)
pg.draw.polygon(
    BULLET_IMAGE, pg.Color('aquamarine1'), [(0, 0), (20, 5), (0, 11)])
PLAYER_IMAGE = pg.Surface((50, 30), pg.SRCALPHA)
pg.draw.polygon(
    PLAYER_IMAGE, pg.Color('dodgerblue1'), [(0, 0), (50, 15), (0, 30)])


class Player(pg.sprite.Sprite):

    def __init__(self, pos, all_sprites, bullet_group):
        super().__init__()
        self.image = PLAYER_IMAGE
        self.orig_image = self.image  # Needed to preserve image quality.
        self.rect = self.image.get_rect(center=(pos))
        self.pos = Vector2(pos)
        self.vel = Vector2(1, 0)
        self.angle = 0
        self.angle_speed = 0
        self.all_sprites = all_sprites
        self.bullet_group = bullet_group

    def handle_event(self, event):
        if event.type == pg.MOUSEBUTTONDOWN:
            # Left button fires a bullet from cannon center with
            # current angle. Add the bullet to the bullet_group.
            if event.button == 1:
                bullet = Bullet(self.pos, self.angle)
                self.bullet_group.add(bullet)
                self.all_sprites.add(bullet)
        elif event.type == pg.KEYDOWN:
            # Rotate self by setting the .angle_speed.
            if event.key in (pg.K_a, pg.K_LEFT):
                self.angle_speed = -3
            elif event.key in (pg.K_d, pg.K_RIGHT):
                self.angle_speed = 3
        elif event.type == pg.KEYUP:
            if event.key in (pg.K_a, pg.K_LEFT):
                self.angle_speed = 0
            elif event.key in (pg.K_d, pg.K_RIGHT):
                self.angle_speed = 0

    def update(self):
        self.pos += self.vel
        self.rect.center = self.pos

        if self.angle_speed != 0:
            self.rotate()

    def rotate(self):
        # Update the angle and the velocity vector.
        self.angle += self.angle_speed
        self.vel.rotate_ip(self.angle_speed)
        # Rotate the image and get a new rect with the previous center.
        self.image = pg.transform.rotozoom(self.orig_image, -self.angle, 1)
        self.rect = self.image.get_rect(center=self.rect.center)


class Bullet(pg.sprite.Sprite):

    def __init__(self, pos, angle):
        super().__init__()
        self.image = pg.transform.rotate(BULLET_IMAGE, -angle)
        self.rect = self.image.get_rect(center=pos)
        # To apply an offset (40 pixels) to the start position,
        # create another vector and rotate it as well.
        offset = Vector2(40, 0).rotate(angle)
        # Add the offset vector to the position vector (the center).
        self.pos = Vector2(pos) + offset
        # Rotate the start velocity vector (9, 0) by the angle.
        self.vel = Vector2(9, 0).rotate(angle)

    def update(self):
        # Add the velocity to the pos to move the sprite.
        self.pos += self.vel
        self.rect.center = self.pos  # Update the rect as well.
        # Remove bullets outside of the screen area.
        if not screen_rect.contains(self.rect):
            self.kill()


def main():
    clock = pg.time.Clock()
    all_sprites = pg.sprite.Group()
    # Bullets will be added to this group.
    bullet_group = pg.sprite.Group()
    # Pass the bullet group to the player.
    player = Player((300, 200), all_sprites, bullet_group)
    all_sprites.add(player)

    playing = True
    while playing:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                playing = False
            # Pass events to the player instance.
            player.handle_event(event)

        all_sprites.update()

        screen.fill(BG_COLOR)
        all_sprites.draw(screen)
        pg.display.update()

        clock.tick(30)


if __name__ == '__main__':
    main()
    pg.quit()

以上是关于射击射弹的物体的主要内容,如果未能解决你的问题,请参考以下文章

如何移动 3D 弹丸 Unity

PyGame故障排除的Python Space Invaders

物体在框体内来回弹的UI

如何检测新对象何时被生成或从统一中删除以获得评分/分数?

UE4 第一人称射击游戏16-重新装弹

答复功能改进建议