Python Forum
why does the counter need to go to -50000 for this to work?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
why does the counter need to go to -50000 for this to work?
#1
I was trying to create an effect like the one on here the other day where there is a bunch of dots and they resolve to form a word (it was a question about edge detection.)

I have a moving_co_ord class, which has the start and end x and y co_ords, and an "in_place" boolean.

So I have an image, which is black text on white, saved as a png. I scan through the image and use the surfarray to find the black dots:

self.img_array = pygame.surfarray.array3d(self.img)
		self.img_co_ords = []
		
		for x in range(600):
			for y in range(80):
				if self.img_array[x][y][0] == 0 and self.img_array[x][y][1] == 0 and self.img_array[x][y][2] == 0:
Then I make x and y displacements and create two new co_ords, and find the size of the array:

xdist = random() * 50
					ydist = random() * 50
					#print "xdist = " + str(xdist)
					#print "ydist = " + str(ydist)
					
					xd = int(xdist)
					yd = int(ydist)
					#print "xd = " + str(xd)
					#print "yd = " + str(yd)
					
					if random() > 0.5:
						sx = x - xd
					else:
						sx = x + xd

					if random() > 0.5:
						sy = y + yd
					else:
						sy = y - yd
						
					self.img_co_ords.append(moving_co_ord(sx, sy, x, y))
self.done_count = len(self.img_co_ords)-1
In the update, I add or subtract one and set the in_place. I thought when the done_count reached zero it would be all done, but it doesn't work, and stops short. If I change the done count to -50000 it works. I have no idea where I am going wrong. Also, please note, this was just something I bashed together to see if I could make the effect work, so it is not meant to be an example of good coding.

Full Code:

import pygame
from pygame.locals import *
from random import random
import sys

pygame.init()
pygame.display.set_caption("Title Screen")
screen = pygame.display.set_mode((600, 400))

clock = pygame.time.Clock() 

class moving_co_ord:

	def __init__(self, sx, sy, ex, ey):
		
		self.sx = sx
		self.sy = sy
		self.ex = ex
		self.ey = ey
		self.in_place = False
	
class TitleScreen:

	def __init__(self):
		
		self.wait_time = 30
		self.img = pygame.image.load("scrambler.png")
		
		self.img_x = screen.get_width()/2 - 300 # 300 is half img width
		self.img_y = screen.get_height()/2 - 40  # 40 is half image height
		
		self.img_array = pygame.surfarray.array3d(self.img)
		self.img_co_ords = []
		
		for x in range(600):
			for y in range(80):
				if self.img_array[x][y][0] == 0 and self.img_array[x][y][1] == 0 and self.img_array[x][y][2] == 0:
					#print "x = " + str(x)
					#print "y = " + str(y)
					 
					xdist = random() * 50
					ydist = random() * 50
					#print "xdist = " + str(xdist)
					#print "ydist = " + str(ydist)
					
					xd = int(xdist)
					yd = int(ydist)
					#print "xd = " + str(xd)
					#print "yd = " + str(yd)
					
					if random() > 0.5:
						sx = x - xd
					else:
						sx = x + xd

					if random() > 0.5:
						sy = y + yd
					else:
						sy = y - yd
						
					self.img_co_ords.append(moving_co_ord(sx, sy, x, y))
		
		print "img_co_ords len = " + str(len(self.img_co_ords))
					
		self.done_count = len(self.img_co_ords)-1
				
	def update(self):
		done = False
		
		while not done:
			#print "self.done_count = " + str(self.done_count)
					
			for co_ord in self.img_co_ords:
				#print "co_ord.sx = " + str(co_ord.sx) + " co_ord.ex = " + str(co_ord.ex) 
				if not co_ord.in_place:
					if co_ord.sx > co_ord.ex:
						co_ord.sx -= 1
					elif co_ord.sx < co_ord.ex:
						co_ord.sx += 1
				
					if co_ord.sy > co_ord.ey:
						co_ord.sy -= 1
					elif co_ord.sy < co_ord.ey:
						co_ord.sy += 1
					 			
					if (co_ord.sy == co_ord.ey) and (co_ord.sx == co_ord.ex):
						co_ord.in_place == True
						#print "self.done_count = " + str(self.done_count)
						self.done_count -= 1
						#print "done count = " + str(self.done_count)
						if self.done_count%1000 == 0:
							self.wait_time -= 1
						if self.done_count == -50000:
							done = True
							break
			
			self.draw()		
	
	def get_key(self):
		done = False
		
		while not done:
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					done = True
				
				if event.type == pygame.KEYDOWN:
					if event.key == pygame.K_q:
						done = True
							
	def draw(self):
		screen.fill((0,0,0))
		print "wait time = " + str(self.wait_time)
		for co_ord in self.img_co_ords:
			pygame.draw.line(screen, (255,255,255), (self.img_x + co_ord.sx, self.img_y + co_ord.sy), (self.img_x + co_ord.sx+1, self.img_y + co_ord.sy))
		
		pygame.time.wait(self.wait_time)
		pygame.display.flip()
	
if __name__=="__main__":
	t = TitleScreen()
	t.update()
	t.get_key()
The image is attached.

Tia.

Attached Files

Thumbnail(s)
   
Reply
#2
Honestly, I'm not sure what self.done_count is even doing for you that isn't already incorporated into the code. The for loop itself should take care of the issue that self.done_count aims to do. What happens if you refactor to remove that? Or what happened before you added it?
Reply
#3
The done count is the count of moving_co_ord objects in the array. I need this so I know when all the moving_co_ords are in place and the title is done and can then switch to the high score screen.
Reply
#4
I don't believe you need all that for that function. This isn't tested (I don't have pygame), but it should accomplish the same task:

    def update(self):
        for co_ord in self.img_co_ords:
            #print "co_ord.sx = " + str(co_ord.sx) + " co_ord.ex = " + str(co_ord.ex) 
            if not co_ord.in_place:
                if co_ord.sx != co_ord.ex:
                    co_ord.sx += (co_ord.ex - co_ord.sx)

                if co_ord.sy != co_ord.ey:
                    co_ord.sy += (co_ord.ey - co_ord.sy)

                co_ord.in_place == True
         
        self.draw()
It's checking if the coordinates match. If they do not, it adds a value to the sx or sy attribute based on the difference between it and its associated partner. If the value is too high, this should add a negative to decrease it; if it is too low, this should add a position to raise it. With this logic, you should only require one pass through the list rendering the outer while loop, the done variable, and the done_count superfluous.

Give it a shot and see if it works.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020