• 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.

Fiszki IT
Fiszki IT
0 głosów
125 wizyt
pytanie zadane 30 maja 2020 w Python przez tonn204 Mądrala (6,660 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 (298,560 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 (298,560 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 (6,660 p.)
Na pewno nić nie zgubiłem. Wszystko jest tak samo, a dalej nie działa.
komentarz 30 maja 2020 przez Nelson89 Mądrala (5,520 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 (6,660 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 Mądrala (5,520 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 (6,660 p.)
Wow, dzięki wielkie napisz w odpowiedzi to dam naj. Jeszcze raz DZIĘKUJĘ!!!!
komentarz 1 czerwca 2020 przez adrian17 Ekspert (298,560 p.)
(to trochę dziwne, bo w kodzie który oryginalnie wrzuciłeś wcięcia były dobre?)
komentarz 3 czerwca 2020 przez Nelson89 Mądrala (5,520 p.)
Tam rzeczywiście wcięcia były dobre.

Podobne pytania

0 głosów
1 odpowiedź 324 wizyt
pytanie zadane 6 sierpnia 2019 w Python przez akinhet Nowicjusz (170 p.)
0 głosów
0 odpowiedzi 91 wizyt
pytanie zadane 2 lipca 2017 w Python przez DODO Bywalec (2,950 p.)
0 głosów
0 odpowiedzi 45 wizyt
pytanie zadane 23 marca 2020 w Python przez AdiReRe Nowicjusz (190 p.)
Porady nie od parady
Pytania na temat serwisu SPOJ należy zadawać z odpowiednią kategorią dotyczącą tej strony.SPOJ

84,836 zapytań

133,644 odpowiedzi

296,137 komentarzy

56,080 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...