Jadi saya membuat game menembak asteroid ini dan saya memiliki kelas yang disebut Laser. Karena saya perlu membuat banyak laser, saya membuat Grup Sprite untuk kelas ini dan menambahkan 25 sprite. Saya membuatnya sedemikian rupa sehingga setiap kali pengguna menekan bilah spasi, laser terakhir (saya berhasil mengaturnya menggunakan daftar sprite) dalam grup naik melintasi layar menggunakan Vector2D dan laser lainnya "tersembunyi" di bawah pesawat ruang angkasa sprite. Berikut adalah kode untuk kelas Laser:

import pygame


class Laser(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.image.load("laser.png")
        self.scale = 0.05
        self.image = pygame.transform.smoothscale(
            self.image,
            (int(self.image.get_rect().width * self.scale),
             int(self.image.get_rect().height * self.scale)),
        )
        self.rect = self.image.get_rect()
        # Getting the rectangle around the image lets you move it.
        self.rect.center = pos
        self.speed = pygame.math.Vector2(0, -5)
        self.speed.rotate_ip(0)
        self.track = 0

    def update(self, pos):
        if self.track == 0:
            self.rect.move_ip(pos)

    def move(self):
        self.rect.move_ip(self.speed)
        self.track = self.track + 1
        # self.track makes it so that the program knows not to call the update function for this Laser object.

Cuplikan kode di main.py yang berkaitan dengan pemotretan dan pembuatan laser (termasuk semua kode akan terlalu banyak):

global lasers
    player.collect((width/2, height), spriteNum)
    for i in range(0, 25):
        lasers.add(Laser((width/2, height)))
    init()
    while True:
        screen.fill([255, 255, 255])
        bigger_img = pygame.transform.scale(background.image, (width, height))
        screen.blit(bigger_img, (0, 0))
        playerPosition = player.update()
        lasers_list = lasers.sprites()
        for i in range(0, len(lasers_list)):
            lasers_list[i].update(playerPosition)
            screen.blit(lasers_list[i].image, lasers_list[i].rect)
            if lasers_list[i].rect.top < 0:
                lasers.remove(lasers_list[i])
        enemies.update(speed)
        clock.tick(60)
        last_laser = lasers.sprites()[len(lasers_list) - 1]
        player_hit = pygame.sprite.spritecollide(player, enemies, False)
        screen.blit(player.image, player.rect)
        enemies.draw(screen)
        lasers.draw(screen)
        screen.blit(last_laser.image, last_laser.rect)
        pygame.display.flip()
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    player.speed[0] = 5
                if event.key == pygame.K_LEFT:
                    player.speed[0] = -5
                if event.key == pygame.K_UP:
                    player.speed[1] = -5
                if event.key == pygame.K_DOWN:
                    player.speed[1] = 5
                if (event.key == pygame.K_SPACE):
                    if  (len(lasers_list) - 1) > -1:
                        last_laser.move()
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_RIGHT:
                    player.speed[0] = 0
                if event.key == pygame.K_LEFT:
                    player.speed[0] = 0
                if event.key == pygame.K_UP:
                    player.speed[1] = 0
                if event.key == pygame.K_DOWN:
                    player.speed[1] = 0
                if event.key == pygame.K_SPACE:
                    abcd = "0"
                    #nothing, I don't feel like I need anything here since no lasers would be launched if the spacebar was up. 

Ok, jadi last_laser muncul jika saya mengubah kode dari ini:

                if (event.key == pygame.K_SPACE):
                    if  (len(lasers_list) - 1) > -1:
                        last_laser.move()

Untuk ini:

                if (event.key == pygame.K_SPACE):
                    last_laser.rect.center = (400, 400)
                    # Some arbitrary x and y values (400, 400).
                    last_laser.track += 1

gambar laser muncul di layar

Tetapi ada beberapa hal yang saya inginkan yang tidak puas dengan kode di atas. Pertama-tama, saya ingin laser menembak dan seperti bergerak melintasi layar (saya tahu gerakannya adalah pewarnaan ulang piksel). Juga, saya ingin itu pergi ke posisi yang berbeda karena akan bergantung pada di mana pengguna memindahkan sprite pesawat ruang angkasanya dan menembak dari. Saya telah mencoba mencari solusi untuk ini selama berjam-jam dan secara khusus membuat akun stack overflow untuk pertanyaan ini, bantuan apa pun akan sangat dihargai. :)

