я новичок во всем этом, и я пытаюсь сделать стрелялку. после того, как я попытаюсь запустить код, я сталкиваюсь с ошибкой TypeError: 'int' object is not subscriptable
по адресу:
строка 269:
collision = isCollision(enemyX[i],enemyY[i],knifeX,knifeY)
строка 118:
distance = math.sqrt((math.pow(enemyX[i] - knifeX,2)) + (math.pow(enemyY[i] - knifeY,2)))
не только здесь, но почти везде в петле, если я поставлю на нее «i»
import pygame
from pygame import mixer
mixer.init()
import random
import math
#Define some colors
BLACK = (0,0,0)
WHITE = (255,255,255)
#intialize the pygame
pygame.init()
#create the screen
screen = pygame.display.set_mode((700,583))
#Caption and icon
pygame.display.set_caption("Yoshi & the rise of mushroom ")
icon = pygame.image.load("Yoshi_icon.png")
pygame.display.set_icon(icon)
#Player
playerImg = pygame.image.load("YoshiMario.png")
playerX = 370
playerY = 480
playerX_change = 0
playerY_change = 0
#Enemy
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 10
for i in range(num_of_enemies):
enemyImg.append(pygame.image.load('msh1.png'))
enemyImg.append(pygame.image.load('msh2.png'))
enemyX.append(random.randint(0,583))
enemyY.append(random.randint(50,150))
enemyX_change.append(2)
enemyY_change.append(20)
#Knife
# ready - you cant see the knife on the screen
# fire - the knife is currently moving
knifeImg = pygame.image.load('diamondsword3.png')
knifeX = 0
knifeY = 480
knifeX_change = 0
knifeY_change = 10
knife_state = "ready"
#Score
score_value = 0
font = pygame.font.Font('freesansbold.ttf',28)
testX = 10
testY = 10
#Game Over Text
over_font = pygame.font.Font('freesansbold.ttf',64)
def show_score(x,y):
score = font.render("Score : "+ str(score_value),True,(255,255,255))
screen.blit(score, (x, y))
def game_over_text():
over_text = over_font.render("GAME OVER",True,(255,255,255))
screen.blit(over_text, (150, 250))
def player(x,y):
screen.blit(playerImg, (x, y))
def enemy(x,y,i):
screen.blit(enemyImg[i], (x, y))
def fire_knife( x, y ):
""" Start a knife flying upwards from the player """
global knife_state, knifeX, knifeY
knifeX = x + 16
knifeY = y + 10
knife_state = "fire"
def knife_hits( enemyX, enemyY ):
""" Return True if the knife hits the enemy at the given (x,y).
If so, prepare the knife for firing again. """
global knife_state, knifeX, knifeY
collision_result = False
if ( knife_state == "fire" and isCollision( enemyX[i], enemyY[i], knifeX, knifeY ) ):
knife_state = "ready"
collision_result = True
return collision_result
def draw_knife( screen ):
""" If the knife is flying, draw it to the screen """
global knife_state, knifeImg, knifeX, knifeY
if ( knife_state == "fire" ):
screen.blit( knifeImg, ( knifeX, knifeY ) )
def update_knife():
""" Make any knife fly up the screen, resetting at the top """
global knife_state, knifeX, knifeY, knifeY_change
# if the knife is already flying, move it
if ( knife_state == "fire" ):
knifeY -= knifeY_change
if ( knifeY <= 0 ):
knife_state = "ready" # went off-screen
def isCollision(enemyX,enemyY,knifeX,knifeY):
distance = math.sqrt((math.pow(enemyX[i] - knifeX,2)) + (math.pow(enemyY[i] - knifeY,2)))
if distance < 27:
return True
else:
return False
#used to manage how fast the screen updates
clock = pygame.time.Clock()
font = pygame.font.Font(None,28)
frame_count = 0
frame_rate = 60
start_time = 90
#game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#if keystroke is pressed check whether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -2
if event.key == pygame.K_RIGHT:
playerX_change = 2
if event.key == pygame.K_UP:
playerY_change = -2
if event.key == pygame.K_DOWN:
playerY_change = 2
if event.key == pygame.K_SPACE:
if knife_state is "ready":
knife_Sound = mixer.Sound("knife_hitwall1.wav")
knife_Sound.play()
# get the current x coordinate of yoshi
knifeX = playerX
fire_knife(playerX,playerY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
playerY_change = 0
## -- Timer going up --
#Calculate total seconds
total_seconds = frame_count // frame_rate
#divide by 60 to get total minures
minutes = total_seconds // 60
#use modulus (remainder) to get seconds
seconds = total_seconds % 60
#use python string formatting to format in leading zeros
output_string = "Time : {0:02}:{1:02}".format(minutes, seconds)
# Blit to the screen
text = font.render(output_string, True, (255,255,255))
screen.blit(text, [10,40])
# --- Timer going down ---
# --- Timer going up ---
# Calculate total seconds
total_seconds = start_time - (frame_count // frame_rate)
if total_seconds < 0:
total_seconds = 0
# Divide by 60 to get total minutes
minutes = total_seconds // 60
# Use modulus (remainder) to get seconds
seconds = total_seconds % 60
# Use python string formatting to format in leading zeros
output_string = "Time left: {0:02}:{1:02}".format(minutes, seconds)
# Blit to the screen
text = font.render(output_string, True,(255,255,255))
screen.blit(text, [10,70])
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
frame_count += 1
# Limit frames per second
clock.tick(frame_rate)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# RGB - Red, Green, Blue
screen.fill((0, 255, 0))
#add a wallpaper
bgimage=pygame.image.load("Background.png")
screen.blit(bgimage, (0, 0))
# 5 = 5 + -0.1 ->5 = 5 - 0.1
# 5 = 5 + 0.1
# checking for boundaries of yoshi/mushroom so it doesnt go out of bounds
playerX += playerX_change
if playerX < 0:
playerX = 0
elif playerX > 645:
playerX = 645
playerY += playerY_change
if playerY < 0:
playerY = 0
elif playerY > 500:
playerY = 500
# enemy movement
for i in range(num_of_enemies):
#Game Over
if enemyY[i]> 440:
for j in range(num_of_enemies):
enemyY[j] = 2000
game_over_text()
break
enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = 2
enemyY[i] += enemyY_change[i]
elif enemyX[i] > 645:
enemyX_change[i] = -2
enemyY[i] += enemyY_change[i]
update_knife() # move the flying knife (if any)
if ( knife_hits( enemyX[i], enemyY[i] ) ):
score_value += 1
print(score_value)
enemyX[i] = random.randint(0,735)
enemyY[i] = random.randint(50,150)
else:
draw_knife( screen ) # paint the flying knife (if any)
player(playerX,playerY)
enemy(enemyX[i],enemyY[i],i)
pygame.display.update()
# collision
collision = isCollision(enemyX[i],enemyY[i],knifeX,knifeY)
if collision:
pop_Sound = mixer.Sound('pop.wav')
pop_Sound.play()
knifeY = 480
knife_state = "ready"
score_value += 1
enemyX[i] = random.randint(0,735)
enemyY[i] = random.randint(50,150)
enemy(enemyX[i],enemyY[i],i)
# knife movement
if knifeY <= 0:
knifeY = 480
knife_state = "ready"
if knife_state == "fire":
fire_knife(knifeX,knifeY)
knifeY -= knifeY_change
playerX += playerX_change
playerY += playerY_change
player(playerX,playerY)
show_score(testX,testY)
pygame.display.update()
Я считаю, что несколько операторов печати для проверки переменных с такими проблемами часто помогают понять, что происходит.
Вы звоните isCollision()
с помощью enemyX[i]
, но затем в isCollision
пытаетесь получить доступ к enemyX[i]
. Итак, вы пытаетесь сделать enemyX[i][i]
. Но поскольку enemyX[i]
является целым числом, попытка получить его индекс [i]
недействительна, поэтому вы получаете эту ошибку.
Вы делаете подписку, когда вызываете функцию isCollision
:
if ( knife_state == "fire" and isCollision( enemyX[i], enemyY[i], knifeX, knifeY ) ):
Следовательно, вы должны удалить подписку в функции:
distance = math.sqrt((math.pow(enemyX[i] - knifeX,2)) + (math.pow(enemyY[i] - knifeY,2)))
def isCollision(enemyX,enemyY,knifeX,knifeY):
distance = math.sqrt((math.pow(enemyX - knifeX,2)) + (math.pow(enemyY - knifeY,2)))
if distance < 27:
return True
else:
return False
сделал как ты сказал. мое размещение «i» удваивается в цикле for, потому что я вызвал его извне, а также поместил его внутри. поэтому я в значительной степени пытаюсь и ошибаюсь, чтобы увидеть, что в порядке. Спасибо
Вы уже отправляете конкретный номер, например. enemyX[i]
когда вы звоните isCollision(enemyX[i], ...)
. Оказавшись в этой функции, вы можете просто использовать переданный аргумент (который вы также вызываете enemyX
- он просто отличается от вызывающего enemyX
) сам по себе, например. math.pow(enemyX -...
. Я рекомендую пересмотреть эти имена переменных.
проверьте типы этих переменных, они, вероятно,
int
s и, следовательно, не могут быть подписаны