• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Błąd w obliczaniu pierwiastka w pygame.

VPS Starter Arubacloud
0 głosów
271 wizyt
pytanie zadane 30 maja 2020 w Python przez tonn204 Mądrala (7,440 p.)

Cześć. Robię prostą grę w pygame według tego poradnika :https://www.youtube.com/watch?v=FfWpgLFMI7w&t=5219s. Niby wszystko dobrze, ale nie wiem co zrobić bo wyskakuje mi taki błąd :

 

gra.py:79: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if bullet_state is "ready":
gra.py:114: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if bullet_state is "fire":
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
gra.py:49: DeprecationWarning: an integer is required (got type float).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
  screen.blit(enemyImg[i], (x, y))
Traceback (most recent call last):
  File "gra.py", line 117, in <module>
    collision = isCollision(enemyX, enemyY, bulletX, bulletY)
  File "gra.py", line 57, in isCollision
    distance = math.sqrt((math.pow(enemyX - bulletX, 2)) + (math.pow(enemyY - bulletY, 2)))
TypeError: unsupported operand type(s) for -: 'list' and 'int'

 

Jak to naprawić? 

 

import pygame
import random
import math

pygame.init()


screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Kosmiczny statek")
icon = pygame.image.load("spaceship.png")
pygame.display.set_icon(icon)
background = pygame.image.load("background.png")


playerImg = pygame.image.load("player.png")
playerX = 370
playerY = 480
playerX_change = 0


enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6 

for i in range(num_of_enemies):
	enemyImg.append(pygame.image.load("enemy.png"))
	enemyX.append(random.randint(0, 736)) 
	enemyY.append(random.randint(50, 150))
	enemyX_change.append(-0.3)
	enemyY_change.append(40)


bulletImg = pygame.image.load("bullet.png")
bulletX = 0
bulletY = 480
bulletX_change = 0
bulletY_change = 10
bullet_state = "ready"

score = 0

def player(x, y):
	screen.blit(playerImg, (x, y))

def enemy(x, y, i):
	screen.blit(enemyImg[i], (x, y))

def fire_bullet(x, y):
	global bullet_state
	bullet_state = "fire"
	screen.blit(bulletImg,(x + 16, y + 10))

def isCollision(enemyX, enemyY, bulletX, bulletY):
	distance = math.sqrt((math.pow(enemyX - bulletX, 2)) + (math.pow(enemyY - bulletY, 2)))
	if distance < 27:
		return True
	else:
		return False




running = True
while running:
	screen.fill((0,0,0))
	screen.blit(background, (0,0))
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			running = False
		if event.type == pygame.KEYDOWN:
			if event.key == pygame.K_LEFT:
				playerX_change = -5
			if event.key == pygame.K_RIGHT:
				playerX_change = 5
			if event.key == pygame.K_SPACE:
				if bullet_state == "ready":
					bulletX = playerX
					fire_bullet(bulletX, bulletY)
		if event.type == pygame.KEYUP:
			if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
				playerX_change = 0

	playerX += playerX_change
	if playerX <= 0:
		playerX = 0
	elif playerX >= 736:
		playerX = 736

	for i in range(num_of_enemies):
		enemyX[i] += enemyX_change[i]
		if enemyX[i] <= 0:
			enemyX_change[i] = 1
			enemyY[i] += enemyY_change[i]
		elif enemyX[i] >= 736:
			enemyX_change[i] = -1
			enemyY[i] += enemyY_change[i]

		collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
		if collision:
			bulletY = 480
			bullet_state = "ready"
			score += 1
			print(score)
			enemyX[i] = random.randint(0, 736)
			enemyY[i] = random.randint(50, 150)
		enemy(enemyX[i], enemyY[i], i)

	if bulletY <= 0:
		bulletY = 480
		bullet_state = "ready"
	if bullet_state is "fire":
		fire_bullet(bulletX, bulletY)
		bulletY -= bulletY_change 
	collision = isCollision(enemyX, enemyY, bulletX, bulletY)
	if collision:
		bulletY = 480
		bullet_state = "ready"
		score += 1
		print(score)
		enemyX = random.randint(0, 735)
		enemyY = random.randint(50, 150)

	player(playerX, playerY)

	pygame.display.update()

 

