Pixel index out of range - python

good afternoon, i would like to ask a question about this error i´m getting in my game. Im doing a simple game in pygame but i cant discover why i´m having this error. i will print the relevant code:
bottomX=-1000
bottomY=300
FishList = []
NumFish=0
while NumFish<20:
xfish=random.randrange(5,2550)
yfish=random.randrange(20,150)
IsInWater=(bottom.get_at([xFish+5,yFish+7])== (80,86,210,255))
if IsInWater:
FishList.append([xFish,yFish])
NumFish= NumFish + 1
for i in range(len(FishList)):
[xFish,yFish] = FishList[i]
mXp = random.randrange(-5,5) #Move in X
mYp = random.randrange(-5,6) #Move in y
FishStillInWater = (xFish+mXp+5>0 and xFish+mXp+5<3000 and yFish+mYp+7>10 and yFish+mYp+7 < 200 and (fundo.get_at([xFish+mXp+5,yFish+mYp+7])== (80,86,210,255)))
if FishStillInWater:
# If in water, moves
FishList[i][0] = xFish + mXp
FishList[i][1] = yGish + mYp
pygame.draw.rect(screen,red,[bottomX + FishList[i][0],300 + FishList[i][1],15,10],0)
for x in range(-7,7):
for y in range(-5,5):
FishDies=screen.get_at([bottomX + FishList[i][0]+x,300 + FishList[i][1]+y])==(0,0,0,255)# 0,0,0,255 is the color of the "bullets"
if FishDies:
yFish = 10000
points= points + 5
The error is:
FishDies=screen.get_at([bottomX + FishList[i][0]+x,300 + FishList[i][1]+y])==(0,0,0,255)
IndexError: pixel index out of range
Thx for your time guys, hope you can help me, if u need any thing else to understand the code tell me plz

Let's break it down a bit.
The error is saying, that you want to access a pixel, that is not on the surface. Here are your calculations:
The smallest possible fish coordinates are the following: (5,20), while the biggest are (2550,150).
You then want to check for the color of the pixel, but the fish might have moved off the screen, or only a part of it have moved.
I would recommend a normal collide_rect to check for collisions with bullets. There are many example on how to do this.

Related

Trying to get a loop to restart when using a shuffled array

Dear Stackoverflow fam,
I wish to run some experiments whereby I import some parameters for a stimulus (random dot kinematogram) and I chose to do this by creating a CSV with said parameters (total of 8 parameters I wish to cycle through). I need to pseudo-randomise the trials so I used the numpy.random.shuffle function to create this array. With this new array "shuffledRDK" i made the following loop
for b in range(2):
for fps in range(120):
blank_trial.draw()
mywin.flip()
time.sleep(6)
print("Trial: " +str(trial_counter) + " , Orientation " +str(shuffledRDK[x,0]) + " Coherence " +str(shuffledRDK[x,1]))
trial_counter += 1
if x in range (9):
x += 1
for fps in range(120):
SignalDots = visual.DotStim(win=mywin, color=(1, 1, 1), dir=(shuffledRDK[x-1,0]), coherence=(shuffledRDK[x-1,1]), fieldSize=(20,20), speed=1, dotSize=5, dotLife=3, nDots=50, fieldShape='circle')
SignalDots.draw()
mywin.flip()
My issue is that at the end of the 8th parameter I wish for the cycle to start again. I get IndexError: index 8 is out of bounds for axis 0 with size 8 which I understand is out of the boundaries of the array but I don't know how to restart it. I've tried putting in if x > 8 statements or similar lines but I still get the index error. Would someone be able to help me out please?
Many thanks in advance
You shouldn't have to increment x up each time; it will do it on it's own as it iterates through the loop. I suppose you are doing this because you want your x to start at 1 and end at 9? you can specify that range explicitly.
for b in range(2):
for fps in range(120):
blank_trial.draw()
mywin.flip()
time.sleep(6)
print("Trial: " +str(trial_counter) + " , Orientation " +str(shuffledRDK[x,0]) + " Coherence " +str(shuffledRDK[x,1]))
trial_counter += 1
if x in range (1, 9):
for fps in range(120):
SignalDots = visual.DotStim(win=mywin, color=(1, 1, 1), dir=(shuffledRDK[x-1,0]), coherence=(shuffledRDK[x-1,1]), fieldSize=(20,20), speed=1, dotSize=5, dotLife=3, nDots=50, fieldShape='circle')
SignalDots.draw()
mywin.flip()
here is a variant using the data.createFactorialTrialList() permutation method and a .yaml configuration file
i edited the for loops to my understanding, as i cannot deduct what you are trying to do completely
from psychopy import core, visual, event, data
from psychopy.iohub.client import launchHubServer
import yaml
io = launchHubServer()
display = io.devices.display
mywin = visual.Window([640, 480], units='pix')
factors_info = yaml.load(open('stim_factors.yaml'))
stim_permutation = data.createFactorialTrialList(factors_info)
trial_handler = data.TrialHandler(trialList = stim_permutation, method ='random', nReps = 1)
for b in range(1):
for fps in range(1):
for stim in trial_handler:
print(f'stim {trial_handler.thisN + 1:d}/{trial_handler.nTotal:d}')
signal_dots = visual.DotStim(win=mywin, color=(1, 1, 1),
dir = trial_handler.thisTrial['dir'],
coherence = trial_handler.thisTrial['coher'],
fieldSize = trial_handler.thisTrial['field_size'],
speed = trial_handler.thisTrial['speed'],
dotSize = trial_handler.thisTrial['dot_size'],
dotLife = trial_handler.thisTrial['dot_life'],
nDots = trial_handler.thisTrial['n_dots'],
fieldShape = 'circle')
signal_dots.draw()
mywin.flip(); event.waitKeys()
io.quit(); mywin.close()
core.quit()
you can see the contents of the .yaml file on the picture's left