EDIT: Laser ditembakkan tetapi sekarang saya perlu mencari tahu bagaimana pemain dapat menembakkan banyak laser. Yang saya maksud dengan itu adalah pemain harus dapat menekan spasi, tunggu beberapa detik, lalu tekan spasi lagi dan 2 laser akan muncul di layar. Saat ini, jika pemain melakukan itu, laser yang ada di layar akan dihapus dan kemudian diposisikan ulang sehingga terlihat seperti laser baru yang datang dari pesawat luar angkasa. Ini membingungkan pemain karena laser yang baru saja naik "menghilang".

2
OrangeJuice 18 April 2020, 06:49

1 menjawab

Jawaban Terbaik

Pertama-tama, Anda memiliki semua laser dalam grup Sprite, tetapi Anda mendapatkan semua laser dari grup dan memasukkannya ke dalam daftar, lalu mengulang daftar untuk memperbarui dan menggambarnya, lalu menggambarnya lagi melalui grup sprite, yang tidak perlu, lebih baik miliki semua sprite dalam grup Sprite dan panggil lasers.update() dan lasers.draw(screen), atau minta mereka dalam daftar dan lakukan apa yang Anda lakukan sekarang, kecuali di sini

for i in range(0, 25):
    lasers.add(Laser((width/2, height)))

Berubah menjadi

for i in range(0, 25):
     lasers_list.append(Laser((width/2, height)))

Ada juga banyak garis yang bisa kamu perpendek dan terlihat sedikit lebih bersih

last_laser = lasers.sprites()[len(lasers_list) - 1]
last_laser = lasers.sprites()[-1] #-1 gets the last in list

if (len(lasers_list) - 1) > -1:
if len(lasers_list) > 0:

self.track = self.track + 1
self.track += 1

Juga akan pindah

screen.blit(lasers_list[i].image, lasers_list[i].rect)
    if lasers_list[i].rect.top < 0:
        lasers.remove(lasers_list[i])

Ke fungsi pembaruan di kelas laser

def update(self, pos):
    if self.track == 0:
        self.rect.move_ip(pos)
    screen.blit(lasers_list[i].image, lasers_list[i].rect)
        if self.rect.top < 0:
            self.kill() #deletes from sprite group

Dalam fungsi pembaruan di kelas laser saya akan menambahkan

def update(self, pos):
    if self.track == 0:
        self.rect.move_ip(pos)
    else:  #if not moving with ship
        self.move() # so it moves on its own
    screen.blit(lasers_list[i].image, lasers_list[i].rect)
        if self.rect.top < 0:
            self.kill() #deletes from sprite group

Karena ini

 if (event.key == pygame.K_SPACE):
     if len(lasers_list) > 0:
         last_laser.move()

Ketika Anda menekan spasi, laser yang sama akan terus bergerak hingga menyentuh bagian atas dan terhapus. Jika itu yang Anda inginkan, itu tidak sempurna, tetapi itu akan berhasil. Jika tidak, Anda mungkin menginginkan penghitung, yang menghitung mundur laser.

Jadi saya pikir itu menyelesaikan bagian kedua dari pertanyaan Anda. Adapun laser tidak muncul saat Anda menekan spasi, jika Anda membersihkan kode Anda dan menggunakan grup sprite atau daftar, bukan keduanya, maka itu akan berfungsi, jika tidak, posting semua kode Anda sehingga saya dapat membuatnya kembali.

1
The Big Kahuna 18 April 2020, 04:33