1 odpowiedź

0 głosów
odpowiedź 30 maja 2020 przez adrian17 Ekspert (344,100 p.)
Tak jak błąd mówi - próbujesz odjąć enemyY (który jest listą) oraz bulletY (który jest liczbą).

Albo enemyY nie powinien byś listą, albo gdzieś zgubiłeś indeksowanie.
komentarz 30 maja 2020 przez adrian17 Ekspert (344,100 p.)

gra.py:79: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if bullet_state is "ready":
gra.py:114: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if bullet_state is "fire":

Tu swoją drogę też ma oczywiście rację.

komentarz 30 maja 2020 przez tonn204 Mądrala (7,440 p.)
Na pewno nić nie zgubiłem. Wszystko jest tak samo, a dalej nie działa.
komentarz 30 maja 2020 przez Nelson89 Dyskutant (7,720 p.)

Tutaj jest tak jak adrian17 napisał. Próbujesz wykonać operacje na liście i na liczbie. Z tego powodu masz błąd. Błąd wyskakuje Ci w linii 117, a w linii 101 wykonujesz taką samą operacje i ona już działa. A działa dlatego, że do funkcji isCollision wrzucasz wartości z list enemyX i enemyY, a nie listy.

komentarz 30 maja 2020 przez tonn204 Mądrala (7,440 p.)

Ok, teraz odejmuje na liczby, ale postacie pojawiają się tylko wtedy jak klikam jakiś klawisz, a graczem nie cięzko się rusz co z tym zrobić

 

import pygame
import random
import math

pygame.init()

# Create screen
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Kosmiczny statek")
icon = pygame.image.load("spaceship.png")
pygame.display.set_icon(icon)
background = pygame.image.load("background.png")

# Create player
playerImg = pygame.image.load("player.png")
playerX = 370
playerY = 480
playerX_change = 0

# Create enemy
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6

for i in range(num_of_enemies):
    enemyImg.append(pygame.image.load('enemy.png'))
    enemyX.append(random.randint(0, 736))
    enemyY.append(random.randint(50, 150))
    enemyX_change.append(4)
    enemyY_change.append(40)


bulletImg = pygame.image.load("bullet.png")
bulletX = 0
bulletY = 480
bulletX_change = 0
bulletY_change = 10
bullet_state = "ready"

score = 0

def player(x, y):
	screen.blit(playerImg, (x, y))

def enemy(x, y, i):
	screen.blit(enemyImg[i], (x, y))

def fire_bullet(x, y):
	global bullet_state
	bullet_state = "fire"
	screen.blit(bulletImg,(x + 16, y + 10))

def isCollision(enemyX, enemyY, bulletX, bulletY):
    distance = math.sqrt((math.pow(enemyX - bulletX, 2)) + (math.pow(enemyY - bulletY, 2)))
    if distance < 27:
        return True
    else:
        return False