Pygame Infinite World Generation Broken

So I'm making a basic 2D platformer game with the pygame module in python. Recently I've been trying to implement infinite world generation, but have been having some problems. The generation works fine, however, at the player's spawn, a bunch of random tiles spawn, obstructing the whole spawn area. I can't seem to find what's causing this.
Here's everything you need to replicate my situation:
map generation:
def generate_chunk(x,y):
chunk_data = []
for y_pos in range(CHUNK_SIZE):
for x_pos in range(CHUNK_SIZE):
target_x = x * CHUNK_SIZE + x_pos
target_y = y * CHUNK_SIZE + y_pos
tile_type = 0 # nothing
if target_y > 10:
tile_type = 2 # dirt
elif target_y == 10:
tile_type = 1 # grass
elif target_y < 10:
tile_type = 0
if tile_type != 0:
chunk_data.append([[target_x,target_y],tile_type])
return chunk_data
...
while True:
...
tile_rects = []
for y in range(3):
for x in range(4):
target_x = x - 1 + int(round(scroll[0]/(CHUNK_SIZE*16)))
target_y = y - 1 + int(round(scroll[1]/(CHUNK_SIZE*16)))
target_chunk = str(target_x) + ';' + str(target_y)
if target_chunk not in game_map:
game_map[target_chunk] = generate_chunk(target_x,target_y)
for tile in game_map[target_chunk]:
display.blit(tile_index[tile[1]],(tile[0][0]*16-scroll[0],tile[0][1]*16-scroll[1]))
if tile[1] in [1,2]:
tile_rects.append(pygame.Rect(tile[0][0]*16,tile[0][1]*16,16,16))
full code:
https://github.com/nice-404/Platformer
I can't seem to figure out what is causing the random tile spawning.
(I have been following DaFluffyPotato's platformer tutorial series because I am new to pygame)
After 2 weeks of debugging and further looking into the chunk generating code, I couldn't find out anything. However, I did figure out that the issue only happened in a small area, at the 0 x value. So what I did was I made the player spawn very far away from this, and made a boundary so that it couldn't walk far enough to see the issue. Not really fixing the issue, but at least it works now.

Python turtle: How can I make the turtle go to a point in a list of points after it goes through the list

For example, point 1 connects to point 9, then point 2 connects to point 10 and so on for len(pointList).
I am currently stuck because once the turtle attempts to access the 32nd point, it gets an out of bounds error because the point it would need to connect to is point 0 but it wont do so with my current code.
Each point will need to connect to the 9th point ahead of it for the length of the list (40 in this case because of the text file line amount)
I am hinted to use % operator, but I do not know how I would use it.
code
from turtle import *
speed(10)
fileName = input("What is the name of the file? ")
file = open(fileName, 'r', encoding='UTF-8')
pointList = []
penup()
for line in file:
lineTokens = line.split()
x = float(lineTokens[0])
y = float(lineTokens[1])
point = (x,y)
pointList.append(point)
def drawPoints():
for point in pointList:
goto(point)
dot(5, "black")
drawPoints()
i = 0
for point in range(len(pointList)):
print(point)
pencolor("red")
goto(pointList[i])
down()
goto(pointList[i + 9])
up()
i += 1
Text file I am reading from to collect points (if needed)
31.286893008046174 -197.53766811902756
61.80339887498949 -190.21130325903073
90.79809994790936 -178.20130483767358
117.55705045849463 -161.80339887498948
141.4213562373095 -141.4213562373095
161.80339887498948 -117.55705045849463
178.20130483767355 -90.79809994790936
190.21130325903067 -61.803398874989504
197.5376681190275 -31.286893008046214
199.99999999999994 -6.394884621840902e-14
197.5376681190275 31.286893008046086
190.21130325903067 61.80339887498938
178.20130483767352 90.79809994790924
161.80339887498945 117.55705045849447
141.42135623730948 141.42135623730934
117.55705045849464 161.8033988749893
90.7980999479094 178.20130483767338
61.80339887498957 190.2113032590305
31.28689300804629 197.5376681190273
1.5987211554602254e-13 199.99999999999974
-31.286893008045972 197.5376681190273
-61.80339887498924 190.21130325903047
-90.79809994790908 178.20130483767332
-117.55705045849432 161.80339887498926
-141.42135623730914 141.42135623730928
-161.80339887498906 117.55705045849444
-178.20130483767312 90.79809994790921
-190.21130325903022 61.80339887498938
-197.53766811902702 31.286893008046114
-199.99999999999946 -5.329070518200751e-15
-197.53766811902702 -31.286893008046125
-190.2113032590302 -61.803398874989384
-178.20130483767304 -90.7980999479092
-161.80339887498897 -117.5570504584944
-141.421356237309 -141.42135623730923
-117.55705045849416 -161.80339887498914
-90.79809994790895 -178.20130483767318
-61.80339887498913 -190.21130325903027
-31.286893008045876 -197.53766811902707
2.327027459614328e-13 -199.99999999999952
You can use the following code:
goto(pointList[(i + 9)%len(pointList)])
What this does is get a zero if the expression i + 9 evaluates to len(pointList)
Another less elegant solution is:
if i + 9 < len(pointList):
goto(pointList[i + 9])
else:
goto(pointList[0])

Can't assign set to variable python

Hi I was wondering if this was possible at all, since I tried it but my variable was always empty. In my project, I'm tracking a static object and a laser pointer via a PiCamera on my raspberry pi, and I calculate the centroids of their contours as (smallx,smally) and (small2x,small2y) respectively.
I use the difference between their coordinates to see if the pointer should go up, down, left, or right in order to meet the 1st static object. After that, it'll choose a direction betweeen 1 through 4 to move, because my direction controls aren't perfectly on an x-y axis and are slanted.
I left the controls and the contour finding out from here and shortened my total code just so that you wouldn't be met with a giant pile of slop to sort through.
EDIT: I' don't think with my understanding I could provide something runnable without posting a couple hundred lines and my little device, but I'll boil it down and post the exact portion of my code where this is relevant. Running Python 2.7.3, using opencv2.4.10
Code:
#import libraries like picamera and opencv
#set empty variables like:
up = down = left = right = set()
smallx = smally = small2x = small2y = 0
#etc etc
with picamera.PiCamera() as camera:
with picamera.array.PiRGBArray(camera) as rawCapture:
#Calibrate my controls with the camera. updates the up, down, left, and right sets.
with picamera.PiCamera() as camera:
with picamera.array.PiRGBArray(camera) as rawCapture:
# Take pictures, threshold them, find contours, append their arrays to list
if len(cnts)>0: #If any objects were identified
contm = sorted(smalList, key=lambda tup: tup[1])
smallest = cnts[smalList[0][0]] #**Take smallest object(my static object)**
smallM = cv2.moments(smallest)
smallx = int(smallM['m10']/smallM['m00']) #**Calculate xcoord**
smally = int(smallM['m01']/smallM['m00']) #**Calculate ycoord**
cv2.line(frame, (smallx,smally), (smallx,smally), 1, 8,0) #Draws centroid
# print(len(cnts))
if len(cnts)==2: #If only 2 objects were identified
smallester = cnts[smalList[1][0]] #** Take pointer object **
small2 = cv2.moments(smallester)
small2x = int(small2['m10']/small2['m00']) #**Calculate xcoord**
small2y = int(small2['m01']/small2['m00']) #**Calculate ycoord**
x = small2x - smallx
y = small2y - smally
print x #These prints return a value
print y
if x < 0: #Difference = Pointer - Object
s1 = right
if x >0:
s1 = left
if y < 0:
s2 = down
if y >0:
s2 = up
print s1, s2 #set([]),set([])
print up,down,left,right #set([1,2]),set([3,4]),set([1,4]),set([2,3])
selecty = s1&s2 #set([])
#Tell the pointer where to go
Should I even be using sets?
Use s1 = s2 = set() instead of = 0.
As for your second question, there are probably better and more known ways to go around your problem. For example, using bit logic:
right = 1
up = 2
left = 4
down = 8
select = 0
if (small2x - smallx) < 0:
select |= right
if (small2x - smallx) >0:
select |= left
if (small2y - smally) < 0:
select |= down
if (small2y - smally) >0:
select |= up
print(select)
print("You chose %s%s%s%s" %("UP " if select & up else "",
"DOWN " if select & down else "",
"LEFT " if select & left else "",
"RIGHT" if select & right else ""))
#Do things after

I have made a Pygame program but when the sprites overlap it has a white outline on some of them

I am making a level editor for a game I am working on. I have it set up so that you can put a picture in a folder and it will split it from a 90x90 pix block to 9 30x30 pix blocks that can be used in the editor. The code that makes the 30x30 blocks looks like this:
one = Image.new('RGBA',(30,30),(255,255,255,0))
two = Image.new('RGBA',(30,30),(255,255,255,0))
three = Image.new('RGBA',(30,30),(255,255,2550,0))
four = Image.new('RGBA',(30,30),(255,255,255,0))
five = Image.new('RGBA',(30,30),(255,255,255,0))
six = Image.new('RGBA',(30,30),(255,255,2550,0))
seven = Image.new('RGBA',(30,30),(255,255,2550,0))
eight = Image.new('RGBA',(30,30),(255,255,255,0))
nine = Image.new('RGBA',(30,30),(255,255,255,0))
for y in range(1,iy):
print ((y/9)*10),"%"
for x in range(1,ix):
pixel = im.getpixel((x,y))
if y<30:
if x<30:
one.putpixel((x,y),pixel)
elif x<60:
four.putpixel((x-30,y),pixel)
else:
seven.putpixel((x-60,y),pixel)
elif y <60:
if x <30:
two.putpixel((x,y-30),pixel)
elif x <60:
five.putpixel((x-30,y-30),pixel)
else:
eight.putpixel((x-60,y-30),pixel)
else:
if x < 30:
three.putpixel((x,y-60),pixel)
elif x < 60:
six.putpixel((x-30,y-60),pixel)
else:
nine.putpixel((x-60,y-60),pixel)
add = [im,one,two,three,four,five,six,seven,eight,nine]
bdict[s]= add
cd = os.getcwd()+'\\'+s +'\\'
one.save(cd + s +'one.png')
two.save(cd+s+'two.png')
three.save(cd+s+'three.png')
four.save(cd+s+'four.png')
five.save(cd+s+'five.png')
six.save(cd+s+'six.png')
seven.save(cd+s+'seven.png')
eight.save(cd+s+'eight.png')
nine.save(cd+s+'nine.png')
im.save(cd + fol)
im = os.getcwd()+'\\'+fol
one = os.getcwd()+'\\'+s+'one.png'
two =os.getcwd()+'\\'+s+'two.png'
three =os.getcwd()+'\\'+s+'three.png'
four = os.getcwd()+'\\'+s+'four.png'
five =os.getcwd()+'\\'+s+'five.png'
six =os.getcwd()+'\\'+s+'six.png'
seven =os.getcwd()+'\\'+s+'seven.png'
eight =os.getcwd()+'\\'+s+'eight.png'
nine =os.getcwd()+'\\'+s+'nine.png'
add = [im,one,two,three,four,five,six,seven,eight,nine]
bdict[s]= add
maxes[0]+=1
when two blocks overlap, they have this strange white bar that only shows up around the top left and right blocks and the bottom left and right blocks. That looks like this:
The only other place that might have the error is where the code loads the sprites, here:
grounds is an array containing the different rectangles while gsprites is an array containing the different sprites in the format that they are loaded by Pygame.
for number in range(0,len(grounds)):
cr = grounds[number]
cr.left += xscroll
cr.top += yscroll
pygame.draw.rect(windowsurface,clear,cr)
change = pygame.transform.scale(gsprites[number],(30,30))
windowsurface.blit(gsprites[number],cr)
cr.left -= xscroll
cr.top -= yscroll
I am running windows vista 32 bit.
Never mind, I figured it out. I was drawing a rect before I blitted the sprite, and it ended up showing up under the sprite.

Categories