Creating an old school amiga demo bitmap scroll in Python 3 and pygame 2
Back in the old days (1980:s) I did some demo coding on first the commodore 64 and later on an Amiga 500. I wouldn't say I was very good at it but I did manage to make some simple demos
One feature that was a "must have" in all Amiga demos was a "sprite scroller". A sprite scroller displays a moving, e g scrolling, text on the screen. But not with the standard font, it must have a special and very cool looking font which was often made in a paint program like Deluxe paint. The bitmap image was then cropped to the characters and displayed in the scroll.
Now, when I try to make my kids interested in coding, I was talking to them about text scrolls. It ended up with me trying to create a "sprite scroller" in Python.
Here is a screenshot of the result
If I recall correctly the way it was done on an Amiga was that I (or a friend) created a font bitmap containing all the characters needed for displaying the text message. The bitmap was then cropped into the different sprites and stored in memory.
So how can this be done in Pyhton? I will be using pygame but you can do this with pyglet as well.
First, we need to get a cool font bitmap. I found "Bitmap fonts" from Ian Hanschen: https://github.com/ianhan/BitmapFonts and I borrowed a few from him.
Now that we have our bitmap font I will create a class for the scroller.
#Class for sprite scroller class sprite_scroll: def __init__(self, filename, text, y_pos, start_pos, char_width, char_height, chars_line, charmap, speed=3): self.text = text #Scroll text self.speed = speed #speed of the scroll self.y_pos = y_pos #y position of the scroll self.x_pos = start_pos #Start x position of the scroll self.char_map = charmap #the order of the characters in the bitmap self.CHAR_W = char_width #width of the char in the bitmap self.CHAR_H = char_height #height of the char in the bitmap self.ROWS_PER_LINE = chars_line #number of chars per line in the bitmap self.font_image = pygame.image.load(filename).convert() self.font_image.set_colorkey((0,0,0)) # Black will not be blit. self.chars = {} #Crop font image and store all chars in an array for i in range(len(self.char_map)): #Crop 3chars one by one from the font image row=int(i/self.ROWS_PER_LINE) col=int(i-(self.ROWS_PER_LINE*row)) cropx,cropy = self.CHAR_W*col,self.CHAR_H*row cropped_region = (cropx, cropy, self.CHAR_W,self.CHAR_H) #Add cropped char to chars array self.chars[i]=self.font_image.subsurface(cropped_region) #Draw the scroll def draw(self): w=0 for character in self.text: w+=self.CHAR_W #Find the position of the char in the array index=self.char_map.find(character) #Draw it to the screen buffer canvas.blit(self.chars[index], (self.y_pos+w,self.x_pos)) #Set scroll position if self.y_pos+(len(self.text)*self.CHAR_W)<0: self.y_pos=SCREEN_W self.y_pos-=self.speed
Then it is only a matter of instanciating the scroller with the input parameters. The size of the chars in the bitmap and the order (charmap) is sometimes tricky to get right. If the bitmap only contains upper case letters then the text must also be upper case and vice versa.
Import pygame (install it with pip if you haven't already), create you program and add this to the progam.
scrolltext=" A very long scroll text. Lorem ipsum dolor sit amet consectetur adipiscing elit. Ut urna tellus varius eget nisl tristique ultrices mattis leo. Cras iaculis purus non posuere volutpat velit massa hendrerit felis eu dictum nisi enim a orci. Ut quis tincidunt nisl. Nulla aliquam euismod velit in interdum. ".upper() scroll_text=sprite_scroll("bennyfnt.png",scrolltext,SCREEN_W,SCREEN_H-100,32,32,10," !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZÖ",4) scroll_text2=sprite_scroll("carebearr.png"," A REALLY FAST SCROLL TEXT!!!! ",SCREEN_W,100,26,26,12," !\"_´@$'()*+#-.:0123456789abcdefgABCDEFGHIJKLMNOPQRSTUVWXYZ",12) scroll_text3=sprite_scroll("mdethfnt.png"," AND A REALLY SLOW SCROLL TEXT AS WELL!!!!! ",SCREEN_W,SCREEN_H/2,32,32,10," !\"ÅÄÖ#'()$+,-._0123456789:;<=>?%ABCDEFGHIJKLMNOPQRSTUVWXYZ",1)
In your pygame main loop add a call to the scroller's draw method
#main loop while run: for event in pygame.event.get(): if event.type == pygame.QUIT: run=False elif event.type == pygame.KEYDOWN: run = False #Clear screen canvas.fill((0,0,0)) scroll_text.draw() scroll_text2.draw() scroll_text3.draw() #Flip updates the whole screen pygame.display.flip() #Set FPS=60 clock.tick(60)
Comments
Post a Comment