# Main loop
running = True
while running:
	screen.fill((0,0,0))
	screen.blit(background, (0,0))
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			running = False
		if event.type == pygame.KEYDOWN:
			if event.key == pygame.K_LEFT:
				playerX_change = -5
			if event.key == pygame.K_RIGHT:
				playerX_change = 5
			if event.key == pygame.K_SPACE:
				if bullet_state == "ready":
					bulletX = playerX
					fire_bullet(bulletX, bulletY)
		if event.type == pygame.KEYUP:
			if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
				playerX_change = 0

		playerX += playerX_change
		if playerX <= 0:
			playerX = 0
		elif playerX >= 736:
			playerX = 736

		for i in range(num_of_enemies):
			enemyX[i] += enemyX_change[i]
			if enemyX[i] <= 0:
				enemyX_change[i] = 4
				enemyY[i] += enemyY_change[i]
			elif enemyX[i] >= 736:
				enemyX_change[i] = -4
				enemyY[i] += enemyY_change[i]

			

			collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
			
			if collision:
				bulletY = 480
				bullet_state = "ready"
				score += 1
				enemyX[i] = random.randint(0, 736)
				enemyY[i] = random.randint(50, 150) 

			enemy(enemyX[i], enemyY[i], i)

	if bulletY <= 0:
		bulletY = 480
		bullet_state = "ready"
	if bullet_state == "fire":
		fire_bullet(bulletX, bulletY)
		bulletY -= bulletY_change 

	player(playerX, playerY)

	pygame.display.update()

 

komentarz 31 maja 2020 przez Nelson89 Dyskutant (7,720 p.)

Kod uruchomiłem u siebie i też mnie zaczęło zastanawiać to, dlaczego jak przyciskam klawisz lub ruszam myszką to pojawiają się przeciwnicy.

Przyjrzyjmy się początkowi głównej pętli:

while running:
    screen.fill((0,0,0))
    screen.blit(background, (0,0))

Na początku każdej pętli czyścisz ekran. W kolejnym kroku w linii 69 sprawdzasz jakie eventy wystąpiły.

    for event in pygame.event.get():

Idąc dalej w w tej pętli sprawdzającej eventy od linii 91 do 111 wykonujesz operacje na "obiektach" enemy. Ustalając aktualną pozycje enemy w linii 111.

        for i in range(num_of_enemies):
            enemyX[i] += enemyX_change[i]
            if enemyX[i] <= 0:
                enemyX_change[i] = 4
                enemyY[i] += enemyY_change[i]
            elif enemyX[i] >= 736:
                enemyX_change[i] = -4
                 enemyY[i] += enemyY_change[i] 
 
            collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
             
            if collision:
                bulletY = 480
                bullet_state = "ready"
                score += 1
                enemyX[i] = random.randint(0, 736)
                enemyY[i] = random.randint(50, 150) 
 
            enemy(enemyX[i], enemyY[i], i)

Wniosek jest taki, że jeżeli nie masz żadnego eventu to ten blok nie zostanie wykonany. Ciekawy efekt można uzyskać wykonując np. dwa eventy (przyciśnięcie klawisza + ruszanie myszką) wtedy gra przyspiesza. Bo dla każdego eventu wykonywane jest przesunięcie przeciwników i pozycji gracza.

Blok (91-111) powinien znajdować się bezpośrednio w głównej pętli, a nie w pętli w której wykonujesz sprawdzenie eventów.

Pozdrawiam,

Nelson

komentarz 31 maja 2020 przez tonn204 Mądrala (7,440 p.)
Wow, dzięki wielkie napisz w odpowiedzi to dam naj. Jeszcze raz DZIĘKUJĘ!!!!
komentarz 1 czerwca 2020 przez adrian17 Ekspert (344,100 p.)
(to trochę dziwne, bo w kodzie który oryginalnie wrzuciłeś wcięcia były dobre?)
komentarz 3 czerwca 2020 przez Nelson89 Dyskutant (7,720 p.)
Tam rzeczywiście wcięcia były dobre.

Podobne pytania

0 głosów
0 odpowiedzi 54 wizyt
pytanie zadane 4 sierpnia 2023 w Python przez Kubas23 Użytkownik (630 p.)
0 głosów
0 odpowiedzi 264 wizyt
pytanie zadane 29 stycznia 2023 w Python przez Kubas23 Użytkownik (630 p.)
0 głosów
1 odpowiedź 407 wizyt
pytanie zadane 17 grudnia 2022 w Python przez Kubas23 Użytkownik (630 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...